Instantly share code, notes, and snippets.

# spudtrooper/googleCorrelateDraw.js Created Sep 3, 2011

What would you like to do?
Plots functions over a domain of 2*PI on * http://www.google.com/trends/correlate/draw.
 /** * Plots functions over a domain of 2*PI on * http://www.google.com/trends/correlate/draw. * * More here: * * http://www.jeffpalm.com/blog/archives/002216.html */ (function() { /* * Translation coordinates for the canvas used for the graph -- * found by inspection. They work for me, god knows if they'll work * for anyone else? * * (MIN_X,MAX_VALUE) (MAX_X,MAX_VALUE) * ^ * | * (MIN_X,MIN_VALUE) ----------> (MAX_X,MIN_VALUE) * */ const MIN_VALUE = 0, MAX_VALUE = 250, MIN_X = 34, MAX_X = 600; function plot(f) { var period = 2*Math.PI; var steps = 30; for (var step=0; step<=steps; step++) { var x = step/period; var value = eval(f.replace(/y/g,x)); // // Translate to the canvas coords: // - tranlate x and scale // - invert and reflect the y value with the origin down the middle // var canvasx = MIN_X + (MAX_X-MIN_X)*(1.0*step/steps); var canvasy = -(value*((MAX_VALUE-MIN_VALUE)/2) - ((MAX_VALUE-MIN_VALUE)/2)); setPoint2(canvasx,canvasy,g); } } /** * Just like the setPoint(event,g,context) function in original * draw.js, except we don't use the context, which is ignored, and * just pass in canvasx and canvasy, which are easier to manage than * creating an event, etc. Seems to work? */ function setPoint2(canvasx, canvasy, g) { var xy = g.toDataCoords(canvasx, canvasy); var x = xy[0], value = xy[1]; var rows = g.numRows(); var closest_row = -1; var smallest_diff = -1; for (var row = 0; row < rows; row++) { var date = g.getValue(row, 0); // millis var diff = Math.abs(date - x); if (smallest_diff < 0 || diff < smallest_diff) { smallest_diff = diff; closest_row = row; } } if (closest_row != -1) { if (lastDrawRow === null) { lastDrawRow = closest_row; lastDrawValue = value; } // If the mouse moves quickly from point A to point B, we won't get events // for the intervening x-values. We use a linear interpolation to create // the impression of smooth drawing. var coeff = (value - lastDrawValue) / (closest_row - lastDrawRow); if (closest_row == lastDrawRow) coeff = 0.0; var minRow = Math.min(lastDrawRow, closest_row); var maxRow = Math.max(lastDrawRow, closest_row); for (var row = minRow; row <= maxRow; row++) { var val = lastDrawValue + coeff * (row - lastDrawRow); val = Math.max(valueRange[0], Math.min(val, valueRange[1])); if (val != null && !isNaN(val)) { data[row][1] = val; } } lastDrawRow = closest_row; lastDrawValue = value; g.updateOptions({ file: data }); // this redraws the chart g.setSelection(closest_row); // prevents the dot from being finnicky. } } function main() { var f = prompt('Enter a function f(y) -- e.g. Math.sin(y):'); plot(f); } main(); })();