var table; var points = []; var tickValueY, tickDistanceY, tickValueX, tickDistanceX, maxvalueX = 0, maxvalueY = 0; function preload() { table = loadTable('airlines.csv', 'csv', 'header'); } function setup() { createCanvas(1000, 1000); var minvalueX = 999999999; var minvalueY = 999999999; // find min and max values for (var j = 0; j < table.getRowCount(); j++){ if (table.getString(j, 'Code') === "SFO" || table.getString(j, 'Code') === "LAX" || table.getString(j, 'Code') === "EWR"){ if (table.getNum(j, 'Delayed') > maxvalueX){ maxvalueX = table.getNum(j, 'Delayed'); } if (table.getNum(j, 'Delayed') < minvalueX){ minvalueX = table.getNum(j, 'Delayed'); } if (table.getNum(j, 'Cancelled') > maxvalueY){ maxvalueY = table.getNum(j, 'Cancelled'); } if (table.getNum(j, 'Cancelled') < minvalueY){ minvalueY = table.getNum(j, 'Cancelled'); } } } // to get decimal-free scales while ((maxvalueX % 100) != 0){ maxvalueX++; } while ((maxvalueY%100) != 0){ maxvalueY++; } while ((minvalueX % 100) != 0){ minvalueX--; } while ((minvalueY%100) != 0){ minvalueY--; } var rangeX = maxvalueX - minvalueX; var rangeY = maxvalueY - minvalueY; tickDistanceY = 850/10; // we want 10 ticks always. the length of the Y axis will not change tickDistanceX = 900/10; // we want 10 ticks always. the length of the X axis will not change tickValueY = rangeY/10; // each tick will correspond to a multiple of this number tickValueX = rangeX/10; // each tick will correspond to a multiple of this number var delayed, cancelled, airportName; for (var i = 0; i < table.getRowCount(); i++){ if (table.getString(i, 'Code') === "SFO" || table.getString(i, 'Code') === "LAX" || table.getString(i, 'Code') === "EWR"){ delayed = table.getNum(i, 'Delayed'); cancelled = table.getNum(i, 'Cancelled'); airportName = table.getString(i, 'Code'); points.push(new Point(getStartPointX(delayed), getStartPointY(cancelled), delayed, cancelled, airportName)); } } } function getStartPointY(value){ return 50+(((maxvalueY-value)/tickValueY)*tickDistanceY); } function getStartPointX(value){ return 950-(((maxvalueX-value)/tickValueX)*tickDistanceX); } function draw(){ clear(); // y axis line(50, 50, 50, 900); // x axis line(50, 900, 950, 900); for (var j = 0; j <= 10; j++){ line(48, 50+(tickDistanceY*j), 53, 50+(tickDistanceY*j)); // does not depend on range text(maxvalueY-(tickValueY*j), 15, 50+(tickDistanceY*j)); } // adding ticks on x-axis for (var k = 0; k <= 10; k++){ line(950-(tickDistanceX*k), 897, 950-(tickDistanceX*k), 904); // does not depend on range text(maxvalueX-(tickValueX*k), 935-(tickDistanceX*k), 920); } text("Number of Delayed Flights", 475, 950); text("Cancelled vs Delayed Flights from SFO, EWR, and LAX in a Month", 350, 10); // legend noFill(); rect(950, 50, 49, 60); fill(0); text("Legend", 955, 65); text("LAX", 965, 105); text("EWR", 965, 95); text("SFO", 965, 83); strokeWeight(0); rect(955, 75, 5, 5); fill('blue'); rect(955, 87, 5, 5); fill('#fae'); rect(955, 97, 5, 5); strokeWeight(1); var hoverName, xcoord, ycoord, xval, yval, isHover = false; for (var i = 0; i < points.length; i++){ points[i].show(); // check if mouse is hovering over, if so, get information if (points[i].checkHover() == true){ isHover = true; hoverName = points[i].getAirportName(); xcoord = points[i].getxCoord(); ycoord = points[i].getyCoord(); xval = points[i].getxVal(); yval = points[i].getyVal(); } } // display hover after ALL points drawn, so the info is not covered by points if (isHover){ fill('red'); ellipse(xcoord, ycoord, 6); fill(240); rect(xcoord-40, ycoord-40, 70, 35); fill(0); text("(" + xval + ", " + yval + ")", xcoord-35, ycoord-10); text(hoverName, xcoord-35, ycoord-25); } rotate(PI/2); text("Number of Cancelled Flights", 200, -5); } class Point { constructor(x, y, xval, yval, airportName) { this.x = x; this.y = y; this.xval = xval; this.yval = yval; this.airportName = airportName; } show(){ if (this.airportName === "SFO"){ fill(0); } else if (this.airportName === "EWR"){ fill('blue'); } else if (this.airportName === "LAX"){ fill('#fae'); } strokeWeight(0); ellipse(this.x, this.y, 6); strokeWeight(1); } checkHover(){ if (dist(this.x, this.y, mouseX, mouseY) < 2){ return true; } else{ return false; } } getxVal(){ return this.xval; } getyVal(){ return this.yval; } getxCoord(){ return this.x; } getyCoord(){ return this.y; } getAirportName(){ return this.airportName; } }