// This list needs to be kept in sync w/ the one in generate-combined.sh
// and the one in jsTestDriver.conf.
var source_files = [
- "src/polyfills/console.js",
- "src/polyfills/dashed-canvas.js",
+ // "src/polyfills/console.js",
+ // "src/polyfills/dashed-canvas.js",
"src/dygraph-options.js",
"src/dygraph-layout.js",
"src/dygraph-canvas.js",
"src/dygraph.js",
"src/dygraph-utils.js",
- "src/dygraph-gviz.js",
+ // "src/dygraph-gviz.js",
"src/dygraph-interaction-model.js",
"src/dygraph-tickers.js",
- "src/dygraph-plugin-base.js",
- "src/plugins/annotations.js",
- "src/plugins/axes.js",
- "src/plugins/chart-labels.js",
- "src/plugins/grid.js",
- "src/plugins/legend.js",
- "src/plugins/range-selector.js",
- "src/dygraph-plugin-install.js",
- "src/dygraph-options-reference.js", // Shouldn't be included in generate-combined.sh
+ // "src/dygraph-plugin-base.js",
+ // "src/plugins/annotations.js",
+ // "src/plugins/axes.js",
+ // "src/plugins/chart-labels.js",
+ // "src/plugins/grid.js",
+ // "src/plugins/legend.js",
+ // "src/plugins/range-selector.js",
+ // "src/dygraph-plugin-install.js",
+ // "src/dygraph-options-reference.js", // Shouldn't be included in generate-combined.sh
"src/datahandler/datahandler.js",
"src/datahandler/default.js",
- "src/datahandler/default-fractions.js",
- "src/datahandler/bars.js",
- "src/datahandler/bars-error.js",
- "src/datahandler/bars-custom.js",
- "src/datahandler/bars-fractions.js"
+ // "src/datahandler/default-fractions.js",
+ // "src/datahandler/bars.js",
+ // "src/datahandler/bars-error.js",
+ // "src/datahandler/bars-custom.js",
+ // "src/datahandler/bars-fractions.js"
];
for (var i = 0; i < source_files.length; i++) {
},
"homepage": "https://github.com/danvk/dygraphs",
"devDependencies": {
+ "babelify": "^6.3.0",
+ "browserify": "^11.2.0",
"closure-compiler": "^0.2.6",
"coveralls": "^2.11.2",
"gulp": "^3.8.10",
"phantomjs": "^1.9.7-8",
"pre-commit": "^1.0.6",
"source-map": "^0.4.2",
- "uglify-js": "^2"
+ "uglify-js": "^2",
+ "watchify": "^3.4.0"
},
"scripts": {
"test": "make test",
/*global Dygraph:false */
/*global DygraphLayout:false */
+"use strict";
+
/**
*
* The data handler is responsible for all data specific operations. All of the
* Initially the unified data is created by the extractSeries method
* @constructor
*/
-Dygraph.DataHandler = function () {
+var DygraphDataHandler = function () {
};
-/**
- * A collection of functions to create and retrieve data handlers.
- * @type {Object.<!Dygraph.DataHandler>}
- */
-Dygraph.DataHandlers = {};
-
-(function() {
-
-"use strict";
-
-var handler = Dygraph.DataHandler;
+var handler = DygraphDataHandler;
/**
* X-value array index constant for unified data samples.
return val;
};
-})();
+export default DygraphDataHandler;
* @author David Eberlein (david.eberlein@ch.sauter-bc.com)
*/
-(function() {
-
/*global Dygraph:false */
"use strict";
+import DygraphDataHandler from './datahandler';
+
/**
* @constructor
* @extends Dygraph.DataHandler
*/
-Dygraph.DataHandlers.DefaultHandler = function() {
+var DefaultHandler = function() {
};
-var DefaultHandler = Dygraph.DataHandlers.DefaultHandler;
-DefaultHandler.prototype = new Dygraph.DataHandler();
+DefaultHandler.prototype = new DygraphDataHandler();
/** @inheritDoc */
DefaultHandler.prototype.extractSeries = function(rawData, i, options) {
return [ minY, maxY ];
};
-})();
+export default DefaultHandler;
* @constructor
*/
-var DygraphCanvasRenderer = (function() {
/*global Dygraph:false */
"use strict";
+import * as utils from './dygraph-utils';
+
/**
* @constructor
this.width = dygraph.width_;
// --- check whether everything is ok before we return
- if (!Dygraph.isCanvasSupported(this.element)) {
+ if (!utils.isCanvasSupported(this.element)) {
throw "Canvas is not supported.";
}
// This ensures that we don't overdraw.
// on Android 3 and 4, setting a clipping area on a canvas prevents it from
// displaying anything.
- if (!Dygraph.isAndroid()) {
+ if (!utils.isAndroid()) {
var ctx = this.dygraph_.canvas_ctx_;
ctx.beginPath();
ctx.rect(this.area.x, this.area.y, this.area.w, this.area.h);
// TODO(konigsberg): Compute attributes outside this method call.
var stepPlot = g.getBooleanOption("stepPlot", e.setName);
- if (!Dygraph.isArrayLike(strokePattern)) {
+ if (!utils.isArrayLike(strokePattern)) {
strokePattern = null;
}
var points = e.points;
var setName = e.setName;
- var iter = Dygraph.createIterator(points, 0, points.length,
+ var iter = utils.createIterator(points, 0, points.length,
DygraphCanvasRenderer._getIteratorPredicate(
g.getBooleanOption("connectSeparatedPoints", setName)));
// Determine which series have specialized plotters.
var plotter_attr = this.dygraph_.getOption("plotter");
var plotters = plotter_attr;
- if (!Dygraph.isArrayLike(plotters)) {
+ if (!utils.isArrayLike(plotters)) {
plotters = [plotters];
}
// this code a bit nasty.
var borderWidth = g.getNumericOption("strokeBorderWidth", setName);
var drawPointCallback = g.getOption("drawPointCallback", setName) ||
- Dygraph.Circles.DEFAULT;
+ utils.Circles.DEFAULT;
var strokePattern = g.getOption("strokePattern", setName);
var drawPoints = g.getBooleanOption("drawPoints", setName);
var pointSize = g.getNumericOption("pointSize", setName);
var stepPlot = g.getBooleanOption("stepPlot", setName);
var points = e.points;
- var iter = Dygraph.createIterator(points, 0, points.length,
+ var iter = utils.createIterator(points, 0, points.length,
DygraphCanvasRenderer._getIteratorPredicate(
g.getBooleanOption("connectSeparatedPoints", setName)));
var prevY = NaN;
var prevYs = [-1, -1];
// should be same color as the lines but only 15% opaque.
- var rgb = Dygraph.toRGB_(color);
+ var rgb = utils.toRGB_(color);
var err_color =
'rgba(' + rgb.r + ',' + rgb.g + ',' + rgb.b + ',' + fillAlpha + ')';
ctx.fillStyle = err_color;
axisY = area.h * axisY + area.y;
var points = sets[setIdx];
- var iter = Dygraph.createIterator(points, 0, points.length,
+ var iter = utils.createIterator(points, 0, points.length,
DygraphCanvasRenderer._getIteratorPredicate(
g.getBooleanOption("connectSeparatedPoints", setName)));
var prevYs = [-1, -1];
var newYs;
// should be same color as the lines but only 15% opaque.
- var rgb = Dygraph.toRGB_(color);
+ var rgb = utils.toRGB_(color);
var err_color =
'rgba(' + rgb.r + ',' + rgb.g + ',' + rgb.b + ',' + fillAlpha + ')';
ctx.fillStyle = err_color;
var point;
while (iter.hasNext) {
point = iter.next();
- if (!Dygraph.isOK(point.y) && !stepPlot) {
+ if (!utils.isOK(point.y) && !stepPlot) {
traceBackPath(ctx, prevX, prevYs[1], pathBack);
pathBack = [];
prevX = NaN;
}
};
-return DygraphCanvasRenderer;
-
-})();
+export default DygraphCanvasRenderer;
--- /dev/null
+'use strict'
+
+import * as DygraphTickers from './dygraph-tickers';
+import DygraphInteraction from './dygraph-interaction-model';
+import DygraphCanvasRenderer from './dygraph-canvas';
+import * as utils from './dygraph-utils';
+
+// Default attribute values.
+var DEFAULT_ATTRS = {
+ highlightCircleSize: 3,
+ highlightSeriesOpts: null,
+ highlightSeriesBackgroundAlpha: 0.5,
+
+ labelsDivWidth: 250,
+ labelsDivStyles: {
+ // TODO(danvk): move defaults from createStatusMessage_ here.
+ },
+ labelsSeparateLines: false,
+ labelsShowZeroValues: true,
+ labelsKMB: false,
+ labelsKMG2: false,
+ showLabelsOnHighlight: true,
+
+ digitsAfterDecimal: 2,
+ maxNumberWidth: 6,
+ sigFigs: null,
+
+ strokeWidth: 1.0,
+ strokeBorderWidth: 0,
+ strokeBorderColor: "white",
+
+ axisTickSize: 3,
+ axisLabelFontSize: 14,
+ rightGap: 5,
+
+ showRoller: false,
+ xValueParser: utils.dateParser,
+
+ delimiter: ',',
+
+ sigma: 2.0,
+ errorBars: false,
+ fractions: false,
+ wilsonInterval: true, // only relevant if fractions is true
+ customBars: false,
+ fillGraph: false,
+ fillAlpha: 0.15,
+ connectSeparatedPoints: false,
+
+ stackedGraph: false,
+ stackedGraphNaNFill: 'all',
+ hideOverlayOnMouseOut: true,
+
+ legend: 'onmouseover',
+ stepPlot: false,
+ avoidMinZero: false,
+ xRangePad: 0,
+ yRangePad: null,
+ drawAxesAtZero: false,
+
+ // Sizes of the various chart labels.
+ titleHeight: 28,
+ xLabelHeight: 18,
+ yLabelWidth: 18,
+
+ axisLineColor: "black",
+ axisLineWidth: 0.3,
+ gridLineWidth: 0.3,
+ axisLabelColor: "black",
+ axisLabelWidth: 50,
+ gridLineColor: "rgb(128,128,128)",
+
+ interactionModel: DygraphInteraction.defaultModel,
+ animatedZooms: false, // (for now)
+
+ // Range selector options
+ showRangeSelector: false,
+ rangeSelectorHeight: 40,
+ rangeSelectorPlotStrokeColor: "#808FAB",
+ rangeSelectorPlotFillGradientColor: "white",
+ rangeSelectorPlotFillColor: "#A7B1C4",
+ rangeSelectorBackgroundStrokeColor: "gray",
+ rangeSelectorBackgroundLineWidth: 1,
+ rangeSelectorPlotLineWidth:1.5,
+ rangeSelectorForegroundStrokeColor: "black",
+ rangeSelectorForegroundLineWidth: 1,
+ rangeSelectorAlpha: 0.6,
+ showInRangeSelector: null,
+
+ // The ordering here ensures that central lines always appear above any
+ // fill bars/error bars.
+ plotter: [
+ DygraphCanvasRenderer._fillPlotter,
+ DygraphCanvasRenderer._errorPlotter,
+ DygraphCanvasRenderer._linePlotter
+ ],
+
+ plugins: [ ],
+
+ // per-axis options
+ axes: {
+ x: {
+ pixelsPerLabel: 70,
+ axisLabelWidth: 60,
+ axisLabelFormatter: utils.dateAxisLabelFormatter,
+ valueFormatter: utils.dateValueFormatter,
+ drawGrid: true,
+ drawAxis: true,
+ independentTicks: true,
+ ticker: DygraphTickers.dateTicker
+ },
+ y: {
+ axisLabelWidth: 50,
+ pixelsPerLabel: 30,
+ valueFormatter: utils.numberValueFormatter,
+ axisLabelFormatter: utils.numberAxisLabelFormatter,
+ drawGrid: true,
+ drawAxis: true,
+ independentTicks: true,
+ ticker: DygraphTickers.numericTicks
+ },
+ y2: {
+ axisLabelWidth: 50,
+ pixelsPerLabel: 30,
+ valueFormatter: utils.numberValueFormatter,
+ axisLabelFormatter: utils.numberAxisLabelFormatter,
+ drawAxis: true, // only applies when there are two axes of data.
+ drawGrid: false,
+ independentTicks: false,
+ ticker: DygraphTickers.numericTicks
+ }
+ }
+};
+
+export default DEFAULT_ATTRS;
* @author Robert Konigsberg (konigsberg@google.com)
*/
-(function() {
/*global Dygraph:false */
"use strict";
+import * as utils from './dygraph-utils';
+
/**
* You can drag this many pixels past the edge of the chart and still have it
* be considered a zoom. This makes it easier to zoom to the exact edge of the
* A collection of functions to facilitate build custom interaction models.
* @class
*/
-Dygraph.Interaction = {};
+var DygraphInteraction = {};
/**
* Checks whether the beginning & ending of an event were close enough that it
* @param {Dygraph} g
* @param {Object} context
*/
-Dygraph.Interaction.maybeTreatMouseOpAsClick = function(event, g, context) {
- context.dragEndX = Dygraph.dragGetX_(event, context);
- context.dragEndY = Dygraph.dragGetY_(event, context);
+DygraphInteraction.maybeTreatMouseOpAsClick = function(event, g, context) {
+ context.dragEndX = utils.dragGetX_(event, context);
+ context.dragEndY = utils.dragGetY_(event, context);
var regionWidth = Math.abs(context.dragEndX - context.dragStartX);
var regionHeight = Math.abs(context.dragEndY - context.dragStartY);
if (regionWidth < 2 && regionHeight < 2 &&
g.lastx_ !== undefined && g.lastx_ != -1) {
- Dygraph.Interaction.treatMouseOpAsClick(g, event, context);
+ DygraphInteraction.treatMouseOpAsClick(g, event, context);
}
context.regionWidth = regionWidth;
* dragStartX/dragStartY/etc. properties). This function modifies the
* context.
*/
-Dygraph.Interaction.startPan = function(event, g, context) {
+DygraphInteraction.startPan = function(event, g, context) {
var i, axis;
context.isPanning = true;
var xRange = g.xAxisRange();
if (g.getOptionForAxis("logscale", "x")) {
- context.initialLeftmostDate = Dygraph.log10(xRange[0]);
- context.dateRange = Dygraph.log10(xRange[1]) - Dygraph.log10(xRange[0]);
+ context.initialLeftmostDate = utils.log10(xRange[0]);
+ context.dateRange = utils.log10(xRange[1]) - utils.log10(xRange[0]);
} else {
context.initialLeftmostDate = xRange[0];
context.dateRange = xRange[1] - xRange[0];
// In log scale, initialTopValue, dragValueRange and unitsPerPixel are log scale.
var logscale = g.attributes_.getForAxis("logscale", i);
if (logscale) {
- axis_data.initialTopValue = Dygraph.log10(yRange[1]);
- axis_data.dragValueRange = Dygraph.log10(yRange[1]) - Dygraph.log10(yRange[0]);
+ axis_data.initialTopValue = utils.log10(yRange[1]);
+ axis_data.dragValueRange = utils.log10(yRange[1]) - utils.log10(yRange[0]);
} else {
axis_data.initialTopValue = yRange[1];
axis_data.dragValueRange = yRange[1] - yRange[0];
* dragStartX/dragStartY/etc. properties). This function modifies the
* context.
*/
-Dygraph.Interaction.movePan = function(event, g, context) {
- context.dragEndX = Dygraph.dragGetX_(event, context);
- context.dragEndY = Dygraph.dragGetY_(event, context);
+DygraphInteraction.movePan = function(event, g, context) {
+ context.dragEndX = utils.dragGetX_(event, context);
+ context.dragEndY = utils.dragGetY_(event, context);
var minDate = context.initialLeftmostDate -
(context.dragEndX - context.dragStartX) * context.xUnitsPerPixel;
}
if (g.getOptionForAxis("logscale", "x")) {
- g.dateWindow_ = [ Math.pow(Dygraph.LOG_SCALE, minDate),
- Math.pow(Dygraph.LOG_SCALE, maxDate) ];
+ g.dateWindow_ = [ Math.pow(utils.LOG_SCALE, minDate),
+ Math.pow(utils.LOG_SCALE, maxDate) ];
} else {
g.dateWindow_ = [minDate, maxDate];
}
}
}
if (g.attributes_.getForAxis("logscale", i)) {
- axis.valueWindow = [ Math.pow(Dygraph.LOG_SCALE, minValue),
- Math.pow(Dygraph.LOG_SCALE, maxValue) ];
+ axis.valueWindow = [ Math.pow(utils.LOG_SCALE, minValue),
+ Math.pow(utils.LOG_SCALE, maxValue) ];
} else {
axis.valueWindow = [ minValue, maxValue ];
}
* dragStartX/dragStartY/etc. properties). This function modifies the
* context.
*/
-Dygraph.Interaction.endPan = Dygraph.Interaction.maybeTreatMouseOpAsClick;
+DygraphInteraction.endPan = DygraphInteraction.maybeTreatMouseOpAsClick;
/**
* Called in response to an interaction model operation that
* dragStartX/dragStartY/etc. properties). This function modifies the
* context.
*/
-Dygraph.Interaction.startZoom = function(event, g, context) {
+DygraphInteraction.startZoom = function(event, g, context) {
context.isZooming = true;
context.zoomMoved = false;
};
* dragStartX/dragStartY/etc. properties). This function modifies the
* context.
*/
-Dygraph.Interaction.moveZoom = function(event, g, context) {
+DygraphInteraction.moveZoom = function(event, g, context) {
context.zoomMoved = true;
- context.dragEndX = Dygraph.dragGetX_(event, context);
- context.dragEndY = Dygraph.dragGetY_(event, context);
+ context.dragEndX = utils.dragGetX_(event, context);
+ context.dragEndY = utils.dragGetY_(event, context);
var xDelta = Math.abs(context.dragStartX - context.dragEndX);
var yDelta = Math.abs(context.dragStartY - context.dragEndY);
// drag direction threshold for y axis is twice as large as x axis
- context.dragDirection = (xDelta < yDelta / 2) ? Dygraph.VERTICAL : Dygraph.HORIZONTAL;
+ context.dragDirection = (xDelta < yDelta / 2) ? utils.VERTICAL : utils.HORIZONTAL;
g.drawZoomRect_(
context.dragDirection,
* @param {Event} event
* @param {Object} context
*/
-Dygraph.Interaction.treatMouseOpAsClick = function(g, event, context) {
+DygraphInteraction.treatMouseOpAsClick = function(g, event, context) {
var clickCallback = g.getFunctionOption('clickCallback');
var pointClickCallback = g.getFunctionOption('pointClickCallback');
* dragStartX/dragStartY/etc. properties). This function modifies the
* context.
*/
-Dygraph.Interaction.endZoom = function(event, g, context) {
+DygraphInteraction.endZoom = function(event, g, context) {
g.clearZoomRect_();
context.isZooming = false;
- Dygraph.Interaction.maybeTreatMouseOpAsClick(event, g, context);
+ DygraphInteraction.maybeTreatMouseOpAsClick(event, g, context);
// The zoom rectangle is visibly clipped to the plot area, so its behavior
// should be as well.
// See http://code.google.com/p/dygraphs/issues/detail?id=280
var plotArea = g.getArea();
if (context.regionWidth >= 10 &&
- context.dragDirection == Dygraph.HORIZONTAL) {
+ context.dragDirection == utils.HORIZONTAL) {
var left = Math.min(context.dragStartX, context.dragEndX),
right = Math.max(context.dragStartX, context.dragEndX);
left = Math.max(left, plotArea.x);
}
context.cancelNextDblclick = true;
} else if (context.regionHeight >= 10 &&
- context.dragDirection == Dygraph.VERTICAL) {
+ context.dragDirection == utils.VERTICAL) {
var top = Math.min(context.dragStartY, context.dragEndY),
bottom = Math.max(context.dragStartY, context.dragEndY);
top = Math.max(top, plotArea.y);
/**
* @private
*/
-Dygraph.Interaction.startTouch = function(event, g, context) {
+DygraphInteraction.startTouch = function(event, g, context) {
event.preventDefault(); // touch browsers are all nice.
if (event.touches.length > 1) {
// If the user ever puts two fingers down, it's not a double tap.
/**
* @private
*/
-Dygraph.Interaction.moveTouch = function(event, g, context) {
+DygraphInteraction.moveTouch = function(event, g, context) {
// If the tap moves, then it's definitely not part of a double-tap.
context.startTimeForDoubleTapMs = null;
/**
* @private
*/
-Dygraph.Interaction.endTouch = function(event, g, context) {
+DygraphInteraction.endTouch = function(event, g, context) {
if (event.touches.length !== 0) {
// this is effectively a "reset"
- Dygraph.Interaction.startTouch(event, g, context);
+ DygraphInteraction.startTouch(event, g, context);
} else if (event.changedTouches.length == 1) {
// Could be part of a "double tap"
// The heuristic here is that it's a double-tap if the two touchend events
* edge of the chart. For events in the interior of the chart, this returns zero.
*/
var distanceFromChart = function(event, g) {
- var chartPos = Dygraph.findPos(g.canvas_);
+ var chartPos = utils.findPos(g.canvas_);
var box = {
left: chartPos.x,
right: chartPos.x + g.canvas_.offsetWidth,
};
var pt = {
- x: Dygraph.pageX(event),
- y: Dygraph.pageY(event)
+ x: utils.pageX(event),
+ y: utils.pageY(event)
};
var dx = distanceFromInterval(pt.x, box.left, box.right),
* this when constructing your own interaction model, e.g.:
* g.updateOptions( {
* interactionModel: {
- * mousedown: Dygraph.defaultInteractionModel.mousedown
+ * mousedown: DygraphInteraction.defaultInteractionModel.mousedown
* }
* } );
*/
-Dygraph.Interaction.defaultModel = {
+DygraphInteraction.defaultModel = {
// Track the beginning of drag events
mousedown: function(event, g, context) {
// Right-click should not initiate a zoom.
context.initializeMouseDown(event, g, context);
if (event.altKey || event.shiftKey) {
- Dygraph.startPan(event, g, context);
+ DygraphInteraction.startPan(event, g, context);
} else {
- Dygraph.startZoom(event, g, context);
+ DygraphInteraction.startZoom(event, g, context);
}
// Note: we register mousemove/mouseup on document to allow some leeway for
// When the mouse moves >200px from the chart edge, cancel the zoom.
var d = distanceFromChart(event, g);
if (d < DRAG_EDGE_MARGIN) {
- Dygraph.moveZoom(event, g, context);
+ DygraphInteraction.moveZoom(event, g, context);
} else {
if (context.dragEndX !== null) {
context.dragEndX = null;
}
}
} else if (context.isPanning) {
- Dygraph.movePan(event, g, context);
+ DygraphInteraction.movePan(event, g, context);
}
};
var mouseup = function(event) {
if (context.isZooming) {
if (context.dragEndX !== null) {
- Dygraph.endZoom(event, g, context);
+ DygraphInteraction.endZoom(event, g, context);
} else {
- Dygraph.Interaction.maybeTreatMouseOpAsClick(event, g, context);
+ DygraphInteraction.maybeTreatMouseOpAsClick(event, g, context);
}
} else if (context.isPanning) {
- Dygraph.endPan(event, g, context);
+ DygraphInteraction.endPan(event, g, context);
}
- Dygraph.removeEvent(document, 'mousemove', mousemove);
- Dygraph.removeEvent(document, 'mouseup', mouseup);
+ utils.removeEvent(document, 'mousemove', mousemove);
+ utils.removeEvent(document, 'mouseup', mouseup);
context.destroy();
};
willDestroyContextMyself: true,
touchstart: function(event, g, context) {
- Dygraph.Interaction.startTouch(event, g, context);
+ DygraphInteraction.startTouch(event, g, context);
},
touchmove: function(event, g, context) {
- Dygraph.Interaction.moveTouch(event, g, context);
+ DygraphInteraction.moveTouch(event, g, context);
},
touchend: function(event, g, context) {
- Dygraph.Interaction.endTouch(event, g, context);
+ DygraphInteraction.endTouch(event, g, context);
},
// Disable zooming out if panning.
}
};
-Dygraph.DEFAULT_ATTRS.interactionModel = Dygraph.Interaction.defaultModel;
+/*
+Dygraph.DEFAULT_ATTRS.interactionModel = DygraphInteraction.defaultModel;
// old ways of accessing these methods/properties
-Dygraph.defaultInteractionModel = Dygraph.Interaction.defaultModel;
-Dygraph.endZoom = Dygraph.Interaction.endZoom;
-Dygraph.moveZoom = Dygraph.Interaction.moveZoom;
-Dygraph.startZoom = Dygraph.Interaction.startZoom;
-Dygraph.endPan = Dygraph.Interaction.endPan;
-Dygraph.movePan = Dygraph.Interaction.movePan;
-Dygraph.startPan = Dygraph.Interaction.startPan;
-
-Dygraph.Interaction.nonInteractiveModel_ = {
+Dygraph.defaultInteractionModel = DygraphInteraction.defaultModel;
+Dygraph.endZoom = DygraphInteraction.endZoom;
+Dygraph.moveZoom = DygraphInteraction.moveZoom;
+Dygraph.startZoom = DygraphInteraction.startZoom;
+Dygraph.endPan = DygraphInteraction.endPan;
+Dygraph.movePan = DygraphInteraction.movePan;
+Dygraph.startPan = DygraphInteraction.startPan;
+*/
+
+DygraphInteraction.nonInteractiveModel_ = {
mousedown: function(event, g, context) {
context.initializeMouseDown(event, g, context);
},
- mouseup: Dygraph.Interaction.maybeTreatMouseOpAsClick
+ mouseup: DygraphInteraction.maybeTreatMouseOpAsClick
};
// Default interaction model when using the range selector.
-Dygraph.Interaction.dragIsPanInteractionModel = {
+DygraphInteraction.dragIsPanInteractionModel = {
mousedown: function(event, g, context) {
context.initializeMouseDown(event, g, context);
- Dygraph.startPan(event, g, context);
+ DygraphInteraction.startPan(event, g, context);
},
mousemove: function(event, g, context) {
if (context.isPanning) {
- Dygraph.movePan(event, g, context);
+ DygraphInteraction.movePan(event, g, context);
}
},
mouseup: function(event, g, context) {
if (context.isPanning) {
- Dygraph.endPan(event, g, context);
+ DygraphInteraction.endPan(event, g, context);
}
}
};
-})();
+export default DygraphInteraction;
* dygraphs.
*/
-var DygraphLayout = (function() {
-
/*global Dygraph:false */
"use strict";
+import * as utils from './dygraph-utils';
+
/**
* Creates a new DygraphLayout object.
*
"annotation.icon property");
return;
}
- Dygraph.update(a, ann[i]);
+ utils.update(a, ann[i]);
if (!a.xval) a.xval = parse(a.x);
this.annotations.push(a);
}
this._xAxis.scale = (xrange !== 0 ? 1 / xrange : 1.0);
if (this.dygraph_.getOptionForAxis("logscale", 'x')) {
- this._xAxis.xlogrange = Dygraph.log10(this._xAxis.maxval) - Dygraph.log10(this._xAxis.minval);
+ this._xAxis.xlogrange = utils.log10(this._xAxis.maxval) - utils.log10(this._xAxis.minval);
this._xAxis.xlogscale = (this._xAxis.xlogrange !== 0 ? 1.0 / this._xAxis.xlogrange : 1.0);
}
for (var i = 0; i < this.yAxes_.length; i++) {
axis.yscale = (axis.yrange !== 0 ? 1.0 / axis.yrange : 1.0);
if (this.dygraph_.getOption("logscale")) {
- axis.ylogrange = Dygraph.log10(axis.maxyval) - Dygraph.log10(axis.minyval);
+ axis.ylogrange = utils.log10(axis.maxyval) - utils.log10(axis.minyval);
axis.ylogscale = (axis.ylogrange !== 0 ? 1.0 / axis.ylogrange : 1.0);
if (!isFinite(axis.ylogrange) || isNaN(axis.ylogrange)) {
console.error('axis ' + i + ' of graph at ' + axis.g +
DygraphLayout.calcXNormal_ = function(value, xAxis, logscale) {
if (logscale) {
- return ((Dygraph.log10(value) - Dygraph.log10(xAxis.minval)) * xAxis.xlogscale);
+ return ((utils.log10(value) - utils.log10(xAxis.minval)) * xAxis.xlogscale);
} else {
return (value - xAxis.minval) * xAxis.scale;
}
*/
DygraphLayout.calcYNormal_ = function(axis, value, logscale) {
if (logscale) {
- var x = 1.0 - ((Dygraph.log10(value) - Dygraph.log10(axis.minyval)) * axis.ylogscale);
+ var x = 1.0 - ((utils.log10(value) - utils.log10(axis.minyval)) * axis.ylogscale);
return isFinite(x) ? x : NaN; // shim for v8 issue; see pull request 276
} else {
return 1.0 - ((value - axis.minyval) * axis.yscale);
this.setPointsOffsets = [];
};
-return DygraphLayout;
-
-})();
+export default DygraphLayout;
*/
/**
- * @fileoverview DygraphOptions is responsible for parsing and returning information about options.
- *
- * Still tightly coupled to Dygraphs, we could remove some of that, you know.
+ * @fileoverview DygraphOptions is responsible for parsing and returning
+ * information about options.
*/
-var DygraphOptions = (function() {
-/*jshint strict:false */
-
-// For "production" code, this gets set to false by uglifyjs.
-// Need to define it outside of "use strict", hence the nested IIFEs.
-if (typeof(DEBUG) === 'undefined') DEBUG=true;
-
-return (function() {
-
// TODO: remove this jshint directive & fix the warnings.
/*jshint sub:true */
/*global Dygraph:false */
"use strict";
+import * as utils from './dygraph-utils';
+import DEFAULT_ATTRS from './dygraph-default-attrs';
+
/*
* Interesting member variables: (REMOVING THIS LIST AS I CLOSURIZE)
* global_ - global attributes (common among all graphs, AIUI)
}
var axis_opts = this.user_["axes"] || {};
- Dygraph.update(this.yAxes_[0].options, axis_opts["y"] || {});
+ utils.update(this.yAxes_[0].options, axis_opts["y"] || {});
if (this.yAxes_.length > 1) {
- Dygraph.update(this.yAxes_[1].options, axis_opts["y2"] || {});
+ utils.update(this.yAxes_[1].options, axis_opts["y2"] || {});
}
- Dygraph.update(this.xAxis_.options, axis_opts["x"] || {});
+ utils.update(this.xAxis_.options, axis_opts["x"] || {});
- if (DEBUG) this.validateOptions_();
+ // if (DEBUG) this.validateOptions_();
};
/**
if (this.global_.hasOwnProperty(name)) {
return this.global_[name];
}
- if (Dygraph.DEFAULT_ATTRS.hasOwnProperty(name)) {
- return Dygraph.DEFAULT_ATTRS[name];
+ if (DEFAULT_ATTRS.hasOwnProperty(name)) {
+ return DEFAULT_ATTRS[name];
}
return null;
};
}
}
// Default axis options third.
- var defaultAxisOptions = Dygraph.DEFAULT_ATTRS.axes[axisString];
+ var defaultAxisOptions = DEFAULT_ATTRS.axes[axisString];
if (defaultAxisOptions.hasOwnProperty(name)) {
return defaultAxisOptions[name];
}
return this.labels_;
};
-if (DEBUG) {
+// TODO: fix this
+// if (DEBUG) {
+if (false) {
/**
* Validate all options.
}
-return DygraphOptions;
-
-})();
-})();
+export default DygraphOptions;
+++ /dev/null
-/*global Dygraph:false */
-
-// Namespace for plugins. Load this before plugins/*.js files.
-Dygraph.Plugins = {};
/*jshint sub:true */
/*global Dygraph:false */
-(function() {
"use strict";
+import * as utils from './dygraph-utils';
+
/** @typedef {Array.<{v:number, label:string, label_v:(string|undefined)}>} */
-Dygraph.TickList = undefined; // the ' = undefined' keeps jshint happy.
+var TickList = undefined; // the ' = undefined' keeps jshint happy.
/** @typedef {function(
* number,
* function(string):*,
* Dygraph=,
* Array.<number>=
- * ): Dygraph.TickList}
+ * ): TickList}
*/
-Dygraph.Ticker = undefined; // the ' = undefined' keeps jshint happy.
+var Ticker = undefined; // the ' = undefined' keeps jshint happy.
-/** @type {Dygraph.Ticker} */
-Dygraph.numericLinearTicks = function(a, b, pixels, opts, dygraph, vals) {
+/** @type {Ticker} */
+export var numericLinearTicks = function(a, b, pixels, opts, dygraph, vals) {
var nonLogscaleOpts = function(opt) {
if (opt === 'logscale') return false;
return opts(opt);
};
- return Dygraph.numericTicks(a, b, pixels, nonLogscaleOpts, dygraph, vals);
+ return numericTicks(a, b, pixels, nonLogscaleOpts, dygraph, vals);
};
-/** @type {Dygraph.Ticker} */
-Dygraph.numericTicks = function(a, b, pixels, opts, dygraph, vals) {
+/** @type {Ticker} */
+export var numericTicks = function(a, b, pixels, opts, dygraph, vals) {
var pixels_per_tick = /** @type{number} */(opts('pixelsPerLabel'));
var ticks = [];
var i, j, tickV, nTicks;
// TODO(danvk): factor this log-scale block out into a separate function.
if (opts("logscale")) {
nTicks = Math.floor(pixels / pixels_per_tick);
- var minIdx = Dygraph.binarySearch(a, Dygraph.PREFERRED_LOG_TICK_VALUES, 1);
- var maxIdx = Dygraph.binarySearch(b, Dygraph.PREFERRED_LOG_TICK_VALUES, -1);
+ var minIdx = utils.binarySearch(a, PREFERRED_LOG_TICK_VALUES, 1);
+ var maxIdx = utils.binarySearch(b, PREFERRED_LOG_TICK_VALUES, -1);
if (minIdx == -1) {
minIdx = 0;
}
if (maxIdx == -1) {
- maxIdx = Dygraph.PREFERRED_LOG_TICK_VALUES.length - 1;
+ maxIdx = PREFERRED_LOG_TICK_VALUES.length - 1;
}
// Count the number of tick values would appear, if we can get at least
// nTicks / 4 accept them.
var lastDisplayed = null;
if (maxIdx - minIdx >= nTicks / 4) {
for (var idx = maxIdx; idx >= minIdx; idx--) {
- var tickValue = Dygraph.PREFERRED_LOG_TICK_VALUES[idx];
+ var tickValue = PREFERRED_LOG_TICK_VALUES[idx];
var pixel_coord = Math.log(tickValue / a) / Math.log(b / a) * pixels;
var tick = { v: tickValue };
if (lastDisplayed === null) {
};
-/** @type {Dygraph.Ticker} */
-Dygraph.dateTicker = function(a, b, pixels, opts, dygraph, vals) {
- var chosen = Dygraph.pickDateTickGranularity(a, b, pixels, opts);
+/** @type {Ticker} */
+export var dateTicker = function(a, b, pixels, opts, dygraph, vals) {
+ var chosen = pickDateTickGranularity(a, b, pixels, opts);
if (chosen >= 0) {
- return Dygraph.getDateAxis(a, b, chosen, opts, dygraph);
+ return getDateAxis(a, b, chosen, opts, dygraph);
} else {
// this can happen if self.width_ is zero.
return [];
};
// Time granularity enumeration
-// TODO(danvk): make this an @enum
-Dygraph.SECONDLY = 0;
-Dygraph.TWO_SECONDLY = 1;
-Dygraph.FIVE_SECONDLY = 2;
-Dygraph.TEN_SECONDLY = 3;
-Dygraph.THIRTY_SECONDLY = 4;
-Dygraph.MINUTELY = 5;
-Dygraph.TWO_MINUTELY = 6;
-Dygraph.FIVE_MINUTELY = 7;
-Dygraph.TEN_MINUTELY = 8;
-Dygraph.THIRTY_MINUTELY = 9;
-Dygraph.HOURLY = 10;
-Dygraph.TWO_HOURLY = 11;
-Dygraph.SIX_HOURLY = 12;
-Dygraph.DAILY = 13;
-Dygraph.TWO_DAILY = 14;
-Dygraph.WEEKLY = 15;
-Dygraph.MONTHLY = 16;
-Dygraph.QUARTERLY = 17;
-Dygraph.BIANNUAL = 18;
-Dygraph.ANNUAL = 19;
-Dygraph.DECADAL = 20;
-Dygraph.CENTENNIAL = 21;
-Dygraph.NUM_GRANULARITIES = 22;
+export var Granularity = {
+ SECONDLY: 0,
+ TWO_SECONDLY: 1,
+ FIVE_SECONDLY: 2,
+ TEN_SECONDLY: 3,
+ THIRTY_SECONDLY : 4,
+ MINUTELY: 5,
+ TWO_MINUTELY: 6,
+ FIVE_MINUTELY: 7,
+ TEN_MINUTELY: 8,
+ THIRTY_MINUTELY: 9,
+ HOURLY: 10,
+ TWO_HOURLY: 11,
+ SIX_HOURLY: 12,
+ DAILY: 13,
+ TWO_DAILY: 14,
+ WEEKLY: 15,
+ MONTHLY: 16,
+ QUARTERLY: 17,
+ BIANNUAL: 18,
+ ANNUAL: 19,
+ DECADAL: 20,
+ CENTENNIAL: 21,
+ NUM_GRANULARITIES: 22
+}
// Date components enumeration (in the order of the arguments in Date)
// TODO: make this an @enum
-Dygraph.DATEFIELD_Y = 0;
-Dygraph.DATEFIELD_M = 1;
-Dygraph.DATEFIELD_D = 2;
-Dygraph.DATEFIELD_HH = 3;
-Dygraph.DATEFIELD_MM = 4;
-Dygraph.DATEFIELD_SS = 5;
-Dygraph.DATEFIELD_MS = 6;
-Dygraph.NUM_DATEFIELDS = 7;
+var DateField = {
+ DATEFIELD_Y: 0,
+ DATEFIELD_M: 1,
+ DATEFIELD_D: 2,
+ DATEFIELD_HH: 3,
+ DATEFIELD_MM: 4,
+ DATEFIELD_SS: 5,
+ DATEFIELD_MS: 6,
+ NUM_DATEFIELDS: 7
+};
/**
*
* @type {Array.<{datefield:number, step:number, spacing:number}>}
*/
-Dygraph.TICK_PLACEMENT = [];
-Dygraph.TICK_PLACEMENT[Dygraph.SECONDLY] = {datefield: Dygraph.DATEFIELD_SS, step: 1, spacing: 1000 * 1};
-Dygraph.TICK_PLACEMENT[Dygraph.TWO_SECONDLY] = {datefield: Dygraph.DATEFIELD_SS, step: 2, spacing: 1000 * 2};
-Dygraph.TICK_PLACEMENT[Dygraph.FIVE_SECONDLY] = {datefield: Dygraph.DATEFIELD_SS, step: 5, spacing: 1000 * 5};
-Dygraph.TICK_PLACEMENT[Dygraph.TEN_SECONDLY] = {datefield: Dygraph.DATEFIELD_SS, step: 10, spacing: 1000 * 10};
-Dygraph.TICK_PLACEMENT[Dygraph.THIRTY_SECONDLY] = {datefield: Dygraph.DATEFIELD_SS, step: 30, spacing: 1000 * 30};
-Dygraph.TICK_PLACEMENT[Dygraph.MINUTELY] = {datefield: Dygraph.DATEFIELD_MM, step: 1, spacing: 1000 * 60};
-Dygraph.TICK_PLACEMENT[Dygraph.TWO_MINUTELY] = {datefield: Dygraph.DATEFIELD_MM, step: 2, spacing: 1000 * 60 * 2};
-Dygraph.TICK_PLACEMENT[Dygraph.FIVE_MINUTELY] = {datefield: Dygraph.DATEFIELD_MM, step: 5, spacing: 1000 * 60 * 5};
-Dygraph.TICK_PLACEMENT[Dygraph.TEN_MINUTELY] = {datefield: Dygraph.DATEFIELD_MM, step: 10, spacing: 1000 * 60 * 10};
-Dygraph.TICK_PLACEMENT[Dygraph.THIRTY_MINUTELY] = {datefield: Dygraph.DATEFIELD_MM, step: 30, spacing: 1000 * 60 * 30};
-Dygraph.TICK_PLACEMENT[Dygraph.HOURLY] = {datefield: Dygraph.DATEFIELD_HH, step: 1, spacing: 1000 * 3600};
-Dygraph.TICK_PLACEMENT[Dygraph.TWO_HOURLY] = {datefield: Dygraph.DATEFIELD_HH, step: 2, spacing: 1000 * 3600 * 2};
-Dygraph.TICK_PLACEMENT[Dygraph.SIX_HOURLY] = {datefield: Dygraph.DATEFIELD_HH, step: 6, spacing: 1000 * 3600 * 6};
-Dygraph.TICK_PLACEMENT[Dygraph.DAILY] = {datefield: Dygraph.DATEFIELD_D, step: 1, spacing: 1000 * 86400};
-Dygraph.TICK_PLACEMENT[Dygraph.TWO_DAILY] = {datefield: Dygraph.DATEFIELD_D, step: 2, spacing: 1000 * 86400 * 2};
-Dygraph.TICK_PLACEMENT[Dygraph.WEEKLY] = {datefield: Dygraph.DATEFIELD_D, step: 7, spacing: 1000 * 604800};
-Dygraph.TICK_PLACEMENT[Dygraph.MONTHLY] = {datefield: Dygraph.DATEFIELD_M, step: 1, spacing: 1000 * 7200 * 365.2524}; // 1e3 * 60 * 60 * 24 * 365.2524 / 12
-Dygraph.TICK_PLACEMENT[Dygraph.QUARTERLY] = {datefield: Dygraph.DATEFIELD_M, step: 3, spacing: 1000 * 21600 * 365.2524}; // 1e3 * 60 * 60 * 24 * 365.2524 / 4
-Dygraph.TICK_PLACEMENT[Dygraph.BIANNUAL] = {datefield: Dygraph.DATEFIELD_M, step: 6, spacing: 1000 * 43200 * 365.2524}; // 1e3 * 60 * 60 * 24 * 365.2524 / 2
-Dygraph.TICK_PLACEMENT[Dygraph.ANNUAL] = {datefield: Dygraph.DATEFIELD_Y, step: 1, spacing: 1000 * 86400 * 365.2524}; // 1e3 * 60 * 60 * 24 * 365.2524 * 1
-Dygraph.TICK_PLACEMENT[Dygraph.DECADAL] = {datefield: Dygraph.DATEFIELD_Y, step: 10, spacing: 1000 * 864000 * 365.2524}; // 1e3 * 60 * 60 * 24 * 365.2524 * 10
-Dygraph.TICK_PLACEMENT[Dygraph.CENTENNIAL] = {datefield: Dygraph.DATEFIELD_Y, step: 100, spacing: 1000 * 8640000 * 365.2524}; // 1e3 * 60 * 60 * 24 * 365.2524 * 100
+var TICK_PLACEMENT = [];
+TICK_PLACEMENT[Granularity.SECONDLY] = {datefield: DateField.DATEFIELD_SS, step: 1, spacing: 1000 * 1};
+TICK_PLACEMENT[Granularity.TWO_SECONDLY] = {datefield: DateField.DATEFIELD_SS, step: 2, spacing: 1000 * 2};
+TICK_PLACEMENT[Granularity.FIVE_SECONDLY] = {datefield: DateField.DATEFIELD_SS, step: 5, spacing: 1000 * 5};
+TICK_PLACEMENT[Granularity.TEN_SECONDLY] = {datefield: DateField.DATEFIELD_SS, step: 10, spacing: 1000 * 10};
+TICK_PLACEMENT[Granularity.THIRTY_SECONDLY] = {datefield: DateField.DATEFIELD_SS, step: 30, spacing: 1000 * 30};
+TICK_PLACEMENT[Granularity.MINUTELY] = {datefield: DateField.DATEFIELD_MM, step: 1, spacing: 1000 * 60};
+TICK_PLACEMENT[Granularity.TWO_MINUTELY] = {datefield: DateField.DATEFIELD_MM, step: 2, spacing: 1000 * 60 * 2};
+TICK_PLACEMENT[Granularity.FIVE_MINUTELY] = {datefield: DateField.DATEFIELD_MM, step: 5, spacing: 1000 * 60 * 5};
+TICK_PLACEMENT[Granularity.TEN_MINUTELY] = {datefield: DateField.DATEFIELD_MM, step: 10, spacing: 1000 * 60 * 10};
+TICK_PLACEMENT[Granularity.THIRTY_MINUTELY] = {datefield: DateField.DATEFIELD_MM, step: 30, spacing: 1000 * 60 * 30};
+TICK_PLACEMENT[Granularity.HOURLY] = {datefield: DateField.DATEFIELD_HH, step: 1, spacing: 1000 * 3600};
+TICK_PLACEMENT[Granularity.TWO_HOURLY] = {datefield: DateField.DATEFIELD_HH, step: 2, spacing: 1000 * 3600 * 2};
+TICK_PLACEMENT[Granularity.SIX_HOURLY] = {datefield: DateField.DATEFIELD_HH, step: 6, spacing: 1000 * 3600 * 6};
+TICK_PLACEMENT[Granularity.DAILY] = {datefield: DateField.DATEFIELD_D, step: 1, spacing: 1000 * 86400};
+TICK_PLACEMENT[Granularity.TWO_DAILY] = {datefield: DateField.DATEFIELD_D, step: 2, spacing: 1000 * 86400 * 2};
+TICK_PLACEMENT[Granularity.WEEKLY] = {datefield: DateField.DATEFIELD_D, step: 7, spacing: 1000 * 604800};
+TICK_PLACEMENT[Granularity.MONTHLY] = {datefield: DateField.DATEFIELD_M, step: 1, spacing: 1000 * 7200 * 365.2524}; // 1e3 * 60 * 60 * 24 * 365.2524 / 12
+TICK_PLACEMENT[Granularity.QUARTERLY] = {datefield: DateField.DATEFIELD_M, step: 3, spacing: 1000 * 21600 * 365.2524}; // 1e3 * 60 * 60 * 24 * 365.2524 / 4
+TICK_PLACEMENT[Granularity.BIANNUAL] = {datefield: DateField.DATEFIELD_M, step: 6, spacing: 1000 * 43200 * 365.2524}; // 1e3 * 60 * 60 * 24 * 365.2524 / 2
+TICK_PLACEMENT[Granularity.ANNUAL] = {datefield: DateField.DATEFIELD_Y, step: 1, spacing: 1000 * 86400 * 365.2524}; // 1e3 * 60 * 60 * 24 * 365.2524 * 1
+TICK_PLACEMENT[Granularity.DECADAL] = {datefield: DateField.DATEFIELD_Y, step: 10, spacing: 1000 * 864000 * 365.2524}; // 1e3 * 60 * 60 * 24 * 365.2524 * 10
+TICK_PLACEMENT[Granularity.CENTENNIAL] = {datefield: DateField.DATEFIELD_Y, step: 100, spacing: 1000 * 8640000 * 365.2524}; // 1e3 * 60 * 60 * 24 * 365.2524 * 100
/**
* NOTE: this assumes that Dygraph.LOG_SCALE = 10.
* @type {Array.<number>}
*/
-Dygraph.PREFERRED_LOG_TICK_VALUES = (function() {
+var PREFERRED_LOG_TICK_VALUES = (function() {
var vals = [];
for (var power = -39; power <= 39; power++) {
var range = Math.pow(10, power);
* @return {number} The appropriate axis granularity for this chart. See the
* enumeration of possible values in dygraph-tickers.js.
*/
-Dygraph.pickDateTickGranularity = function(a, b, pixels, opts) {
+var pickDateTickGranularity = function(a, b, pixels, opts) {
var pixels_per_tick = /** @type{number} */(opts('pixelsPerLabel'));
- for (var i = 0; i < Dygraph.NUM_GRANULARITIES; i++) {
- var num_ticks = Dygraph.numDateTicks(a, b, i);
+ for (var i = 0; i < Granularity.NUM_GRANULARITIES; i++) {
+ var num_ticks = numDateTicks(a, b, i);
if (pixels / num_ticks >= pixels_per_tick) {
return i;
}
* @param {number} granularity (one of the granularities enumerated above)
* @return {number} (Approximate) number of ticks that would result.
*/
-Dygraph.numDateTicks = function(start_time, end_time, granularity) {
- var spacing = Dygraph.TICK_PLACEMENT[granularity].spacing;
+var numDateTicks = function(start_time, end_time, granularity) {
+ var spacing = TICK_PLACEMENT[granularity].spacing;
return Math.round(1.0 * (end_time - start_time) / spacing);
};
* @param {number} granularity (one of the granularities enumerated above)
* @param {function(string):*} opts Function mapping from option name -> value.
* @param {Dygraph=} dg
- * @return {!Dygraph.TickList}
+ * @return {!TickList}
*/
-Dygraph.getDateAxis = function(start_time, end_time, granularity, opts, dg) {
+export var getDateAxis = function(start_time, end_time, granularity, opts, dg) {
var formatter = /** @type{AxisLabelFormatter} */(
opts("axisLabelFormatter"));
var utc = opts("labelsUTC");
- var accessors = utc ? Dygraph.DateAccessorsUTC : Dygraph.DateAccessorsLocal;
+ var accessors = utc ? utils.DateAccessorsUTC : utils.DateAccessorsLocal;
- var datefield = Dygraph.TICK_PLACEMENT[granularity].datefield;
- var step = Dygraph.TICK_PLACEMENT[granularity].step;
- var spacing = Dygraph.TICK_PLACEMENT[granularity].spacing;
+ var datefield = TICK_PLACEMENT[granularity].datefield;
+ var step = TICK_PLACEMENT[granularity].step;
+ var spacing = TICK_PLACEMENT[granularity].spacing;
// Choose a nice tick position before the initial instant.
// Currently, this code deals properly with the existent daily granularities:
// by setting the start_date_offset to 0.
var start_date = new Date(start_time);
var date_array = [];
- date_array[Dygraph.DATEFIELD_Y] = accessors.getFullYear(start_date);
- date_array[Dygraph.DATEFIELD_M] = accessors.getMonth(start_date);
- date_array[Dygraph.DATEFIELD_D] = accessors.getDate(start_date);
- date_array[Dygraph.DATEFIELD_HH] = accessors.getHours(start_date);
- date_array[Dygraph.DATEFIELD_MM] = accessors.getMinutes(start_date);
- date_array[Dygraph.DATEFIELD_SS] = accessors.getSeconds(start_date);
- date_array[Dygraph.DATEFIELD_MS] = accessors.getMilliseconds(start_date);
+ date_array[DateField.DATEFIELD_Y] = accessors.getFullYear(start_date);
+ date_array[DateField.DATEFIELD_M] = accessors.getMonth(start_date);
+ date_array[DateField.DATEFIELD_D] = accessors.getDate(start_date);
+ date_array[DateField.DATEFIELD_HH] = accessors.getHours(start_date);
+ date_array[DateField.DATEFIELD_MM] = accessors.getMinutes(start_date);
+ date_array[DateField.DATEFIELD_SS] = accessors.getSeconds(start_date);
+ date_array[DateField.DATEFIELD_MS] = accessors.getMilliseconds(start_date);
var start_date_offset = date_array[datefield] % step;
- if (granularity == Dygraph.WEEKLY) {
+ if (granularity == Granularity.WEEKLY) {
// This will put the ticks on Sundays.
start_date_offset = accessors.getDay(start_date);
}
date_array[datefield] -= start_date_offset;
- for (var df = datefield + 1; df < Dygraph.NUM_DATEFIELDS; df++) {
+ for (var df = datefield + 1; df < DateField.NUM_DATEFIELDS; df++) {
// The minimum value is 1 for the day of month, and 0 for all other fields.
- date_array[df] = (df === Dygraph.DATEFIELD_D) ? 1 : 0;
+ date_array[df] = (df === DateField.DATEFIELD_D) ? 1 : 0;
}
// Generate the ticks.
var ticks = [];
var tick_date = accessors.makeDate.apply(null, date_array);
var tick_time = tick_date.getTime();
- if (granularity <= Dygraph.HOURLY) {
+ if (granularity <= Granularity.HOURLY) {
if (tick_time < start_time) {
tick_time += spacing;
tick_date = new Date(tick_time);
tick_time = tick_date.getTime();
}
while (tick_time <= end_time) {
- if (granularity >= Dygraph.DAILY ||
+ if (granularity >= Granularity.DAILY ||
accessors.getHours(tick_date) % step === 0) {
ticks.push({ v: tick_time,
label: formatter.call(dg, tick_date, granularity, opts, dg)
// These are set here so that this file can be included after dygraph.js
// or independently.
-if (Dygraph &&
- Dygraph.DEFAULT_ATTRS &&
- Dygraph.DEFAULT_ATTRS['axes'] &&
- Dygraph.DEFAULT_ATTRS['axes']['x'] &&
- Dygraph.DEFAULT_ATTRS['axes']['y'] &&
- Dygraph.DEFAULT_ATTRS['axes']['y2']) {
- Dygraph.DEFAULT_ATTRS['axes']['x']['ticker'] = Dygraph.dateTicker;
- Dygraph.DEFAULT_ATTRS['axes']['y']['ticker'] = Dygraph.numericTicks;
- Dygraph.DEFAULT_ATTRS['axes']['y2']['ticker'] = Dygraph.numericTicks;
-}
-
-})();
+// if (Dygraph &&
+// Dygraph.DEFAULT_ATTRS &&
+// Dygraph.DEFAULT_ATTRS['axes'] &&
+// Dygraph.DEFAULT_ATTRS['axes']['x'] &&
+// Dygraph.DEFAULT_ATTRS['axes']['y'] &&
+// Dygraph.DEFAULT_ATTRS['axes']['y2']) {
+// Dygraph.DEFAULT_ATTRS['axes']['x']['ticker'] = Dygraph.dateTicker;
+// Dygraph.DEFAULT_ATTRS['axes']['y']['ticker'] = Dygraph.numericTicks;
+// Dygraph.DEFAULT_ATTRS['axes']['y2']['ticker'] = Dygraph.numericTicks;
+// }
* search) and generic DOM-manipulation functions.
*/
-(function() {
-
/*global Dygraph:false, Node:false */
"use strict";
-Dygraph.LOG_SCALE = 10;
-Dygraph.LN_TEN = Math.log(Dygraph.LOG_SCALE);
+import * as DygraphTickers from './dygraph-tickers';
+
+export var LOG_SCALE = 10;
+export var LN_TEN = Math.log(LOG_SCALE);
/**
* @private
* @param {number} x
* @return {number}
*/
-Dygraph.log10 = function(x) {
- return Math.log(x) / Dygraph.LN_TEN;
+export var log10 = function(x) {
+ return Math.log(x) / LN_TEN;
};
/** A dotted line stroke pattern. */
-Dygraph.DOTTED_LINE = [2, 2];
+export var DOTTED_LINE = [2, 2];
/** A dashed line stroke pattern. */
-Dygraph.DASHED_LINE = [7, 3];
+export var DASHED_LINE = [7, 3];
/** A dot dash stroke pattern. */
-Dygraph.DOT_DASH_LINE = [7, 2, 2, 2];
+export var DOT_DASH_LINE = [7, 2, 2, 2];
+
+// Directions for panning and zooming. Use bit operations when combined
+// values are possible.
+export var HORIZONTAL = 1;
+export var VERTICAL = 2;
/**
* Return the 2d context for a dygraph canvas.
*
* This method is only exposed for the sake of replacing the function in
- * automated tests, e.g.
+ * automated tests.
*
- * var oldFunc = Dygraph.getContext();
- * Dygraph.getContext = function(canvas) {
- * var realContext = oldFunc(canvas);
- * return new Proxy(realContext);
- * };
* @param {!HTMLCanvasElement} canvas
* @return {!CanvasRenderingContext2D}
* @private
*/
-Dygraph.getContext = function(canvas) {
+export var getContext = function(canvas) {
return /** @type{!CanvasRenderingContext2D}*/(canvas.getContext("2d"));
};
* on the event. The function takes one parameter: the event object.
* @private
*/
-Dygraph.addEvent = function addEvent(elem, type, fn) {
+export var addEvent = function addEvent(elem, type, fn) {
elem.addEventListener(type, fn, false);
};
/**
- * Add an event handler. This event handler is kept until the graph is
- * destroyed with a call to graph.destroy().
- *
- * @param {!Node} elem The element to add the event to.
- * @param {string} type The type of the event, e.g. 'click' or 'mousemove'.
- * @param {function(Event):(boolean|undefined)} fn The function to call
- * on the event. The function takes one parameter: the event object.
- * @private
- */
-Dygraph.prototype.addAndTrackEvent = function(elem, type, fn) {
- Dygraph.addEvent(elem, type, fn);
- this.registeredEvents_.push({ elem : elem, type : type, fn : fn });
-};
-
-/**
* Remove an event handler.
* @param {!Node} elem The element to remove the event from.
* @param {string} type The type of the event, e.g. 'click' or 'mousemove'.
* @param {function(Event):(boolean|undefined)} fn The function to call
* on the event. The function takes one parameter: the event object.
- * @private
*/
-Dygraph.removeEvent = function(elem, type, fn) {
+export function removeEvent(elem, type, fn) {
elem.removeEventListener(type, fn, false);
};
-Dygraph.prototype.removeTrackedEvents_ = function() {
- if (this.registeredEvents_) {
- for (var idx = 0; idx < this.registeredEvents_.length; idx++) {
- var reg = this.registeredEvents_[idx];
- Dygraph.removeEvent(reg.elem, reg.type, reg.fn);
- }
- }
-
- this.registeredEvents_ = [];
-};
-
/**
* Cancels further processing of an event. This is useful to prevent default
* browser actions, e.g. highlighting text on a double-click.
* @param {!Event} e The event whose normal behavior should be canceled.
* @private
*/
-Dygraph.cancelEvent = function(e) {
+export function cancelEvent(e) {
e = e ? e : window.event;
if (e.stopPropagation) {
e.stopPropagation();
* @return { string } "rgb(r,g,b)" where r, g and b range from 0-255.
* @private
*/
-Dygraph.hsvToRGB = function (hue, saturation, value) {
+export function hsvToRGB(hue, saturation, value) {
var red;
var green;
var blue;
* @return {{x:number,y:number}}
* @private
*/
-Dygraph.findPos = function(obj) {
+export function findPos(obj) {
var p = obj.getBoundingClientRect(),
w = window,
d = document.documentElement;
* @return {number}
* @private
*/
-Dygraph.pageX = function(e) {
+export function pageX(e) {
return (!e.pageX || e.pageX < 0) ? 0 : e.pageX;
};
* @return {number}
* @private
*/
-Dygraph.pageY = function(e) {
+export function pageY(e) {
return (!e.pageY || e.pageY < 0) ? 0 : e.pageY;
};
* @param {!DygraphInteractionContext} context Interaction context object.
* @return {number} The amount by which the drag has moved to the right.
*/
-Dygraph.dragGetX_ = function(e, context) {
- return Dygraph.pageX(e) - context.px;
+export function dragGetX_(e, context) {
+ return pageX(e) - context.px;
};
/**
* @param {!DygraphInteractionContext} context Interaction context object.
* @return {number} The amount by which the drag has moved down.
*/
-Dygraph.dragGetY_ = function(e, context) {
- return Dygraph.pageY(e) - context.py;
+export function dragGetY_(e, context) {
+ return pageY(e) - context.py;
};
/**
* @return {boolean} Whether the number is zero or NaN.
* @private
*/
-Dygraph.isOK = function(x) {
+export function isOK(x) {
return !!x && !isNaN(x);
};
* @return {boolean} Whether the point has numeric x and y.
* @private
*/
-Dygraph.isValidPoint = function(p, opt_allowNaNY) {
+export function isValidPoint(p, opt_allowNaNY) {
if (!p) return false; // null or undefined object
if (p.yval === null) return false; // missing point
if (p.x === null || p.x === undefined) return false;
* @return {string} A string formatted like %g in printf. The max generated
* string length should be precision + 6 (e.g 1.123e+300).
*/
-Dygraph.floatFormat = function(x, opt_precision) {
+export function floatFormat(x, opt_precision) {
// Avoid invalid precision values; [1, 21] is the valid range.
var p = Math.min(Math.max(1, opt_precision || 2), 21);
* @return {string}
* @private
*/
-Dygraph.zeropad = function(x) {
+export function zeropad(x) {
if (x < 10) return "0" + x; else return "" + x;
};
* day, hour, minute, second and millisecond) according to local time,
* and factory method to call the Date constructor with an array of arguments.
*/
-Dygraph.DateAccessorsLocal = {
- getFullYear: function(d) {return d.getFullYear();},
- getMonth: function(d) {return d.getMonth();},
- getDate: function(d) {return d.getDate();},
- getHours: function(d) {return d.getHours();},
- getMinutes: function(d) {return d.getMinutes();},
- getSeconds: function(d) {return d.getSeconds();},
- getMilliseconds: function(d) {return d.getMilliseconds();},
- getDay: function(d) {return d.getDay();},
+export var DateAccessorsLocal = {
+ getFullYear: d => d.getFullYear(),
+ getMonth: d => d.getMonth(),
+ getDate: d => d.getDate(),
+ getHours: d => d.getHours(),
+ getMinutes: d => d.getMinutes(),
+ getSeconds: d => d.getSeconds(),
+ getMilliseconds: d => d.getMilliseconds(),
+ getDay: d => d.getDay(),
makeDate: function(y, m, d, hh, mm, ss, ms) {
return new Date(y, m, d, hh, mm, ss, ms);
}
* day of month, hour, minute, second and millisecond) according to UTC time,
* and factory method to call the Date constructor with an array of arguments.
*/
-Dygraph.DateAccessorsUTC = {
- getFullYear: function(d) {return d.getUTCFullYear();},
- getMonth: function(d) {return d.getUTCMonth();},
- getDate: function(d) {return d.getUTCDate();},
- getHours: function(d) {return d.getUTCHours();},
- getMinutes: function(d) {return d.getUTCMinutes();},
- getSeconds: function(d) {return d.getUTCSeconds();},
- getMilliseconds: function(d) {return d.getUTCMilliseconds();},
- getDay: function(d) {return d.getUTCDay();},
+export var DateAccessorsUTC = {
+ getFullYear: d => d.getUTCFullYear(),
+ getMonth: d => d.getUTCMonth(),
+ getDate: d => d.getUTCDate(),
+ getHours: d => d.getUTCHours(),
+ getMinutes: d => d.getUTCMinutes(),
+ getSeconds: d => d.getUTCSeconds(),
+ getMilliseconds: d => d.getUTCMilliseconds(),
+ getDay: d => d.getUTCDay(),
makeDate: function(y, m, d, hh, mm, ss, ms) {
return new Date(Date.UTC(y, m, d, hh, mm, ss, ms));
}
* @return {string} A time of the form "HH:MM" or "HH:MM:SS"
* @private
*/
-Dygraph.hmsString_ = function(hh, mm, ss) {
+export function hmsString_(hh, mm, ss) {
var zeropad = Dygraph.zeropad;
var ret = zeropad(hh) + ":" + zeropad(mm);
if (ss) {
* "YYYY/MM/DD", "YYYY/MM/DD HH:MM" or "YYYY/MM/DD HH:MM:SS"
* @private
*/
-Dygraph.dateString_ = function(time, utc) {
- var zeropad = Dygraph.zeropad;
- var accessors = utc ? Dygraph.DateAccessorsUTC : Dygraph.DateAccessorsLocal;
+export function dateString_(time, utc) {
+ var accessors = utc ? DateAccessorsUTC : DateAccessorsLocal;
var date = new Date(time);
var y = accessors.getFullYear(date);
var m = accessors.getMonth(date);
var frac = hh * 3600 + mm * 60 + ss;
var ret = year + "/" + month + "/" + day;
if (frac) {
- ret += " " + Dygraph.hmsString_(hh, mm, ss);
+ ret += " " + hmsString_(hh, mm, ss);
}
return ret;
};
* @return {number} The rounded number
* @private
*/
-Dygraph.round_ = function(num, places) {
+export function round_(num, places) {
var shift = Math.pow(10, places);
return Math.round(num * shift)/shift;
};
* @return {number} Index of the element, or -1 if it isn't found.
* @private
*/
-Dygraph.binarySearch = function(val, arry, abs, low, high) {
+export function binarySearch(val, arry, abs, low, high) {
if (low === null || low === undefined ||
high === null || high === undefined) {
low = 0;
return mid;
}
}
- return Dygraph.binarySearch(val, arry, abs, low, mid - 1);
+ return binarySearch(val, arry, abs, low, mid - 1);
} else if (element < val) {
if (abs < 0) {
// Accept if element < val, but also if prior element > val.
return mid;
}
}
- return Dygraph.binarySearch(val, arry, abs, mid + 1, high);
+ return binarySearch(val, arry, abs, mid + 1, high);
}
return -1; // can't actually happen, but makes closure compiler happy
};
* @return {number} Milliseconds since epoch.
* @private
*/
-Dygraph.dateParser = function(dateStr) {
+export function dateParser(dateStr) {
var dateStrSlashed;
var d;
// Issue: http://code.google.com/p/dygraphs/issues/detail?id=255
if (dateStr.search("-") == -1 ||
dateStr.search("T") != -1 || dateStr.search("Z") != -1) {
- d = Dygraph.dateStrToMillis(dateStr);
+ d = dateStrToMillis(dateStr);
if (d && !isNaN(d)) return d;
}
while (dateStrSlashed.search("-") != -1) {
dateStrSlashed = dateStrSlashed.replace("-", "/");
}
- d = Dygraph.dateStrToMillis(dateStrSlashed);
+ d = dateStrToMillis(dateStrSlashed);
} else if (dateStr.length == 8) { // e.g. '20090712'
// TODO(danvk): remove support for this format. It's confusing.
dateStrSlashed = dateStr.substr(0,4) + "/" + dateStr.substr(4,2) + "/" +
dateStr.substr(6,2);
- d = Dygraph.dateStrToMillis(dateStrSlashed);
+ d = dateStrToMillis(dateStrSlashed);
} else {
// Any format that Date.parse will accept, e.g. "2009/07/12" or
// "2009/07/12 12:34:56"
- d = Dygraph.dateStrToMillis(dateStr);
+ d = dateStrToMillis(dateStr);
}
if (!d || isNaN(d)) {
* @return {number} millis since epoch
* @private
*/
-Dygraph.dateStrToMillis = function(str) {
+export function dateStrToMillis(str) {
return new Date(str).getTime();
};
* @param {!Object} o
* @return {!Object}
*/
-Dygraph.update = function(self, o) {
+export function update(self, o) {
if (typeof(o) != 'undefined' && o !== null) {
for (var k in o) {
if (o.hasOwnProperty(k)) {
* @return {!Object}
* @private
*/
-Dygraph.updateDeep = function (self, o) {
+export function updateDeep(self, o) {
// Taken from http://stackoverflow.com/questions/384286/javascript-isdom-how-do-you-check-if-a-javascript-object-is-a-dom-object
function isNode(o) {
return (
if (o.hasOwnProperty(k)) {
if (o[k] === null) {
self[k] = null;
- } else if (Dygraph.isArrayLike(o[k])) {
+ } else if (isArrayLike(o[k])) {
self[k] = o[k].slice();
} else if (isNode(o[k])) {
// DOM objects are shallowly-copied.
if (typeof(self[k]) != 'object' || self[k] === null) {
self[k] = {};
}
- Dygraph.updateDeep(self[k], o[k]);
+ updateDeep(self[k], o[k]);
} else {
self[k] = o[k];
}
* @return {boolean}
* @private
*/
-Dygraph.isArrayLike = function(o) {
+export function isArrayLike(o) {
var typ = typeof(o);
if (
(typ != 'object' && !(typ == 'function' &&
* @return {boolean}
* @private
*/
-Dygraph.isDateLike = function (o) {
+export function isDateLike(o) {
if (typeof(o) != "object" || o === null ||
typeof(o.getTime) != 'function') {
return false;
* @return {!Array}
* @private
*/
-Dygraph.clone = function(o) {
+export function clone(o) {
// TODO(danvk): figure out how MochiKit's version works
var r = [];
for (var i = 0; i < o.length; i++) {
- if (Dygraph.isArrayLike(o[i])) {
+ if (isArrayLike(o[i])) {
r.push(Dygraph.clone(o[i]));
} else {
r.push(o[i]);
* @return {!HTMLCanvasElement}
* @private
*/
-Dygraph.createCanvas = function() {
+export function createCanvas() {
return document.createElement('canvas');
};
* @return {number} The ratio of the device pixel ratio and the backing store
* ratio for the specified context.
*/
-Dygraph.getContextPixelRatio = function(context) {
+export function getContextPixelRatio(context) {
try {
var devicePixelRatio = window.devicePixelRatio;
var backingStoreRatio = context.webkitBackingStorePixelRatio ||
* @return {boolean}
* @private
*/
-Dygraph.isAndroid = function() {
+export function isAndroid() {
return (/Android/).test(navigator.userAgent);
};
* @param {function(!Array,?):boolean=} predicate
* @constructor
*/
-Dygraph.Iterator = function(array, start, length, predicate) {
+export function Iterator(array, start, length, predicate) {
start = start || 0;
length = length || array.length;
this.hasNext = true; // Use to identify if there's another element.
/**
* @return {Object}
*/
-Dygraph.Iterator.prototype.next = function() {
+Iterator.prototype.next = function() {
if (!this.hasNext) {
return null;
}
* returned. If omitted, all elements are accepted.
* @private
*/
-Dygraph.createIterator = function(array, start, length, opt_predicate) {
- return new Dygraph.Iterator(array, start, length, opt_predicate);
+export function createIterator(array, start, length, opt_predicate) {
+ return new Iterator(array, start, length, opt_predicate);
};
// Shim layer with setTimeout fallback.
// From: http://paulirish.com/2011/requestanimationframe-for-smart-animating/
// Should be called with the window context:
// Dygraph.requestAnimFrame.call(window, function() {})
-Dygraph.requestAnimFrame = (function() {
+export var requestAnimFrame = (function() {
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
* @param {function()} cleanupFn A function to call after all repeatFn calls.
* @private
*/
-Dygraph.repeatAndCleanup = function(repeatFn, maxFrames, framePeriodInMillis,
+export function repeatAndCleanup(repeatFn, maxFrames, framePeriodInMillis,
cleanupFn) {
var frameNumber = 0;
var previousFrameNumber;
* @return {boolean} true if the graph needs new points else false.
* @private
*/
-Dygraph.isPixelChangingOptionList = function(labels, attrs) {
+export function isPixelChangingOptionList(labels, attrs) {
// Assume that we do not require new points.
// This will change to true if we actually do need new points.
return false;
};
-Dygraph.Circles = {
+export var Circles = {
DEFAULT : function(g, name, ctx, canvasx, canvasy, color, radius) {
ctx.beginPath();
ctx.fillStyle = color;
*
* Usage:
* element.addEventListener('mousedown', function() {
- * var tarper = new Dygraph.IFrameTarp();
+ * var tarper = new utils.IFrameTarp();
* tarper.cover();
* var mouseUpHandler = function() {
* ...
*
* @constructor
*/
-Dygraph.IFrameTarp = function() {
+export function IFrameTarp() {
/** @type {Array.<!HTMLDivElement>} */
this.tarps = [];
};
* Find all the iframes in the document and cover them with high z-index
* transparent divs.
*/
-Dygraph.IFrameTarp.prototype.cover = function() {
+IFrameTarp.prototype.cover = function() {
var iframes = document.getElementsByTagName("iframe");
for (var i = 0; i < iframes.length; i++) {
var iframe = iframes[i];
/**
* Remove all the iframe covers. You should call this in a mouseup handler.
*/
-Dygraph.IFrameTarp.prototype.uncover = function() {
+IFrameTarp.prototype.uncover = function() {
for (var i = 0; i < this.tarps.length; i++) {
this.tarps[i].parentNode.removeChild(this.tarps[i]);
}
* @param {string} data
* @return {?string} the delimiter that was detected (or null on failure).
*/
-Dygraph.detectLineDelimiter = function(data) {
+export function detectLineDelimiter(data) {
for (var i = 0; i < data.length; i++) {
var code = data.charAt(i);
if (code === '\r') {
* @return {boolean} Whether containee is inside (or equal to) container.
* @private
*/
-Dygraph.isNodeContainedBy = function(containee, container) {
+export function isNodeContainedBy(containee, container) {
if (container === null || containee === null) {
return false;
}
// This masks some numeric issues in older versions of Firefox,
// where 1.0/Math.pow(10,2) != Math.pow(10,-2).
/** @type {function(number,number):number} */
-Dygraph.pow = function(base, exp) {
+export function pow(base, exp) {
if (exp < 0) {
return 1.0 / Math.pow(base, -exp);
}
* @return {{r:number,g:number,b:number,a:number?}} Parsed RGB tuple.
* @private
*/
-Dygraph.toRGB_ = function(colorStr) {
+export function toRGB_(colorStr) {
// Strategy: First try to parse colorStr directly. This is fast & avoids DOM
// manipulation. If that fails (e.g. for named colors like 'red'), then
// create a hidden DOM element and parse its computed color.
* optimization if you have one.
* @return {boolean} Whether the browser supports canvas.
*/
-Dygraph.isCanvasSupported = function(opt_canvasElement) {
+export function isCanvasSupported(opt_canvasElement) {
try {
var canvas = opt_canvasElement || document.createElement("canvas");
canvas.getContext("2d");
* @param {number=} opt_line_no The line number from which the string comes.
* @param {string=} opt_line The text of the line from which the string comes.
*/
-Dygraph.parseFloat_ = function(x, opt_line_no, opt_line) {
+export function parseFloat_(x, opt_line_no, opt_line) {
var val = parseFloat(x);
if (!isNaN(val)) return val;
return null;
};
-})();
+
+// Label constants for the labelsKMB and labelsKMG2 options.
+// (i.e. '100000' -> '100K')
+var KMB_LABELS = [ 'K', 'M', 'B', 'T', 'Q' ];
+var KMG2_BIG_LABELS = [ 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y' ];
+var KMG2_SMALL_LABELS = [ 'm', 'u', 'n', 'p', 'f', 'a', 'z', 'y' ];
+
+/**
+ * @private
+ * Return a string version of a number. This respects the digitsAfterDecimal
+ * and maxNumberWidth options.
+ * @param {number} x The number to be formatted
+ * @param {Dygraph} opts An options view
+ */
+export function numberValueFormatter(x, opts) {
+ var sigFigs = opts('sigFigs');
+
+ if (sigFigs !== null) {
+ // User has opted for a fixed number of significant figures.
+ return floatFormat(x, sigFigs);
+ }
+
+ var digits = opts('digitsAfterDecimal');
+ var maxNumberWidth = opts('maxNumberWidth');
+
+ var kmb = opts('labelsKMB');
+ var kmg2 = opts('labelsKMG2');
+
+ var label;
+
+ // switch to scientific notation if we underflow or overflow fixed display.
+ if (x !== 0.0 &&
+ (Math.abs(x) >= Math.pow(10, maxNumberWidth) ||
+ Math.abs(x) < Math.pow(10, -digits))) {
+ label = x.toExponential(digits);
+ } else {
+ label = '' + round_(x, digits);
+ }
+
+ if (kmb || kmg2) {
+ var k;
+ var k_labels = [];
+ var m_labels = [];
+ if (kmb) {
+ k = 1000;
+ k_labels = KMB_LABELS;
+ }
+ if (kmg2) {
+ if (kmb) console.warn("Setting both labelsKMB and labelsKMG2. Pick one!");
+ k = 1024;
+ k_labels = KMG2_BIG_LABELS;
+ m_labels = KMG2_SMALL_LABELS;
+ }
+
+ var absx = Math.abs(x);
+ var n = pow(k, k_labels.length);
+ for (var j = k_labels.length - 1; j >= 0; j--, n /= k) {
+ if (absx >= n) {
+ label = round_(x / n, digits) + k_labels[j];
+ break;
+ }
+ }
+ if (kmg2) {
+ // TODO(danvk): clean up this logic. Why so different than kmb?
+ var x_parts = String(x.toExponential()).split('e-');
+ if (x_parts.length === 2 && x_parts[1] >= 3 && x_parts[1] <= 24) {
+ if (x_parts[1] % 3 > 0) {
+ label = round_(x_parts[0] /
+ pow(10, (x_parts[1] % 3)),
+ digits);
+ } else {
+ label = Number(x_parts[0]).toFixed(2);
+ }
+ label += m_labels[Math.floor(x_parts[1] / 3) - 1];
+ }
+ }
+ }
+
+ return label;
+};
+
+/**
+ * variant for use as an axisLabelFormatter.
+ * @private
+ */
+export function numberAxisLabelFormatter(x, granularity, opts) {
+ return numberValueFormatter.call(this, x, opts);
+};
+
+/**
+ * @type {!Array.<string>}
+ * @private
+ * @constant
+ */
+var SHORT_MONTH_NAMES_ = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
+
+
+/**
+ * Convert a JS date to a string appropriate to display on an axis that
+ * is displaying values at the stated granularity. This respects the
+ * labelsUTC option.
+ * @param {Date} date The date to format
+ * @param {number} granularity One of the Dygraph granularity constants
+ * @param {Dygraph} opts An options view
+ * @return {string} The date formatted as local time
+ * @private
+ */
+export function dateAxisLabelFormatter(date, granularity, opts) {
+ var utc = opts('labelsUTC');
+ var accessors = utc ? DateAccessorsUTC : DateAccessorsLocal;
+
+ var year = accessors.getFullYear(date),
+ month = accessors.getMonth(date),
+ day = accessors.getDate(date),
+ hours = accessors.getHours(date),
+ mins = accessors.getMinutes(date),
+ secs = accessors.getSeconds(date),
+ millis = accessors.getSeconds(date);
+
+ if (granularity >= DygraphTickers.Granularity.DECADAL) {
+ return '' + year;
+ } else if (granularity >= DygraphTickers.Granularity.MONTHLY) {
+ return SHORT_MONTH_NAMES_[month] + ' ' + year;
+ } else {
+ var frac = hours * 3600 + mins * 60 + secs + 1e-3 * millis;
+ if (frac === 0 || granularity >= DygraphTickers.Granularity.DAILY) {
+ // e.g. '21 Jan' (%d%b)
+ return zeropad(day) + ' ' + SHORT_MONTH_NAMES_[month];
+ } else {
+ return hmsString_(hours, mins, secs);
+ }
+ }
+};
+// alias in case anyone is referencing the old method.
+// Dygraph.dateAxisFormatter = Dygraph.dateAxisLabelFormatter;
+
+/**
+ * Return a string version of a JS date for a value label. This respects the
+ * labelsUTC option.
+ * @param {Date} date The date to be formatted
+ * @param {Dygraph} opts An options view
+ * @private
+ */
+export function dateValueFormatter(d, opts) {
+ return dateString_(d, opts('labelsUTC'));
+};
*/
// For "production" code, this gets set to false by uglifyjs.
-if (typeof(DEBUG) === 'undefined') DEBUG=true;
+// if (typeof(DEBUG) === 'undefined') DEBUG=true;
+var DEBUG = true;
+
+import DygraphLayout from './dygraph-layout';
+import DygraphCanvasRenderer from './dygraph-canvas';
+import DygraphOptions from './dygraph-options';
+import DygraphInteraction from './dygraph-interaction-model';
+import * as DygraphTickers from './dygraph-tickers';
+import * as utils from './dygraph-utils';
+import DEFAULT_ATTRS from './dygraph-default-attrs';
+import DygraphDataHandler from './datahandler/datahandler';
+import DefaultHandler from './datahandler/default';
+
+import AnnotationsPlugin from './plugins/annotations';
+import AxesPlugin from './plugins/axes';
+import ChartLabelsPlugin from './plugins/chart-labels';
+import GridPlugin from './plugins/grid';
+import LegendPlugin from './plugins/legend';
+import RangeSelectorPlugin from './plugins/range-selector';
-var Dygraph = (function() {
/*global DygraphLayout:false, DygraphCanvasRenderer:false, DygraphOptions:false, G_vmlCanvasManager:false,ActiveXObject:false */
"use strict";
Dygraph.ANIMATION_STEPS = 12;
Dygraph.ANIMATION_DURATION = 200;
-// Label constants for the labelsKMB and labelsKMG2 options.
-// (i.e. '100000' -> '100K')
-Dygraph.KMB_LABELS = [ 'K', 'M', 'B', 'T', 'Q' ];
-Dygraph.KMG2_BIG_LABELS = [ 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y' ];
-Dygraph.KMG2_SMALL_LABELS = [ 'm', 'u', 'n', 'p', 'f', 'a', 'z', 'y' ];
-
-// These are defined before DEFAULT_ATTRS so that it can refer to them.
-/**
- * @private
- * Return a string version of a number. This respects the digitsAfterDecimal
- * and maxNumberWidth options.
- * @param {number} x The number to be formatted
- * @param {Dygraph} opts An options view
- */
-Dygraph.numberValueFormatter = function(x, opts) {
- var sigFigs = opts('sigFigs');
-
- if (sigFigs !== null) {
- // User has opted for a fixed number of significant figures.
- return Dygraph.floatFormat(x, sigFigs);
- }
-
- var digits = opts('digitsAfterDecimal');
- var maxNumberWidth = opts('maxNumberWidth');
-
- var kmb = opts('labelsKMB');
- var kmg2 = opts('labelsKMG2');
-
- var label;
-
- // switch to scientific notation if we underflow or overflow fixed display.
- if (x !== 0.0 &&
- (Math.abs(x) >= Math.pow(10, maxNumberWidth) ||
- Math.abs(x) < Math.pow(10, -digits))) {
- label = x.toExponential(digits);
- } else {
- label = '' + Dygraph.round_(x, digits);
- }
-
- if (kmb || kmg2) {
- var k;
- var k_labels = [];
- var m_labels = [];
- if (kmb) {
- k = 1000;
- k_labels = Dygraph.KMB_LABELS;
- }
- if (kmg2) {
- if (kmb) console.warn("Setting both labelsKMB and labelsKMG2. Pick one!");
- k = 1024;
- k_labels = Dygraph.KMG2_BIG_LABELS;
- m_labels = Dygraph.KMG2_SMALL_LABELS;
- }
-
- var absx = Math.abs(x);
- var n = Dygraph.pow(k, k_labels.length);
- for (var j = k_labels.length - 1; j >= 0; j--, n /= k) {
- if (absx >= n) {
- label = Dygraph.round_(x / n, digits) + k_labels[j];
- break;
- }
- }
- if (kmg2) {
- // TODO(danvk): clean up this logic. Why so different than kmb?
- var x_parts = String(x.toExponential()).split('e-');
- if (x_parts.length === 2 && x_parts[1] >= 3 && x_parts[1] <= 24) {
- if (x_parts[1] % 3 > 0) {
- label = Dygraph.round_(x_parts[0] /
- Dygraph.pow(10, (x_parts[1] % 3)),
- digits);
- } else {
- label = Number(x_parts[0]).toFixed(2);
- }
- label += m_labels[Math.floor(x_parts[1] / 3) - 1];
- }
- }
- }
-
- return label;
-};
-
-/**
- * variant for use as an axisLabelFormatter.
- * @private
- */
-Dygraph.numberAxisLabelFormatter = function(x, granularity, opts) {
- return Dygraph.numberValueFormatter.call(this, x, opts);
-};
-
-/**
- * @type {!Array.<string>}
- * @private
- * @constant
- */
-Dygraph.SHORT_MONTH_NAMES_ = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
-
-
-/**
- * Convert a JS date to a string appropriate to display on an axis that
- * is displaying values at the stated granularity. This respects the
- * labelsUTC option.
- * @param {Date} date The date to format
- * @param {number} granularity One of the Dygraph granularity constants
- * @param {Dygraph} opts An options view
- * @return {string} The date formatted as local time
- * @private
- */
-Dygraph.dateAxisLabelFormatter = function(date, granularity, opts) {
- var utc = opts('labelsUTC');
- var accessors = utc ? Dygraph.DateAccessorsUTC : Dygraph.DateAccessorsLocal;
-
- var year = accessors.getFullYear(date),
- month = accessors.getMonth(date),
- day = accessors.getDate(date),
- hours = accessors.getHours(date),
- mins = accessors.getMinutes(date),
- secs = accessors.getSeconds(date),
- millis = accessors.getSeconds(date);
-
- if (granularity >= Dygraph.DECADAL) {
- return '' + year;
- } else if (granularity >= Dygraph.MONTHLY) {
- return Dygraph.SHORT_MONTH_NAMES_[month] + ' ' + year;
- } else {
- var frac = hours * 3600 + mins * 60 + secs + 1e-3 * millis;
- if (frac === 0 || granularity >= Dygraph.DAILY) {
- // e.g. '21 Jan' (%d%b)
- return Dygraph.zeropad(day) + ' ' + Dygraph.SHORT_MONTH_NAMES_[month];
- } else {
- return Dygraph.hmsString_(hours, mins, secs);
- }
- }
-};
-// alias in case anyone is referencing the old method.
-Dygraph.dateAxisFormatter = Dygraph.dateAxisLabelFormatter;
-
-/**
- * Return a string version of a JS date for a value label. This respects the
- * labelsUTC option.
- * @param {Date} date The date to be formatted
- * @param {Dygraph} opts An options view
- * @private
- */
-Dygraph.dateValueFormatter = function(d, opts) {
- return Dygraph.dateString_(d, opts('labelsUTC'));
-};
-
/**
* Standard plotters. These may be used by clients.
* Available plotters are:
Dygraph.Plotters = DygraphCanvasRenderer._Plotters;
-// Default attribute values.
-Dygraph.DEFAULT_ATTRS = {
- highlightCircleSize: 3,
- highlightSeriesOpts: null,
- highlightSeriesBackgroundAlpha: 0.5,
-
- labelsDivWidth: 250,
- labelsDivStyles: {
- // TODO(danvk): move defaults from createStatusMessage_ here.
- },
- labelsSeparateLines: false,
- labelsShowZeroValues: true,
- labelsKMB: false,
- labelsKMG2: false,
- showLabelsOnHighlight: true,
-
- digitsAfterDecimal: 2,
- maxNumberWidth: 6,
- sigFigs: null,
-
- strokeWidth: 1.0,
- strokeBorderWidth: 0,
- strokeBorderColor: "white",
-
- axisTickSize: 3,
- axisLabelFontSize: 14,
- rightGap: 5,
-
- showRoller: false,
- xValueParser: Dygraph.dateParser,
-
- delimiter: ',',
-
- sigma: 2.0,
- errorBars: false,
- fractions: false,
- wilsonInterval: true, // only relevant if fractions is true
- customBars: false,
- fillGraph: false,
- fillAlpha: 0.15,
- connectSeparatedPoints: false,
-
- stackedGraph: false,
- stackedGraphNaNFill: 'all',
- hideOverlayOnMouseOut: true,
-
- legend: 'onmouseover',
- stepPlot: false,
- avoidMinZero: false,
- xRangePad: 0,
- yRangePad: null,
- drawAxesAtZero: false,
-
- // Sizes of the various chart labels.
- titleHeight: 28,
- xLabelHeight: 18,
- yLabelWidth: 18,
-
- axisLineColor: "black",
- axisLineWidth: 0.3,
- gridLineWidth: 0.3,
- axisLabelColor: "black",
- axisLabelWidth: 50,
- gridLineColor: "rgb(128,128,128)",
-
- interactionModel: null, // will be set to Dygraph.Interaction.defaultModel
- animatedZooms: false, // (for now)
-
- // Range selector options
- showRangeSelector: false,
- rangeSelectorHeight: 40,
- rangeSelectorPlotStrokeColor: "#808FAB",
- rangeSelectorPlotFillGradientColor: "white",
- rangeSelectorPlotFillColor: "#A7B1C4",
- rangeSelectorBackgroundStrokeColor: "gray",
- rangeSelectorBackgroundLineWidth: 1,
- rangeSelectorPlotLineWidth:1.5,
- rangeSelectorForegroundStrokeColor: "black",
- rangeSelectorForegroundLineWidth: 1,
- rangeSelectorAlpha: 0.6,
- showInRangeSelector: null,
-
- // The ordering here ensures that central lines always appear above any
- // fill bars/error bars.
- plotter: [
- Dygraph.Plotters.fillPlotter,
- Dygraph.Plotters.errorPlotter,
- Dygraph.Plotters.linePlotter
- ],
-
- plugins: [ ],
-
- // per-axis options
- axes: {
- x: {
- pixelsPerLabel: 70,
- axisLabelWidth: 60,
- axisLabelFormatter: Dygraph.dateAxisLabelFormatter,
- valueFormatter: Dygraph.dateValueFormatter,
- drawGrid: true,
- drawAxis: true,
- independentTicks: true,
- ticker: null // will be set in dygraph-tickers.js
- },
- y: {
- axisLabelWidth: 50,
- pixelsPerLabel: 30,
- valueFormatter: Dygraph.numberValueFormatter,
- axisLabelFormatter: Dygraph.numberAxisLabelFormatter,
- drawGrid: true,
- drawAxis: true,
- independentTicks: true,
- ticker: null // will be set in dygraph-tickers.js
- },
- y2: {
- axisLabelWidth: 50,
- pixelsPerLabel: 30,
- valueFormatter: Dygraph.numberValueFormatter,
- axisLabelFormatter: Dygraph.numberAxisLabelFormatter,
- drawAxis: true, // only applies when there are two axes of data.
- drawGrid: false,
- independentTicks: false,
- ticker: null // will be set in dygraph-tickers.js
- }
- }
-};
-
-// Directions for panning and zooming. Use bit operations when combined
-// values are possible.
-Dygraph.HORIZONTAL = 1;
-Dygraph.VERTICAL = 2;
-
-// Installed plugins, in order of precedence (most-general to most-specific).
-// Plugins are installed after they are defined, in plugins/install.js.
-Dygraph.PLUGINS = [
-];
-
// Used for initializing annotation CSS rules only once.
Dygraph.addedAnnotationCSS = false;
// user_attrs_ and then computed attrs_. This way Dygraphs can set intelligent
// defaults without overriding behavior that the user specifically asks for.
this.user_attrs_ = {};
- Dygraph.update(this.user_attrs_, attrs);
+ utils.update(this.user_attrs_, attrs);
// This sequence ensures that Dygraph.DEFAULT_ATTRS is never modified.
this.attrs_ = {};
- Dygraph.updateDeep(this.attrs_, Dygraph.DEFAULT_ATTRS);
+ utils.updateDeep(this.attrs_, DEFAULT_ATTRS);
this.boundaryIds_ = [];
this.setIndexByName_ = {};
e.propagationStopped = true;
}
};
- Dygraph.update(e, extra_props);
+ utils.update(e, extra_props);
var callback_plugin_pairs = this.eventListeners_[name];
if (callback_plugin_pairs) {
* @return { ... } The value of the option.
*/
Dygraph.prototype.attr_ = function(name, seriesName) {
- if (DEBUG) {
- if (typeof(Dygraph.OPTIONS_REFERENCE) === 'undefined') {
- console.error('Must include options reference JS for testing');
- } else if (!Dygraph.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.
- Dygraph.OPTIONS_REFERENCE[name] = true;
- }
- }
+ // if (DEBUG) {
+ // if (typeof(Dygraph.OPTIONS_REFERENCE) === 'undefined') {
+ // console.error('Must include options reference JS for testing');
+ // } else if (!Dygraph.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.
+ // Dygraph.OPTIONS_REFERENCE[name] = true;
+ // }
+ // }
return seriesName ? this.attributes_.getForSeries(name, seriesName) : this.attributes_.get(name);
};
enclosing.appendChild(this.graphDiv);
// Create the canvas for interactive parts of the chart.
- this.canvas_ = Dygraph.createCanvas();
+ this.canvas_ = utils.createCanvas();
this.canvas_.style.position = "absolute";
// ... and for static parts of the chart.
this.hidden_ = this.createPlotKitCanvas_(this.canvas_);
- this.canvas_ctx_ = Dygraph.getContext(this.canvas_);
- this.hidden_ctx_ = Dygraph.getContext(this.hidden_);
+ this.canvas_ctx_ = utils.getContext(this.canvas_);
+ this.hidden_ctx_ = utils.getContext(this.hidden_);
this.resizeElements_();
// 2. e.relatedTarget is outside the chart
var target = e.target || e.fromElement;
var relatedTarget = e.relatedTarget || e.toElement;
- if (Dygraph.isNodeContainedBy(target, dygraph.graphDiv) &&
- !Dygraph.isNodeContainedBy(relatedTarget, dygraph.graphDiv)) {
+ if (utils.isNodeContainedBy(target, dygraph.graphDiv) &&
+ !utils.isNodeContainedBy(relatedTarget, dygraph.graphDiv)) {
dygraph.mouseOut_(e);
}
};
this.graphDiv.style.width = this.width_ + "px";
this.graphDiv.style.height = this.height_ + "px";
- var canvasScale = Dygraph.getContextPixelRatio(this.canvas_ctx_);
+ var canvasScale = 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 = Dygraph.getContextPixelRatio(this.hidden_ctx_);
+ var hiddenScale = 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
* @private
*/
Dygraph.prototype.createPlotKitCanvas_ = function(canvas) {
- var h = Dygraph.createCanvas();
+ var h = utils.createCanvas();
h.style.position = "absolute";
// TODO(danvk): h should be offset from canvas. canvas needs to include
// some extra area to make it easier to zoom in on the far left and far
// We cover iframes during mouse interactions. See comments in
// dygraph-utils.js for more info on why this is a good idea.
- tarp: new Dygraph.IFrameTarp(),
+ tarp: new utils.IFrameTarp(),
// contextB is the same thing as this context object but renamed.
initializeMouseDown: function(event, g, contextB) {
event.cancelBubble = true;
}
- var canvasPos = Dygraph.findPos(g.canvas_);
+ var canvasPos = utils.findPos(g.canvas_);
contextB.px = canvasPos.x;
contextB.py = canvasPos.y;
- contextB.dragStartX = Dygraph.dragGetX_(event, contextB);
- contextB.dragStartY = Dygraph.dragGetY_(event, contextB);
+ contextB.dragStartX = utils.dragGetX_(event, contextB);
+ contextB.dragStartY = utils.dragGetY_(event, contextB);
contextB.cancelNextDblclick = false;
contextB.tarp.cover();
},
* dots.
*
* @param {number} direction the direction of the zoom rectangle. Acceptable
- * values are Dygraph.HORIZONTAL and Dygraph.VERTICAL.
+ * values are utils.HORIZONTAL and utils.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.
var ctx = this.canvas_ctx_;
// Clean up from the previous rect if necessary
- if (prevDirection == Dygraph.HORIZONTAL) {
+ if (prevDirection == utils.HORIZONTAL) {
ctx.clearRect(Math.min(startX, prevEndX), this.layout_.getPlotArea().y,
Math.abs(startX - prevEndX), this.layout_.getPlotArea().h);
- } else if (prevDirection == Dygraph.VERTICAL) {
+ } else if (prevDirection == utils.VERTICAL) {
ctx.clearRect(this.layout_.getPlotArea().x, Math.min(startY, prevEndY),
this.layout_.getPlotArea().w, Math.abs(startY - prevEndY));
}
// Draw a light-grey rectangle to show the new viewing area
- if (direction == Dygraph.HORIZONTAL) {
+ if (direction == utils.HORIZONTAL) {
if (endX && startX) {
ctx.fillStyle = "rgba(128,128,128,0.33)";
ctx.fillRect(Math.min(startX, endX), this.layout_.getPlotArea().y,
Math.abs(endX - startX), this.layout_.getPlotArea().h);
}
- } else if (direction == Dygraph.VERTICAL) {
+ } else if (direction == utils.VERTICAL) {
if (endY && startY) {
ctx.fillStyle = "rgba(128,128,128,0.33)";
ctx.fillRect(this.layout_.getPlotArea().x, Math.min(startY, endY),
}
var that = this;
- Dygraph.repeatAndCleanup(function(step) {
+ utils.repeatAndCleanup(function(step) {
if (valueRanges.length) {
for (var i = 0; i < that.axes_.length; i++) {
var w = valueRanges[step][i];
if (event.offsetX && event.offsetY) {
return [ event.offsetX, event.offsetY ];
} else {
- var eventElementPos = Dygraph.findPos(this.mouseEventElement_);
- var canvasx = Dygraph.pageX(event) - eventElementPos.x;
- var canvasy = Dygraph.pageY(event) - eventElementPos.y;
+ var eventElementPos = utils.findPos(this.mouseEventElement_);
+ var canvasx = utils.pageX(event) - eventElementPos.x;
+ var canvasy = utils.pageY(event) - eventElementPos.y;
return [canvasx, canvasy];
}
};
var len = points.length;
for (var j = 0; j < len; j++) {
var point = points[j];
- if (!Dygraph.isValidPoint(point, true)) continue;
+ if (!utils.isValidPoint(point, true)) continue;
var dist = Math.abs(point.canvasx - domX);
if (dist < minDistX) {
minDistX = dist;
that.clearSelection();
}
};
- Dygraph.repeatAndCleanup(
+ utils.repeatAndCleanup(
function(n) {
// ignore simultaneous animations
if (that.animateId != thisId) return;
ctx.save();
for (i = 0; i < this.selPoints_.length; i++) {
var pt = this.selPoints_[i];
- if (!Dygraph.isOK(pt.canvasy)) continue;
+ if (!utils.isOK(pt.canvasy)) continue;
var circleSize = this.getNumericOption('highlightCircleSize', pt.name);
var callback = this.getFunctionOption("drawHighlightPointCallback", pt.name);
var color = this.plotter_.colors[pt.name];
if (!callback) {
- callback = Dygraph.Circles.DEFAULT;
+ callback = utils.Circles.DEFAULT;
}
ctx.lineWidth = this.getNumericOption('strokeWidth', pt.name);
ctx.strokeStyle = color;
handlerClass = this.attr_('dataHandler');
} else if (this.fractions_) {
if (this.getBooleanOption('errorBars')) {
- handlerClass = Dygraph.DataHandlers.FractionsBarsHandler;
+ handlerClass = DygraphDataHandlers.FractionsBarsHandler;
} else {
- handlerClass = Dygraph.DataHandlers.DefaultFractionHandler;
+ handlerClass = DygraphDataHandlers.DefaultFractionHandler;
}
} else if (this.getBooleanOption('customBars')) {
- handlerClass = Dygraph.DataHandlers.CustomBarsHandler;
+ handlerClass = DygraphDataHandlers.CustomBarsHandler;
} else if (this.getBooleanOption('errorBars')) {
- handlerClass = Dygraph.DataHandlers.ErrorBarsHandler;
+ handlerClass = DygraphDataHandlers.ErrorBarsHandler;
} else {
- handlerClass = Dygraph.DataHandlers.DefaultHandler;
+ handlerClass = DefaultHandler;
}
return handlerClass;
};
for (axis = 0; axis < this.attributes_.numAxes(); axis++) {
// Add a new axis, making a copy of its per-axis options.
opts = { g : this };
- Dygraph.update(opts, this.attributes_.axisOptions(axis));
+ utils.update(opts, this.attributes_.axisOptions(axis));
this.axes_[axis] = opts;
}
Dygraph.prototype.setXAxisOptions_ = function(isDate) {
if (isDate) {
- this.attrs_.xValueParser = Dygraph.dateParser;
- this.attrs_.axes.x.valueFormatter = Dygraph.dateValueFormatter;
- this.attrs_.axes.x.ticker = Dygraph.dateTicker;
- this.attrs_.axes.x.axisLabelFormatter = Dygraph.dateAxisLabelFormatter;
+ this.attrs_.xValueParser = utils.dateParser;
+ this.attrs_.axes.x.valueFormatter = utils.dateValueFormatter;
+ this.attrs_.axes.x.ticker = DygraphTickers.dateTicker;
+ this.attrs_.axes.x.axisLabelFormatter = utils.dateAxisLabelFormatter;
} else {
/** @private (shut up, jsdoc!) */
this.attrs_.xValueParser = function(x) { return parseFloat(x); };
// TODO(danvk): use Dygraph.numberValueFormatter here?
/** @private (shut up, jsdoc!) */
this.attrs_.axes.x.valueFormatter = function(x) { return x; };
- this.attrs_.axes.x.ticker = Dygraph.numericTicks;
+ this.attrs_.axes.x.ticker = DygraphTickers.numericTicks;
this.attrs_.axes.x.axisLabelFormatter = this.attrs_.axes.x.valueFormatter;
}
};
*/
Dygraph.prototype.parseCSV_ = function(data) {
var ret = [];
- var line_delimiter = Dygraph.detectLineDelimiter(data);
+ var line_delimiter = utils.detectLineDelimiter(data);
var lines = data.split(line_delimiter || "\n");
var vals, j;
(1 + i) + " ('" + line + "') which is not of this form.");
fields[j] = [0, 0];
} else {
- fields[j] = [Dygraph.parseFloat_(vals[0], i, line),
- Dygraph.parseFloat_(vals[1], i, line)];
+ fields[j] = [utils.parseFloat_(vals[0], i, line),
+ utils.parseFloat_(vals[1], i, line)];
}
}
} else if (this.getBooleanOption("errorBars")) {
(inFields.length - 1) + "): '" + line + "'");
}
for (j = 1; j < inFields.length; j += 2) {
- fields[(j + 1) / 2] = [Dygraph.parseFloat_(inFields[j], i, line),
- Dygraph.parseFloat_(inFields[j + 1], i, line)];
+ fields[(j + 1) / 2] = [utils.parseFloat_(inFields[j], i, line),
+ utils.parseFloat_(inFields[j + 1], i, line)];
}
} else if (this.getBooleanOption("customBars")) {
// Bars are a low;center;high tuple
} else {
vals = val.split(";");
if (vals.length == 3) {
- fields[j] = [ Dygraph.parseFloat_(vals[0], i, line),
- Dygraph.parseFloat_(vals[1], i, line),
- Dygraph.parseFloat_(vals[2], i, line) ];
+ fields[j] = [ utils.parseFloat_(vals[0], i, line),
+ utils.parseFloat_(vals[1], i, line),
+ utils.parseFloat_(vals[2], i, line) ];
} else {
console.warn('When using customBars, values must be either blank ' +
'or "low;center;high" tuples (got "' + val +
} else {
// Values are just numbers
for (j = 1; j < inFields.length; j++) {
- fields[j] = Dygraph.parseFloat_(inFields[j], i, line);
+ fields[j] = utils.parseFloat_(inFields[j], i, line);
}
}
if (ret.length > 0 && fields[0] < ret[ret.length - 1][0]) {
}
}
- if (Dygraph.isDateLike(data[0][0])) {
+ if (utils.isDateLike(data[0][0])) {
// Some intelligent defaults for a date x-axis.
- this.attrs_.axes.x.valueFormatter = Dygraph.dateValueFormatter;
- this.attrs_.axes.x.ticker = Dygraph.dateTicker;
- this.attrs_.axes.x.axisLabelFormatter = Dygraph.dateAxisLabelFormatter;
+ this.attrs_.axes.x.valueFormatter = utils.dateValueFormatter;
+ this.attrs_.axes.x.ticker = DygraphTickers.dateTicker;
+ this.attrs_.axes.x.axisLabelFormatter = utils.dateAxisLabelFormatter;
// Assume they're all dates.
- var parsedData = Dygraph.clone(data);
+ var parsedData = utils.clone(data);
for (i = 0; i < data.length; i++) {
if (parsedData[i].length === 0) {
console.error("Row " + (1 + i) + " of data is empty");
// Some intelligent defaults for a numeric x-axis.
/** @private (shut up, jsdoc!) */
this.attrs_.axes.x.valueFormatter = function(x) { return x; };
- this.attrs_.axes.x.ticker = Dygraph.numericTicks;
- this.attrs_.axes.x.axisLabelFormatter = Dygraph.numberAxisLabelFormatter;
+ this.attrs_.axes.x.ticker = DygraphTickers.numericTicks;
+ this.attrs_.axes.x.axisLabelFormatter = utils.numberAxisLabelFormatter;
return data;
}
};
var indepType = data.getColumnType(0);
if (indepType == 'date' || indepType == 'datetime') {
- this.attrs_.xValueParser = Dygraph.dateParser;
- this.attrs_.axes.x.valueFormatter = Dygraph.dateValueFormatter;
- this.attrs_.axes.x.ticker = Dygraph.dateTicker;
- this.attrs_.axes.x.axisLabelFormatter = Dygraph.dateAxisLabelFormatter;
+ this.attrs_.xValueParser = utils.dateParser;
+ this.attrs_.axes.x.valueFormatter = utils.dateValueFormatter;
+ this.attrs_.axes.x.ticker = DygraphTickers.dateTicker;
+ this.attrs_.axes.x.axisLabelFormatter = utils.dateAxisLabelFormatter;
} else if (indepType == 'number') {
this.attrs_.xValueParser = function(x) { return parseFloat(x); };
this.attrs_.axes.x.valueFormatter = function(x) { return x; };
- this.attrs_.axes.x.ticker = Dygraph.numericTicks;
+ this.attrs_.axes.x.ticker = DygraphTickers.numericTicks;
this.attrs_.axes.x.axisLabelFormatter = this.attrs_.axes.x.valueFormatter;
} else {
throw new Error(
data = data();
}
- if (Dygraph.isArrayLike(data)) {
+ if (utils.isArrayLike(data)) {
this.rawData_ = this.parseArray_(data);
this.cascadeDataDidUpdateEvent_();
this.predraw_();
this.predraw_();
} else if (typeof data == 'string') {
// Heuristic: a newline means it's CSV data. Otherwise it's an URL.
- var line_delimiter = Dygraph.detectLineDelimiter(data);
+ var line_delimiter = utils.detectLineDelimiter(data);
if (line_delimiter) {
this.loadedEvent_(data);
} else {
// highlightCircleSize
// Check if this set options will require new points.
- var requiresNewPoints = Dygraph.isPixelChangingOptionList(this.attr_("labels"), attrs);
+ var requiresNewPoints = utils.isPixelChangingOptionList(this.attr_("labels"), attrs);
- Dygraph.updateDeep(this.user_attrs_, attrs);
+ utils.updateDeep(this.user_attrs_, attrs);
this.attributes_.reparseSeries();
console.warn("Unable to add default annotation CSS rule; display may be off.");
};
-if (typeof exports === "object" && typeof module !== "undefined") {
- module.exports = Dygraph;
-}
+/**
+ * Add an event handler. This event handler is kept until the graph is
+ * destroyed with a call to graph.destroy().
+ *
+ * @param {!Node} elem The element to add the event to.
+ * @param {string} type The type of the event, e.g. 'click' or 'mousemove'.
+ * @param {function(Event):(boolean|undefined)} fn The function to call
+ * on the event. The function takes one parameter: the event object.
+ * @private
+ */
+Dygraph.prototype.addAndTrackEvent = function(elem, type, fn) {
+ utils.addEvent(elem, type, fn);
+ this.registeredEvents_.push({elem, type, fn});
+};
-return Dygraph;
+Dygraph.prototype.removeTrackedEvents_ = function() {
+ if (this.registeredEvents_) {
+ for (var idx = 0; idx < this.registeredEvents_.length; idx++) {
+ var reg = this.registeredEvents_[idx];
+ utils.removeEvent(reg.elem, reg.type, reg.fn);
+ }
+ }
+
+ this.registeredEvents_ = [];
+};
+
+
+// Installed plugins, in order of precedence (most-general to most-specific).
+Dygraph.PLUGINS = [
+ LegendPlugin,
+ AxesPlugin,
+ RangeSelectorPlugin, // Has to be before ChartLabels so that its callbacks are called after ChartLabels' callbacks.
+ ChartLabelsPlugin,
+ AnnotationsPlugin,
+ GridPlugin
+];
-})();
+export default Dygraph;
/*global Dygraph:false */
-Dygraph.Plugins.Annotations = (function() {
-
"use strict";
/**
layout.
TODO(danvk): cache DOM elements.
-
*/
var annotations = function() {
this.detachLabels();
};
-return annotations;
-
-})();
+export default annotations;
/*global Dygraph:false */
-Dygraph.Plugins.Axes = (function() {
-
'use strict';
/*
context.restore();
};
-return axes;
-})();
+export default axes;
*/
/*global Dygraph:false */
-Dygraph.Plugins.ChartLabels = (function() {
-
"use strict";
// TODO(danvk): move chart label options out of dygraphs and into the plugin.
this.detachLabels_();
};
-
-return chart_labels;
-})();
+export default chart_labels;
*/
/*global Dygraph:false */
-Dygraph.Plugins.Grid = (function() {
-
/*
Current bits of jankiness:
grid.prototype.destroy = function() {
};
-return grid;
-
-})();
+export default grid;
*/
/*global Dygraph:false */
-Dygraph.Plugins.Legend = (function() {
/*
Current bits of jankiness:
- Uses two private APIs:
/*global Dygraph:false */
"use strict";
+import * as utils from '../dygraph-utils';
+
/**
* Creates the legend, which appears when the user hovers over the chart.
for (i = 0; i < sel_points.length; i++) {
var pt = sel_points[i];
if (pt.yval === 0 && !showZeros) continue;
- if (!Dygraph.isOK(pt.canvasy)) continue;
+ if (!utils.isOK(pt.canvasy)) continue;
if (sepLines) html += "<br/>";
var series = g.getPropertiesForSeries(pt.name);
return dash;
};
-
-return legend;
-})();
+export default legend;
* a timeline range selector widget for dygraphs.
*/
-Dygraph.Plugins.RangeSelector = (function() {
-
/*global Dygraph:false */
"use strict";
+import * as utils from '../dygraph-utils';
+import DygraphInteraction from '../dygraph-interaction-model';
+
var rangeSelector = function() {
this.hasTouchInterface_ = typeof(TouchEvent) != 'undefined';
this.isMobileDevice_ = /mobile|android/gi.test(navigator.appVersion);
*/
rangeSelector.prototype.resize_ = function() {
function setElementRect(canvas, context, rect) {
- var canvasScale = Dygraph.getContextPixelRatio(context);
+ var canvasScale = utils.getContextPixelRatio(context);
canvas.style.top = rect.y + 'px';
canvas.style.left = rect.x + 'px';
* Creates the background and foreground canvases.
*/
rangeSelector.prototype.createCanvases_ = function() {
- this.bgcanvas_ = Dygraph.createCanvas();
+ this.bgcanvas_ = utils.createCanvas();
this.bgcanvas_.className = 'dygraph-rangesel-bgcanvas';
this.bgcanvas_.style.position = 'absolute';
this.bgcanvas_.style.zIndex = 9;
- this.bgcanvas_ctx_ = Dygraph.getContext(this.bgcanvas_);
+ this.bgcanvas_ctx_ = utils.getContext(this.bgcanvas_);
- this.fgcanvas_ = Dygraph.createCanvas();
+ this.fgcanvas_ = utils.createCanvas();
this.fgcanvas_.className = 'dygraph-rangesel-fgcanvas';
this.fgcanvas_.style.position = 'absolute';
this.fgcanvas_.style.zIndex = 9;
this.fgcanvas_.style.cursor = 'default';
- this.fgcanvas_ctx_ = Dygraph.getContext(this.fgcanvas_);
+ this.fgcanvas_ctx_ = utils.getContext(this.fgcanvas_);
};
/**
// We cover iframes during mouse interactions. See comments in
// dygraph-utils.js for more info on why this is a good idea.
- var tarp = new Dygraph.IFrameTarp();
+ var tarp = new utils.IFrameTarp();
// functions, defined below. Defining them this way (rather than with
// "function foo() {...}" makes JSHint happy.
};
onZoomStart = function(e) {
- Dygraph.cancelEvent(e);
+ utils.cancelEvent(e);
isZooming = true;
clientXLast = e.clientX;
handle = e.target ? e.target : e.srcElement;
if (e.type === 'mousedown' || e.type === 'dragstart') {
// These events are removed manually.
- Dygraph.addEvent(topElem, 'mousemove', onZoom);
- Dygraph.addEvent(topElem, 'mouseup', onZoomEnd);
+ utils.addEvent(topElem, 'mousemove', onZoom);
+ utils.addEvent(topElem, 'mouseup', onZoomEnd);
}
self.fgcanvas_.style.cursor = 'col-resize';
tarp.cover();
if (!isZooming) {
return false;
}
- Dygraph.cancelEvent(e);
+ utils.cancelEvent(e);
var delX = e.clientX - clientXLast;
if (Math.abs(delX) < 4) {
}
isZooming = false;
tarp.uncover();
- Dygraph.removeEvent(topElem, 'mousemove', onZoom);
- Dygraph.removeEvent(topElem, 'mouseup', onZoomEnd);
+ utils.removeEvent(topElem, 'mousemove', onZoom);
+ utils.removeEvent(topElem, 'mouseup', onZoomEnd);
self.fgcanvas_.style.cursor = 'default';
// If on a slower device, zoom now.
onPanStart = function(e) {
if (!isPanning && isMouseInPanZone(e) && self.getZoomHandleStatus_().isZoomed) {
- Dygraph.cancelEvent(e);
+ utils.cancelEvent(e);
isPanning = true;
clientXLast = e.clientX;
if (e.type === 'mousedown') {
// These events are removed manually.
- Dygraph.addEvent(topElem, 'mousemove', onPan);
- Dygraph.addEvent(topElem, 'mouseup', onPanEnd);
+ utils.addEvent(topElem, 'mousemove', onPan);
+ utils.addEvent(topElem, 'mouseup', onPanEnd);
}
return true;
}
if (!isPanning) {
return false;
}
- Dygraph.cancelEvent(e);
+ utils.cancelEvent(e);
var delX = e.clientX - clientXLast;
if (Math.abs(delX) < 4) {
return false;
}
isPanning = false;
- Dygraph.removeEvent(topElem, 'mousemove', onPan);
- Dygraph.removeEvent(topElem, 'mouseup', onPanEnd);
+ utils.removeEvent(topElem, 'mousemove', onPan);
+ utils.removeEvent(topElem, 'mouseup', onPanEnd);
// If on a slower device, do pan now.
if (!dynamic) {
doPan();
onZoomHandleTouchEvent = function(e) {
if (e.type == 'touchstart' && e.targetTouches.length == 1) {
if (onZoomStart(e.targetTouches[0])) {
- Dygraph.cancelEvent(e);
+ utils.cancelEvent(e);
}
} else if (e.type == 'touchmove' && e.targetTouches.length == 1) {
if (onZoom(e.targetTouches[0])) {
- Dygraph.cancelEvent(e);
+ utils.cancelEvent(e);
}
} else {
onZoomEnd(e);
onCanvasTouchEvent = function(e) {
if (e.type == 'touchstart' && e.targetTouches.length == 1) {
if (onPanStart(e.targetTouches[0])) {
- Dygraph.cancelEvent(e);
+ utils.cancelEvent(e);
}
} else if (e.type == 'touchmove' && e.targetTouches.length == 1) {
if (onPan(e.targetTouches[0])) {
- Dygraph.cancelEvent(e);
+ utils.cancelEvent(e);
}
} else {
onPanEnd(e);
}
};
- this.setDefaultOption_('interactionModel', Dygraph.Interaction.dragIsPanInteractionModel);
+ this.setDefaultOption_('interactionModel', DygraphInteraction.dragIsPanInteractionModel);
this.setDefaultOption_('panEdgeFraction', 0.0001);
var dragStartEvent = window.opera ? 'mousedown' : 'dragstart';
// Also, expand the Y range to compress the mini plot a little.
var extraPercent = 0.25;
if (logscale) {
- yMax = Dygraph.log10(yMax);
+ yMax = utils.log10(yMax);
yMax += yMax*extraPercent;
- yMin = Dygraph.log10(yMin);
+ yMin = utils.log10(yMin);
for (i = 0; i < combinedSeries.length; i++) {
- combinedSeries[i][1] = Dygraph.log10(combinedSeries[i][1]);
+ combinedSeries[i][1] = utils.log10(combinedSeries[i][1]);
}
} else {
var yExtra;
};
};
-return rangeSelector;
-
-})();
+export default rangeSelector;
<html>
<head>
<title>demo</title>
+ <!--
<script type="text/javascript" src="../dygraph-dev.js"></script>
+ -->
+ <script type="text/javascript" src="../bundle.js"></script>
</head>
<body>
<h2>Demo</h2>
title: 'Interesting Shapes',
xlabel: 'Date',
ylabel: 'Count',
- axisLineColor: 'white'
+ axisLineColor: 'white',
+ showRangeSelector: true
// drawXGrid: false
}
);