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"){ 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; for (var i = 0; i < table.getRowCount(); i++){ if (table.getString(i, 'Code') === "SFO"){ delayed = table.getNum(i, 'Delayed'); cancelled = table.getNum(i, 'Cancelled'); points.push(new Point(getStartPointX(delayed), getStartPointY(cancelled), delayed, cancelled)); } } } 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("Number of Cancelled vs Delayed Flights from SFO in a Month", 350, 10); var xcoord, ycoord, xval, yval, isHover = false; for (var i = 0; i < points.length; i++){ points[i].show(); if (points[i].checkHover() == true){ isHover = true; xcoord = points[i].getxCoord(); ycoord = points[i].getyCoord(); xval = points[i].getxVal(); yval = points[i].getyVal(); } } if (isHover){ fill('red'); ellipse(xcoord, ycoord, 6); fill(240); rect(xcoord-40, ycoord-40, 70, 30); fill(0); text("(" + xval + ", " + yval + ")", xcoord-35, ycoord-20); } rotate(PI/2); text("Number of Cancelled Flights", 200, -5); } class Point { constructor(x, y, xval, yval) { this.x = x; this.y = y; this.xval = xval; this.yval = yval; } show(){ fill(0); ellipse(this.x, this.y, 3); // hover over if (dist(this.x, this.y, mouseX, mouseY) < 2){ fill('red'); ellipse(this.x, this.y, 6); fill(240); rect(this.x-40, this.y-40, 70, 30); fill(0); text("(" + this.xval + ", " + this.yval + ")", this.x-35, this.y-20); } } 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; } }