drawing trees in processing uta hinrichs, cpsc 583, 2011 adapted from petra isenberg’s cpsc...
Post on 21-Dec-2015
219 views
TRANSCRIPT
Drawing Trees in Processing
Uta Hinrichs, CPSC 583, 2011adapted 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
Heer, Bostock, Ogievtsky
circular node-link diagrams
Heer, Bostock, Ogievtsky
sunburst layout
Christopher Collins, 2006
phyllo trees
Carpendale, 2004; Isenberg 2006
voronoi treemaps
Balzer & Deussen, 2005
major tree layouts
node-link containmentalignmen
t, adjacenc
y
some terminology
node-link-diagram
root node
leave node
child nodeparent node
some terminology
containmentalignmen
t, adjacenc
y
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
• JTreeLib JavaDochttp://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
A H G I F E B C D
pre-order traversal
A
H
G
B
I
F E
C
D
preorder(node) print node.value (or do something else with the node)
for (all children of this node)preorder(child)
G F E I H D C B A
post-order traversal
A
H
G
B
I
F E
C
D
postorder(node)
for(all children of this node)postorder(child)
print node.value (or do something else)
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
void draw(){ preorder(root);}preorder(NAryTreeNode node){ //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);
}
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(NAryTreeNode node){ //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(int i)• set/getNodeSize(int width, int height)• set/getPosition(int X, int Y)• getLevel()
A
H
G
B
I
F E
C
D
solution – nestedpublic void draw(){fill(255,150,30);preorder(root);}
public void preorder(NAryTreeNode n){drawNode(n);int numberOfChildren = n.getChildCount();
for(int i = 0; i<numberOfChildren; i++){NAryTreeNode childN = (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 – alignmentpublic void draw(){fill(255,150,30);preorder(root);}
public void preorder(NAryTreeNode n){drawNode(n);int numberOfChildren = n.getChildCount();
for(int i = 0; i<numberOfChildren; i++){NAryTreeNode childN = (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());}