User Tools

Site Tools


courses:2009.03.25.xml.multilayering

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
courses:2009.03.25.xml.multilayering [2009/03/25 14:01]
camille fixed typo
courses:2009.03.25.xml.multilayering [2009/03/25 14:01] (current)
camille fixed typo
Line 1: Line 1:
 +====== march 25 2009: XML dataset, info visualization and basic multilayering ======
  
 +==== Recreating Google Analytics graph in Processing with XML data ====
 +  * Start with the raw XML file from Google Analytics, containing one year of results. {{:​courses:​data_raw.xml.zip|}}
 +  * Clean manually the XML data to focus just on the needed data. Use a good XML editor for this part, it is much nicer. Some freebies: [[http://​free.editix.com]],​ [[http://​www.freexmleditor.com]]
 +  * Final XML file after cleaning: {{:​courses:​google_data.xml.zip|}}
 +
 +
 +==== Step 0: draw all points ====
 +
 +{{:​courses:​xml_google_0.jpg|}}
 +
 +Source files:​{{:​courses:​xml_google_0.zip|}}
 +<code java>
 +XMLElement xml;
 +
 +void setup() {
 +  size(800, 300);
 +  ​
 +  // load the xml file, make sure the file is in the sketch folder
 +  xml = new XMLElement(this,​ "​google_data.xml"​);​
 +  ​
 +  noStroke();
 +  smooth();
 +  // count the number of points we have in the file  ​
 +  int datapoints = xml.getChildCount();​
 +  println(datapoints);​
 +    ​
 +  // loop for all nodes/​points in the xml
 +  for (int i = 0; i < datapoints; i++){
 +
 +    XMLElement onePoint = xml.getChild(i); ​
 +    ​
 +    // extract value, we use int( ) to cast String to an int
 +    int oneValue = int(onePoint.getChild(0).getContent());​
 +
 +    int xPos = i * 2;
 +
 +    ellipse(xPos,​ height - oneValue, 3, 3);
 +
 +    //println(i + " " +  oneValue);
 +
 +  }
 +
 +}
 +</​code>​
 +
 +==== Step 1: draw as a shape ====
 +
 +{{:​courses:​xml_google_1.jpg|}}
 +
 +Source files:​{{:​courses:​xml_google_1.zip|}}
 +<code java>
 +XMLElement xml;
 +
 +void setup() {
 +  size(800, 300);
 +
 +  // load the xml file, make sure the file is in the sketch folder
 +  xml = new XMLElement(this,​ "​google_data.xml"​);​
 +
 +  noStroke();
 +  smooth();
 +
 +  // count the number of points we have in the file  ​
 +  int datapoints = xml.getChildCount();​
 +  println(datapoints);​
 +
 +  // color for the shape
 +  fill(255, 0, 0);
 +
 +  // we start the shape at bottom left
 +  beginShape();​
 +  vertex(0, height);
 +
 +  // loop for all nodes/​points in the xml
 +  for (int i = 0; i < datapoints; i++){
 +
 +    XMLElement onePoint = xml.getChild(i); ​
 +
 +    // extract value, we use int( ) to cast String to an int
 +    int oneValue = int(onePoint.getChild(0).getContent());​
 +
 +    int xPos = i * 2;
 +
 +    // add all the points to main shape
 +    vertex(xPos,​ height - oneValue);
 +
 +    //println(i + " " +  oneValue);
 +
 +  }
 +
 +  // last point on the bottom
 +  vertex(datapoints * 2, height);
 +  endShape(CLOSE);​
 +
 +}
 +</​code>​
 +
 +==== Step 2: isolate part of the data, different color ====
 +
 +{{:​courses:​xml_google_2.jpg|}}
 +
 +Source files:​{{:​courses:​xml_google_2.zip|}}
 +<code java>
 +XMLElement xml;
 +
 +void setup() {
 +  size(800, 300);
 +
 +  // load the xml file, make sure the file is in the sketch folder
 +  xml = new XMLElement(this,​ "​google_data.xml"​);​
 +
 +  noStroke();
 +  smooth();
 +  // count the number of points we have in the file  ​
 +  int datapoints = xml.getChildCount();​
 +  println(datapoints);​
 +
 +  // color for rect
 +  fill(255, 0, 0);
 +
 +  // change drawing mode as it is easier to draw in this config
 +  rectMode(CORNERS);​
 +
 +  // loop for all nodes/​points in the xml
 +  for (int i = 0; i < datapoints; i++){
 +
 +    XMLElement onePoint = xml.getChild(i); ​
 +
 +    // extract value, we use int( ) to cast String to an int
 +    int oneValue = int(onePoint.getChild(0).getContent());​
 +
 +    // extract date String
 +    String oneDate = onePoint.getChild(1).getContent();​
 +
 +    int xPos = i * 2;
 +
 +    //​ selection for the color based on month
 +    // indexOf returns the index position of the sub-text in the string
 +    // indexOf returns -1 if the sub-text is not found in the String
 +
 +    if ( oneDate.indexOf("​October"​) > 0 ){
 +      fill(0, 255, 0);
 +    }
 +    else if (oneDate.indexOf("​December"​) > 0){
 +      fill (100, 100, 0);
 +    }
 +    else{
 +      fill(255);
 +    }
 +
 +    // draw the skinny rectangles
 +    rect(xPos, height, xPos + 2, height - oneValue); ​
 +
 +    //println(i + " " +  oneValue);
 +
 +  }
 +
 +}
 +</​code>​
 +
 +==== Step 3: only show data from one month ====
 +
 +{{:​courses:​xml_google_3.jpg|}}
 +
 +Source files:​{{:​courses:​xml_google_3.zip|}}
 +<code java>
 +XMLElement xml;
 +
 +// arrays to store the values, maximum of 31 days per month
 +int[] octoberValues = new int[32];
 +int[] novemberValues = new int[32];
 +int[] decemberValues = new int[32];
 +
 +//​ pointers for each array
 +int octoberPointer = 0;
 +int novemberPointer = 0;
 +int decemberPointer = 0;
 +
 +
 +void setup() {
 +  size(800, 300);
 +  frameRate(10);​
 +  noStroke();
 +  fill(255, 0, 0);
 +
 +  // load the xml file, make sure the file is in the sketch folder
 +  xml = new XMLElement(this,​ "​google_data.xml"​);​
 +
 +
 +  // count the number of points we have in the file  ​
 +  int datapoints = xml.getChildCount();​
 +
 +  for (int i = 0; i < datapoints; i++){
 +
 +    XMLElement onePoint = xml.getChild(i); ​
 +
 +    // extract value, we use int( ) to cast String to an int
 +    int oneValue = int(onePoint.getChild(0).getContent());​
 +
 +    // extract date String
 +    String oneDate = onePoint.getChild(1).getContent();​
 +
 +    //​ selection for the color based on month
 +    if (oneDate.indexOf("​October"​) > 0 ){
 +
 +      // save the value to the array
 +      octoberValues[octoberPointer] = oneValue;
 +
 +      // increment to pointer, ready for next reading
 +      octoberPointer++;​
 +    }
 +    //println(i + " " +  oneValue);
 +  }
 +
 +}
 +
 +void draw(){
 +
 +  smooth();
 +
 +  // draw one shape for the October data only
 +  beginShape();​
 +  vertex (0, height);
 +
 +  // loop through all values
 +  for (int i = 0; i< octoberPointer;​ i++){
 +
 +    int oneValue = octoberValues[i];​
 +
 +    // scale the x value to we can spread/​extend to a large portion of the screen
 +    int xPos = i * 20;
 +
 +    vertex(xPos,​ height - oneValue);
 +
 +  }
 +  vertex(800, height);
 +  endShape(CLOSE);​
 +
 +}
 +</​code>​
 +
 +
 +==== Step 4: all 3 curves in 3D, moving along the Z axis ====
 +
 +{{:​courses:​xml_google_4.jpg|}}
 +
 +Source files:​{{:​courses:​xml_google_4.zip|}}
 +<code java>
 +XMLElement xml;
 +
 +int[] octoberValues = new int[32];
 +int[] novemberValues = new int[32];
 +int[] decemberValues = new int[32];
 +
 +int octoberPointer = 0;
 +int novemberPointer = 0;
 +int decemberPointer = 0;
 +
 +float octoberZ = 0.0;
 +
 +
 +void setup() {
 +  size(800, 300, P3D);
 +  frameRate(15);​
 +  noStroke();
 +
 +  xml = new XMLElement(this,​ "​google_data.xml"​);​
 +
 +  int datapoints = xml.getChildCount();​
 +
 +  for (int i = 0; i < datapoints; i++){
 +
 +    XMLElement onePoint = xml.getChild(i); ​
 +
 +    int oneValue = int(onePoint.getChild(0).getContent());​
 +    String oneDate = onePoint.getChild(1).getContent();​
 +
 +    // selection for the color based on month
 +    if (oneDate.indexOf("​October"​) > 0 ){
 +      octoberValues[octoberPointer] = oneValue;
 +      octoberPointer++;​
 +    }
 +
 +    if (oneDate.indexOf("​November"​) > 0 ){
 +      novemberValues[novemberPointer] = oneValue;
 +      novemberPointer++;​
 +    }
 +
 +    if (oneDate.indexOf("​December"​) > 0 ){
 +      decemberValues[decemberPointer] = oneValue;
 +      decemberPointer++;​
 +    }
 +    //println(i + " " +  oneValue);
 +
 +  }
 +
 +}
 +
 +void draw(){
 +  smooth();
 +  background(255);​
 +
 +  // october curve
 +  fill(255, 255, 0, 100);
 +  beginShape();​
 +  vertex (0, height, octoberZ);
 +
 +  for (int i = 0; i< octoberPointer;​ i++){
 +    int oneValue = octoberValues[i];​
 +    int xPos = i * 20;
 +    vertex(xPos,​ height - oneValue, octoberZ);
 +  }
 +  vertex(800, height, octoberZ);
 +  endShape(CLOSE);​
 +  // end of october curve
 +  octoberZ = octoberZ - 10;
 +
 +  // november curve
 +  fill(0, 0, 155, 100);
 +  beginShape();​
 +  vertex (0, height, -50);
 +
 +  for (int i = 0; i< novemberPointer;​ i++){
 +    int oneValue = novemberValues[i];​
 +    int xPos = i * 20;
 +    vertex(xPos,​ height - oneValue, -50);
 +  }
 +  vertex(800, height, -50);
 +  endShape(CLOSE);​
 +  // end of november curve
 +
 +
 +  // december curve
 +  fill(255, 0, 0, 100);
 +  beginShape();​
 +  vertex (0, height, -100);
 +
 +  for (int i = 0; i< decemberPointer;​ i++){
 +    int oneValue = decemberValues[i];​
 +    int xPos = i * 20;
 +    vertex(xPos,​ height - oneValue, -100);
 +  }
 +  vertex(800, height, -100);
 +  endShape(CLOSE);​
 +  // end of december curve
 +
 +
 +  println(octoberZ);​
 +}
 +</​code>​
 +
 +
 +==== Step 5: 3 curves in 3D, preparing Z position for each curve ====
 +
 +{{:​courses:​xml_google_5.jpg|}}
 +
 +Active key presses: o, n, d
 +
 +Source files:​{{:​courses:​xml_google_5.zip|}}
 +<code java>
 +XMLElement xml;
 +
 +int[] octoberValues = new int[32];
 +int[] novemberValues = new int[32];
 +int[] decemberValues = new int[32];
 +
 +int octoberPointer = 0;
 +int novemberPointer = 0;
 +int decemberPointer = 0;
 +
 +// variables for z position for each curve
 +float octoberZ = 0.0;
 +float novemberZ = 0.0;
 +float decemberZ = 0.0;
 +float baseZ = -10000;
 +
 +
 +void setup() {
 +  size(800, 300, P3D);
 +  frameRate(25);​
 +  noStroke();
 +
 +  xml = new XMLElement(this,​ "​google_data.xml"​);​
 +
 +  int datapoints = xml.getChildCount();​
 +
 +  for (int i = 0; i < datapoints; i++){
 +
 +    XMLElement onePoint = xml.getChild(i); ​
 +
 +    int oneValue = int(onePoint.getChild(0).getContent());​
 +    String oneDate = onePoint.getChild(1).getContent();​
 +
 +    // selection for the color based on month
 +    if (oneDate.indexOf("​October"​) > 0 ){
 +      octoberValues[octoberPointer] = oneValue;
 +      octoberPointer++;​
 +    }
 +
 +    if (oneDate.indexOf("​November"​) > 0 ){
 +      novemberValues[novemberPointer] = oneValue;
 +      novemberPointer++;​
 +    }
 +
 +    if (oneDate.indexOf("​December"​) > 0 ){
 +      decemberValues[decemberPointer] = oneValue;
 +      decemberPointer++;​
 +    }
 +    //println(i + " " +  oneValue);
 +
 +  }
 +
 +}
 +
 +void draw(){
 +  smooth();
 +  background(255);​
 +
 +  // october curve
 +  fill(255, 255, 0, 100);
 +  beginShape();​
 +  vertex (0, height, octoberZ);
 +
 +  for (int i = 0; i< octoberPointer;​ i++){
 +    int oneValue = octoberValues[i];​
 +    int xPos = i * 20;
 +    vertex(xPos,​ height - oneValue, octoberZ);
 +  }
 +  vertex(800, height, octoberZ);
 +  endShape(CLOSE);​
 +  // end of october curve
 +  octoberZ = octoberZ - 10;
 +
 +  // november curve
 +  fill(0, 0, 155, 100);
 +  beginShape();​
 +  vertex (0, height, -50);
 +
 +  for (int i = 0; i< novemberPointer;​ i++){
 +    int oneValue = novemberValues[i];​
 +    int xPos = i * 20;
 +    vertex(xPos,​ height - oneValue, -50);
 +  }
 +  vertex(800, height, -50);
 +  endShape(CLOSE);​
 +  // end of november curve
 +
 +
 +  // december curve
 +  fill(255, 0, 0, 100);
 +  beginShape();​
 +  vertex (0, height, -100);
 +
 +  for (int i = 0; i< decemberPointer;​ i++){
 +    int oneValue = decemberValues[i];​
 +    int xPos = i * 20;
 +    vertex(xPos,​ height - oneValue, -100);
 +  }
 +  vertex(800, height, -100);
 +  endShape(CLOSE);​
 +  // end of december curve
 +
 +
 +  println(octoberZ);​
 +}
 +</​code>​
 +
 +
 +
 +==== Step 6: Static swap between curves ​ ====
 +
 +{{:​courses:​xml_google_6.jpg|}}
 +
 +Active key presses: o, n, d
 +
 +Source files:​{{:​courses:​xml_google_6.zip|}}
 +<code java>
 +import processing.opengl.*;​
 +
 +XMLElement xml;
 +
 +int[] octoberValues = new int[32];
 +int[] novemberValues = new int[32];
 +int[] decemberValues = new int[32];
 +
 +int octoberPointer = 0;
 +int novemberPointer = 0;
 +int decemberPointer = 0;
 +
 +float octoberZ = -10000;
 +float novemberZ =-10000;
 +float decemberZ = -10000;
 +float baseZ = -10000;
 +
 +
 +void setup() {
 +  size(800, 300, OPENGL);
 +  frameRate(25);​
 +  noStroke();
 +  xml = new XMLElement(this,​ "​google_data.xml"​);​
 +
 +  int datapoints = xml.getChildCount();​
 +
 +  for (int i = 0; i < datapoints; i++){
 +
 +    XMLElement onePoint = xml.getChild(i); ​
 +
 +    int oneValue = int(onePoint.getChild(0).getContent());​
 +    String oneDate = onePoint.getChild(1).getContent();​
 +
 +    // selection for the color based on month
 +    if (oneDate.indexOf("​October"​) > 0 ){
 +      octoberValues[octoberPointer] = oneValue;
 +      octoberPointer++;​
 +    }
 +
 +    if (oneDate.indexOf("​November"​) > 0 ){
 +      novemberValues[novemberPointer] = oneValue;
 +      novemberPointer++;​
 +    }
 +
 +    if (oneDate.indexOf("​December"​) > 0 ){
 +      decemberValues[decemberPointer] = oneValue;
 +      decemberPointer++;​
 +    }
 +    //println(i + " " +  oneValue);
 +
 +  }
 +
 +}
 +
 +void draw(){
 +  smooth();
 +  background(255);​
 +
 +  // october curve
 +  fill(255, 255, 0, 100);
 +  beginShape();​
 +  vertex (0, height, octoberZ);
 +
 +  for (int i = 0; i< octoberPointer;​ i++){
 +    int oneValue = octoberValues[i];​
 +    int xPos = i * 20;
 +    vertex(xPos,​ height - oneValue, octoberZ);
 +  }
 +  vertex(800, height, octoberZ);
 +  endShape(CLOSE);​
 +  // end of october curve
 +
 +  // november curve
 +  fill(0, 0, 155, 100);
 +  beginShape();​
 +  vertex (0, height, novemberZ);
 +
 +  for (int i = 0; i< novemberPointer;​ i++){
 +    int oneValue = novemberValues[i];​
 +    int xPos = i * 20;
 +    vertex(xPos,​ height - oneValue, novemberZ);
 +  }
 +  vertex(800, height, novemberZ);
 +  endShape(CLOSE);​
 +  // end of november curve
 +
 +
 +  // december curve
 +  fill(255, 0, 0, 100);
 +  beginShape();​
 +  vertex (0, height, decemberZ);
 +
 +  for (int i = 0; i< decemberPointer;​ i++){
 +    int oneValue = decemberValues[i];​
 +    int xPos = i * 20;
 +    vertex(xPos,​ height - oneValue, decemberZ);
 +  }
 +  vertex(800, height, decemberZ);
 +  endShape(CLOSE);​
 +  // end of december curve
 +
 +
 +  println(octoberZ);​
 +}
 +
 +void keyPressed() {
 +  if (key == '​o'​) {
 +    octoberZ = 0;
 +    novemberZ = baseZ;
 +    decemberZ = baseZ;
 +  } 
 +
 +  if (key == '​n'​) {
 +    octoberZ = baseZ;
 +    novemberZ = 0;
 +    decemberZ = baseZ;
 +  } 
 +
 +  if (key == '​d'​) {
 +    octoberZ = baseZ;
 +    novemberZ = baseZ;
 +    decemberZ = 0;
 +  } 
 +}
 +</​code>​
 +
 +
 +==== Step 7: smooth movement for all curves ​ ====
 +
 +{{:​courses:​xml_google_7.jpg|}}
 +
 +Active key presses: o, n, d
 +
 +Source files:​{{:​courses:​xml_google_7.zip|}}
 +<code java>
 +import processing.opengl.*;​
 +Integrator[] interpolators;​
 +
 +XMLElement xml;
 +
 +int[] octoberValues = new int[32];
 +int[] novemberValues = new int[32];
 +int[] decemberValues = new int[32];
 +
 +int octoberPointer = 0;
 +int novemberPointer = 0;
 +int decemberPointer = 0;
 +
 +float octoberZ = -10000;
 +float novemberZ =-10000;
 +float decemberZ = -10000;
 +float baseZ = -10000;
 +
 +
 +void setup() {
 +  size(800, 300, OPENGL);
 +  frameRate(25);​
 +  noStroke();
 +
 +  //​ initialize the interpolators
 +  interpolators = new Integrator[3];​
 +  interpolators[0] = new Integrator(-10000);​
 +  interpolators[1] = new Integrator(-10000);​
 +  interpolators[2] = new Integrator(-10000);​
 +
 +  // change the friction value of the october curve
 +  interpolators[0].damping = 0.7;
 +
 +  xml = new XMLElement(this,​ "​google_data.xml"​);​
 +
 +  int datapoints = xml.getChildCount();​
 +
 +  for (int i = 0; i < datapoints; i++){
 +
 +    XMLElement onePoint = xml.getChild(i); ​
 +
 +    int oneValue = int(onePoint.getChild(0).getContent());​
 +    String oneDate = onePoint.getChild(1).getContent();​
 +
 +    // selection for the color based on month
 +    if (oneDate.indexOf("​October"​) > 0 ){
 +      octoberValues[octoberPointer] = oneValue;
 +      octoberPointer++;​
 +    }
 +
 +    if (oneDate.indexOf("​November"​) > 0 ){
 +      novemberValues[novemberPointer] = oneValue;
 +      novemberPointer++;​
 +    }
 +
 +    if (oneDate.indexOf("​December"​) > 0 ){
 +      decemberValues[decemberPointer] = oneValue;
 +      decemberPointer++;​
 +    }
 +    //println(i + " " +  oneValue);
 +
 +  }
 +
 +}
 +
 +void draw(){
 +  smooth();
 +  background(255);​
 +
 +  // october curve
 +  interpolators[0].update();​
 +  fill(255, 255, 0, 100);
 +  beginShape();​
 +  vertex (0, height, interpolators[0].value);​
 +
 +  for (int i = 0; i< octoberPointer;​ i++){
 +    int oneValue = octoberValues[i];​
 +    int xPos = i * 20;
 +    vertex(xPos,​ height - oneValue, interpolators[0].value);​
 +  }
 +  vertex(800, height, interpolators[0].value);​
 +  endShape(CLOSE);​
 +  // end of october curve
 +
 +  // november curve
 +  interpolators[1].update();​
 +  fill(0, 0, 155, 100);
 +  beginShape();​
 +  vertex (0, height, interpolators[1].value);​
 +
 +  for (int i = 0; i< novemberPointer;​ i++){
 +    int oneValue = novemberValues[i];​
 +    int xPos = i * 20;
 +    vertex(xPos,​ height - oneValue, interpolators[1].value);​
 +  }
 +  vertex(800, height, interpolators[1].value);​
 +  endShape(CLOSE);​
 +  // end of november curve
 +
 +
 +  // december curve
 +  interpolators[2].update();​
 +  fill(255, 0, 0, 100);
 +  beginShape();​
 +  vertex (0, height, interpolators[2].value);​
 +
 +  for (int i = 0; i< decemberPointer;​ i++){
 +    int oneValue = decemberValues[i];​
 +    int xPos = i * 20;
 +    vertex(xPos,​ height - oneValue, interpolators[2].value);​
 +  }
 +  vertex(800, height, interpolators[2].value);​
 +  endShape(CLOSE);​
 +  // end of december curve
 +
 +
 +  println(octoberZ);​
 +}
 +
 +void keyPressed() {
 +  if (key == '​o'​) {
 +    //octoberZ = 0;
 +    interpolators[0].target(-100);​
 +    interpolators[1].target(baseZ);​
 +    interpolators[2].target(baseZ);​
 +  } 
 +
 +  if (key == '​n'​) {
 +    interpolators[0].target(baseZ);​
 +    interpolators[1].target(-100);​
 +    interpolators[2].target(baseZ);​
 +  } 
 +
 +  if (key == '​d'​) {
 +    interpolators[0].target(baseZ);​
 +    interpolators[1].target(baseZ);​
 +    interpolators[2].target(-100);​
 +  } 
 +}
 +</​code>​
courses/2009.03.25.xml.multilayering.txt · Last modified: 2009/03/25 14:01 by camille