Click here to Skip to main content
Email Password   helpLost your password?

Sample with specific colors in Internet Explorer

Figure 1. Sample with specific colors rendered with VML in Internet Explorer.

Sample with specific colors in Firefox

Figure 2. Sample with specific colors rendered with canvas in Firefox.

Sample showing collapsed and selected nodes

Figure 3. Sample showing collapsed and selected nodes rendered with VML in Internet Explorer.

Contents

Introduction

This article presents a JavaScript component which renders a tree on the screen using VML (Vector Markup Language) in Internet Explorer 6+ or the <canvas> element in Firefox 1.5+.

There are plenty of JavaScript trees out there, and most of them have a better cross-browser compatibility than this, are faster and better optimized. The goal of this code is to present a client-side implementation of the Walker's layout algorithm (see References), leaving off code optimizations. In short, the component has born after the algorithm, as I think that a living sample would be better than an abstract source-code level implementation.

One of the classic treeview JavaScript components I use sometimes is Geir Landr�'s DTree: outstanding and simple. Some time ago, an article appeared here at CodeProject that presents a horizontal JavaScript tree, based upon DTree, which uses HTML tables to render the tree in a horizontal manner. I want to mention those here as they inspired me to publish this article. Moreover, much of the functionalities of this version mimic that on those scripts.

I hope this component will fill the gap in projects when a tree layout is needed, but without server-side code. Of course, any comments, corrections, suggestions, etc... are very welcome.

Features

The best way to get an idea of what could be accomplished by using this component is to download the sources and play with the sample included. The API reference below could give you a more precise idea of what could be done. But, as a briefing, features include:

I would like to say that this is a work in progress. In particular, the code is structured to allow different rendering technologies and I must definitively work harder on this topic.

Background

The Walker's algorithm expands on the previous works of Reingold, Tilford, Shannon et al. providing a solution where a tree drawing occupies as little space as possible while satisfying the following aesthetic rules:

  1. Nodes of the same level are aligned, and the axis of all levels are parallel.
  2. A parent should be centered over its children.
  3. A tree and the same tree defined in reverse order, should produce layouts that are reflections of one another. The same subtree must be rendered the same way no matter where it appears in the tree.

The Walker's algorithm goal over its predecessors was to provide a solution to fully satisfy the third rule, by means of spacing out evenly smaller subtrees in the interior of adjacent larger subtrees.

The difference of the apportion routine in Walker's algorithm

Figure 4. Samples showing the difference of the apportion routine in Walker's algorithm..

The main concepts of the algorithm are:

The algorithm works in two passes. The first pass (firstWalk) is a postorder traversal. The different subtrees are processed recursively from bottom to top and left to right positioning the rigid units that form each subtree until no one touch each other. As the traversal goes, smaller subtrees are combined forming larger subtrees until we reach the root. During the process, the apportion routine space out evenly the inner smaller subtrees that could float between two adjacent larger subtrees (to satisfy the symmetry of the 3rd rule). The second pass (secondWalk) is a preorder traversal which calculates the final node position by adding all the ancestors modifiers to the preliminary coordinate of each node.

Gao Chaowei (see References) proposed an optimization to the firstWalk routine which consists in an incremental version of the Walker's algorithm. This version avoids to recalculate the node preliminary coordinate and modifier when changes made to the tree structure don't imply modifications to their values. This optimization is not yet implemented in this component.

The algorithm also adjust the calculations if the layout is to be made in a different direction (i.e. bottom to top). Different uses may require different views. In occident, traditionally a top disposition means power, like in organizational hierarchies; a bottom layout means evolution or growth, like in biology; whereas left and right layouts could mean time evolution. (But this is a particular consideration).

Just a word to mention that, an uniform layout algorithm like this one is adequate for relative small trees. Trees with a large number of nodes may require other layout and visualization techniques, like the ability to zoom, pan and focus, collapse some but not all the children of a node, adding interactive searching. There are a number of other solutions to achieve the same objectives including, but not limited to, hyperbolic trees, treemaps, Degree of interest calculations, ... The curious reader could find a lot of information on the net.

Using the code

Quick & dirty guide to get things up and working

Let's build an example, (all samples are included in the download) to understand how to draw a simple tree. After that, with the API reference and looking at the advanced samples code you could fully understand how to use this component.

First of all, you must include the component script and link the style-sheet in the <head> section of your HTML page (remember to set the paths upon your installation):

<head>
    <!-- Content goes here... -->
    <script type="text/javascript" src="ECOTree.js"></script>
    <link type="text/css" rel="style-sheet" href="ECOTree.css" />
    <!-- Content goes here... -->
</head>

Besides, if you plan to user Internet Explorer you must add the next lines to the <head> section of your HTML page for VML to render correctly:

<head>
    <!-- Content goes here... -->
    <xml:namespace ns="urn:schemas-microsoft-com:vml" prefix="v"/>
    <style>v\:*{ behavior:url(#default#VML);}</style>         
    <!-- Content goes here... -->
</head>

In your HTML page you must place a block container for the tree, like a <div> with an ID that you must supply to the tree constructor. Then you must include a <script> block to create the tree itself, add some nodes -probably from a database in real projects- and then draw the tree. Let's look at an example:

<div id="myTreeContainer"></div>
var myTree = new ECOTree("myTree","myTreeContainer");
myTree.add(0,-1,"Apex Node");
myTree.add(1,0,"Left Child");
myTree.add(2,0,"Right Child");
myTree.UpdateTree();

The result will be:

Quick example 1

Figure 5. Quick example 1.

You must ensure that the script block gets executed once the page is loaded, or at least when the container is loaded. So you could choose to insert the script after the container or to create the tree inside a function that gets called when the OnLoad event occurs for the document or body, as usual.

Note that the component has default values for almost everything, causing that those five lines of code could create a tree that you can collapse or expand at will, and you can select/unselect multiple nodes by simply clicking them. Also, every node has a hyperlink Javascript:void(0); by default. Almost every time, you will want to change the look and feel and the behavior of the tree to better fit your needs. This can be done with the config instance member of the tree. Let's modify the previous example by adding some lines:

var myTree = new ECOTree("myTree","myTreeContainer");    
myTree.config.linkType = 'B';
myTree.config.iRootOrientation = ECOTree.RO_BOTTOM;                        
myTree.config.topYAdjustment = -160;
myTree.config.linkColor = "black";
myTree.config.nodeColor = "#FFAAAA";
myTree.config.nodeBorderColor = "black";
myTree.config.useTarget = false;
myTree.config.selectMode = ECOTree.SL_SINGLE;
myTree.add(0,-1,"Apex Node");
myTree.add(1,0,"Left Child");
myTree.add(2,0,"Right Child");
myTree.UpdateTree();

With these minor changes, the tree now will look like this:

Quick example 2

Figure 6. Quick example 2.

This time, the nodes don't have a hyperlink (useTarget = false) and you can select only one node at a time (selectMode = ECOTree.SL_SINGLE).

OK, now that the basics had been covered, let's go on to discover all the possibilities.

API Reference

ECOTree configuration

Here are the config parameters with their default values:

this.config = {
    iMaxDepth : 100,
    iLevelSeparation : 40,
    iSiblingSeparation : 40,
    iSubtreeSeparation : 80,
    iRootOrientation : ECOTree.RO_TOP,
    iNodeJustification : ECOTree.NJ_TOP,
    topXAdjustment : 0,
    topYAdjustment : 0,
    render : "AUTO",
    linkType : "M",
    linkColor : "blue",
    nodeColor : "#CCCCFF",
    nodeFill : ECOTree.NF_GRADIENT,
    nodeBorderColor : "blue",
    nodeSelColor : "#FFFFCC",
    levelColors : ["#5555FF","#8888FF","#AAAAFF","#CCCCFF"],
    levelBorderColors : ["#5555FF","#8888FF","#AAAAFF","#CCCCFF"],
    colorStyle : ECOTree.CS_NODE,
    useTarget : true,
    searchMode : ECOTree.SM_DSC,
    selectMode : ECOTree.SL_MULTIPLE,
    defaultNodeWidth : 80,
    defaultNodeHeight : 40,
    defaultTarget : 'Javascript:void(0);',
    expandedImage : './img/less.gif',
    collapsedImage : './img/plus.gif',
    transImage : './img/trans.gif'
}

ECOTree public methods

Samples Included

In the download you can find several simple examples you can play with. All the images in this article are made with the code on the examples. There is an advanced example which will let you play with almost all the options in the component. The data in the samples has been obtained in the Wikipedia.

References

Future Enhancements

History

You must Sign In to use this message board.
 
 
Per page   
 FirstPrevNext
GeneralSafari (iPhone) / Chrome issues...
chimarax9
0:52 28 Feb '10  
Colors/shapes don't render in Safari or chrome, any ideas...?
GeneralSlow chart
Reza Nazemi
22:57 22 Feb '10  
Hi,
I added aroung 500 people to this chart.
When I click to expand or collapse a node, it'll take 30 second.
Is this normal?
I think maybe i made a mistake to get it slow.

Please guide me.
GeneralNode alignment is not working
rk01
3:02 2 Feb '10  
Hi,

I am using IE 6, The node alignment is not seems to be working for me, It always sticks to center, can anyone guide me to change it to top aligned.

I just want to have my root node in the top left position always.

any help on this is greatly appreciated.

Thanks in advance,

RK
GeneralContaining the graph within a cell
AndyMarch1987
6:38 4 Jan '10  
Hey,

Thanks for this library it was exactly what i was after.

Is it possible to restrict the size of the graph to within a cell or div? I've tried modifing the line below to include an overflow value but it does not have the desired affect.

case "VML":
s.push('<v:group coordsize="5000, 5000" coordorigin="0, 0" style="position:relative;width=5000px;height=5000px;" >');

I also tried the same approach on the containing cell again no luck.

Does anyone have a solution to this?
Generaltext not rendered in Firefox 3.5.5
arifainchtein
4:20 9 Dec '09  
I am using the code inside of a jsp page running it in firefox 3.5.5 on snow leopard. the boxes in the tree render ok, but the text inside of it does not show at all. do you have any suggestions?
GeneralRe: text not rendered in Firefox 3.5.5
arifainchtein
6:12 9 Dec '09  
one more thing. If I open one of the samples in firefox as a file, it works ok, however, if i put the file in a tomcat environment and access the sample file via regular http, I get the same error. it seems that there is a problem with the samples as well when running them under tomcat.
GeneralRe: text not rendered in Firefox 3.5.5
Crizzly
12:43 12 Jan '10  
Hi, I encountered the same problem - I think - on Glassfish. The text is rendered, but below the canvas. The reason seems to be that the style attribute of the corresponding div is empty, which is ceated in line 708 of ECOTree. The strange thing is, if I write e.g. "shtyle" instead of "style" the code is rendered (but not helpfull...). Did you find a solution by now? I'll let you know if I find one...
GeneralRe: text not rendered in Firefox 3.5.5
Crizzly
13:00 12 Jan '10  
Hi there, found the solution: I added "px" to the positions in the style part - it was obviously similar to the problem someone encountered with IE8. I hope that can help you, too.
GeneralRe: text not rendered in Firefox 3.5.5
Alejandro Morales
11:53 8 Feb '10  
The solve is simple. If you have a DOCTYPE tag in your HTML Doc, firefox don't render the text. You just have to delete this tag and ready.
GeneralRe: text not rendered in Firefox 3.5.5
chimarax9
10:09 28 Feb '10  
Does anyone know of a similar fix for Sarfari or Chrome?
GeneralIdea for Family Tree
u329
19:26 26 Aug '09  
Thank for your code,give me good idea for developing web family tree site.
all I need to do is try to make horizontal relation for husband and wife(s),
and create DB for storage unlimited generation family data .

actually,I already make it about few months ago.cause I just modify part of code to fitting my requirement,so embarrassed to publish what I changed.

Regards,
GeneralAlign to center
Antonio_Lopez
0:26 12 Aug '09  
Hi! I'm trying to align the Tree to the center using topXAdjustment, but whole Tree move on this distance. I expected that only root was moving. Browser FF3. Thanks)
GeneralThank you!
Reza Nazemi
20:53 30 Jul '09  
I really appreciate, It works fine and we can create all kind of Org chart very easy, thanks mate
Generaltree not working with ie8
Praveensoli
0:13 14 Jul '09  
Hi,
it's great code. I am trying to implement one of the my module but its not working with ie8.
Is there any problem with vml or any other issue.
please send reply asap.
I am waiting for ur replay.
thanks,
Praveen
GeneralRe: tree not working with ie8
axadmin
8:52 4 Sep '09  
I have had issues with IE8 using IE8 standards,

I needed to follow the steps in this link for VML support in standards mode.
https://connect.microsoft.com/IE/feedback/ViewFeedback.aspx?FeedbackID=333905

Updated the style statement from link above to include all the VML tags
<style type="text/css>
v\:rect, v\:roundrect, v\:line, v\:polyline, v\:curve, v\:arc, v\:oval, v\:image, v\:shape, v\:group, v\:skew, v\:stroke, v\:fill { behavior:url(#default#VML); display:inline-block }
</style>



Updated ECOTree.js
Line 708 added px top left width and height
s.push('
+ node.id + '" class="econode" style="removed:'+(node.YPosition+this.canvasoffsetTop)+'px; removed:'+(node.XPosition+this.canvasoffsetLeft)+'px; width:'+node.w+'px; height:'+node.h+'px;" ');


Line 735 added px to height and width and changed top to margin-top and left to margin-left

s.push('style="position:relative; margin-top:'+node.YPosition+'px; margin-left:'+node.XPosition+'px; width:'+node.w+'px; height:'+node.h+'px" ');


Line 793 changing the equal signs in the height and width to :

s.push('<;v:group coordsize="4000, 4000" coordorigin="0, 0" class="relative" style="removed:relative;width:4000px;height:4000px;display:inline-block;" >;');

I am having an issue with expand and collapse working on it.
hope this helps.
GeneralRe: tree not working with ie8
Praveensoli
0:47 29 Sep '09  
Thanks a lot its working fine.
QuestionVML:Group element scrollbars
Eisenfuss
5:11 7 Jul '09  
Hi all,
first of all i have to say NICE CODE Thumbs Up

I have the problem that no scrollbars were displayed.
Which parameters i need to change to display scrollbars (width,height) ?
Generalproblem with collapse node
Sabitha P
20:27 4 Jun '09  
Hi,
Collpase node not working for few nodes but working for the rest.
How to resolve this?
Has anyone faced the same problem?

-Thanks.
Generalproblem with IE8!!! please help!
Member 3913151
4:54 3 Jun '09  
It is a really great work! Thank you very much!
But there seems to bew a problem with IE8. The nodes aren't displayed..
Could you please post a solution?
Does anyone else have this problemm too??
thank you!
GeneralRe: problem with IE8!!! please help!
fr33j6ck
11:15 30 Jun '09  
Works for me. Maybe you aren't allowing active content?
GeneralRe: problem with IE8!!! please help!
Praveensoli
0:51 13 Jul '09  
Hi,thanks a lot for giving such a nice code,
how ever its not properly working with IE8.
please suggest what should i do.
i am eagerly waiting for u r response.thanks in advance.
Questionproblem with the print [modified]
Member 3911851
4:49 13 May '09  
I'm using asp.net 2.0, MS AJAX and IE7. I put the tree inside scrollable div.
1- the print just show the words inside the nodes and the image(no vml effects)
2- when the Root position is top it prints many pages the first page is only has part of the tree left side and the rest pages are empty.

modified on Wednesday, May 13, 2009 10:11 AM

Questionlong time to expand all when tree is big(many level nodes) [modified]
Member 3911851
4:31 13 May '09  
I'm using asp.net 2.0, MS AJAX and IE7. I put the tree inside scrollable div.
When I expand all the tree it takes long time.
I think this step:
ECOTree.prototype.UpdateTree = function () {

this.elm.innerHTML = this;

takes long time.

modified on Wednesday, May 13, 2009 10:08 AM

Questionhow to include many persons with a hyperlink in a single node
Sabitha P
21:42 12 May '09  
Hi,

I have the requirement to show all the team members reporting under one manager in a single node with a hyperlink to their corresponding profiles in the organization chart.
Is it possible to customize this script in displaying many people under one node?
Please give me some tips regarding this.
If someone has tried this before please provide me with the sample code.

-Thanks in advance.

Sab
Generalhow to implement horizontal line between two node??
regey
23:11 29 Apr '09  
great javascript code, thank you very much...

i want to ask, how to implement horizontal line between two node? or adding spouse node at current node?
it is possible?

thank's for the attention Smile

Regard's
Yogi Eka.


Last Updated 28 Nov 2006 | Advertise | Privacy | Terms of Use | Copyright © CodeProject, 1999-2010