diff options
| author | orbiter <orbiter@6c8d7289-2bf4-0310-a012-ef5d649a1542> | 2008-05-07 22:49:07 +0000 |
|---|---|---|
| committer | orbiter <orbiter@6c8d7289-2bf4-0310-a012-ef5d649a1542> | 2008-05-07 22:49:07 +0000 |
| commit | 58830e9b2881a49e968fc458eae21a1a0ef12475 (patch) | |
| tree | 522855357ee364d1282917116888b3913ad06e57 /htroot/processing/domaingraph | |
| parent | 9bc56a9edc0f7057c12a9af123670a243a02ad11 (diff) | |
added new terminal servlet using current visualization methods and a new one: a processing (processing.org) applet.
the new servlet can be found at
http://localhost:8080/terminal_p.html
..to be enhanced..
git-svn-id: https://svn.berlios.de/svnroot/repos/yacy/trunk@4773 6c8d7289-2bf4-0310-a012-ef5d649a1542
Diffstat (limited to 'htroot/processing/domaingraph')
| -rwxr-xr-x | htroot/processing/domaingraph/applet/domaingraph.jar | bin | 0 -> 187496 bytes | |||
| -rwxr-xr-x | htroot/processing/domaingraph/applet/domaingraph.java | 229 | ||||
| -rwxr-xr-x | htroot/processing/domaingraph/applet/domaingraph.pde | 227 | ||||
| -rwxr-xr-x | htroot/processing/domaingraph/applet/index.html | 104 | ||||
| -rwxr-xr-x | htroot/processing/domaingraph/applet/loading.gif | bin | 0 -> 2232 bytes | |||
| -rwxr-xr-x | htroot/processing/domaingraph/domaingraph.pde | 227 |
6 files changed, 787 insertions, 0 deletions
diff --git a/htroot/processing/domaingraph/applet/domaingraph.jar b/htroot/processing/domaingraph/applet/domaingraph.jar Binary files differnew file mode 100755 index 000000000..9cb521ca7 --- /dev/null +++ b/htroot/processing/domaingraph/applet/domaingraph.jar diff --git a/htroot/processing/domaingraph/applet/domaingraph.java b/htroot/processing/domaingraph/applet/domaingraph.java new file mode 100755 index 000000000..98f521cf2 --- /dev/null +++ b/htroot/processing/domaingraph/applet/domaingraph.java @@ -0,0 +1,229 @@ +import processing.core.*; import traer.physics.*; import traer.animation.*; import processing.net.*; import java.applet.*; import java.awt.*; import java.awt.image.*; import java.awt.event.*; import java.io.*; import java.net.*; import java.text.*; import java.util.*; import java.util.zip.*; import javax.sound.midi.*; import javax.sound.midi.spi.*; import javax.sound.sampled.*; import javax.sound.sampled.spi.*; import java.util.regex.*; import javax.xml.parsers.*; import javax.xml.transform.*; import javax.xml.transform.dom.*; import javax.xml.transform.sax.*; import javax.xml.transform.stream.*; import org.xml.sax.*; import org.xml.sax.ext.*; import org.xml.sax.helpers.*; public class domaingraph extends PApplet {// Domain visualization graph for YaCy +// by Michael Christen +// +// this applet uses code and the physics engine from +// http://www.cs.princeton.edu/~traer/physics/ +// from Jeffrey Traer Bernstein +// redistribution is granted according to forum posting in +// http://processing.org/discourse/yabb_beta/YaBB.cgi?board=os_libraries_tools;action=display;num=1139193613 + + + + + +final float NODE_SIZE = 6; +final float EDGE_LENGTH = 50; +final float EDGE_STRENGTH = 0.01f; +final float SPACER_STRENGTH = 10; + +ParticleSystem physics; +Smoother3D centroid; +PFont font; +Client myClient; +Particle center0, center1; // two gravity centers to support object ordering for non-quadratic fields +String parsingHostName = ""; +String parsingHostID = ""; +HashMap nodes = new HashMap(); // map that holds host objects + +public void setup() { + + String[] fontList = PFont.list(); + //println(fontList); + font = createFont(fontList[0], 32); //just take any, should be mostly Arial + textFont(font, 12); + + size(660, 400); + smooth(); + frameRate( 24 ); + strokeWeight( 2 ); + ellipseMode( CENTER ); + + physics = new ParticleSystem( 0, 0.25f ); + centroid = new Smoother3D( 0.8f ); + + initializePhysics(); + initRequest(); +} + +public void initRequest() { + myClient = new Client(this, "localhost", 8080); + myClient.write("GET /xml/webstructure.xml HTTP/1.1\n"); + myClient.write("Host: localhost\n\n"); +} + +public void processRequestResponse() { + if (myClient.available() > 0) { + String line = myClient.readStringUntil((byte) 10); + //println("Line: " + line); + if (line == null) line = ""; else line = line.trim(); + if (line.startsWith("<domain")) processDomain(parseProps(line.substring(7, line.length() - 1).trim())); + if (line.startsWith("<citation")) processCitation(parseProps(line.substring(9, line.length() - 2).trim())); + } +} + +public HashMap parseProps(String s) { + String[] l = s.split(" "); + HashMap map = new HashMap(); + int p; + String z; + for (int i = 0; i < l.length; i++) { + p = l[i].indexOf("="); + if (p > 0) { + z = l[i].substring(p + 1).trim(); + if (z.charAt(0) == '"') z = z.substring(1); + if (z.charAt(z.length() - 1) == '"') z = z.substring(0, z.length() - 1); + map.put(l[i].substring(0, p), z); + } + } + return map; +} + +public void processDomain(HashMap props) { + //println("Domain: " + props.toString()); + parsingHostName = (String) props.get("host"); if (parsingHostName == null) parsingHostName = ""; + parsingHostID = (String) props.get("id"); if (parsingHostID == null) parsingHostID = ""; + host h = new host(parsingHostName, physics.makeParticle(1.0f, random(0, EDGE_LENGTH * 30), random(- EDGE_LENGTH * 2, EDGE_LENGTH * 2), 0)); + nodes.put(parsingHostID, h); + addAttraction(h.node); +} + +public void processCitation(HashMap props) { + //println("Citation: " + props.toString()); + String host = (String) props.get("host"); if (host == null) host = ""; + String id = (String) props.get("id"); if (id == null) id = ""; + int count = 0; + try { + String counts = (String) props.get("count"); if (counts != null) count = Integer.parseInt(counts); + } catch (NumberFormatException e) {} + // find the two nodes that have a relation + host h = (host) nodes.get(id); + if (h == null) return; // host is not known TODO: store these and create relation later + host p = (host) nodes.get(parsingHostID); // this should be successful + addRelation(h.node, p.node); +} + +public void draw() { + processRequestResponse(); + + physics.tick( 1.0f ); + if (physics.numberOfParticles() > 1) updateCentroid(); + centroid.tick(); + + background( 0 ); + translate( width/2 , height/2 ); + scale( centroid.z() ); + translate( -centroid.x(), -centroid.y() ); + + drawNetwork(); +} + +public void drawNetwork() { + fill( 100, 255, 100 ); + + // draw vertices + noStroke(); + String name; + Iterator j = nodes.values().iterator(); + host h; + while (j.hasNext()) { + h = (host) j.next(); + Particle v = h.node; + ellipse(v.position().x(), v.position().y(), NODE_SIZE, NODE_SIZE); + name = h.name; + text(name, v.position().x() - (name.length() * 26 / 10), v.position().y() + 14); + } + + // draw center + /* + ellipse( center0.position().x(), center0.position().y(), NODE_SIZE * 2, NODE_SIZE * 2 ); + name = "Center0"; + text(name, center0.position().x() - (name.length() * 26 / 10), center0.position().y() + 14); + ellipse( center1.position().x(), center1.position().y(), NODE_SIZE * 2, NODE_SIZE * 2 ); + name = "Center1"; + text(name, center1.position().x() - (name.length() * 26 / 10), center1.position().y() + 14); + */ + + // draw edges + stroke( 160 ); + beginShape( LINES ); + for ( int i = 0; i < physics.numberOfSprings(); ++i ) { + Spring e = physics.getSpring( i ); + Particle a = e.getOneEnd(); + Particle b = e.getTheOtherEnd(); + vertex( a.position().x(), a.position().y() ); + vertex( b.position().x(), b.position().y() ); + } + endShape(); +} + +public void keyPressed() { + if ( key == 'c' ) { + initializePhysics(); + return; + } + + if ( key == ' ' ) { + Particle p = physics.makeParticle(); + addRelation(p, physics.getParticle( (int) random( 0, physics.numberOfParticles()-1) )); + addAttraction(p); + return; + } +} + +public void updateCentroid() { + float + xMax = Float.NEGATIVE_INFINITY, + xMin = Float.POSITIVE_INFINITY, + yMin = Float.POSITIVE_INFINITY, + yMax = Float.NEGATIVE_INFINITY; + + for ( int i = 0; i < physics.numberOfParticles(); ++i ) { + Particle p = physics.getParticle( i ); + xMax = max( xMax, p.position().x() ); + xMin = min( xMin, p.position().x() ); + yMin = min( yMin, p.position().y() ); + yMax = max( yMax, p.position().y() ); + } + float deltaX = xMax-xMin; + float deltaY = yMax-yMin; + if ( deltaY > deltaX ) + centroid.setTarget( xMin + 0.5f*deltaX, yMin +0.5f*deltaY, height/(deltaY+50) ); + else + centroid.setTarget( xMin + 0.5f*deltaX, yMin +0.5f*deltaY, width/(deltaX+50) ); +} + +public void initializePhysics() { + physics.clear(); + center0 = physics.makeParticle(1.0f, 0, 0, 0); + center0.makeFixed(); + center1 = physics.makeParticle(1.0f, EDGE_LENGTH * 30, 0, 0); + center1.makeFixed(); + centroid.setValue( 0, 0, 1.0f ); +} + +public void addAttraction(Particle p) { + physics.makeAttraction(center0, p, 5000.0f, 3 * EDGE_LENGTH); + physics.makeAttraction(center1, p, 5000.0f, 3 * EDGE_LENGTH); + + // spacers + for ( int i = 0; i < physics.numberOfParticles(); ++i ) { + Particle q = physics.getParticle( i ); + if (p != q) physics.makeAttraction( p, q, -SPACER_STRENGTH, 20); + } +} + +public void addRelation(Particle p, Particle other) { + physics.makeSpring( p, other, EDGE_STRENGTH, EDGE_STRENGTH, EDGE_LENGTH ); + //p.moveTo( q.position().x() + random( -1, 1 ), q.position().y() + random( -1, 1 ), 0 ); +} + +static class host { + String name; + Particle node; + public host(String name, Particle node) { + this.name = name; + this.node = node; + } +} + + static public void main(String args[]) { PApplet.main(new String[] { "domaingraph" }); }}
\ No newline at end of file diff --git a/htroot/processing/domaingraph/applet/domaingraph.pde b/htroot/processing/domaingraph/applet/domaingraph.pde new file mode 100755 index 000000000..e79f083e7 --- /dev/null +++ b/htroot/processing/domaingraph/applet/domaingraph.pde @@ -0,0 +1,227 @@ +// Domain visualization graph for YaCy +// by Michael Christen +// +// this applet uses code and the physics engine from +// http://www.cs.princeton.edu/~traer/physics/ +// from Jeffrey Traer Bernstein +// redistribution is granted according to forum posting in +// http://processing.org/discourse/yabb_beta/YaBB.cgi?board=os_libraries_tools;action=display;num=1139193613 + +import traer.physics.*; +import traer.animation.*; +import processing.net.*; + +final float NODE_SIZE = 6; +final float EDGE_LENGTH = 50; +final float EDGE_STRENGTH = 0.01; +final float SPACER_STRENGTH = 10; + +ParticleSystem physics; +Smoother3D centroid; +PFont font; +Client myClient; +Particle center0, center1; // two gravity centers to support object ordering for non-quadratic fields +String parsingHostName = ""; +String parsingHostID = ""; +HashMap nodes = new HashMap(); // map that holds host objects + +void setup() { + + String[] fontList = PFont.list(); + //println(fontList); + font = createFont(fontList[0], 32); //just take any, should be mostly Arial + textFont(font, 12); + + size(660, 400); + smooth(); + frameRate( 24 ); + strokeWeight( 2 ); + ellipseMode( CENTER ); + + physics = new ParticleSystem( 0, 0.25 ); + centroid = new Smoother3D( 0.8 ); + + initializePhysics(); + initRequest(); +} + +void initRequest() { + myClient = new Client(this, "localhost", 8080); + myClient.write("GET /xml/webstructure.xml HTTP/1.1\n"); + myClient.write("Host: localhost\n\n"); +} + +void processRequestResponse() { + if (myClient.available() > 0) { + String line = myClient.readStringUntil((byte) 10); + //println("Line: " + line); + if (line == null) line = ""; else line = line.trim(); + if (line.startsWith("<domain")) processDomain(parseProps(line.substring(7, line.length() - 1).trim())); + if (line.startsWith("<citation")) processCitation(parseProps(line.substring(9, line.length() - 2).trim())); + } +} + +HashMap parseProps(String s) { + String[] l = s.split(" "); + HashMap map = new HashMap(); + int p; + String z; + for (int i = 0; i < l.length; i++) { + p = l[i].indexOf("="); + if (p > 0) { + z = l[i].substring(p + 1).trim(); + if (z.charAt(0) == '"') z = z.substring(1); + if (z.charAt(z.length() - 1) == '"') z = z.substring(0, z.length() - 1); + map.put(l[i].substring(0, p), z); + } + } + return map; +} + +void processDomain(HashMap props) { + //println("Domain: " + props.toString()); + parsingHostName = (String) props.get("host"); if (parsingHostName == null) parsingHostName = ""; + parsingHostID = (String) props.get("id"); if (parsingHostID == null) parsingHostID = ""; + host h = new host(parsingHostName, physics.makeParticle(1.0, random(0, EDGE_LENGTH * 30), random(- EDGE_LENGTH * 2, EDGE_LENGTH * 2), 0)); + nodes.put(parsingHostID, h); + addAttraction(h.node); +} + +void processCitation(HashMap props) { + //println("Citation: " + props.toString()); + String host = (String) props.get("host"); if (host == null) host = ""; + String id = (String) props.get("id"); if (id == null) id = ""; + int count = 0; + try { + String counts = (String) props.get("count"); if (counts != null) count = Integer.parseInt(counts); + } catch (NumberFormatException e) {} + // find the two nodes that have a relation + host h = (host) nodes.get(id); + if (h == null) return; // host is not known TODO: store these and create relation later + host p = (host) nodes.get(parsingHostID); // this should be successful + addRelation(h.node, p.node); +} + +void draw() { + processRequestResponse(); + + physics.tick( 1.0 ); + if (physics.numberOfParticles() > 1) updateCentroid(); + centroid.tick(); + + background( 0 ); + translate( width/2 , height/2 ); + scale( centroid.z() ); + translate( -centroid.x(), -centroid.y() ); + + drawNetwork(); +} + +void drawNetwork() { + fill( 100, 255, 100 ); + + // draw vertices + noStroke(); + String name; + Iterator j = nodes.values().iterator(); + host h; + while (j.hasNext()) { + h = (host) j.next(); + Particle v = h.node; + ellipse(v.position().x(), v.position().y(), NODE_SIZE, NODE_SIZE); + name = h.name; + text(name, v.position().x() - (name.length() * 26 / 10), v.position().y() + 14); + } + + // draw center + /* + ellipse( center0.position().x(), center0.position().y(), NODE_SIZE * 2, NODE_SIZE * 2 ); + name = "Center0"; + text(name, center0.position().x() - (name.length() * 26 / 10), center0.position().y() + 14); + ellipse( center1.position().x(), center1.position().y(), NODE_SIZE * 2, NODE_SIZE * 2 ); + name = "Center1"; + text(name, center1.position().x() - (name.length() * 26 / 10), center1.position().y() + 14); + */ + + // draw edges + stroke( 160 ); + beginShape( LINES ); + for ( int i = 0; i < physics.numberOfSprings(); ++i ) { + Spring e = physics.getSpring( i ); + Particle a = e.getOneEnd(); + Particle b = e.getTheOtherEnd(); + vertex( a.position().x(), a.position().y() ); + vertex( b.position().x(), b.position().y() ); + } + endShape(); +} + +void keyPressed() { + if ( key == 'c' ) { + initializePhysics(); + return; + } + + if ( key == ' ' ) { + Particle p = physics.makeParticle(); + addRelation(p, physics.getParticle( (int) random( 0, physics.numberOfParticles()-1) )); + addAttraction(p); + return; + } +} + +void updateCentroid() { + float + xMax = Float.NEGATIVE_INFINITY, + xMin = Float.POSITIVE_INFINITY, + yMin = Float.POSITIVE_INFINITY, + yMax = Float.NEGATIVE_INFINITY; + + for ( int i = 0; i < physics.numberOfParticles(); ++i ) { + Particle p = physics.getParticle( i ); + xMax = max( xMax, p.position().x() ); + xMin = min( xMin, p.position().x() ); + yMin = min( yMin, p.position().y() ); + yMax = max( yMax, p.position().y() ); + } + float deltaX = xMax-xMin; + float deltaY = yMax-yMin; + if ( deltaY > deltaX ) + centroid.setTarget( xMin + 0.5*deltaX, yMin +0.5*deltaY, height/(deltaY+50) ); + else + centroid.setTarget( xMin + 0.5*deltaX, yMin +0.5*deltaY, width/(deltaX+50) ); +} + +void initializePhysics() { + physics.clear(); + center0 = physics.makeParticle(1.0, 0, 0, 0); + center0.makeFixed(); + center1 = physics.makeParticle(1.0, EDGE_LENGTH * 30, 0, 0); + center1.makeFixed(); + centroid.setValue( 0, 0, 1.0 ); +} + +void addAttraction(Particle p) { + physics.makeAttraction(center0, p, 5000.0, 3 * EDGE_LENGTH); + physics.makeAttraction(center1, p, 5000.0, 3 * EDGE_LENGTH); + + // spacers + for ( int i = 0; i < physics.numberOfParticles(); ++i ) { + Particle q = physics.getParticle( i ); + if (p != q) physics.makeAttraction( p, q, -SPACER_STRENGTH, 20); + } +} + +void addRelation(Particle p, Particle other) { + physics.makeSpring( p, other, EDGE_STRENGTH, EDGE_STRENGTH, EDGE_LENGTH ); + //p.moveTo( q.position().x() + random( -1, 1 ), q.position().y() + random( -1, 1 ), 0 ); +} + +static class host { + String name; + Particle node; + public host(String name, Particle node) { + this.name = name; + this.node = node; + } +} diff --git a/htroot/processing/domaingraph/applet/index.html b/htroot/processing/domaingraph/applet/index.html new file mode 100755 index 000000000..6aac5de48 --- /dev/null +++ b/htroot/processing/domaingraph/applet/index.html @@ -0,0 +1,104 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> + <head> + <!-- charset must remain utf-8 to be handled properly by Processing --> + <meta http-equiv="content-type" content="text/html; charset=utf-8" /> + + <title>domaingraph : Built with Processing</title> + + <style type="text/css"> + /* <![CDATA[ */ + + body { + margin: 60px 0px 0px 55px; + font-family: verdana, geneva, arial, helvetica, sans-serif; + font-size: 11px; + background-color: #ddddcc; + text-decoration: none; + font-weight: normal; + line-height: normal; + } + + a { color: #3399cc; } + a:link { color: #3399cc; text-decoration: underline; } + a:visited { color: #3399cc; text-decoration: underline; } + a:active { color: #3399cc; text-decoration: underline; } + a:hover { color: #3399cc; text-decoration: underline; } + + /* ]]> */ + </style> + + </head> + <body> + <div id="content"> + <div id="domaingraph_container"> + + <!--[if !IE]> --> + <object classid="java:domaingraph.class" + type="application/x-java-applet" + archive="domaingraph.jar" + width="660" height="400" + standby="Loading Processing software..." > + + <param name="archive" value="domaingraph.jar" /> + + <param name="mayscript" value="true" /> + <param name="scriptable" value="true" /> + + <param name="image" value="loading.gif" /> + <param name="boxmessage" value="Loading Processing software..." /> + <param name="boxbgcolor" value="#FFFFFF" /> + + <param name="test_string" value="outer" /> + <!--<![endif]--> + + <object classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93" + codebase="http://java.sun.com/update/1.4.2/jinstall-1_4_2_12-windows-i586.cab" + width="660" height="400" + standby="Loading Processing software..." > + + <param name="code" value="domaingraph" /> + <param name="archive" value="domaingraph.jar" /> + + <param name="mayscript" value="true" /> + <param name="scriptable" value="true" /> + + <param name="image" value="loading.gif" /> + <param name="boxmessage" value="Loading Processing software..." /> + <param name="boxbgcolor" value="#FFFFFF" /> + + <param name="test_string" value="inner" /> + + <p> + <strong> + This browser does not have a Java Plug-in. + <br /> + <a href="http://java.sun.com/products/plugin/downloads/index.html" title="Download Java Plug-in"> + Get the latest Java Plug-in here. + </a> + </strong> + </p> + + </object> + + <!--[if !IE]> --> + </object> + <!--<![endif]--> + + </div> + + <p> + + </p> + + <p> + Source code: <a href="domaingraph.pde">domaingraph</a> + </p> + + <p> + Built with <a href="http://processing.org" title="Processing.org">Processing</a> + </p> + </div> + </body> +</html> diff --git a/htroot/processing/domaingraph/applet/loading.gif b/htroot/processing/domaingraph/applet/loading.gif Binary files differnew file mode 100755 index 000000000..1ddae5089 --- /dev/null +++ b/htroot/processing/domaingraph/applet/loading.gif diff --git a/htroot/processing/domaingraph/domaingraph.pde b/htroot/processing/domaingraph/domaingraph.pde new file mode 100755 index 000000000..e79f083e7 --- /dev/null +++ b/htroot/processing/domaingraph/domaingraph.pde @@ -0,0 +1,227 @@ +// Domain visualization graph for YaCy +// by Michael Christen +// +// this applet uses code and the physics engine from +// http://www.cs.princeton.edu/~traer/physics/ +// from Jeffrey Traer Bernstein +// redistribution is granted according to forum posting in +// http://processing.org/discourse/yabb_beta/YaBB.cgi?board=os_libraries_tools;action=display;num=1139193613 + +import traer.physics.*; +import traer.animation.*; +import processing.net.*; + +final float NODE_SIZE = 6; +final float EDGE_LENGTH = 50; +final float EDGE_STRENGTH = 0.01; +final float SPACER_STRENGTH = 10; + +ParticleSystem physics; +Smoother3D centroid; +PFont font; +Client myClient; +Particle center0, center1; // two gravity centers to support object ordering for non-quadratic fields +String parsingHostName = ""; +String parsingHostID = ""; +HashMap nodes = new HashMap(); // map that holds host objects + +void setup() { + + String[] fontList = PFont.list(); + //println(fontList); + font = createFont(fontList[0], 32); //just take any, should be mostly Arial + textFont(font, 12); + + size(660, 400); + smooth(); + frameRate( 24 ); + strokeWeight( 2 ); + ellipseMode( CENTER ); + + physics = new ParticleSystem( 0, 0.25 ); + centroid = new Smoother3D( 0.8 ); + + initializePhysics(); + initRequest(); +} + +void initRequest() { + myClient = new Client(this, "localhost", 8080); + myClient.write("GET /xml/webstructure.xml HTTP/1.1\n"); + myClient.write("Host: localhost\n\n"); +} + +void processRequestResponse() { + if (myClient.available() > 0) { + String line = myClient.readStringUntil((byte) 10); + //println("Line: " + line); + if (line == null) line = ""; else line = line.trim(); + if (line.startsWith("<domain")) processDomain(parseProps(line.substring(7, line.length() - 1).trim())); + if (line.startsWith("<citation")) processCitation(parseProps(line.substring(9, line.length() - 2).trim())); + } +} + +HashMap parseProps(String s) { + String[] l = s.split(" "); + HashMap map = new HashMap(); + int p; + String z; + for (int i = 0; i < l.length; i++) { + p = l[i].indexOf("="); + if (p > 0) { + z = l[i].substring(p + 1).trim(); + if (z.charAt(0) == '"') z = z.substring(1); + if (z.charAt(z.length() - 1) == '"') z = z.substring(0, z.length() - 1); + map.put(l[i].substring(0, p), z); + } + } + return map; +} + +void processDomain(HashMap props) { + //println("Domain: " + props.toString()); + parsingHostName = (String) props.get("host"); if (parsingHostName == null) parsingHostName = ""; + parsingHostID = (String) props.get("id"); if (parsingHostID == null) parsingHostID = ""; + host h = new host(parsingHostName, physics.makeParticle(1.0, random(0, EDGE_LENGTH * 30), random(- EDGE_LENGTH * 2, EDGE_LENGTH * 2), 0)); + nodes.put(parsingHostID, h); + addAttraction(h.node); +} + +void processCitation(HashMap props) { + //println("Citation: " + props.toString()); + String host = (String) props.get("host"); if (host == null) host = ""; + String id = (String) props.get("id"); if (id == null) id = ""; + int count = 0; + try { + String counts = (String) props.get("count"); if (counts != null) count = Integer.parseInt(counts); + } catch (NumberFormatException e) {} + // find the two nodes that have a relation + host h = (host) nodes.get(id); + if (h == null) return; // host is not known TODO: store these and create relation later + host p = (host) nodes.get(parsingHostID); // this should be successful + addRelation(h.node, p.node); +} + +void draw() { + processRequestResponse(); + + physics.tick( 1.0 ); + if (physics.numberOfParticles() > 1) updateCentroid(); + centroid.tick(); + + background( 0 ); + translate( width/2 , height/2 ); + scale( centroid.z() ); + translate( -centroid.x(), -centroid.y() ); + + drawNetwork(); +} + +void drawNetwork() { + fill( 100, 255, 100 ); + + // draw vertices + noStroke(); + String name; + Iterator j = nodes.values().iterator(); + host h; + while (j.hasNext()) { + h = (host) j.next(); + Particle v = h.node; + ellipse(v.position().x(), v.position().y(), NODE_SIZE, NODE_SIZE); + name = h.name; + text(name, v.position().x() - (name.length() * 26 / 10), v.position().y() + 14); + } + + // draw center + /* + ellipse( center0.position().x(), center0.position().y(), NODE_SIZE * 2, NODE_SIZE * 2 ); + name = "Center0"; + text(name, center0.position().x() - (name.length() * 26 / 10), center0.position().y() + 14); + ellipse( center1.position().x(), center1.position().y(), NODE_SIZE * 2, NODE_SIZE * 2 ); + name = "Center1"; + text(name, center1.position().x() - (name.length() * 26 / 10), center1.position().y() + 14); + */ + + // draw edges + stroke( 160 ); + beginShape( LINES ); + for ( int i = 0; i < physics.numberOfSprings(); ++i ) { + Spring e = physics.getSpring( i ); + Particle a = e.getOneEnd(); + Particle b = e.getTheOtherEnd(); + vertex( a.position().x(), a.position().y() ); + vertex( b.position().x(), b.position().y() ); + } + endShape(); +} + +void keyPressed() { + if ( key == 'c' ) { + initializePhysics(); + return; + } + + if ( key == ' ' ) { + Particle p = physics.makeParticle(); + addRelation(p, physics.getParticle( (int) random( 0, physics.numberOfParticles()-1) )); + addAttraction(p); + return; + } +} + +void updateCentroid() { + float + xMax = Float.NEGATIVE_INFINITY, + xMin = Float.POSITIVE_INFINITY, + yMin = Float.POSITIVE_INFINITY, + yMax = Float.NEGATIVE_INFINITY; + + for ( int i = 0; i < physics.numberOfParticles(); ++i ) { + Particle p = physics.getParticle( i ); + xMax = max( xMax, p.position().x() ); + xMin = min( xMin, p.position().x() ); + yMin = min( yMin, p.position().y() ); + yMax = max( yMax, p.position().y() ); + } + float deltaX = xMax-xMin; + float deltaY = yMax-yMin; + if ( deltaY > deltaX ) + centroid.setTarget( xMin + 0.5*deltaX, yMin +0.5*deltaY, height/(deltaY+50) ); + else + centroid.setTarget( xMin + 0.5*deltaX, yMin +0.5*deltaY, width/(deltaX+50) ); +} + +void initializePhysics() { + physics.clear(); + center0 = physics.makeParticle(1.0, 0, 0, 0); + center0.makeFixed(); + center1 = physics.makeParticle(1.0, EDGE_LENGTH * 30, 0, 0); + center1.makeFixed(); + centroid.setValue( 0, 0, 1.0 ); +} + +void addAttraction(Particle p) { + physics.makeAttraction(center0, p, 5000.0, 3 * EDGE_LENGTH); + physics.makeAttraction(center1, p, 5000.0, 3 * EDGE_LENGTH); + + // spacers + for ( int i = 0; i < physics.numberOfParticles(); ++i ) { + Particle q = physics.getParticle( i ); + if (p != q) physics.makeAttraction( p, q, -SPACER_STRENGTH, 20); + } +} + +void addRelation(Particle p, Particle other) { + physics.makeSpring( p, other, EDGE_STRENGTH, EDGE_STRENGTH, EDGE_LENGTH ); + //p.moveTo( q.position().x() + random( -1, 1 ), q.position().y() + random( -1, 1 ), 0 ); +} + +static class host { + String name; + Particle node; + public host(String name, Particle node) { + this.name = name; + this.node = node; + } +} |
