And error bars will be calculated automatically using a binomial distribution.
For further documentation and examples, see http://dygraphs.com/
-
*/
-// Polyfills
-import 'core-js/es6/symbol';
-import 'core-js/fn/symbol/iterator';
-
import DygraphLayout from './dygraph-layout';
import DygraphCanvasRenderer from './dygraph-canvas';
import DygraphOptions from './dygraph-options';
};
Dygraph.NAME = "Dygraph";
-Dygraph.VERSION = "1.1.0";
+Dygraph.VERSION = "2.1.0";
// Various default values
Dygraph.DEFAULT_ROLL_PERIOD = 1;
*/
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);
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
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
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) {
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());
}
//
// - 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.
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];
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
return null;
}
+ validateNativeFormat(data);
+
var i;
if (this.attr_("labels") === null) {
console.warn("Using default labels. Set labels explicitly via 'labels' " +
/**
* 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
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;
/**
* Make a copy of input attributes, removing file as a convenience.
+ * @private
*/
Dygraph.copyUserAttrs_ = function(attrs) {
var my_attrs = {};