//Data Structure Parameters Node rootNode; ArrayList transactions = null; int date; int dew0; int dew1; String[] months = {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"}; String[] DeweyNamesLong = {"Information & Computer Science", "Philosophy & Psychology", "Religion", "Social Sciences", "Languages", "Science & Mathematics", "Technology & Applied Science", "Arts & Recreation", "Literature", "History & Geography & Biography" }; String[] DeweyNames = {"Info", "Phil", "Reli", "Soci.", "Lang", "Scie", "Tech", "Arts", "Lite", "Hist" }; String[] DeweyNums = {"000","100","200","300","400","500","600","700","800","900"}; String[] DeweyNumSubs = {"00","10","20","30","40","50","60","70","80","90"}; //stats float total = 0; float maxCategory = -1000000000; float minCategory = 1000000000; float avgCategory = 0; float totalCatSub = 0; float maxCatSub = -100000000.0; float minCatSub = 100000000.0; float avgCatSub = 0; float[] totalCatSubLev2 = new float[10]; float[] maxCatSubLev2 = new float[10]; float[] minCatSubLev2 = new float[10]; float[] avgCatSubLev2 = new float[10]; //Drawing Method Parameters float rs = 0; float[] c1 = new float[10]; float[] c2 = new float[10]; float x = 0; float y = 0; float x1 = 0; float y1 = 0; int posX = width/2; int posY = height/2; int num = 0; int gridspacing = 20; boolean grid = false; PFont Largefont; PFont Medfont; PFont Smallfont; Integrator interpolators_c0; Integrator[] interpolators_c1; Integrator[][] interpolators_c2; //Lovely Colors: int trans = 125; int linetrans = 70; int circtrans = 70; int fontclr = 255; int lineclr = 255; color from = #00E3FF; color to = #405EFF; //Interactivity boolean track = false; boolean explode = false; boolean toggle = false; void setup() { size(800,600); background(0); frameRate(60); smooth(); rootNode = new Node("root", color(255,0,0)); println("about to load..."); this.transactions = loadTransactions("splxmldata.txt"); Largefont = loadFont("HelveticaNeue-Light-30.vlw"); Medfont = loadFont("HelveticaNeue-Light-22.vlw"); Smallfont = loadFont("HelveticaNeue-Light-10.vlw"); initNodes(rootNode, 1); for(int i=0; i < transactions.size(); i+=1) { Transaction t = (Transaction) transactions.get(i); date = Integer.parseInt(t.ckidate); dew0 = Integer.parseInt(t.deweyClass.substring(0,1)); dew1 = Integer.parseInt(t.deweyClass.substring(1,2)); loadDataIntoNodes(dew0, dew1,date-1); } println(rootNode); printNodes(rootNode, 1); calculateStats(0); //Animation interpolators_c0 = new Integrator(rootNode.monthCounts[0]); interpolators_c0.attraction = .05; interpolators_c1 = new Integrator[10]; for (int x = 0; x < 10; x++) { interpolators_c1[x] = new Integrator(rootNode.children[x].monthCounts[0]); interpolators_c1[x].attraction = .05; } interpolators_c2 = new Integrator[10][10]; for (int x = 0; x < 10; x++) { for (int y = 0; y < 10; y++) { interpolators_c2[x][y] = new Integrator(rootNode.children[x].children[y].monthCounts[0]); interpolators_c2[x][y].attraction = .05; } } posX = width/2+width/10; posY = height/2+height/100; } void draw() { fill(0,100); noStroke(); rect(-2,-2,width+2,height+2); drawGrid(); interpolators_c0.update(); for(int x=0; x < 10; x++) { interpolators_c1[x].update(); for(int y=0; y < 10; y++) { interpolators_c2[x][y].update(); } } //insert recursive drawing function: pushMatrix(); drawCircles(num); popMatrix(); //root textFont(Smallfont); fill(255,100); textAlign(RIGHT,BOTTOM); text("REZA ALI - MAT 259 - INFORMATION VISUALIZATION", width-5, height-15); text("PROJECT 2 - 2D SPACE", width-5, height-5); if(toggle) { textFont(Medfont); textAlign(LEFT,TOP); for(int g = 0; g < 10; g++) { fill(lerpColor(#FFAA40,#3CFF03,(float)g/10),trans); text(DeweyNums[g] + " - " + DeweyNamesLong[g], 5,(5+g*20)); } } } void loadDataIntoNodes(int lev1, int lev2, int monthIdx) { rootNode.totalCount += 1; rootNode.monthCounts[monthIdx] += 1; Node child1 = rootNode.children[lev1]; child1.totalCount += 1; child1.monthCounts[monthIdx] += 1; Node child2 = child1.children[lev2]; child2.totalCount += 1; child2.monthCounts[monthIdx] += 1; } void initNodes(Node parent, int level) { parent.totalCount = 0; for (int month = 0; month < parent.monthCounts.length; month++) { parent.monthCounts[month] = 0; } for (int node = 0; node < parent.children.length; node++) { if (level == 1) { Node child = new Node("" + node + "00", color(0,255,0)); //println("\t" + level + ": " + node); initNodes(child, 2); //println("\t" + child); parent.children[node] = child; } if (level == 2) { Node child = new Node("" + node + "0", color(0,0,255) ); //println("\t\t" + level + ": " + node); initNodes(child, 3); //println("\t\t" + child); parent.children[node] = child; } } } void printNodes(Node parent, int level) { for (int node = 0; node < parent.children.length; node++) { if (level == 1) { print("" + level + ":\t"); } if (level == 2) { print("" + level + ":\t\t"); } println(parent.children[node]); if (level < 2) { printNodes(parent.children[node], level + 1); } } } public ArrayList loadTransactions(String nameOfDataFileWithinDataDirectory) { ArrayList transactions = new ArrayList(); String[] lines = loadStrings(nameOfDataFileWithinDataDirectory); for (int i = 0; i < lines.length; i++) { transactions.add(parseTransaction(lines[i])); } return transactions; } public Transaction parseTransaction(String line) { String sections[] = split(line, ","); Transaction t = new Transaction(); t.ckidate = sections[0]; if(sections.length> 1){ t.deweyClass = sections[1]; } return t; } void keyPressed() { /*if(key == 's') { saveFrame("Dewey-###.png"); }*/ if(key == '3') { explode = !explode; } if(key == '2') { toggle = !toggle; } if(key== '1') { num++; if(num>10) { num=0; } calculateStats(num); setCurrent(num); } if(key =='4') { grid = !grid; } } void calculateStats(int num) { for(int q = 0; q < 10; q++) { maxCatSubLev2[q] =-100000000.0; minCatSubLev2[q] = 100000000.0; } total = rootNode.totalCount; avgCategory = total/10.0; for(int l = 0; l < 12; l++) { if(rootNode.monthCounts[l] > maxCategory) { maxCategory = rootNode.monthCounts[l]; } if(rootNode.monthCounts[l] < minCategory) { minCategory = rootNode.monthCounts[l]; } } //println(minCategory); //println(maxCategory); maxCategory = maxCategory/total; minCategory = minCategory/total; for(int i = 0; i < 10; i++) { totalCatSub = rootNode.monthCounts[num]; avgCatSub = totalCatSub/10.0; //loop for months.... if(rootNode.children[i].monthCounts[num] > maxCatSub) { maxCatSub = rootNode.children[i].monthCounts[num]; } if(rootNode.children[i].monthCounts[num] < minCatSub) { minCatSub = rootNode.children[i].monthCounts[num]; } } maxCatSub = maxCatSub/totalCatSub; minCatSub = minCatSub/totalCatSub; for(int i = 0; i < 10; i++) { totalCatSubLev2[i] = rootNode.children[i].monthCounts[num]; avgCatSubLev2[i] = totalCatSubLev2[i]/10; for(int k = 0; k < 10; k++) { if(rootNode.children[i].children[k].monthCounts[num] > maxCatSubLev2[i]) { maxCatSubLev2[i] = rootNode.children[i].children[k].monthCounts[num]; } if(rootNode.children[i].children[k].monthCounts[num] < minCatSubLev2[i]) { minCatSubLev2[i] = rootNode.children[i].children[k].monthCounts[num]; } } maxCatSubLev2[i] = maxCatSubLev2[i]/totalCatSubLev2[i]; minCatSubLev2[i] = minCatSubLev2[i]/totalCatSubLev2[i]; } } void drawCircles(int monthIndex) { rs = (interpolators_c0.value/(float)rootNode.totalCount); rs = map(rs,minCategory,maxCategory,width/12,width/3); if(explode) { rs = pow(rs,1.05); } if(track) { translate(mouseX,mouseY); } else { translate(posX,posY); } noStroke(); fill(lerpColor(from, to,rs/(width/3)),circtrans); ellipse(0, 0, rs,rs); ellipse(0, 0, rs*.75,rs*.75); fill(fontclr,trans); textFont(Largefont); textAlign(CENTER,CENTER); text("Total",0,-50); text("Library",0,-25); text("Transations in",0,0); text(months[monthIndex],0,25); text((int)interpolators_c0.value,0,+50); for(int i = 0; i < 10; i++) { c1[i] = (interpolators_c1[i].value/(float)rootNode.monthCounts[monthIndex]); c1[i] = map(c1[i],minCatSub,maxCatSub,rs/3,rs/1.5); if(explode) { c1[i] = pow(c1[i],1.2); } x = (c1[i]+rs/2)*sin(((180-i*36)/180.0)*PI); y = (c1[i]+rs/2)*cos(((180-i*36)/180.0)*PI); strokeWeight(.5); stroke(lineclr,linetrans); line(0,0,x,y); noStroke(); fill(lerpColor(#FFAA40,#3CFF03,(float)i/10),circtrans); ellipse(x,y,c1[i],c1[i]); ellipse(x,y,c1[i]*.85,c1[i]*.85); fill(fontclr,trans); textFont(Medfont); textAlign(CENTER,CENTER); text(DeweyNames[i],x,y); text((int)interpolators_c1[i].value,x,y+18); text(DeweyNums[i],x,y-18); translate(x,y); for(int k = 0; k < 10; k++) { c2[k] = (interpolators_c2[i][k].value/(float)rootNode.children[i].monthCounts[monthIndex]); c2[k] = map(c2[k],minCatSubLev2[k],maxCatSubLev2[k],c1[i]/3,c1[i]/2); if(explode) { c2[i] = pow(c2[i],.9); } x1 = (c2[k]+c2[k]/2)*sin(((180-k*36)/180.0)*PI); y1 = (c2[k]+c2[k]/2)*cos(((180-k*36)/180.0)*PI); strokeWeight(.5); stroke(lineclr,linetrans); line(0,0,x1,y1); noStroke(); fill(lerpColor(#001E93,#81B0FF,2*(interpolators_c2[i][k].value/(float)rootNode.children[i].monthCounts[monthIndex])),circtrans); ellipse(x1,y1,c2[k],c2[k]); ellipse(x1,y1,c2[k]*.75,c2[k]*.75); fill(fontclr,trans); textFont(Smallfont); textAlign(CENTER,TOP); text((int)interpolators_c2[i][k].value,x1,y1); textAlign(CENTER,BOTTOM); text(DeweyNumSubs[k],x1,y1); } translate(-x,-y); } } void setCurrent(int num){ interpolators_c0.target(rootNode.monthCounts[num]); for(int x=0; x < 10; x++) { interpolators_c1[x].target(rootNode.children[x].monthCounts[num]); for(int y=0; y < 10; y++) { interpolators_c2[x][y].target(rootNode.children[x].children[y].monthCounts[num]); } } } void mousePressed() { track= !track; posX = mouseX; posY = mouseY; } void drawGrid() { if(grid){ for(int k = 0; k < width; k += gridspacing){ stroke(128,80); strokeWeight(.5); line(0,k,width,k); line(k,0,k,height); } } }