From 06ed32c32b4b3414500e63dc459f88505fab68fa Mon Sep 17 00:00:00 2001 From: Dan Vanderkam Date: Mon, 22 Jul 2013 16:58:52 -0400 Subject: [PATCH] basic closurization of dygraph-canvas.js --- closure-todo.txt | 5 ++- dygraph-canvas.js | 96 ++++++++++++++++++++---------------------------------- dygraph-externs.js | 39 ++++++++++++++++++++++ dygraph-utils.js | 22 +++++++++++++ dygraph.js | 10 +++--- 5 files changed, 106 insertions(+), 66 deletions(-) diff --git a/closure-todo.txt b/closure-todo.txt index f9c0357..3d724bb 100644 --- a/closure-todo.txt +++ b/closure-todo.txt @@ -9,7 +9,7 @@ This file tracks which files have been fully "closurized", i.e. compile under the Closure Compiler without any errors or warnings. Core: -- dygraph-canvas.js +x dygraph-canvas.js - dygraph-interaction-model.js x dygraph-layout.js x dygraph-options.js @@ -35,3 +35,6 @@ compiler: java -jar ../../closure-compiler-read-only/build/compiler.jar --js=dygraph-utils.js --js=dashed-canvas.js --js=dygraph-options-reference.js --js=dygraph-tickers.js --js=dygraph-gviz.js --js=dygraph-options.js --js=dygraph-layout.js --js_output_file=/tmp/out.js --compilation_level ADVANCED_OPTIMIZATIONS --warning_level VERBOSE --externs dygraph-externs.js As each file is closurized, it can be added as a "--js" parameter. + +NOTES +- Should add .getNumericOption() and .getStringOption() which are aliases for .getOption() but returns number/string, not *. diff --git a/dygraph-canvas.js b/dygraph-canvas.js index c7fed05..5a02f2a 100644 --- a/dygraph-canvas.js +++ b/dygraph-canvas.js @@ -15,34 +15,10 @@ */ /** + * @constructor + * * The DygraphCanvasRenderer class does the actual rendering of the chart onto * a canvas. It's based on PlotKit.CanvasRenderer. - * @param {Object} element The canvas to attach to - * @param {Object} elementContext The 2d context of the canvas (injected so it - * can be mocked for testing.) - * @param {Layout} layout The DygraphLayout object for this graph. - * @constructor - */ - -var DygraphCanvasRenderer = (function() { - -/*jshint globalstrict: true */ -/*global Dygraph:false,RGBColorParser:false */ -"use strict"; - -// Utility methods for this file. -var isCanvasSupported_, - getIteratorPredicate_, - predicateThatSkipsEmptyPoints_, - drawSeries_, - drawPointsOnLine_, - linePlotter_, - fillPlotter_, - errorPlotter_; - - -/** - * @constructor * * This gets called when there are "new points" to chart. This is generally the * case when the underlying data being charted has changed. It is _not_ called @@ -70,9 +46,9 @@ var DygraphCanvasRenderer = function(dygraph, element, elementContext, layout) { this.width = this.element.width; // --- check whether everything is ok before we return - // NOTE(konigsberg): isIE is never defined in this object. Bug of some sort. - if (!this.isIE && !(isCanvasSupported_(this.element))) - throw "Canvas is not supported."; + if (!(Dygraph.isCanvasSupported(this.element))) { + throw "Canvas is not supported."; + } // internal state this.area = layout.getPlotArea(); @@ -100,6 +76,23 @@ var DygraphCanvasRenderer = function(dygraph, element, elementContext, layout) { } }; + +(function() { + +/*jshint globalstrict: true */ +/*global Dygraph:false,RGBColorParser:false */ +"use strict"; + +// Utility methods for this file. +var getIteratorPredicate_, + predicateThatSkipsEmptyPoints_, + drawSeries_, + drawPointsOnLine_, + linePlotter_, + fillPlotter_, + errorPlotter_; + + /** * Clears out all chart content and DOM elements. * This is called immediately before render() on every frame, including @@ -130,29 +123,6 @@ DygraphCanvasRenderer.prototype.clear = function() { }; /** - * Checks whether the browser supports the <canvas> tag. - */ -isCanvasSupported_ = function(canvasName) { - var canvas = null; - try { - if (typeof(canvasName) == 'undefined' || canvasName === null) { - canvas = document.createElement("canvas"); - } else { - canvas = canvasName; - } - canvas.getContext("2d"); - } - catch (e) { - var ie = navigator.appVersion.match(/MSIE (\d\.\d)/); - var opera = (navigator.userAgent.toLowerCase().indexOf("opera") != -1); - if ((!ie) || (ie[1] < 6) || (opera)) - return false; - return true; - } - return true; -}; - -/** * This method is responsible for drawing everything on the chart, including * lines, error bars, fills and axes. * It is called immediately after clear() on every frame, including during pans @@ -438,8 +408,8 @@ DygraphCanvasRenderer.prototype._updatePoints = function() { * * @param {string=} opt_seriesName when specified, only that series will * be drawn. (This is used for expedited redrawing with highlightSeriesOpts) - * @param {CanvasRenderingContext2D} opt_ctx when specified, the drawing - * context. However, lines are typically drawn on the object's + * @param {CanvasRenderingContext2D=} opt_ctx when specified, the drawing + * context. However, lines are typically drawn on the object's * elementContext. * @private */ @@ -454,19 +424,24 @@ DygraphCanvasRenderer.prototype._renderLineChart = function(opt_seriesName, opt_ this.colors = this.dygraph_.colorsMap_; // Determine which series have specialized plotters. - var plotter_attr = this.dygraph_.attr_("plotter"); - var plotters = plotter_attr; + var plotter_attr = /** @type{!Array.|!Dygraph.PlotterType}*/(this.dygraph_.getOption("plotter")); + + /** @type{!Array.} */ + var plotters; if (!Dygraph.isArrayLike(plotters)) { plotters = [plotters]; + } else { + plotters = /** @type {!Array.} */(plotter_attr); } + /** @type {Object.} */ var setPlotters = {}; // series name -> plotter fn. for (i = 0; i < setNames.length; i++) { setName = setNames[i]; - var setPlotter = this.dygraph_.attr_("plotter", setName); + var setPlotter = this.dygraph_.getOption("plotter", setName); if (setPlotter == plotter_attr) continue; // not specialized. - setPlotters[setName] = setPlotter; + setPlotters[setName] = /** @type {!Dygraph.PlotterType} */(setPlotter); } for (i = 0; i < plotters.length; i++) { @@ -491,11 +466,12 @@ DygraphCanvasRenderer.prototype._renderLineChart = function(opt_seriesName, opt_ } var color = this.colors[setName]; - var strokeWidth = this.dygraph_.getOption("strokeWidth", setName); + var strokeWidth = /** @type{number}*/(this.dygraph_.getOption("strokeWidth", setName)); ctx.save(); ctx.strokeStyle = color; ctx.lineWidth = strokeWidth; + // TODO(danvk): add an @typedef for this Object. p({ points: points, setName: setName, @@ -802,6 +778,4 @@ DygraphCanvasRenderer._Plotters = { errorPlotter: errorPlotter_ }; -return DygraphCanvasRenderer; - })(); diff --git a/dygraph-externs.js b/dygraph-externs.js index c40139c..171d90d 100644 --- a/dygraph-externs.js +++ b/dygraph-externs.js @@ -141,6 +141,21 @@ Dygraph.prototype.cascadeEvents_ = function(name, extra_props) {}; Dygraph.prototype.registeredEvents_; /** + * @type {CanvasRenderingContext2D} + */ +Dygraph.prototype.canvas_ctx_; + +/** + * @type {CanvasRenderingContext2D} + */ +Dygraph.prototype.hidden_ctx_; + +/** + * @type {Object.} + */ +Dygraph.prototype.colorsMap_; + +/** * @return {!Array.} two element [left, right] array. */ Dygraph.prototype.xAxisRange = function() {}; @@ -158,6 +173,24 @@ Dygraph.prototype.axisPropertiesForSeries = function(setName) {}; */ Dygraph.prototype.toPercentYCoord = function(y, axis) {}; +/** + * @param {string} name The name of the option (e.g. 'strokeWidth') + * @param {string=} opt_seriesName Series name to get per-series values. + * @return {*} The value of the option. + */ +Dygraph.prototype.getOption = function(name, opt_seriesName) {}; + +/** + * @return {?Array.} The names of each series (including the x-axis), + * or null if they haven't been defined yet. + */ +Dygraph.prototype.getLabels = function() {}; + +/** + * @return {Array.} The list of colors. + */ +Dygraph.prototype.getColors = function() {}; + /** @type {{axes: Object}} */ Dygraph.DEFAULT_ATTRS; @@ -216,3 +249,9 @@ Dygraph.Rect; * }} */ Dygraph.AxisType; + +/** + * TODO(danvk): be more specific than "Object". + * @typedef {function(Object)} + */ +Dygraph.PlotterType; diff --git a/dygraph-utils.js b/dygraph-utils.js index df4fcad..55e4da6 100644 --- a/dygraph-utils.js +++ b/dygraph-utils.js @@ -1192,4 +1192,26 @@ Dygraph.toRGB_ = function(color_str) { }; }; +/** + * Checks whether the browser supports the <canvas> tag. + * @param {HTMLCanvasElement=} opt_canvasElement Pass a canvas element as an + * optimization if you have one. + * @return {boolean} Whether the browser supports canvas. + */ +Dygraph.isCanvasSupported = function(opt_canvasElement) { + var canvas; + try { + canvas = opt_canvasElement || document.createElement("canvas"); + canvas.getContext("2d"); + } + catch (e) { + var ie = navigator.appVersion.match(/MSIE (\d\.\d)/); + var opera = (navigator.userAgent.toLowerCase().indexOf("opera") != -1); + if ((!ie) || (ie[1] < 6) || (opera)) + return false; + return true; + } + return true; +}; + })(); diff --git a/dygraph.js b/dygraph.js index 2a1cb72..ec04936 100644 --- a/dygraph.js +++ b/dygraph.js @@ -642,9 +642,9 @@ Dygraph.prototype.attr_ = function(name, seriesName) { * dygraphs will remain in a consistent state. If you want to modify an option, * use updateOptions() instead. * - * @param { String } name The name of the option (e.g. 'strokeWidth') - * @param { String } [opt_seriesName] Series name to get per-series values. - * @return { ... } The value of the option. + * @param {string} name The name of the option (e.g. 'strokeWidth') + * @param {string=} opt_seriesName Series name to get per-series values. + * @return {*} The value of the option. */ Dygraph.prototype.getOption = function(name, opt_seriesName) { return this.attr_(name, opt_seriesName); @@ -1175,7 +1175,7 @@ Dygraph.prototype.setColors_ = function() { * Return the list of colors. This is either the list of colors passed in the * attributes or the autogenerated list of rgb(r,g,b) strings. * This does not return colors for invisible series. - * @return {Array} The list of colors. + * @return {Array.} The list of colors. */ Dygraph.prototype.getColors = function() { return this.colors_; @@ -3826,6 +3826,8 @@ Dygraph.prototype.annotations = function() { * x-axis, so the data series names start at index 1. * * Returns null when labels have not yet been defined. + * @return {?Array.} The names of each series (including the x-axis), + * or null if they haven't been defined yet. */ Dygraph.prototype.getLabels = function() { var labels = this.attr_("labels"); -- 2.7.4