/** * Bodycount * * visualizes the iraqi body count data from * http://www.iraqbodycount.net * * by Evan Raskob 2003_09_18 */ String lines[]; BFont metaBold; int cnt; //counter variable int maxmaxdead = 0; // maximum number of max dead reported int maxmindead = 0; // maximum number of min dead reported static final int ROWCOUNT = 177; // # of rows of data in file static final int RECTWIDTH = 3; // width of rectangles to draw, in pixels int min_max_dead[][]; // array of max,min data void setup() { size(ROWCOUNT*(RECTWIDTH+1), 400); min_max_dead = new int[2][177]; lines = loadStrings("iraqbodycount.txt"); background(#989898); metaBold = loadFont("Meta-Bold.vlw.gz"); setFont(metaBold, 40); hint(SMOOTH_IMAGES); // load data into array, find max/min of max & min bodycounts for (cnt = 0; cnt < ROWCOUNT; cnt++) { min_max_dead[0][cnt] = Integer.parseInt((splitStrings(lines[cnt], '\t')[6])); min_max_dead[1][cnt] = Integer.parseInt((splitStrings(lines[cnt], '\t')[7])); // find and store maximum number of deaths so that we can scale the graphics later if (min_max_dead[0][cnt] > maxmindead) maxmindead = min_max_dead[0][cnt]; if (min_max_dead[1][cnt] > maxmaxdead) maxmaxdead = min_max_dead[1][cnt]; /** DEBUG ** println("min = " + min_max_dead[0][cnt]); println("max = " + min_max_dead[1][cnt]); println("size = " + min_max_dead[0].length); */ } cursor(CROSS); } void loop() { // variables to hold the "scaled" versions of the data // "scaled" means divided by max bodycount for all data float scaled_diff = 0.0; float scaled_min = 0.0; float scaled_max = 0.0; float redFill = 0.0; // the red pixel fill value for the rectangles // start drawing push(); // Draw a rectagle for each row of data // representing the min bodycount proportional to // the max of the max body count reported. // Rectangle lengths are exponential (sqrt) // to add more visual weight to lower bodycounts // relative to higher bodycounts. for (cnt = 0; cnt < ROWCOUNT; cnt++) { scaled_diff = 1.0*(getMaxDead(cnt) - getMinDead(cnt))/getMaxDead(cnt); scaled_min = 1.0*getMinDead(cnt)/maxmaxdead; scaled_max = 1.0*getMaxDead(cnt)/maxmaxdead; //println("sm: " + scaled_min); // calculate red fill color value redFill = 90.0 + sqrt(1.0*getMinDead(cnt)/maxmindead) * 165.0; fill(redFill, 10, 15); rect(cnt*(RECTWIDTH+1), 0, RECTWIDTH, sqrt(scaled_min)*350.0); /** redFill = sqrt(scaled_diff)*255.0; fill(redFill, redFill, redFill); rect(cnt*(RECTWIDTH+1), sqrt(scaled_min)*350.0, RECTWIDTH, sqrt(scaled_max)*scaled_diff*350.0); */ } fill(230, 210, 120); int textX = 25; int textY = 85; int maxdead = getMaxDead(int(mouseX/(RECTWIDTH+1))); int mindead = getMinDead(int(mouseX/(RECTWIDTH+1))); float diffdead = (sqrt(1.0*maxdead/maxmaxdead) - sqrt(1.0*mindead/maxmaxdead)); float md = sqrt(1.0*maxdead/maxmaxdead); float nd = sqrt(1.0*mindead/maxmaxdead); if (mouseX > 0 && mouseX < ROWCOUNT*(RECTWIDTH+1)) { textX = constrain(mouseX+15, 2, width-60); textY = constrain(mouseY, 70, height-80); setFont(metaBold, 20); text("max :"+ maxdead, textX, textY); textY+=20; text("min :"+ mindead, textX, textY); // draw crosshair cursor fill(200,201,60); noStroke(); rectMode(CENTER_DIAMETER); rect(mouseX, mouseY, 2,10); rect(mouseX, mouseY, 10,2); stroke(0); rectMode(CORNER); } pop(); } // utility function for getting the max dead value // given a row number (index) int getMaxDead(int index) { int good = constrain(index, 0, ROWCOUNT); return min_max_dead[1][good]; } // utility function for getting the min dead value // given a row number (index) int getMinDead(int index) { int good = constrain(index, 0, ROWCOUNT); return min_max_dead[0][good]; }