/* SPL Visualization - SPL Total CD checkin on Feb 1, 2008 ** Name: Yung-Ting Chuang ** Class: MAT259 ** Perm Number: 607-6417 ** In this project I collected all ** CDs that is being checkin on Feb 1, 2008 */ import proxml.*; // imports the proxml library PFont font; XMLInOut xml; // creates a variable named 'xml' that will hold an XMLInOut object boolean isXMLParsed = false; /* GRAPH STYLE INFORMATION */ int graphXPos = 100; // the x Position of the graph int graphYPos = 50; int graphWidth = 775; // graph width int graphHeight = 650; String filename="Checkout on February 1 2008,.xml"; String filenameShort; String[] filenameType; //int classical=0, jazz=0, rock=0, gospel=0, pop=0, misc=0; //int rap=0, country=0, reggae=0, folk=0; int[][] data = new int[24][10]; void setup() { smooth(); for(int a=0; a<24; a++){ for(int b=0; b<10; b++){ data[a][b]=0; } } size(1024,768); font = loadFont("HelveticaNeue-CondensedBold-16.vlw"); xml = new XMLInOut(this); // creates an XMLInOut object and stores it in the 'xml' variable //xml.loadElement("http://tango.mat.ucsb.edu/mat259/aggregatedfiles/yung-ting_oneday_1_15.xml"); // loads the xml file into the XMLInOut object stored in the variable 'xml' xml.loadElement(filename); // you can also download the xml file into your sketch folder and then load it locally... just comment out the above line and uncomment this one } void xmlEvent(XMLElement element) { // this method is called when the main (or root) xml element is finished loading. 'element' represents the root xml element XMLElement[] days; // create an array of XMLElements named 'e' XMLElement[] hours; XMLElement[] books; XMLElement[] ss; int i,j, kk, k; XMLElement t, subject; String itemtype; int dewey; int totalCD = 0; int totalCheckin = 0; String music_type="", music_word="", music_word2=""; String[] musictype; if(element.hasChildren()) { //this gets all the elements in one day days = element.getChildren(); for(i=0; i=780 && dewey<=788))){ //if(itemtype.equals("accd")){ //println("No." + totalCD); totalCD++; //println("item type is: " + itemtype); //println("dewey: " + dewey); for(k=0; k=2){ music_word2 = musictype[1]; } if(music_word.equalsIgnoreCase("jazz") || music_word.equalsIgnoreCase("blues") ||music_word.equalsIgnoreCase("latin") || music_word.equalsIgnoreCase("soul") ||music_word.equalsIgnoreCase("bop") || music_word.equalsIgnoreCase("swing"))data[j][1]++; else if(music_word.equalsIgnoreCase("rock") ||music_word.equalsIgnoreCase("punk") ||(music_word.equalsIgnoreCase("new") && music_word2.equalsIgnoreCase("wave")) ||(music_word.equalsIgnoreCase("heavy") && music_word2.equalsIgnoreCase("metal")) ||(music_word.equalsIgnoreCase("grunge")))data[j][2]++; else if(music_word.equalsIgnoreCase("rap"))data[j][5]++; else if(music_word.equalsIgnoreCase("popular"))data[j][4]++; else if(music_word.equalsIgnoreCase("reggae"))data[j][6]++; else if(music_word.equalsIgnoreCase("folk") || music_word.equalsIgnoreCase("world"))data[j][7]++; else if(music_word.equalsIgnoreCase("gospel") || music_word.equalsIgnoreCase("bluegrass") || music_word.equalsIgnoreCase("christian"))data[j][3]++; else if(music_word.equalsIgnoreCase("country") || dewey==781)data[j][8]++; else if(dewey==785 || dewey==784 || dewey==786 || dewey==787 || dewey==788)data[j][0]++; else if(dewey==782) data[j][9]++; } //println("subject is: " + subject.firstChild().getText()); } } } } } } println("finally we know there are " + totalCD + " CD"); println("finally we know there are " + totalCheckin + " items checkin"); for(int aa=0; aa<24; aa++){ println(aa + " array"); println("finally we know there are " + log(data[aa][0])/log(10) + " classical items"); println("finally we know there are " + log(data[aa][1])/log(10) + " jazz items"); println("finally we know there are " + log(data[aa][2])/log(10) + " rock items"); println("finally we know there are " + log(data[aa][3])/log(10) + " gospel items"); println("finally we know there are " + log(data[aa][4])/log(10) + " pop items"); println("finally we know there are " + log(data[aa][5])/log(10) + " rap items"); println("finally we know there are " + log(data[aa][6])/log(10) + " reggae items"); println("finally we know there are " + log(data[aa][7])/log(10) + " folk items"); println("finally we know there are " + log(data[aa][8])/log(10) + " country items"); println("finally we know there are " + log(data[aa][9])/log(10) + " misc vocal music items"); } //wanna see all data for(int a=0; a<24; a++){ //for(int b=0; b<10; b++){ //println("data at : " + a + "," + b + " has " + data[a][b] + " items"); println("data at : " + a + " has " + data[a][4] + " items = log " + log(data[a][4])/log(10)); // } } isXMLParsed = true; } void draw() { background(255); fill(0xFF775555); textFont(font); if(!isXMLParsed) { // if the xml has not finished parsing... text("LOADING AND PARSING XML ...", 15, 30); // ... notify the user }else{ drawGrid(); // draw the grid and axis labels (a custom function made below) drawData(); // draw the datapoints //circle activity ellipse(mouseX, mouseY, 33, 33); } } void drawData() { noStroke(); // don't draw a border around the datapoint rectanges noLoop(); // don't loop anymore once the data is drawn to the screen fill(0xFFDDCCCC); //first draw all points for(int c=10; c<18; c++){ int d=c+1; fill(255, 223, 1); if(data[c][0]==0) ellipse(graphXPos+(d-11)*108, graphYPos+graphHeight, 10, 10); else ellipse(graphXPos+(d-11)*108, graphYPos+graphHeight-((log(data[c][0])/log(10))/0.01*2.4), 10, 10); //rect(graphXPos+d*108, graphYPos+graphHeight-((log(data[c][0])/log(10))/0.01*2.4), 10, 10); fill(103, 45, 255); if(data[c][1]==0) ellipse(graphXPos+(d-11)*108, graphYPos+graphHeight, 10, 10); else ellipse(graphXPos+(d-11)*108, graphYPos+graphHeight-((log(data[c][1])/log(10))/0.01*2.4), 10, 10); //rect(graphXPos+d*108, graphYPos+graphHeight-((log(data[c][1])/log(10))/0.01*2.4), 10, 10); fill(54, 20, 255); if(data[c][2]==0) ellipse(graphXPos+(d-11)*108, graphYPos+graphHeight, 10, 10); else ellipse(graphXPos+(d-11)*108, graphYPos+graphHeight-((log(data[c][2])/log(10))/0.01*2.4), 10, 10); //rect(graphXPos+d*108, graphYPos+graphHeight-((log(data[c][2])/log(10))/0.01*2.4), 10, 10); fill(145, 239, 255); if(data[c][3]==0) ellipse(graphXPos+(d-11)*108, graphYPos+graphHeight, 10, 10); else ellipse(graphXPos+(d-11)*108, graphYPos+graphHeight-((log(data[c][3])/log(10))/0.01*2.4), 10, 10); //rect(graphXPos+d*108, graphYPos+graphHeight-((log(data[c][3])/log(10))/0.01*2.4), 10, 10); fill(179, 118, 0); if(data[c][4]==0) ellipse(graphXPos+(d-11)*108, graphYPos+graphHeight, 10, 10); else ellipse(graphXPos+(d-11)*108, graphYPos+graphHeight-((log(data[c][4])/log(10))/0.01*2.4), 10, 10); //rect(graphXPos+d*108, graphYPos+graphHeight-((log(data[c][4])/log(10))/0.01*2.4), 10, 10); fill(0); if(data[c][5]==0) ellipse(graphXPos+(d-11)*108, graphYPos+graphHeight, 10, 10); else ellipse(graphXPos+(d-11)*108, graphYPos+graphHeight-((log(data[c][5])/log(10))/0.01*2.4), 10, 10); //rect(graphXPos+d*108, graphYPos+graphHeight-((log(data[c][5])/log(10))/0.01*2.4), 10, 10); fill(56,179,91); if(data[c][6]==0) ellipse(graphXPos+(d-11)*108, graphYPos+graphHeight, 10, 10); else ellipse(graphXPos+(d-11)*108, graphYPos+graphHeight-((log(data[c][6])/log(10))/0.01*2.4), 10, 10); //rect(graphXPos+d*108, graphYPos+graphHeight-((log(data[c][6])/log(10))/0.01*2.4), 10, 10); fill(146,168,179); if(data[c][7]==0) ellipse(graphXPos+(d-11)*108, graphYPos+graphHeight, 10, 10); else ellipse(graphXPos+(d-11)*108, graphYPos+graphHeight-((log(data[c][7])/log(10))/0.01*2.4), 10, 10); //rect(graphXPos+d*108, graphYPos+graphHeight-((log(data[c][7])/log(10))/0.01*2.4), 10, 10); fill(179,148,115); if(data[c][8]==0) ellipse(graphXPos+(d-11)*108, graphYPos+graphHeight, 10, 10); else ellipse(graphXPos+(d-11)*108, graphYPos+graphHeight-((log(data[c][8])/log(10))/0.01*2.4), 10, 10); //rect(graphXPos+d*108, graphYPos+graphHeight-((log(data[c][8])/log(10))/0.01*2.4), 10, 10); fill(81,255,161); if(data[c][9]==0) ellipse(graphXPos+(d-11)*108, graphYPos+graphHeight, 10, 10); else ellipse(graphXPos+(d-11)*108, graphYPos+graphHeight-((log(data[c][9])/log(10))/0.01*2.4), 10, 10); //rect(graphXPos+d*108, graphYPos+graphHeight-((log(data[c][9])/log(10))/0.01*2.4), 10, 10); } //stroke(0xFFDDCCCC); //then connect them together for(int e=11; e<18; e++){ int f=e-1; strokeWeight(2); stroke(255, 223, 1); if(data[f][0]==0 && data[f+1][0]!=0) line(graphXPos+(e-11)*108, graphYPos+graphHeight, graphXPos+(e+1-11)*108, graphYPos+graphHeight-((log(data[f+1][0])/log(10))/0.01*2.4)); else if(data[f][0]!=0 && data[f+1][0]==0) line(graphXPos+(e-11)*108, graphYPos+graphHeight-((log(data[f][0])/log(10))/0.01*2.4), graphXPos+(e+1-11)*108, graphYPos+graphHeight); else if(data[f][0]==0 && data[f+1][0]==0) line(graphXPos+(e-11)*108, graphYPos+graphHeight, graphXPos+(e+1-11)*108, graphYPos+graphHeight); else line(graphXPos+(e-11)*108, graphYPos+graphHeight-((log(data[f][0])/log(10))/0.01*2.4), graphXPos+(e+1-11)*108, graphYPos+graphHeight-((log(data[f+1][0])/log(10))/0.01*2.4)); stroke(103, 45, 255); if(data[f][1]==0 && data[f+1][1]!=0) line(graphXPos+(e-11)*108, graphYPos+graphHeight, graphXPos+(e+1-11)*108, graphYPos+graphHeight-((log(data[f+1][1])/log(10))/0.01*2.4)); else if(data[f][1]!=0 && data[f+1][1]==0) line(graphXPos+(e-11)*108, graphYPos+graphHeight-((log(data[f][1])/log(10))/0.01*2.4), graphXPos+(e+1-11)*108, graphYPos+graphHeight); else if(data[f][1]==0 && data[f+1][1]==0) line(graphXPos+(e-11)*108, graphYPos+graphHeight, graphXPos+(e+1-11)*108, graphYPos+graphHeight); else line(graphXPos+(e-11)*108, graphYPos+graphHeight-((log(data[f][1])/log(10))/0.01*2.4), graphXPos+(e+1-11)*108, graphYPos+graphHeight-((log(data[f+1][1])/log(10))/0.01*2.4)); stroke(54, 20, 255); if(data[f][2]==0 && data[f+1][2]!=0) line(graphXPos+(e-11)*108, graphYPos+graphHeight, graphXPos+(e+1-11)*108, graphYPos+graphHeight-((log(data[f+1][2])/log(10))/0.01*2.4)); else if(data[f][2]!=0 && data[f+1][2]==0) line(graphXPos+(e-11)*108, graphYPos+graphHeight-((log(data[f][2])/log(10))/0.01*2.4), graphXPos+(e+1-11)*108, graphYPos+graphHeight); else if(data[f][2]==0 && data[f+1][2]==0) line(graphXPos+(e-11)*108, graphYPos+graphHeight, graphXPos+(e+1-11)*108, graphYPos+graphHeight); else line(graphXPos+(e-11)*108, graphYPos+graphHeight-((log(data[f][2])/log(10))/0.01*2.4), graphXPos+(e+1-11)*108, graphYPos+graphHeight-((log(data[f+1][2])/log(10))/0.01*2.4)); stroke(145, 239, 255); if(data[f][3]==0 && data[f+1][3]!=0) line(graphXPos+(e-11)*108, graphYPos+graphHeight, graphXPos+(e+1-11)*108, graphYPos+graphHeight-((log(data[f+1][3])/log(10))/0.01*2.4)); else if(data[f][3]!=0 && data[f+1][3]==0) line(graphXPos+(e-11)*108, graphYPos+graphHeight-((log(data[f][3])/log(10))/0.01*2.4), graphXPos+(e+1-11)*108, graphYPos+graphHeight); else if(data[f][3]==0 && data[f+1][3]==0) line(graphXPos+(e-11)*108, graphYPos+graphHeight, graphXPos+(e+1-11)*108, graphYPos+graphHeight); else line(graphXPos+(e-11)*108, graphYPos+graphHeight-((log(data[f][3])/log(10))/0.01*2.4), graphXPos+(e+1-11)*108, graphYPos+graphHeight-((log(data[f+1][3])/log(10))/0.01*2.4)); stroke(179, 118, 0); if(data[f][4]==0 && data[f+1][4]!=0) line(graphXPos+(e-11)*108, graphYPos+graphHeight, graphXPos+(e+1-11)*108, graphYPos+graphHeight-((log(data[f+1][4])/log(10))/0.01*2.4)); else if(data[f][4]!=0 && data[f+1][4]==0) line(graphXPos+(e-11)*108, graphYPos+graphHeight-((log(data[f][4])/log(10))/0.01*2.4), graphXPos+(e+1-11)*108, graphYPos+graphHeight); else if(data[f][4]==0 && data[f+1][4]==0) line(graphXPos+(e-11)*108, graphYPos+graphHeight, graphXPos+(e+1-11)*108, graphYPos+graphHeight); else line(graphXPos+(e-11)*108, graphYPos+graphHeight-((log(data[f][4])/log(10))/0.01*2.4), graphXPos+(e+1-11)*108, graphYPos+graphHeight-((log(data[f+1][4])/log(10))/0.01*2.4)); stroke(0, 0,0); if(data[f][5]==0 && data[f+1][5]!=0) line(graphXPos+(e-11)*108, graphYPos+graphHeight, graphXPos+(e+1-11)*108, graphYPos+graphHeight-((log(data[f+1][5])/log(10))/0.01*2.4)); else if(data[f][5]!=0 && data[f+1][5]==0) line(graphXPos+(e-11)*108, graphYPos+graphHeight-((log(data[f][5])/log(10))/0.01*2.4), graphXPos+(e+1-11)*108, graphYPos+graphHeight); else if(data[f][5]==0 && data[f+1][5]==0) line(graphXPos+(e-11)*108, graphYPos+graphHeight, graphXPos+(e+1-11)*108, graphYPos+graphHeight); else line(graphXPos+(e-11)*108, graphYPos+graphHeight-((log(data[f][5])/log(10))/0.01*2.4), graphXPos+(e+1-11)*108, graphYPos+graphHeight-((log(data[f+1][5])/log(10))/0.01*2.4)); stroke(56,179,91); if(data[f][6]==0 && data[f+1][6]!=0) line(graphXPos+(e-11)*108, graphYPos+graphHeight, graphXPos+(e+1-11)*108, graphYPos+graphHeight-((log(data[f+1][6])/log(10))/0.01*2.4)); else if(data[f][6]!=0 && data[f+1][6]==0) line(graphXPos+(e-11)*108, graphYPos+graphHeight-((log(data[f][6])/log(10))/0.01*2.4), graphXPos+(e+1-11)*108, graphYPos+graphHeight); else if(data[f][6]==0 && data[f+1][6]==0) line(graphXPos+(e-11)*108, graphYPos+graphHeight, graphXPos+(e+1-11)*108, graphYPos+graphHeight); else line(graphXPos+(e-11)*108, graphYPos+graphHeight-((log(data[f][6])/log(10))/0.01*2.4), graphXPos+(e+1-11)*108, graphYPos+graphHeight-((log(data[f+1][6])/log(10))/0.01*2.4)); stroke(146,168,179); if(data[f][7]==0 && data[f+1][7]!=0) line(graphXPos+(e-11)*108, graphYPos+graphHeight, graphXPos+(e+1-11)*108, graphYPos+graphHeight-((log(data[f+1][7])/log(10))/0.01*2.4)); else if(data[f][7]!=0 && data[f+1][7]==0) line(graphXPos+(e-11)*108, graphYPos+graphHeight-((log(data[f][7])/log(10))/0.01*2.4), graphXPos+(e+1-11)*108, graphYPos+graphHeight); else if(data[f][7]==0 && data[f+1][7]==0) line(graphXPos+(e-11)*108, graphYPos+graphHeight, graphXPos+(e+1-11)*108, graphYPos+graphHeight); else line(graphXPos+(e-11)*108, graphYPos+graphHeight-((log(data[f][7])/log(10))/0.01*2.4), graphXPos+(e+1-11)*108, graphYPos+graphHeight-((log(data[f+1][7])/log(10))/0.01*2.4)); stroke(179,148,115); if(data[f][8]==0 && data[f+1][8]!=0) line(graphXPos+(e-11)*108, graphYPos+graphHeight, graphXPos+(e+1-11)*108, graphYPos+graphHeight-((log(data[f+1][8])/log(10))/0.01*2.4)); else if(data[f][8]!=0 && data[f+1][8]==0) line(graphXPos+(e-11)*108, graphYPos+graphHeight-((log(data[f][8])/log(10))/0.01*2.4), graphXPos+(e+1-11)*108, graphYPos+graphHeight); else if(data[f][8]==0 && data[f+1][8]==0) line(graphXPos+(e-11)*108, graphYPos+graphHeight, graphXPos+(e+1-11)*108, graphYPos+graphHeight); else line(graphXPos+(e-11)*108, graphYPos+graphHeight-((log(data[f][8])/log(10))/0.01*2.4), graphXPos+(e+1-11)*108, graphYPos+graphHeight-((log(data[f+1][8])/log(10))/0.01*2.4)); stroke(81,255,161); if(data[f][9]==0 && data[f+1][9]!=0) line(graphXPos+(e-11)*108, graphYPos+graphHeight, graphXPos+(e+1-11)*108, graphYPos+graphHeight-((log(data[f+1][9])/log(10))/0.01*2.4)); else if(data[f][9]!=0 && data[f+1][9]==0) line(graphXPos+(e-11)*108, graphYPos+graphHeight-((log(data[f][9])/log(10))/0.01*2.4), graphXPos+(e+1-11)*108, graphYPos+graphHeight); else if(data[f][9]==0 && data[f+1][9]==0) line(graphXPos+(e-11)*108, graphYPos+graphHeight, graphXPos+(e+1-11)*108, graphYPos+graphHeight); else line(graphXPos+(e-11)*108, graphYPos+graphHeight-((log(data[f][9])/log(10))/0.01*2.4), graphXPos+(e+1-11)*108, graphYPos+graphHeight-((log(data[f+1][9])/log(10))/0.01*2.4)); } //now draw textbox for color information stroke(0xFFDDCCCC); // set the stroke (border) color for future drawing method calls fill(255); //rect(graphXPos+graphWidth+20, graphYPos, 100, graphHeight); fill(255, 223, 1); //ellipse(graphXPos+graphWidth+40, graphYPos+graphHeight - (1*60), 10, 10); //rect(graphXPos+graphWidth+40, graphYPos+graphHeight - (1*60), 10, 10); text("Classical", graphXPos+graphWidth+50, graphYPos+graphHeight+5 - (1*20)-400); fill(103, 45, 255); //ellipse(graphXPos+graphWidth+40, graphYPos+graphHeight - (2*60), 10, 10); //rect(graphXPos+graphWidth+40, graphYPos+graphHeight - (2*60), 10, 10); text("Jazz", graphXPos+graphWidth+50, graphYPos+graphHeight+5 - (2*20)-400); fill(54, 20, 255); //ellipse(graphXPos+graphWidth+40, graphYPos+graphHeight - (3*60), 10, 10); //rect(graphXPos+graphWidth+40, graphYPos+graphHeight - (3*60), 10, 10); text("Rock", graphXPos+graphWidth+50, graphYPos+graphHeight+5 - (3*20)-400); fill(145, 239, 255); //ellipse(graphXPos+graphWidth+40, graphYPos+graphHeight - (4*60), 10, 10); //rect(graphXPos+graphWidth+40, graphYPos+graphHeight - (4*60), 10, 10); text("Gospel", graphXPos+graphWidth+50, graphYPos+graphHeight+5 - (4*20)-400); fill(179, 118, 0); //ellipse(graphXPos+graphWidth+40, graphYPos+graphHeight - (5*60), 10, 10); //rect(graphXPos+graphWidth+40, graphYPos+graphHeight - (5*60), 10, 10); text("Pop", graphXPos+graphWidth+50, graphYPos+graphHeight+5 - (5*20)-400); fill(0); //ellipse(graphXPos+graphWidth+40, graphYPos+graphHeight - (6*60), 10, 10); //rect(graphXPos+graphWidth+40, graphYPos+graphHeight - (6*60), 10, 10); text("Rap", graphXPos+graphWidth+50, graphYPos+graphHeight+5 - (6*20)-400); fill(56,179,91); //ellipse(graphXPos+graphWidth+40, graphYPos+graphHeight - (7*60), 10, 10); //rect(graphXPos+graphWidth+40, graphYPos+graphHeight - (7*60), 10, 10); text("Reggae", graphXPos+graphWidth+50, graphYPos+graphHeight+5 - (7*20)-400); fill(146,168,179); //ellipse(graphXPos+graphWidth+40, graphYPos+graphHeight - (8*60), 10, 10); //rect(graphXPos+graphWidth+40, graphYPos+graphHeight - (8*60), 10, 10); text("Folk", graphXPos+graphWidth+50, graphYPos+graphHeight+5 - (8*20)-400); fill(179,148,115); //ellipse(graphXPos+graphWidth+40, graphYPos+graphHeight - (9*60), 10, 10); //rect(graphXPos+graphWidth+40, graphYPos+graphHeight - (9*60), 10, 10); text("Country", graphXPos+graphWidth+50, graphYPos+graphHeight+5 - (9*20)-400); fill(81,255,161); //ellipse(graphXPos+graphWidth+40, graphYPos+graphHeight - (10*60), 10, 10); //rect(graphXPos+graphWidth+40, graphYPos+graphHeight - (10*60), 10, 10); text("Misc", graphXPos+graphWidth+50, graphYPos+graphHeight+5 - (10*20)-400); } void drawGrid() { stroke(0xFFDDCCCC); // set the stroke (border) color for future drawing method calls fill(255); // set the fill to white //rect(graphXPos, graphYPos, graphWidth, graphHeight); // draw a rectangle with a border where the data will go... we will draw the datapoints over the top of this... just drawn to get the border line(graphXPos, graphYPos, graphXPos, graphYPos+graphHeight); line(graphXPos, graphYPos+graphHeight, graphXPos+graphWidth, graphYPos+graphHeight); fill(0xFFBB9999); // set the fill color for when we draw our text textFont(font); textAlign(RIGHT); // align our text flush right with the x coordinate we give when we call the text() method //this is for drawing Y-axis for(int i=0; i <= 10; i++) { // this loops write the axis labels for the y axis if(i!=0){ text(str(int(pow(10, i*0.25))), 85, graphYPos+graphHeight - (i*60)); line(90, graphYPos+graphHeight - (i*60), 100, graphYPos+graphHeight-(i*60)); } } //this is for drawing X-axis for(int i=0; i <= 7; i++) { // this loops write the axis labels for the y axis if(i!=0) line(graphXPos+(i*108), graphYPos+graphHeight, graphXPos+(i*108), graphYPos+graphHeight+5); text(str(i+10), graphXPos+(i*108), graphYPos+graphHeight+20); } textAlign(LEFT); fill(0xFF775555); filenameType = filename.split(","); filenameShort = filenameType[0]; text("SPL Total CD " + filenameShort + " (Total # checkin vs. Hour)", 100, 30); // write title text text("Hour", graphXPos+graphWidth-20, graphYPos+graphHeight+40); text("Total", graphXPos-95, graphYPos+20); }