// An example of Force Directed Graphing using OO parent/child relationships // by Nathan Ramella (nar@hush.com) // // Original source used from GraphToy2 found at http://www.cricketschirping.com/weblog/?p=966 // by banksean public class Node { boolean isSelected = false; boolean isHovering = false; boolean isDragging = false; float lastTouch = 0; boolean isOpen = true; boolean isClosed = false; float SPRING_CONSTANT = .5; float DAMPING_CONSTANT = .2; int RESTLENGTH = 20; float SPRING_CONSTANT_PARENT = .2; float DAMPING_CONSTANT_PARENT = .2; int RESTLENGTH_PARENT = 10; int MAGNET_CONSTANT = -700; int MAGNET_DISTANCE = 20; Particle p; ParticleSystem ps; Node parent; Edge edge; Spring spring; int myColor = color(255,255,0); int myStrokeWeight = 2; int myStrokeColor = color(255,255,0); int myFillColor = color(120,120,0); int h = 10; int w = 10; String label = ""; String type = ""; ArrayList children = new ArrayList(); public Node(String label, ParticleSystem ps) { this.label = label; this.ps = ps; this.p = ps.makeParticle(.1, 0, 0, 0); } public String getLabel() { return this.label; } public Node(String label, ParticleSystem ps, Node parent) { this.label = label; setParent(parent); this.ps = ps; this.p = this.ps.makeParticle(1.0, (parent.getParticle().position().x() + (0.01-(float)Math.random()*0.01)), (parent.getParticle().position().y() + (0.01-(float)Math.random()*0.01)), 0.0); } public void setFill(color c) { this.myColor = c; } public void setStroke(int weight, color c) { this.myStrokeWeight = weight; this.myStrokeColor = c; } public Node(String label) { this.label = label; } public void flip() { if (isClosed) { setOpen(); } else { setClosed(); } } public void setClosed() { isOpen = false; isClosed = true; } public void setOpen() { isOpen = true; isClosed = false; } public void setEdge(Edge e) { this.edge = e; } public void setSpring(Spring s) { this.spring = s; } public Node addChild(String label) { Node n = new Node(label, this.ps, this); Spring s = ps.makeSpring(this.getParticle(), n.getParticle(), SPRING_CONSTANT_PARENT, DAMPING_CONSTANT_PARENT, RESTLENGTH_PARENT); Edge e = new Edge(this, n, s); for (int i = 0; i < ps.numberOfParticles(); i++) { Particle a = ps.getParticle(i); ps.makeAttraction(n.getParticle(), a, MAGNET_CONSTANT, MAGNET_DISTANCE ); } ps.makeAttraction(n.getParticle(), p, MAGNET_CONSTANT, MAGNET_DISTANCE ); n.setEdge(e); n.setSpring(s); children.add(n); return n; } public Particle getParticle() { return p; } public void setParent(Node parent) { if (parent != null) { this.parent = parent; } } public String getId() { return label; } public String getType() { return this.type; } public ArrayList getChildren() { return children; } public void setPosition(float x, float y, float z) { p.moveTo(x, y, z); } void growRandom(int potentialChildren) { for (int i = 0; i < (Math.random() * potentialChildren); i++) { int uid = (int) Math.random() * 100000; addChild(Integer.toString(uid)); } } public void draw() { fill(myFillColor); strokeWeight(myStrokeWeight); stroke(myStrokeColor); /* if (isHovering) { fill(0,255,0); } if (isSelected) { fill(0,0,255); } else { fill(0); } */ if (this.edge != null) { this.edge.draw(); } int growSize = children.size()*2; ellipse(this.p.position().x(),this.p.position().y(),h+growSize,w+growSize); } public boolean containsPoint(float x, float y) { float dx = p.position().x()-x; float dy = p.position().y()-y; return (abs(dx) < w*2.0 && abs(dy) 0) { return true; } else { return false; } } public ArrayList getNodes() { ArrayList nodes = new ArrayList(); for (Iterator it=this.children.iterator(); it.hasNext(); ) { Node n = (Node) it.next(); nodes.addAll(n.getNodes()); } nodes.add(this); return nodes; } }