Tree Data Model

Overview

The tree data model represents data as a hierarchical tree-like structure with data items connected by parent-child relationships.

It is used in the following chart types:

This article explains how to set tree-like data, access data items, and perform data operations: see the Setting Data, Accessing Items, and Data Manipulation sections.

Setting Data

Tree data structures in Anychart are defined as instances of the anychart.data.Tree class, and data items are defined as instances of anychart.data.Tree.DataItem.

To create a chart based on tree-like data, you should organize your data either as a tree or as a table. Then it is processed by the component, and an instance of anychart.data.Tree is created – see the subsections below for detailed explanation.

As Tree

If your data is organized as a tree, pass it to the anychart.data.tree() method with "as-tree" as the second parameter. Then pass the instance of the anychart.data.Tree class created by this method to the chart constructor.

You can as well skip the first step and pass your data to the data() method of the chart or directly to the chart constructor, also with the as-tree parameter. In this case the instance of anychart.data.tree() is created implicitly.

The choice of data fields depends on the chart type. But children is always required – it is used to specify the hierarchy of elements:

// create data
var data = [
  {name:     "Root", children: [
    {name:   "Parent 1", children: [
      {name: "Child 1-1", value: 150000000},
      {name: "Child 1-2", value:  45000000},
      {name: "Child 1-3", value:   3200000}
    ]},
    {name:   "Parent 2", children: [
      {name: "Child 2-1", value:  55000000},
      {name: "Child 2-2", value:  10600000},
      {name: "Child 2-3", value:   5200000}
    ]},
    {name:   "Parent 3", children: [
      {name: "Child 3-1", value:  21000000},
      {name: "Child 3-2", value:   9000000}
    ]}  
  ]} 
];

// create a storage for the data tree
treeData = anychart.data.tree(data, "as-tree");

// create a chart and set the data
var chart = anychart.treeMap(treeData);

Playground

As Table

If your data is organized as a table, pass it to the anychart.data.tree() method with "as-table" as the second parameter. Then pass the instance of the anychart.data.Tree class created by this method to the chart constructor.

You can as well skip the first step and pass your data to the data() method of the chart or directly to the chart constructor, also with the as-table parameter. In this case the instance of anychart.data.tree() is created implicitly.

The choice of data fields depends on the chart type. But id and parent are always required – they are used to specify the hierarchy of elements:

// create data
var data = [
  {id:  1, parent: null, name: "Root"},
  {id:  2, parent:    1, name: "Parent 1"},
  {id:  3, parent:    2, name: "Child 1-1", value: 150000000},
  {id:  4, parent:    2, name: "Child 1-2", value:  45000000},
  {id:  5, parent:    2, name: "Child 1-3", value:   3200000},
  {id:  6, parent:    1, name: "Parent 2"},
  {id:  7, parent:    6, name: "Child 2-1", value:  55000000},
  {id:  8, parent:    6, name: "Child 2-2", value:  10600000},
  {id:  9, parent:    6, name: "Child 2-3", value:   5200000},
  {id: 10, parent:    1, name: "Parent 3"},
  {id: 11, parent:   10, name: "Child 3-1", value:  21000000},
  {id: 12, parent:   10, name: "Child 3-2", value:   9000000}
];
// create a storage for the data tree
treeData = anychart.data.tree(data, "as-table");

// create a chart and set the data
var chart = anychart.treeMap(treeData);

Playground

Accessing Items

Data items in AnyChart are defined as instances of the anychart.data.Tree.DataItem class. If you need to access them, you can either search for them or call special methods.

To access items at the root level, use the following methods of anychart.data.Tree:

To go deeper, use the methods of anychart.data.Tree.DataItem:

For example, that is how you get the sixth child of the third child of the first root item:

treeData.getChildAt(0).getChildAt(2).getChildAt(5);

Manipulating data very often requires accessing data items, so the methods listed above are used in most samples in the Data Manipulation section.

Data Manipulation

You can perform the following data operations (including CRUD):

Note: Operations with non-tree data are described in the Data Manipulation article.

Reading

You can read the value of an item's data field with a given name: access the instance of anychart.data.Tree.DataItem and use the get() method.

In the sample below, this method is used to display the name of the last child in the title of the chart:

// get the name of the last child
var lastChild = treeData.getChildAt(0).getChildren().length - 1;
var lastChildName = treeData.getChildAt(0).getChildAt(lastChild).get("name");

Playground

Adding

You can add a root item to your data: call the addChild() or addChildAt() method on the instance of anychart.data.Tree. Please note that the second method adds an item with a given index.

To add a child element to a data item, access the instance of anychart.data.Tree.DataItem and call addChild() or addChildAt() on it:

var itemCount = 1;

// add a new data item
function addItem(){
  var name = "New Child " + itemCount++;
  treeData.getChildAt(0).addChild({"name": name, "value": 10000000});
};

Playground

You can also add several root items at once: use the addData() method.

Note: Only one root element can be displayed on the Treemap chart, so using this method does not change the way the Treemap looks, though the data is updated anyway.

Here is a Sunburst chart with a button adding two root nodes at a time:

var itemCount = 1;

// add new data
function addItems(){
  //create new data
  var name_1 = "New Node " + itemCount++;
  var name_2 = "New Node " + itemCount++;
  var newData = [
    {"name": name_1, "value": 10000000},
    {"name": name_2, "value": 10000000}
  ];
  // add new data
  treeData.addData(newData, "as-tree");
};

Playground

Updating

To update a data field of an item, access the instance of anychart.data.Tree.DataItem and call set(). Use the name of the field and a new value as parameters:

// update the first child
function updateItem(){
  var name = document.getElementById("inputName").value;
  var value = document.getElementById("inputValue").value;
  var color = document.getElementById("inputColor").value;
  treeData.getChildAt(0).getChildAt(0).set("name", name);
  treeData.getChildAt(0).getChildAt(0).set("value", value);
  treeData.getChildAt(0).getChildAt(0).set("fill", color);
};

Playground

Removing

To remove root items from your data, call one of the following methods on the instance of anychart.data.Tree:

To remove a child of a data item, access the instance of anychart.data.Tree.DataItem and call one of these methods:

In this sample the current last child of the root item is removed each time you press the button:

var lastChild = treeData.getChildAt(0).getChildren().length - 1;
treeData.getChildAt(0).removeChildAt(lastChild);

Playground

Searching

To search for an item, use the search() and searchItems() methods of the anychart.data.Tree.DataItem class. Please note that searchItems(), unlike search(), always returns an array, which is the only difference between them.

These methods accept three parameters: the name of a data field, a value, and a comparison function. The function is optional: you can just search for an item with a given value in a given data field.

The following sample shows how to perform a search with the searchItems() method and a comparison function – it is used to find items with values greater than a given number. The names of these items are displayed in the title of the chart, and the fill color of their nodes is changed:

// a comparison function
function comparisonFunction(fieldValue, comparisonValue) {
  if (comparisonValue > fieldValue)
    return true;
  else
    return false;
};

// search items with values greater than a given one
function searchValues(){

  // search items
  var inputValue = (document.getElementById("inputValue").value) * 1000000;
  var items = treeData.searchItems("value", inputValue, comparisonFunction);

  /* get the names of the found items, add them to a string variable,
  and set the fill colors of their nodes */
  var text = "";
  for (var i = 0; i < items.length; i++) {
    text += items[i].get("name") + ", ";
    items[i].set("fill", "#00bfa5");
  };
  if (items.length == 0)
    text = "(none)";

  // update the chart title
  chart.title("Tree Data Model: Searching<br><br>" +
              "<span style = 'color:#990000'>" +
              text.substr(0, text.length - 2) + "</span>");
};

Playground

In the next sample search(), combined with the drillTo method of the Treemap, is used to find an item with a certain name and drill down to it:

/* locate an item in the data tree
and get it as an object */
var item = treeData.search("name", "Item 3-4");

// drill down to the item
chart.drillTo(item);

Playground

Traversing

Traversing is a process of going through all the items of a tree. You can access them directly, but AnyChart offers an easier and faster out-of-the-box solution.

To perform a traversal, use the getTraverser() method to obtain the anychart.data.Traverser object. Then call its methods:

  • advance() – advances the traverser to the next data item
  • current() – returns the current item
  • get() – returns the current item's value in a given data field
  • getDepth() – returns the depth of the current item
  • meta() – sets/gets the meta value of the current item
  • nodeYieldCondition() – sets/gets a function that determines whether an item is returned
  • set() – sets the value of the current item in a given data field
  • reset() – resets the traverser to its default position before the first item
  • toArray() – returns the current traverser as an array of data items
  • traverseChildrenCondition() – sets/gets a function that determines whether the traverser goes through the children of an item

In the sample below the advance() and get() methods are used to display the names of all the data items:

// get the traverser of a tree
var traverser = treeData.getTraverser();

/* get the element displaying
the information about the tree */
var treeInfo = document.getElementById("treeInfo");

// display the names of all data items in the tree
while (traverser.advance()) {
  var newElement = document.createElement("li");
  newElement.innerText = traverser.get("name");
  treeInfo.appendChild(newElement);
};

Playground

In the next sample advance() and current(), combined with the drillTo method of the Treemap, are used to drill down through all the nodes of the chart. The reset() method allows starting the traversal again when it is finished.

// get the traverser of a tree
traverser = treeData.getTraverser();

// skip the root node
traverser.advance();

// get the next data item and drill to it
function nextItem() {
  // try to go to the next item
  if (traverser.advance()) {
    /* get the current item
    as an instance of the dataItem class */
    var dataItem = traverser.current();
    // drill down to the item
    chart.drillTo(dataItem);
  }
  else {
    //reset the traverser
    traverser.reset();
  }
};

Playground