Press "Enter" to skip to content

Draw with health data 2.0

Génération de dessin à partir des données du logiciel « Santé » de l’iPhone;
Le fichier healthXml.xml est généré par analyse et nettoyage du fichier exporter.xml du logiciel « Santé » grâce à un javascript (dossier: parsingXmlData) ;La forme du monde et les troncs sont générés à partir de l’heure et de la durée de chaque enregistrement; La taille des branches correspond à la distance parcourue, le nombre de sections, aux nombres de pas.

Sources: drawWorldWithHealthData.pde / Processing 3.3.1

/*  - drawWorldWithHealthData.pde - processing 3.0.1 - transat@stephanecabee.net
    - DataArt - Generation de dessin a partir de données XML.
    - Fichier healthXml.xml généré par script javascript à partir du fichier exporter.xml du logiciel "Santé" de l'iPhone (dossier//ParsingXmlData).
*/

XML xml;
XML[] recordXml;
XML[] newDateRecordsXml;
int numRecords;
int recordId = 153;  //choix de l'id de l'enregistrement

PGraphics healthShape;
PGraphics healthLine;

void setup() {
  size(1280, 960);
  background(255, 255, 255);
  smooth();
  
  //Chargement et stockage des données XML
  xml = loadXML("healthXml.xml");
  recordXml = xml.getChildren("record");
  numRecords = recordXml.length;
  println("Enregistrements: " + numRecords);
  readXML();
}

void draw() {
}


//Fonction de dessin du monde
void drawWorld(){
  newDateRecordsXml = recordXml[recordId].getChildren("records");
  String recordDate = recordXml[recordId].getString("date");
  PVector startPoint = new PVector();
  
  stroke(51, 153, 255);
  fill(0);
  strokeWeight(1);
  textSize(20);
  text(recordDate, width/2, height-20);
  
  //Dessin des troncs
  healthLine = createGraphics(width, height);
  healthLine.beginDraw();
  healthLine.noFill();
  
  healthShape = createGraphics(width, height);
  healthShape.beginDraw();
  healthShape.beginShape();
  color shapeColor = color(200, 200, 200, 80);
  healthShape.fill(shapeColor);
  healthShape.noStroke();
  
  for(int i=0; i<newDateRecordsXml.length; i++){
    //Récuperation des données des enregistrements
    int[] recordTime = int(split(newDateRecordsXml[i].getChildren("time")[0].getContent(), ':'));
    int recordHours = recordTime[0];
    int recordMinutes = int(recordTime[1]*10/60);
    int recordSteps = int(newDateRecordsXml[i].getChildren("steps")[0].getContent());
    String timeVector = str(recordHours) + '.' + str(recordMinutes);
    float timeFactor = float(timeVector);
    float recordDistance = float(newDateRecordsXml[i].getChildren("distance")[0].getContent())*200;
    float recordDuration = float(newDateRecordsXml[i].getChildren("duration")[0].getContent());
    float minuteOfHours = (recordTime[1]*10/60);
    float timeOfRecord = recordTime[0] + minuteOfHours/10;
    println("timeofRecord: " + timeOfRecord);
    
    int middleWidth = width/2;
    int middleHeight = height/2;
    
    PVector vStart = new PVector(0, middleHeight/2);
    vStart.rotate(radians(timeOfRecord*30) + PI);
    PVector vEnd = new PVector(0, recordDistance);
    vEnd.rotate(radians(timeOfRecord*30) + PI);
    
    PVector vSelected, v12, v24;
    vSelected = new PVector();
    v12 = new PVector(-recordDistance/2, -recordDistance/4);
    v12.rotate(radians(timeOfRecord*30) + PI);
    v24 = new PVector(recordDistance/2, -recordDistance/4);
    v24.rotate(radians(timeOfRecord*30) + PI);
    
    if(i == 0){
       startPoint.x = vStart.x - vEnd.x + middleWidth;
       startPoint.y = vStart.y - vEnd.y + middleHeight;
     }
    
    healthLine.pushMatrix();
    healthLine.translate(middleWidth, middleHeight);
    healthLine.noFill();
    healthLine.stroke(map(timeOfRecord, 0, 24, 0, 124));
    healthLine.strokeWeight(recordDuration/80);
    healthLine.strokeCap(SQUARE);
    healthLine.line(vStart.x, vStart.y, vStart.x + vEnd.x, vStart.y + vEnd.y);
    
    PVector vBranch = new PVector(0, recordDistance/recordSteps);
    vBranch.rotate(radians(timeOfRecord*30) + PI);
    
    //Dessin des branches
    healthLine.strokeWeight(0.1);
    for(int j=0; j<recordSteps; j++){
      if( (j % 2) == 0){
        vSelected = v12;
        healthLine.line(vStart.x + vBranch.x * j, vStart.y + vBranch.y * j, vStart.x + vBranch.x * j - vSelected.x, vStart.y + vBranch.y * j - vSelected.y); 
        println("v12");
      }else{
        vSelected = v24;
        healthLine.line(vStart.x + vBranch.x * j, vStart.y + vBranch.y * j, vStart.x + vBranch.x * j - vSelected.x, vStart.y + vBranch.y * j - vSelected.y); 
        println("v24");
      }
    }
    healthLine.popMatrix();
    
    //Dessin de la forme du monde
    healthShape.curveVertex(vStart.x + vEnd.x + middleWidth, vStart.y + vEnd.y + middleHeight);
    
    if( i == newDateRecordsXml.length - 1 ){
      healthShape.curveVertex(startPoint.x, startPoint.y);
      healthShape.endShape(CLOSE);
      healthShape.endDraw();
      
      healthLine.endDraw();
    }
    
  }
  
  image(healthShape, 0, 0);
  image(healthLine, 0, 0);
}


void readXML() {
  // Boucle de traitement des données XML
  for (int i = 0; i < 1; i++) {
    // Selection des données du tableau XML pour chaque entrée
    newDateRecordsXml = recordXml[recordId].getChildren("records");
    String recordDate = recordXml[recordId].getString("date");
    println("Record date: " + recordDate);
    
    for(int j=0; j<newDateRecordsXml.length; j++){
      String recordsId = newDateRecordsXml[j].getChildren("recordId")[0].getContent();
      String recordsTime = newDateRecordsXml[j].getChildren("time")[0].getContent();
      float recordsDuration = float(newDateRecordsXml[j].getChildren("duration")[0].getContent());
      float recordsDistance = float(newDateRecordsXml[j].getChildren("distance")[0].getContent());
      int recordsSteps = int(newDateRecordsXml[j].getChildren("steps")[0].getContent());
      println("   - " + recordsId + " / Début: " + recordsTime + " / Durée: " + recordsDuration + " / Distance: " + recordsDistance + " / Pas: " + recordsSteps + ".");
    }
  }
  
  drawWorld();
}

Comments are closed.