Data Tree

Download Download from Github

Data Tree

Download Download from Github

DataTree is a highly customisable, JavaScript- and jQuery-powered tree visualisation tool. Data can be in XML or JSON format, fed directly (as a string) or fetched from a web service, and can be lazy-loaded as a user delves deeper into the tree.

DataTree has a dependency on jQuery 2.x.

All manner of callbacks are supported, and deep-linking and cross-page-transition state retention is also possible, among other features. Styling is handled by the accompanying CSS file.

Examples 🔗

Example 1: A simple tree, loaded into the element with ID "container", with the (XML) data to be retrieved from a filepath.

new DataTree({ fpath: 'some/path/xml.xml', container: '#tree' });

Example 2: A tree where data is lazy-loaded from an XML-based web service, via sub-tree requests, as the user traverses. The web service is told initially to load root-level data and then, as the user traverses the tree, is told by the sub-tree request callback to load data pertaining to the clicked branch.

new DataTree({ fpath: 'web_service.php?level=root', container: '#tree', subTreeBranches: true, subTreeRequest: li => 'web_service.php?id=''id'), attrsAsData: 1 });


Constructor 🔗

DataTree is initiated by instantiating the DataTree() constructor, which accepts a single object of params, including:

  • container (string) - a jQuery selector string targeting the container element you want to insert the tree into.
  • fpath (string) - a path to an XML or JSON file, or a web service that outputs XML or JSON. This is not necessary if feeding the data manually via the xml param.
  • xml (string) - instead of referencing an XML file, you can pass a literal XML string into this argument.
  • json (string/bool/object) - denotes that you're using JSON data, not XML. This should be:
    • A boolean, if you're loading data over a web service (via fpath), which tells DataTree to conver the JSON response to XML before output
    • A literal JSON string or JavaScript object from which to generate the tree - the JSON equivalent to xml
  • jsonp (bool) - pass true if you are loading your data over JSON-P rather than locally
  • startExpanded (bool) - whether the tree should be fully expanded when the page loads. Default is false. Cannot be used in conjunction with web service-derived data, or if you are stipulating a specific open path via openAtPath.
  • renderCallback (function) - a callback function to act on or interrogate the resultant tree HTML. It is automatically passed a jQuery reference to the tree ul as its only argument.
  • XMLCallback (function) - a callback function to act on or interrogate the XML data before it is transformed into HTML.
  • cache (bool) - used with fpath; controls whether to allow caching on the root-level data request. Default is true.
  • noSubTreeCache - used with fpath and sub-trees. If true, sub-tree request responses will be cached and not re-fetched from the server should the same sub-tree request be triggered again later. Default is false.
  • plusMinCallback (function) - a callback function to be invoked when a user clicks the plus/minus link next to a node, i.e. expands or collapses it. Your callback function will automatically be passed 4 arguments:
    • li (jQuery object) - a jQuery reference to the node li.
    • XPath (string) - the XPath of the node li.
    • event (event object) - a jQuery click event object.
    • state (string) - denoting the current expanded/collapsed state of the li, either 'open' or 'closed'
  • clickCallback (function) - a callback to be invoked when a user clicks one of the nodes. It receives the same data as with plusMinCallback, except the 4th argument.
  • hideNodeNames (bool) - whether or not to show the names of nodes in the tree. Default is false.
  • openAtPath (string) - a jQuery selector pointing to a node within the XML that represents where the tree should open at, e.g. books city[name="Derby"]
  • attrs (string) - controls how attributes from the XML should behave in the resultant tree. Options: 'show' (they will be present and visible); 'hide' (present but hidden); 'ignore' (they will be absent from the tree). 'hidden' is useful if you want to interrogate the tree based on the existence or value of certain attributes, without them being visible to the user. Default is 'show'.
  • attrsAsClasses (bool/array) - transfer some or all attributes from the XML to become classes on the lis. Pass true to apply this to all attributes, or, for just some of them, an array of attribute names.
  • attrsAsData (bool/array) - identical to attrsAsClasses, except attributes will become jQuery data (i.e. accessible via .data()) on the element rather than classes.
  • subTreeBranches (string/bool) - branches that, when expanded, lazy-load more data. Pass true for this to apply to all branches. See Sub-tree requests.
  • subTreeRequest (function) - a callback function that, when a sub-tree branch (see subTreeBranches) is expanded, returns the URL to the data to load into it. It is automatically passed a jQuery reference to the clicked li as its only argument.
  • noURLTracking (bool) - if true, the steps taken navigating the tree will not be logged in the URL hash. Note that this will mean the tree returns to its original state on page refresh. Default is false.


DataTree exposes a handful of instance methods including:

  • ::jumpTo(selector, closeOthers) - jump to a specific branch in the tree. selector should be a string pointing to the branch li in the tree, while closeOthers is a boolean which, if passed and true, denotes any existing expanded branch(es) should be closed.
  • ::getNode(selector) - returns the XML element (XML) or JS object (JSON) relating to a given branch li in the tree. selector should be a string pointing to a single branch li in the tree.

Sub-trees 🔗

DataTree allows you to load data in stages, known as lazy loading. You might initially load only the outer skeleton of the tree (i.e. the children of the root) and then load deeper levels of data only when (and if) the user expands one of those nodes. This is a common situation where the data is being served dynamically by a server-side web service.

Let's look again at Example 2 from above, which features sub-tree requests.

new DataTree({ fpath: 'web_service.php?level=root', container: '#tree', subTreeBranches: true, subTreeRequest: li => 'web_service.php?id=''id'), attrsAsData: 1 });

There, we initialise the tree, and fetch and load in the root-level data from the web service. We also stipulate that all branches, when expanded, should fire sub-tree requests, i.e. load data under themselves. We also transer all attributes from the XML to become jQuery data properties on the resultant lis.

We then specify that, when sub-tree branch is expanded, the URL from which to fetch the data will be generated by a callback function, passed to the subTreeRequest param.

Our callback is automatically passed as its only argument a jQuery reference to the expanded li. We can then interrogate that li as a means to determine the URL from which to get the next batch of data.

We told DataTree at initialisation to transfer XML attributes to become jQuery data properties on the resultant lis. Assuming one of these attributes was id, we can then use that, as shown, in generating the URL to talk to the web service.

Deep linking 🔗

By default, during traversal DataTree tracks, via the URL hash, which branches are expanded at any given time. This has two positive implications:

  • When the page is refreshed, the tree retains its state
  • You can link to points within the tree, rather than just to its root

To link to a specific point in the tree, you need to know the route to it - that is, the zero-indexed route of the nodes that lead to it.

So for example, given the following XML:

<characters> <character> <name>Mario</name> <games> <game platform='wii'>Mario Galaxy</game> <game platform='wii'>Mario Galaxy 2</game> <game platform='switch'>Mario 3D World</game> </games> </character> <character> <name>Kirby</name> <games> <game platform='wii'>Kirby's Epic Yarn</game> <game platform='ds'>Kirby's Mass Attack</game> <game platform='wii'>Kirby's Return to Dreamland</game> </games> </character> </characters>

We can deep-link to games involving Nintendo's Kirby character with a URL like:


That says:

  1. Within the first DataTree instance (i.e. tree0)
  2. At the root level, open the first (0) branch (characters)
  3. Then, open the second (1) branch (character), since Kirby is the second branch

Note the hash contains the tree instance ID ("tree" followed by a zero-indexed number), so it won't confuse it with another instance of DataTree in the same page, should there be one. The structure thereafter is simply the indexes leading down to the desired node.

It is possible to link to not just one but multiple nodes, too. To do this, use the pipe character in the above hash structure at the point where more than one branch is expanded.

So to auto-expand the games branches relating to both Kirby and Mario, the URL would be:


To establish a route, browse to it manually and see how the URL changes (provided URL tracking is enabled - see the noURLTracking param).

Download Download from Github

Did I help you? Feel free to be amazing and buy me a coffee on Ko-fi!