Data Tree
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.
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='+li.data('id'),
attrsAsData: 1
});
API 🔗
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 thexml
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
- A boolean, if you're loading data over a web service (via
jsonp
(bool) - pass true if you are loading your data over JSON-P rather than locallystartExpanded
(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 viaopenAtPath
.renderCallback
(function) - a callback function to act on or interrogate the resultant tree HTML. It is automatically passed a jQuery reference to the treeul
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 withfpath
; controls whether to allow caching on the root-level data request. Default is true.noSubTreeCache
- used withfpath
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 nodeli
.XPath
(string) - the XPath of the nodeli
.event
(event object) - a jQuery click event object.state
(string) - denoting the current expanded/collapsed state of theli
, 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 withplusMinCallback
, 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. bookscity[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 theli
s. Pass true to apply this to all attributes, or, for just some of them, an array of attribute names.attrsAsData
(bool/array) - identical toattrsAsClasses
, 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 (seesubTreeBranches
) is expanded, returns the URL to the data to load into it. It is automatically passed a jQuery reference to the clickedli
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.
Methods
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 branchli
in the tree, whilecloseOthers
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 branchli
in the tree.selector
should be a string pointing to a single branchli
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='+li.data('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 li
s.
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 li
s. 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:
- http://example.com/page.html#tree0:0,1;
That says:
- Within the first DataTree instance (i.e. tree0)
- At the root level, open the first (0) branch (
characters
) - 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:
- http://example.com/page.html#tree0:0,0|0,1;
To establish a route, browse to it manually and see how the URL changes (provided URL tracking is enabled - see the noURLTracking
param).
Did I help you? Feel free to be amazing and buy me a coffee on Ko-fi!