Can anyone tell me why this processing js sketch wont load the tsv data?

edited January 2015 in JavaScript Mode

I have created a simple graphic that loads a tsv file and parses it out into a visual display. Works fine locally but when published I get a grey screen and nothing on the website. I have removed everything from the data directory and it still does nothing?

http://datavisualizing.com/uncategorized/processing-flu-test/

//Visualizing Sketch By John R. Potter Based on "Datavisualizing" by Ben Fry
/* @pjs preload="font="http://datavisualizing.com/sketches/Flu/arial.ttf"; */
FloatTable data;
float dataMin,dataMax;
float plotX1,plotY1;
float plotX2,plotY2;
float labelX,labelY;

int currentColumn = 0;
int columnCount;

int weekMin, weekMax;
int[] weeks;

PFont plotFont;
// Declare variables PShape,PImage,Pfont etc….


//Declare constants

// Color Palette


void setup() {
  size(600,405);
 data = new FloatTable("flu.tsv");
 columnCount = data.getColumnCount();
 weeks = int(data.getRowNames());
 weekMin = weeks[0];
 weekMax = weeks[weeks.length - 1];
 dataMin = 0;
 dataMax =data.getTableMax();
 int weekInterval = 10;
 
 
 // Corners of the plotted time series
 plotX1 = 50;
 plotX2 = width - plotX1;
 plotY1 = 60;
 plotY2 = height - plotY1;
 labelX = 50;
 labelY = height - 25;
 plotFont = createFont("SanSerif",20);
 textFont(plotFont);
 smooth();
} 

void draw(){
  background(224);
  // Show plot area as a white box
  rectMode(CORNERS);
  noStroke();
  fill(255);
  rect(plotX1-10,plotY1-10,plotX2+10,plotY2+10);
  strokeWeight(5);
    // Draw the title of current plot.
  fill(0);
  textSize(20);
  String title = data.getColumnName(currentColumn);
  text (title,plotX1 + 80,plotY1 - 20);
  // Draw data points for first column
  stroke(#5679c1);
  noFill();
  drawDataLine(currentColumn);
  drawWeekLabels();
  drawVolumeLabels();
  drawAxisLabels();
}



// Draw the data as a series of points.

void drawDataLine(int col){
  beginShape();
  strokeWeight(2);
  int rowCount = data.getRowCount ();
  for (int row = 0 ; row < rowCount; row ++){
    if (data.isValid(row,col)){
      float value = data.getFloat(row,col);
      float x = map(weeks[row],weekMin,weekMax,plotX1,plotX2);
      float y = map(value,dataMin,dataMax,plotY2,plotY1);
      vertex(x,y);
    }
  }
  endShape();
}

void drawWeekLabels() {
  int rowCount = data.getRowCount ();
  fill(0);
  textSize(10);
  textAlign(CENTER,TOP);
  stroke(224);
  strokeWeight(1);
  for (int row = 0; row < rowCount; row ++) {
      float x = map(weeks[row], weekMin,weekMax,plotX1,plotX2);
      text(weeks[row],x,plotY2 + 10);   
      line(x,plotY1,x,plotY2); 
  }
}

void drawVolumeLabels(){
  fill(0);
  textSize(10);
  int volumeInterval = 5;
  for(float v = dataMin; v <= dataMax; v += volumeInterval){
    float y = map(v, dataMin,dataMax,plotY2,plotY1);
    if (v == dataMin){
      textAlign(RIGHT);
    }else if (v==dataMax){
      textAlign(RIGHT,TOP);
    }else{
      textAlign(RIGHT,CENTER);
    }
    text(floor(v),plotX1-10,y);
  }
}

void drawAxisLabels(){
  fill(0);
  textSize(13);
  textLeading(15);
  textAlign(CENTER,CENTER);
  pushMatrix();
  translate(labelX,(plotY1+plotY2)/2);
  rotate(HALF_PI);
  translate(-labelX,-(plotY1+plotY2)/2);
  text("% Confirmed Flu Cases",labelX,(plotY1+plotY2)/2 + 30);
  popMatrix();
  textAlign(CENTER);
  text("Week Of The Year 2014",(plotX1+plotX2)/2,labelY);
}


// first line of the file should be the column headers
// first column should be the row titles
// all other values are expected to be floats
// getFloat(0, 0) returns the first data value in the upper lefthand corner
// files should be saved as "text, tab-delimited"
// empty rows are ignored
// extra whitespace is ignored


class FloatTable {
  int rowCount;
  int columnCount;
  float[][] data;
  String[] rowNames;
  String[] columnNames;
  
  
  FloatTable(String filename) {
    String[] rows = loadStrings(filename);
    
    String[] columns = split(rows[0], "\t");
    columnNames = subset(columns, 1); // upper-left corner ignored
    scrubQuotes(columnNames);
    columnCount = columnNames.length;

    rowNames = new String[rows.length-1];
    data = new float[rows.length-1][];

    // start reading at row 1, because the first row was only the column headers
    for (int i = 1; i < rows.length; i++) {
      if (trim(rows[i]).length() == 0) {
        continue; // skip empty rows
      }
      if (rows[i].startsWith("#")) {
        continue;  // skip comment lines
      }

      // split the row on the tabs
      String[] pieces = split(rows[i], "\t");
      scrubQuotes(pieces);
      
      // copy row title
      rowNames[rowCount] = pieces[0];
      // copy data into the table starting at pieces[1]
      data[rowCount] = parseFloat(subset(pieces, 1));

      // increment the number of valid rows found so far
      rowCount++;      
    }
    // resize the 'data' array as necessary
    data = (float[][]) subset(data, 0, rowCount);
  }
  
  
  void scrubQuotes(String[] array) {
    for (int i = 0; i < array.length; i++) {
      if (array[i].length() > 2) {
        // remove quotes at start and end, if present
        if (array[i].startsWith("\"") && array[i].endsWith("\"")) {
          array[i] = array[i].substring(1, array[i].length() - 1);
        }
      }
      // make double quotes into single quotes
      array[i] = array[i].replaceAll("\"\"", "\"");
    }
  }
  
  
  int getRowCount() {
    return rowCount;
  }
  
  
  String getRowName(int rowIndex) {
    return rowNames[rowIndex];
  }
  
  
  String[] getRowNames() {
    return rowNames;
  }

  
  // Find a row by its name, returns -1 if no row found. 
  // This will return the index of the first row with this name.
  // A more efficient version of this function would put row names
  // into a Hashtable (or HashMap) that would map to an integer for the row.
  int getRowIndex(String name) {
    for (int i = 0; i < rowCount; i++) {
      if (rowNames[i].equals(name)) {
        return i;
      }
    }
    //println("No row named '" + name + "' was found");
    return -1;
  }
  
  
  // technically, this only returns the number of columns 
  // in the very first row (which will be most accurate)
  int getColumnCount() {
    return columnCount;
  }
  
  
  String getColumnName(int colIndex) {
    return columnNames[colIndex];
  }
  
  
  String[] getColumnNames() {
    return columnNames;
  }


  float getFloat(int rowIndex, int col) {
    // Remove the 'training wheels' section for greater efficiency
    // It's included here to provide more useful error messages
    
    // begin training wheels
    if ((rowIndex < 0) || (rowIndex >= data.length)) {
      throw new RuntimeException("There is no row " + rowIndex);
    }
    if ((col < 0) || (col >= data[rowIndex].length)) {
      throw new RuntimeException("Row " + rowIndex + " does not have a column " + col);
    }
    // end training wheels
    
    return data[rowIndex][col];
  }
  
  
  boolean isValid(int row, int col) {
    if (row < 0) return false;
    if (row >= rowCount) return false;
    //if (col >= columnCount) return false;
    if (col >= data[row].length) return false;
    if (col < 0) return false;
    return !Float.isNaN(data[row][col]);
  }
  
  
  float getColumnMin(int col) {
    float m = Float.MAX_VALUE;
    for (int i = 0; i < rowCount; i++) {
      if (!Float.isNaN(data[i][col])) {
        if (data[i][col] < m) {
          m = data[i][col];
        }
      }
    }
    return m;
  }

  
  float getColumnMax(int col) {
    float m = -Float.MAX_VALUE;
    for (int i = 0; i < rowCount; i++) {
      if (isValid(i, col)) {
        if (data[i][col] > m) {
          m = data[i][col];
        }
      }
    }
    return m;
  }

  
  float getRowMin(int row) {
    float m = Float.MAX_VALUE;
    for (int i = 0; i < columnCount; i++) {
      if (isValid(row, i)) {
        if (data[row][i] < m) {
          m = data[row][i];
        }
      }
    }
    return m;
  } 

  
  float getRowMax(int row) {
    float m = -Float.MAX_VALUE;
    for (int i = 1; i < columnCount; i++) {
      if (!Float.isNaN(data[row][i])) {
        if (data[row][i] > m) {
          m = data[row][i];
        }
      }
    }
    return m;
  }
  
  
  float getTableMin() {
    float m = Float.MAX_VALUE;
    for (int i = 0; i < rowCount; i++) {
      for (int j = 0; j < columnCount; j++) {
        if (isValid(i, j)) {
          if (data[i][j] < m) {
            m = data[i][j];
          }
        }
      }
    }
    return m;
  }

  
  float getTableMax() {
    float m = -Float.MAX_VALUE;
    for (int i = 0; i < rowCount; i++) {
      for (int j = 0; j < columnCount; j++) {
        if (isValid(i, j)) {
          if (data[i][j] > m) {
            m = data[i][j];
          }
        }
      }
    }
    return m;
  }
}

Answers

  • Answer ✓

    In order to successfully have a cross-mode Java-JS sketch, we gotta adhere to Processing's API:
    http://processingjs.org/reference/

    Java things like Float_MAX_VALUE, RuntimeException, replaceAll(), etc. can't be transpiled into JS at present!
    You may try finding some equivalent/similar or implement those by yourself! 8-|

    Other options is re-write your sketch in "CoffeeScript Mode", which at least have classes, or in P5.JS, which is JS:

  • Thanks once again GoTo..... This really throws a kink in my plans for my new blog, which was going to showcase interactive visualizations based on free and open data sets.... looks like I might have to look into one of the solutions you mentioned......

Sign In or Register to comment.