300 likes | 446 Views
Drawing Trees in Processing. Uta Hinrichs , CPSC 583, 2011. adapted from Petra Isenberg’s CPSC 599.28, 2008. trees for representing hierarchical data. Book chapter section subsection paragraph File systems Sport events. squarified treemap. SequoiaView. node-link diagrams.
E N D
Drawing Trees in Processing UtaHinrichs, CPSC 583, 2011 adapted from Petra Isenberg’s CPSC 599.28, 2008
trees for representing hierarchical data • Book • chapter • section • subsection • paragraph • File systems • Sport events
squarifiedtreemap SequoiaView
node-link diagrams Heer, Bostock, Ogievtsky
circular node-link diagrams Heer, Bostock, Ogievtsky
sunburst layout Christopher Collins, 2006
phyllo trees Carpendale, 2004; Isenberg 2006
voronoitreemaps Balzer & Deussen, 2005
major tree layouts alignment, adjacency containment node-link
some terminology root node child node parent node leave node node-link-diagram
some terminology alignment, adjacency containment
coding the tree layout • 1D tree map • alignment layout
tree drawing • create new sketch • create initial program structure public void setup() { size(600, 600); // window size background(200); // set a background color noLoop(); // we don't need to redraw constantly } public void draw() { }
adding external libraries • download: http://innovis.cpsc.ucalgary.ca/Courses/InfoVisNotes2011 • JTreeLib.jar: library for tree data structures • Crimson.jar: reading in xml files • Tree data set: test data to play with
adding external libraries • add the libraries to your processing sketch • Import File System • Add to Build Path • JTreeLibJavaDoc http://pages.cpsc.ucalgary.ca/~pneumann/projects/JTreeLib/ import ca.ucalgary.innovis.*; import java.io.File; public class treeDrawing extends PApplet{ public void setup()... public void draw()...
load tree data & start a tree import ca.ucalgary.innovis.*; import java.io.File; NAryTree tree; // tree data structure void setup() { [...] File myData = new File("data//smallTreeTest.tree"); tree = NAryTreeLoader.loadTree(myData); } void draw() { }
JTreeLib • NAryTree • contains NAryTreeNodes • getRoot() • getLeafCount() • getNodeCount() • NAryTreeNode • getChildCount() • getChildAt(index) • getParent() • setNodeSize(w,h), getWidth(), getHeight() • setPosition(), getXPosition(), getYPosition() • getIndex(child)
drawing the first node [...] NAryTreeNode root; // root node void setup() { [...] File myData = new File("data//smallTreeTest.tree"); tree = NAryTreeLoader.loadTree(myData); root = (NAryTreeNode)tree.getRoot(); root.setNodeSize(500,50); root.setPosition(10,10); } void draw() { }
draw the root node! [...] NAryTreeNode root; // root node void setup() { [...] File myData = new File("data//smallTreeTest.tree"); tree = NAryTreeLoader.loadTree(myData); root = (NAryTreeNode)tree.getRoot(); root.setNodeSize(500,50); root.setPosition(10,10); } void draw() { //draw the root node here! }
solution [...] void setup() { [...] root = (NAryTreeNode)tree.getRoot(); root.setNodeSize(500,50); root.setPosition(10,10); } void draw() { fill(255,150,30); rect((float)root.getXPosition(), (float)root.getYPosition(), (float)root.getWidth(), (float)root.getHeight()); }
what about all the other nodes? • think about it!
solution • the layout of each tree node depends on • the size of its parent • the position of its parent • its position among its siblings
tree traversal • how to visit each tree node • exactly once • in a systematic way • several methods • classified by the order in which nodes are visited • most easily described through recursion
pre-order traversal preorder(node) print node.value (or do something else with the node) for (all children of this node) preorder(child) A H G I F E B C D A H B G I C E D F
post-order traversal G F E I H D C B A postorder(node) for(all children of this node) postorder(child) print node.value (or do something else) A H B G I C E D F
which traversal do we need? • size & position of each tree node (except the root) depends on • the size of its parent • the position of its parent • its position among its siblings
preorder function preorder(node) print node.value (or do something else with the node) for (all children of this node) preorder(child) void draw() { preorder(root); } preorder(NAryTreeNodenode) { //draw node //for(child of node) //calculate child’s width & height based on node’s width & height //calculate child’s position based on node’s position //preorder(child); }
some hints • getChildCount() • getChildAt(inti) • set/getNodeSize(int width, int height) • set/getPosition(int X, int Y) • getLevel() A void draw() { preorder(root); } preorder(NAryTreeNodenode) { //draw node //for(child of node) //calculate child’s width & height based on node’s width & height //calculate child’s position based on node’s position //preorder(child); } H B G I C E D F
solution – nested public void draw() { fill(255,150,30); preorder(root); } public void preorder(NAryTreeNode n) { drawNode(n); intnumberOfChildren = n.getChildCount(); for(inti = 0; i<numberOfChildren; i++) { NAryTreeNodechildN = (NAryTreeNode)n.getChildAt(i); childN.setNodeSize(n.getWidth()/numberOfChildren, 50); childN.setPosition(n.getXPosition() + i*childN.getWidth(), 0); preorder(childN); } } public void drawNode(NAryTreeNode n) { rect((float)n.getXPosition(), (float)n.getYPosition(), (float)n.getWidth(), (float)n.getHeight()); System.out.println(n.getLabel()); }
solution – alignment public void draw() { fill(255,150,30); preorder(root); } public void preorder(NAryTreeNode n) { drawNode(n); intnumberOfChildren = n.getChildCount(); for(inti = 0; i<numberOfChildren; i++) { NAryTreeNodechildN = (NAryTreeNode)n.getChildAt(i); childN.setNodeSize(n.getWidth()/numberOfChildren, 50); childN.setPosition(n.getXPosition() + i*childN.getWidth(), childN.getLevel()*50); preorder(childN); } } public void drawNode(NAryTreeNode n) { rect((float)n.getXPosition(), (float)n.getYPosition(), (float)n.getWidth(), (float)n.getHeight()); System.out.println(n.getLabel()); }