Dygraph.NAME = "Dygraph";
Dygraph.VERSION = "1.0.1";
Dygraph.__repr__ = function() {
- return "[" + this.NAME + " " + this.VERSION + "]";
+ return "[" + Dygraph.NAME + " " + Dygraph.VERSION + "]";
};
/**
* Returns information about the Dygraph class.
*/
Dygraph.toString = function() {
- return this.__repr__();
+ return Dygraph.__repr__();
};
// Various default values
* @private
* Return a string version of a number. This respects the digitsAfterDecimal
* and maxNumberWidth options.
- * @param {Number} x The number to be formatted
+ * @param {number} x The number to be formatted
* @param {Dygraph} opts An options view
- * @param {String} name The name of the point's data series
+ * @param {string} name The name of the point's data series
* @param {Dygraph} g The dygraph object
*/
Dygraph.numberValueFormatter = function(x, opts, pt, g) {
* Convert a JS date to a string appropriate to display on an axis that
* is displaying values at the stated granularity.
* @param {Date} date The date to format
- * @param {Number} granularity One of the Dygraph granularity constants
- * @return {String} The formatted date
+ * @param {number} granularity One of the Dygraph granularity constants
+ * @return {string} The formatted date
* @private
*/
Dygraph.dateAxisFormatter = function(date, granularity) {
// TODO(danvk): support 'onmouseover' and 'never', and remove synonyms.
legend: 'onmouseover', // the only relevant value at the moment is 'always'.
+ legendFollow: false,
stepPlot: false,
avoidMinZero: false,
* and context <canvas> inside of it. See the constructor for details.
* on the parameters.
* @param {Element} div the Element to render the graph into.
- * @param {String | Function} file Source data
+ * @param {string | Function} file Source data
* @param {Object} attrs Miscellaneous other options
* @private
*/
};
/**
+ * Fetch a plugin instance of a particular class. Only for testing.
+ * @private
+ * @param {!Class} type The type of the plugin.
+ * @return {Object} Instance of the plugin, or null if there is none.
+ */
+Dygraph.prototype.getPluginInstance_ = function(type) {
+ for (var i = 0; i < this.plugins_.length; i++) {
+ var p = this.plugins_[i];
+ if (p.plugin instanceof type) {
+ return p.plugin;
+ }
+ }
+ return null;
+};
+
+/**
* Returns the zoomed status of the chart for one or both axes.
*
* Axis is an optional parameter. Can be set to 'x' or 'y'.
* Returns the value of an option. This may be set by the user (either in the
* constructor or by calling updateOptions) or by dygraphs, and may be set to a
* per-series value.
- * @param { String } name The name of the option, e.g. 'rollPeriod'.
- * @param { String } [seriesName] The name of the series to which the option
+ * @param {string} name The name of the option, e.g. 'rollPeriod'.
+ * @param {string} [seriesName] The name of the series to which the option
* will be applied. If no per-series value of this option is available, then
* the global value is returned. This is optional.
* @return { ... } The value of the option.
* 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);
/**
* Returns the current rolling period, as set by the user or an option.
- * @return {Number} The number of points in the rolling window
+ * @return {number} The number of points in the rolling window
*/
Dygraph.prototype.rollPeriod = function() {
return this.rollPeriod_;
* If y is null, this returns null.
* if axis is null, this uses the first axis.
*
- * @param { Number } y The data y-coordinate.
- * @param { Number } [axis] The axis number on which the data coordinate lives.
- * @return { Number } A fraction in [0, 1] where 0 = the top edge.
+ * @param {number} y The data y-coordinate.
+ * @param {number} [axis] The axis number on which the data coordinate lives.
+ * @return {number} A fraction in [0, 1] where 0 = the top edge.
*/
Dygraph.prototype.toPercentYCoord = function(y, axis) {
if (y === null) {
* values can fall outside the canvas.
*
* If x is null, this returns null.
- * @param { Number } x The data x-coordinate.
- * @return { Number } A fraction in [0, 1] where 0 = the left edge.
+ * @param {number} x The data x-coordinate.
+ * @return {number} A fraction in [0, 1] where 0 = the left edge.
*/
Dygraph.prototype.toPercentXCoord = function(x) {
if (x === null) {
/**
* Returns the number of columns (including the independent variable).
- * @return { Integer } The number of columns.
+ * @return {number} The number of columns.
*/
Dygraph.prototype.numColumns = function() {
if (!this.rawData_) return 0;
/**
* Returns the number of rows (excluding any header/label row).
- * @return { Integer } The number of rows, less any header.
+ * @return {number} The number of rows, less any header.
*/
Dygraph.prototype.numRows = function() {
if (!this.rawData_) return 0;
* Returns the value in the given row and column. If the row and column exceed
* the bounds on the data, returns null. Also returns null if the value is
* missing.
- * @param { Number} row The row number of the data (0-based). Row 0 is the
- * first row of data, not a header row.
- * @param { Number} col The column number of the data (0-based)
- * @return { Number } The value in the specified cell or null if the row/col
- * were out of range.
+ * @param {number} row The row number of the data (0-based). Row 0 is the
+ * first row of data, not a header row.
+ * @param {number} col The column number of the data (0-based)
+ * @return {number} The value in the specified cell or null if the row/col
+ * were out of range.
*/
Dygraph.prototype.getValue = function(row, col) {
if (row < 0 || row > this.rawData_.length) return null;
// ... and for static parts of the chart.
this.hidden_ = this.createPlotKitCanvas_(this.canvas_);
- this.resizeElements_();
-
this.canvas_ctx_ = Dygraph.getContext(this.canvas_);
this.hidden_ctx_ = Dygraph.getContext(this.hidden_);
+ this.resizeElements_();
+
// The interactive parts of the graph are drawn on top of the chart.
this.graphDiv.appendChild(this.hidden_);
this.graphDiv.appendChild(this.canvas_);
Dygraph.prototype.resizeElements_ = function() {
this.graphDiv.style.width = this.width_ + "px";
this.graphDiv.style.height = this.height_ + "px";
- this.canvas_.width = this.width_;
- this.canvas_.height = this.height_;
+
+ var canvasScale = Dygraph.getContextPixelRatio(this.canvas_ctx_);
+ this.canvas_.width = this.width_ * canvasScale;
+ this.canvas_.height = this.height_ * canvasScale;
this.canvas_.style.width = this.width_ + "px"; // for IE
this.canvas_.style.height = this.height_ + "px"; // for IE
- this.hidden_.width = this.width_;
- this.hidden_.height = this.height_;
+ if (canvasScale !== 1) {
+ this.canvas_ctx_.scale(canvasScale, canvasScale);
+ }
+
+ var hiddenScale = Dygraph.getContextPixelRatio(this.hidden_ctx_);
+ this.hidden_.width = this.width_ * hiddenScale;
+ this.hidden_.height = this.height_ * hiddenScale;
this.hidden_.style.width = this.width_ + "px"; // for IE
this.hidden_.style.height = this.height_ + "px"; // for IE
+ if (hiddenScale !== 1) {
+ this.hidden_ctx_.scale(hiddenScale, hiddenScale);
+ }
};
/**
* 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<string>} The list of colors.
+ * @return {Array.<string>} The list of colors.
*/
Dygraph.prototype.getColors = function() {
return this.colors_;
* avoid extra redrawing, but it's tricky to avoid interactions with the status
* dots.
*
- * @param {Number} direction the direction of the zoom rectangle. Acceptable
- * values are Dygraph.HORIZONTAL and Dygraph.VERTICAL.
- * @param {Number} startX The X position where the drag started, in canvas
- * coordinates.
- * @param {Number} endX The current X position of the drag, in canvas coords.
- * @param {Number} startY The Y position where the drag started, in canvas
- * coordinates.
- * @param {Number} endY The current Y position of the drag, in canvas coords.
- * @param {Number} prevDirection the value of direction on the previous call to
- * this function. Used to avoid excess redrawing
- * @param {Number} prevEndX The value of endX on the previous call to this
- * function. Used to avoid excess redrawing
- * @param {Number} prevEndY The value of endY on the previous call to this
- * function. Used to avoid excess redrawing
+ * @param {number} direction the direction of the zoom rectangle. Acceptable
+ * values are Dygraph.HORIZONTAL and Dygraph.VERTICAL.
+ * @param {number} startX The X position where the drag started, in canvas
+ * coordinates.
+ * @param {number} endX The current X position of the drag, in canvas coords.
+ * @param {number} startY The Y position where the drag started, in canvas
+ * coordinates.
+ * @param {number} endY The current Y position of the drag, in canvas coords.
+ * @param {number} prevDirection the value of direction on the previous call to
+ * this function. Used to avoid excess redrawing
+ * @param {number} prevEndX The value of endX on the previous call to this
+ * function. Used to avoid excess redrawing
+ * @param {number} prevEndY The value of endY on the previous call to this
+ * function. Used to avoid excess redrawing
* @private
*/
Dygraph.prototype.drawZoomRect_ = function(direction, startX, endX, startY,
* points near lowX or highX. Don't confuse this function with doZoomXDates,
* which accepts dates that match the raw data. This function redraws the graph.
*
- * @param {Number} lowX The leftmost pixel value that should be visible.
- * @param {Number} highX The rightmost pixel value that should be visible.
+ * @param {number} lowX The leftmost pixel value that should be visible.
+ * @param {number} highX The rightmost pixel value that should be visible.
* @private
*/
Dygraph.prototype.doZoomX_ = function(lowX, highX) {
* method with doZoomX which accepts pixel coordinates. This function redraws
* the graph.
*
- * @param {Number} minDate The minimum date that should be visible.
- * @param {Number} maxDate The maximum date that should be visible.
+ * @param {number} minDate The minimum date that should be visible.
+ * @param {number} maxDate The maximum date that should be visible.
* @private
*/
Dygraph.prototype.doZoomXDates_ = function(minDate, maxDate) {
* Zoom to something containing [lowY, highY]. These are pixel coordinates in
* the canvas. This function redraws the graph.
*
- * @param {Number} lowY The topmost pixel value that should be visible.
- * @param {Number} highY The lowest pixel value that should be visible.
+ * @param {number} lowY The topmost pixel value that should be visible.
+ * @param {number} highY The lowest pixel value that should be visible.
* @private
*/
Dygraph.prototype.doZoomY_ = function(lowY, highY) {
/**
* Given a canvas X coordinate, find the closest row.
- * @param {Number} domX graph-relative DOM X coordinate
- * Returns: row number, integer
+ * @param {number} domX graph-relative DOM X coordinate
+ * Returns {number} row number.
* @private
*/
Dygraph.prototype.findClosestRow = function(domX) {
* that's closest to the supplied DOM coordinates using the standard
* Euclidean X,Y distance.
*
- * @param {Number} domX graph-relative DOM X coordinate
- * @param {Number} domY graph-relative DOM Y coordinate
+ * @param {number} domX graph-relative DOM X coordinate
+ * @param {number} domY graph-relative DOM Y coordinate
* Returns: {row, seriesName, point}
* @private
*/
* then finds the series which puts the Y coordinate on top of its filled area,
* using linear interpolation between adjacent point pairs.
*
- * @param {Number} domX graph-relative DOM X coordinate
- * @param {Number} domY graph-relative DOM Y coordinate
+ * @param {number} domX graph-relative DOM X coordinate
+ * @param {number} domY graph-relative DOM Y coordinate
* Returns: {row, seriesName, point}
* @private
*/
ctx.lineWidth = this.getNumericOption('strokeWidth', pt.name);
ctx.strokeStyle = color;
ctx.fillStyle = color;
- callback(this.g, pt.name, ctx, canvasx, pt.canvasy,
+ callback(this, pt.name, ctx, canvasx, pt.canvasy,
color, circleSize, pt.idx);
}
ctx.restore();
* Manually set the selected points and display information about them in the
* legend. The selection can be cleared using clearSelection() and queried
* using getSelection().
- * @param { Integer } row number that should be highlighted (i.e. appear with
+ * @param {number} row Row number that should be highlighted (i.e. appear with
* hover dots on the chart). Set to false to clear any selection.
- * @param { seriesName } optional series name to highlight that series with the
+ * @param {seriesName} optional series name to highlight that series with the
* the highlightSeriesOpts setting.
* @param { locked } optional If true, keep seriesName selected when mousing
* over the graph, disabling closest-series highlighting. Call clearSelection()
/**
* Returns the number of the currently selected row. To get data for this row,
* you can use the getValue method.
- * @return { Integer } row number, or -1 if nothing is selected
+ * @return {number} row number, or -1 if nothing is selected
*/
Dygraph.prototype.getSelection = function() {
if (!this.selPoints_ || this.selPoints_.length < 1) {
/**
* Fires when there's data available to be graphed.
- * @param {String} data Raw CSV data to be plotted
+ * @param {string} data Raw CSV data to be plotted
* @private
*/
Dygraph.prototype.loadedEvent_ = function(data) {
var actualYval = point.yval;
if (isNaN(actualYval) || actualYval === null) {
- // Interpolate/extend for stacking purposes if possible.
- updateNextPoint(i);
- if (prevPoint && nextPoint && fillMethod != 'none') {
- // Use linear interpolation between prevPoint and nextPoint.
- actualYval = prevPoint.yval + (nextPoint.yval - prevPoint.yval) *
- ((xval - prevPoint.xval) / (nextPoint.xval - prevPoint.xval));
- } else if (prevPoint && fillMethod == 'all') {
- actualYval = prevPoint.yval;
- } else if (nextPoint && fillMethod == 'all') {
- actualYval = nextPoint.yval;
- } else {
+ if(fillMethod == 'none') {
actualYval = 0;
+ } else {
+ // Interpolate/extend for stacking purposes if possible.
+ updateNextPoint(i);
+ if (prevPoint && nextPoint && fillMethod != 'none') {
+ // Use linear interpolation between prevPoint and nextPoint.
+ actualYval = prevPoint.yval + (nextPoint.yval - prevPoint.yval) *
+ ((xval - prevPoint.xval) / (nextPoint.xval - prevPoint.xval));
+ } else if (prevPoint && fillMethod == 'all') {
+ actualYval = prevPoint.yval;
+ } else if (nextPoint && fillMethod == 'all') {
+ actualYval = nextPoint.yval;
+ } else {
+ actualYval = 0;
+ }
}
} else {
prevPoint = point;
/**
* Returns the number of y-axes on the chart.
- * @return {Number} the number of axes.
+ * @return {number} the number of axes.
*/
Dygraph.prototype.numAxes = function() {
return this.attributes_.numAxes();
/**
* @private
* Returns axis properties for the given series.
- * @param { String } setName The name of the series for which to get axis
+ * @param {string} setName The name of the series for which to get axis
* properties, e.g. 'Y1'.
- * @return { Object } The axis properties.
+ * @return {Object} The axis properties.
*/
Dygraph.prototype.axisPropertiesForSeries = function(series) {
// TODO(danvk): handle errors.
/**
* Detects the type of the str (date or numeric) and sets the various
* formatting attributes in this.attrs_ based on this type.
- * @param {String} str An x value.
+ * @param {string} str An x value.
* @private
*/
Dygraph.prototype.detectTypeFromString_ = function(str) {
};
/**
- * @private
* The user has provided their data as a pre-packaged JS array. If the x values
* are numeric, this is the same as dygraphs' internal format. If the x values
* are dates, we need to convert them from Date objects to ms since epoch.
- * @param {[Object]} data
- * @return {[Object]} data with numeric x values.
+ * @param {!Array} data
+ * @return {Object} data with numeric x values.
+ * @private
*/
Dygraph.prototype.parseArray_ = function(data) {
// Peek at the first x value to see if it's numeric.
* number. All subsequent columns must be numbers. If there is a clear mismatch
* between this.xValueParser_ and the type of the first column, it will be
* fixed. Fills out rawData_.
- * @param {[Object]} data See above.
+ * @param {!google.visualization.DataTable} data See above.
* @private
*/
Dygraph.prototype.parseDataTable_ = function(data) {
* There's a huge variety of options that can be passed to this method. For a
* full list, see http://dygraphs.com/options.html.
*
- * @param {Object} attrs The new properties and values
- * @param {Boolean} [block_redraw] Usually the chart is redrawn after every
- * call to updateOptions(). If you know better, you can pass true to explicitly
- * block the redraw. This can be useful for chaining updateOptions() calls,
- * avoiding the occasional infinite loop and preventing redraws when it's not
- * necessary (e.g. when updating a callback).
+ * @param {Object} input_attrs The new properties and values
+ * @param {boolean} block_redraw Usually the chart is redrawn after every
+ * call to updateOptions(). If you know better, you can pass true to
+ * explicitly block the redraw. This can be useful for chaining
+ * updateOptions() calls, avoiding the occasional infinite loop and
+ * preventing redraws when it's not necessary (e.g. when updating a
+ * callback).
*/
Dygraph.prototype.updateOptions = function(input_attrs, block_redraw) {
if (typeof(block_redraw) == 'undefined') block_redraw = false;
* This is far more efficient than destroying and re-instantiating a
* Dygraph, since it doesn't have to reparse the underlying data.
*
- * @param {Number} [width] Width (in pixels)
- * @param {Number} [height] Height (in pixels)
+ * @param {number} width Width (in pixels)
+ * @param {number} height Height (in pixels)
*/
Dygraph.prototype.resize = function(width, height) {
if (this.resize_lock) {
/**
* Adjusts the number of points in the rolling average. Updates the graph to
* reflect the new averaging period.
- * @param {Number} length Number of points over which to average the data.
+ * @param {number} length Number of points over which to average the data.
*/
Dygraph.prototype.adjustRoll = function(length) {
this.rollPeriod_ = length;