X-Git-Url: https://adrianiainlam.tk/git/?a=blobdiff_plain;f=src%2Fdygraph.js;h=1de4485d582bcdfa7757c4b9b9828870ffbc01f2;hb=6611837c5490f2f4b6d61967aa1ad658ed5f11d4;hp=13c67441dd611c0075c33b4b40e50bfbfd4de01e;hpb=87f78fb2306da355f82c436ee204cacf7a06fe10;p=dygraphs.git diff --git a/src/dygraph.js b/src/dygraph.js index 13c6744..1de4485 100644 --- a/src/dygraph.js +++ b/src/dygraph.js @@ -40,7 +40,6 @@ And error bars will be calculated automatically using a binomial distribution. For further documentation and examples, see http://dygraphs.com/ - */ import DygraphLayout from './dygraph-layout'; @@ -90,7 +89,7 @@ var Dygraph = function(div, data, opts) { }; Dygraph.NAME = "Dygraph"; -Dygraph.VERSION = "1.1.0"; +Dygraph.VERSION = "2.1.0"; // Various default values Dygraph.DEFAULT_ROLL_PERIOD = 1; @@ -367,14 +366,16 @@ Dygraph.prototype.toString = function() { */ Dygraph.prototype.attr_ = function(name, seriesName) { // For "production" code, this gets removed by uglifyjs. - if (process.env.NODE_ENV != 'production') { - if (typeof(OPTIONS_REFERENCE) === 'undefined') { - console.error('Must include options reference JS for testing'); - } else if (!OPTIONS_REFERENCE.hasOwnProperty(name)) { - console.error('Dygraphs is using property ' + name + ', which has no ' + - 'entry in the Dygraphs.OPTIONS_REFERENCE listing.'); - // Only log this error once. - OPTIONS_REFERENCE[name] = true; + if (typeof(process) !== 'undefined') { + if (process.env.NODE_ENV != 'production') { + if (typeof(OPTIONS_REFERENCE) === 'undefined') { + console.error('Must include options reference JS for testing'); + } else if (!OPTIONS_REFERENCE.hasOwnProperty(name)) { + console.error('Dygraphs is using property ' + name + ', which has no ' + + 'entry in the Dygraphs.OPTIONS_REFERENCE listing.'); + // Only log this error once. + OPTIONS_REFERENCE[name] = true; + } } } return seriesName ? this.attributes_.getForSeries(name, seriesName) : this.attributes_.get(name); @@ -860,7 +861,9 @@ Dygraph.prototype.resizeElements_ = function() { this.graphDiv.style.width = this.width_ + "px"; this.graphDiv.style.height = this.height_ + "px"; - var canvasScale = utils.getContextPixelRatio(this.canvas_ctx_); + var pixelRatioOption = this.getNumericOption('pixelRatio') + + var canvasScale = pixelRatioOption || utils.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 @@ -869,7 +872,7 @@ Dygraph.prototype.resizeElements_ = function() { this.canvas_ctx_.scale(canvasScale, canvasScale); } - var hiddenScale = utils.getContextPixelRatio(this.hidden_ctx_); + var hiddenScale = pixelRatioOption || utils.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 @@ -1349,11 +1352,12 @@ Dygraph.prototype.resetZoom = function() { const zoomCallback = this.getFunctionOption('zoomCallback'); // TODO(danvk): merge this block w/ the code below. + // TODO(danvk): factor out a generic, public zoomTo method. if (!animatedZooms) { this.dateWindow_ = null; - for (const axis of this.axes_) { + this.axes_.forEach(axis => { if (axis.valueRange) delete axis.valueRange; - } + }); this.drawGraph_(); if (zoomCallback) { @@ -1376,9 +1380,9 @@ Dygraph.prototype.resetZoom = function() { this.doAnimatedZoom(oldWindow, newWindow, oldValueRanges, newValueRanges, () => { this.dateWindow_ = null; - for (const axis of this.axes_) { + this.axes_.forEach(axis => { if (axis.valueRange) delete axis.valueRange; - } + }); if (zoomCallback) { zoomCallback.call(this, minDate, maxDate, this.yAxisRanges()); } @@ -2437,9 +2441,8 @@ Dygraph.prototype.computeYAxisRanges_ = function(extremes) { // // - backwards compatible (yRangePad not set): // 10% padding for automatic Y ranges, but not for user-supplied - // ranges, and move a close-to-zero edge to zero except if - // avoidMinZero is set, since drawing at the edge results in - // invisible lines. Unfortunately lines drawn at the edge of a + // ranges, and move a close-to-zero edge to zero, since drawing at the edge + // results in invisible lines. Unfortunately lines drawn at the edge of a // user-supplied range will still be invisible. If logscale is // set, add a variable amount of padding at the top but // none at the bottom. @@ -2512,11 +2515,9 @@ Dygraph.prototype.computeYAxisRanges_ = function(extremes) { minAxisY = minY - ypad * span; // Backwards-compatible behavior: Move the span to start or end at zero if it's - // close to zero, but not if avoidMinZero is set. - if (!this.getBooleanOption("avoidMinZero")) { - if (minAxisY < 0 && minY >= 0) minAxisY = 0; - if (maxAxisY > 0 && maxY <= 0) maxAxisY = 0; - } + // close to zero. + if (minAxisY < 0 && minY >= 0) minAxisY = 0; + if (maxAxisY > 0 && maxY <= 0) maxAxisY = 0; } } axis.extremeRange = [minAxisY, maxAxisY]; @@ -2779,6 +2780,23 @@ Dygraph.prototype.parseCSV_ = function(data) { return ret; }; +// In native format, all values must be dates or numbers. +// This check isn't perfect but will catch most mistaken uses of strings. +function validateNativeFormat(data) { + const firstRow = data[0]; + const firstX = firstRow[0]; + if (typeof firstX !== 'number' && !utils.isDateLike(firstX)) { + throw new Error(`Expected number or date but got ${typeof firstX}: ${firstX}.`); + } + for (let i = 1; i < firstRow.length; i++) { + const val = firstRow[i]; + if (val === null || val === undefined) continue; + if (typeof val === 'number') continue; + if (utils.isArrayLike(val)) continue; // e.g. error bars or custom bars. + throw new Error(`Expected number or array but got ${typeof val}: ${val}.`); + } +} + /** * 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 @@ -2798,6 +2816,8 @@ Dygraph.prototype.parseArray_ = function(data) { return null; } + validateNativeFormat(data); + var i; if (this.attr_("labels") === null) { console.warn("Using default labels. Set labels explicitly via 'labels' " + @@ -2993,6 +3013,7 @@ Dygraph.prototype.parseDataTable_ = function(data) { /** * Signals to plugins that the chart data has updated. * This happens after the data has updated but before the chart has redrawn. + * @private */ Dygraph.prototype.cascadeDataDidUpdateEvent_ = function() { // TODO(danvk): there are some issues checking xAxisRange() and using @@ -3107,7 +3128,7 @@ Dygraph.prototype.updateOptions = function(input_attrs, block_redraw) { if (file) { // This event indicates that the data is about to change, but hasn't yet. - // TODO(danvk): support cancelation of the update via this event. + // TODO(danvk): support cancellation of the update via this event. this.cascadeEvents_('dataWillUpdate', {}); this.file_ = file; @@ -3125,6 +3146,7 @@ Dygraph.prototype.updateOptions = function(input_attrs, block_redraw) { /** * Make a copy of input attributes, removing file as a convenience. + * @private */ Dygraph.copyUserAttrs_ = function(attrs) { var my_attrs = {};