import netscape.javascript.*; import processing.net.*; PFont fontA; Client c; String data=""; String alldata=""; String texttodraw=""; color[] colorarray = { #990000, #0066CC, #000000, #C0C0C0, #C0C0C0 }; float offsetfortext=200; float borderwidth=10; float diagramwidth=800; float diagramheight=800-offsetfortext; float marginedwidth=diagramwidth-2*borderwidth; float marginedheight=diagramheight-2*borderwidth; float marginedmindimension=min(marginedwidth,marginedheight); float maxradius=0; boolean labelbeingdrawn=false; Markers markers; GrayLines graylines; GrayCircles graycircles; int updown = 0; //zoom and translation uses code from http://processing.org/discourse/yabb_beta/YaBB.cgi?board=Programs;action=display;num=1209738832 int leftright = 0; float targetzoom=1; float currentzoom=targetzoom; float previouszoom=targetzoom; float zoomFraction=1.0; JSObject win; String targetURL; float scaleX(float startingX) { float finalX = diagramwidth/2 + (marginedmindimension/2) * startingX/maxradius; return finalX; } float scaleY(float startingY) { float finalY =offsetfortext/2+diagramheight/2 + (marginedmindimension/2) * startingY/maxradius; return finalY; } void setup() { fontA = loadFont("Optima-Regular-12.vlw"); win = JSObject.getWindow(this); targetURL = "http://treetapper.nescent.org/templates/findneed_stream.php?tablenames=generalquestion,posedquestion&tableoptions=0,0"; // Set the font and its size (in units of pixels) textFont(fontA, 12); markers=new Markers(); graylines=new GrayLines(); graycircles=new GrayCircles(); ellipseMode(CENTER); frameRate(60); size(800,800); diagramwidth=width; diagramheight=height; smooth(); noStroke(); //fill(#FFFFFF); //rect(0, 0, diagramwidth, diagramheight); c = new Client(this, "treetapper.nescent.org", 80); // Connect to server on port 80 c.write("GET http://treetapper.nescent.org/templates/findneed_stream.php?tablenames=posedquestion&tableoptions=0 HTTP/1.1\n"); // Use the HTTP "GET" command to ask for a Web page // c.write("GET " + targetURL + " HTTP/1.1\n"); // Use the HTTP "GET" command to ask for a Web page maxradius=2; //CHANGE THIS BASED ON DEPTH ABOVE c.write("Host: TreeTapper\n\n"); // Be polite and say who we are } void draw() { String newtargetURL = (String) win.getMember("globalTargetURL"); if (newtargetURL.equals( targetURL)) { } else { noLoop(); if (newtargetURL.indexOf("findneed_stream.php")>0) { targetURL=newtargetURL; currentzoom=1; targetzoom=1; zoomFraction=1; leftright=0; updown=0; c.clear(); c.stop(); c = new Client(this, "treetapper.nescent.org", 80); // Connect to server on port 80 // String testurl="http://treetapper.nescent.org/templates/findneed_stream.php?tablenames=criterion,generalquestion,posedquestion&tableoptions=0,0,0"; //c.write("GET http://treetapper.nescent.org/templates/findneed_stream.php?tablenames=criterion,generalquestion,posedquestion&tableoptions=0,0,0 HTTP/1.1\n"); c.write("GET " + targetURL + " HTTP/1.1\n"); // Use the HTTP "GET" command to ask for a Web page c.write("Host: TreeTapper\n\n"); // Be polite and say who we are graylines.clear(); markers.clear(); graycircles.clear(); data=""; alldata=""; //clear out existing data String globaltableoptionsString=(String) win.getMember("globaltableoptions"); int tableoptions[]=int(split(globaltableoptionsString,',')); maxradius=0; float circleradius[]=new float[tableoptions.length]; for (int i=0; i 0) { // If there's incoming data from the client... data=c.readString(); alldata=alldata + data; } String element=""; //contains a full <> element int xmlstart = alldata.indexOf('<'); int xmlend = alldata.indexOf('>'); if (xmlstart>=0 && xmlend>0 && xmlend>xmlstart) { //if there's a match element=alldata.substring(xmlstart+1,xmlend); //println("element is " + element); String elementlist[] = split(element, '|'); if (int(elementlist[0])==0) { //is a regular marker //0|startlat|startlng|endlat|endlng|colortype|methodcount|softwarecount|label|methodlabel|softwarelabel|tooltip|url //noStroke(); //fill(colorarray[int(elementlist[5])]); //ellipse(scaleX(float(elementlist[3])), scaleY(float(elementlist[4])),5,5); markers.addMarker(scaleX(float(elementlist[1])), scaleY(float(elementlist[2])),scaleX(float(elementlist[3])), scaleY(float(elementlist[4])),colorarray[int(elementlist[5])],elementlist[8],elementlist[12]); } else if (int(elementlist[0])==1) { //is a gray line graylines.addGrayLine(scaleX(float(elementlist[1])), scaleY(float(elementlist[2])),scaleX(float(elementlist[3])), scaleY(float(elementlist[4])),colorarray[3],markers.getlast()); } String alldatanew=alldata.substring(xmlend+1); alldata=alldatanew; } graycircles.display(); graylines.display(); markers.display(); drawlabeltext(); } class Marker{ float startX,startY,endX,endY,currentX,currentY; float stepFraction=0.2; float totalFraction=0.0; float diameter=5; color fillcolor; String label; String weblink; Marker(float startX, float startY, float endX, float endY, color fillcolor, String label, String weblink) { this.startX=startX; this.startY=startY; this.currentX=startX; this.currentY=startY; this.endX=endX; this.endY=endY; this.fillcolor=fillcolor; this.label=label; this.weblink=weblink; } void display() { noStroke(); fill(fillcolor); ellipse(currentX,currentY,diameter/currentzoom,diameter/currentzoom); if (totalFraction<1.0) { totalFraction=min(totalFraction+stepFraction,1.0); //so that we don't go past if an integral number of stepFractions can't sum to 1 (i.e., stepFraction=0.09) currentX=startX+totalFraction*(endX-startX); currentY=startY+totalFraction*(endY-startY); } else { //we're there! Draw line, too stroke(fillcolor); line(startX,startY,endX,endY); } } boolean finished() { boolean done=false; if ((currentX==endX) && (currentY==endY)) { done=true; } return done; } void overMarker() { float disX = currentzoom*(currentX + leftright) - mouseX; float disY = currentzoom*(currentY + updown) - mouseY; if((sqrt(sq(disX) + sq(disY)) < currentzoom*diameter/2) && !labelbeingdrawn ) { labelbeingdrawn=true; stroke(153); fill(#FFFF33); ellipse(currentX,currentY,4*diameter/currentzoom,4*diameter/currentzoom); noStroke(); fill(fillcolor); ellipse(currentX,currentY,diameter/currentzoom,diameter/currentzoom); texttodraw=label; if (mousePressed==true) { //we're clicking on the point link(weblink); } } } } void drawlabeltext() { scale(1.0); translate (-leftright,-updown); textAlign(LEFT,TOP); textMode(SCREEN); //text(label, currentX+diameter*2, currentY-diameter*2,200,200); int textwidth=int(width-2*borderwidth); int textheight=int(offsetfortext-2*borderwidth); fill(color(230,230,230,200)); noStroke(); rect(0,0,width/currentzoom,offsetfortext/currentzoom); fill(0); text(texttodraw, borderwidth,borderwidth,textwidth,textheight); } class Markers{ ArrayList markers; Markers() { //constructor markers=new ArrayList(); } void addMarker(float startX, float startY, float endX, float endY, color fillcolor, String label, String weblink) { markers.add(new Marker( startX, startY, endX, endY, fillcolor, label, weblink)); } void clear() { markers.clear(); } int getlast() { int lastid=-1+markers.size(); return lastid; } boolean checkfinished(int markerid) { Marker n=(Marker) markers.get(markerid); if (n.finished()) { return true; } else { return false; } } void display() { if (markers.size()>0) { Marker m = (Marker) markers.get(0); m.display(); m.overMarker(); } for (int i=1; i < markers.size(); i++) { Marker n=(Marker) markers.get(i-1); if (n.finished()) { //only display a marker if the previous one has finished moving Marker m = (Marker) markers.get(i); m.display(); m.overMarker(); } else if (markers.size()-i>20) { //if there are lot of markers already stored, start drawing anyway Marker m = (Marker) markers.get(i); m.display(); m.overMarker(); } } } } class GrayLines{ ArrayList graylines; GrayLines() { //constructor graylines=new ArrayList(); } void addGrayLine(float startX, float startY, float endX, float endY, color linecolor, int lastmarker) { graylines.add(new GrayLine( startX, startY, endX, endY, linecolor, lastmarker)); } void clear() { graylines.clear(); } void display() { for (int i=0; i < graylines.size(); i++) { GrayLine m=(GrayLine) graylines.get(i); m.display(); } } } class GrayCircle{ float radius, centerX, centerY; color linecolor; GrayCircle(float centerX, float centerY, float radius, color linecolor) { this.radius=radius; this.linecolor=linecolor; this.centerX=centerX; this.centerY=centerY; } void display() { stroke(linecolor); noFill(); ellipse(centerX,centerY,2*radius,2*radius); } } class GrayCircles{ ArrayList graycircles; GrayCircles() { //constructor graycircles=new ArrayList(); } void addGrayCircle(float centerX, float centerY, float radius, color linecolor) { graycircles.add(new GrayCircle( centerX, centerY, radius, linecolor)); } void clear() { graycircles.clear(); } void display() { for (int i=0; i < graycircles.size(); i++) { GrayCircle m=(GrayCircle) graycircles.get(i); m.display(); } } } class GrayLine{ float startX,startY,endX,endY; color linecolor; int lastmarker; GrayLine(float startX, float startY, float endX, float endY, color linecolor, int lastmarker) { this.startX=startX; this.startY=startY; this.endX=endX; this.endY=endY; this.linecolor=linecolor; this.lastmarker=lastmarker; } void display() { if (markers.checkfinished(lastmarker)) { stroke(linecolor); line(startX,startY,endX,endY); } } } void keyPressed() { if (key == CODED) { if (keyCode == DOWN) { updown = updown-30; } else if (keyCode == UP ) { updown = updown+30; } else if (keyCode == RIGHT) { leftright = leftright-30; } else if (keyCode == LEFT) { leftright = leftright+30; } } if(key == '+') { previouszoom=currentzoom; targetzoom=currentzoom + 0.5; zoomFraction=0; //println(zoom); } else if (key == '-') { previouszoom=currentzoom; targetzoom=max(currentzoom - 0.5, 0.5); zoomFraction=0; // println(zoom); } }