-// Copyright 2006 Dan Vanderkam (danvdk@gmail.com)
-// All Rights Reserved.
+/**
+ * @license
+ * Copyright 2006 Dan Vanderkam (danvdk@gmail.com)
+ * MIT-licensed (http://opensource.org/licenses/MIT)
+ */
/**
* @fileoverview Creates an interactive, zoomable graph based on a CSV file or
interactionModel: null, // will be set to Dygraph.Interaction.defaultModel
+ // Range selector options
+ showRangeSelector: false,
+ rangeSelectorHeight: 40,
+ rangeSelectorPlotStrokeColor: "#808FAB",
+ rangeSelectorPlotFillColor: "#A7B1C4",
+
// per-axis options
axes: {
x: {
document.readyState != 'complete') {
var self = this;
setTimeout(function() { self.__init__(div, file, attrs) }, 100);
+ return;
}
// Support two-argument constructor
if (div.style.height == '' && attrs.height) {
div.style.height = attrs.height + "px";
}
- if (div.style.height == '' && div.offsetHeight == 0) {
+ if (div.style.height == '' && div.clientHeight == 0) {
div.style.height = Dygraph.DEFAULT_HEIGHT + "px";
if (div.style.width == '') {
div.style.width = Dygraph.DEFAULT_WIDTH + "px";
}
}
// these will be zero if the dygraph's div is hidden.
- this.width_ = div.offsetWidth;
- this.height_ = div.offsetHeight;
+ this.width_ = div.clientWidth;
+ this.height_ = div.clientHeight;
// TODO(danvk): set fillGraph to be part of attrs_ here, not user_attrs_.
if (attrs['stackedGraph']) {
this.hidden_ = this.createPlotKitCanvas_(this.canvas_);
this.hidden_ctx_ = Dygraph.getContext(this.hidden_);
+ if (this.attr_('showRangeSelector')) {
+ // The range selector must be created here so that its canvases and contexts get created here.
+ // For some reason, if the canvases and contexts don't get created here, things don't work in IE.
+ // The range selector also sets xAxisHeight in order to reserve space.
+ this.rangeSelector_ = new DygraphRangeSelector(this);
+ }
+
// The interactive parts of the graph are drawn on top of the chart.
this.graphDiv.appendChild(this.hidden_);
this.graphDiv.appendChild(this.canvas_);
this.mouseEventElement_ = this.canvas_;
+ // Create the grapher
+ this.layout_ = new DygraphLayout(this);
+
+ if (this.rangeSelector_) {
+ // This needs to happen after the graph canvases are added to the div and the layout object is created.
+ this.rangeSelector_.addToGraph(this.graphDiv, this.layout_);
+ }
+
var dygraph = this;
Dygraph.addEvent(this.mouseEventElement_, 'mousemove', function(e) {
dygraph.mouseMove_(e);
dygraph.mouseOut_(e);
});
- // Create the grapher
- this.layout_ = new DygraphLayout(this);
-
this.createStatusMessage_();
this.createDragInterface_();
* up any previous zoom rectangles that were drawn. This could be optimized to
* avoid extra redrawing, but it's tricky to avoid interactions with the status
* dots.
- *
+ *
* @param {Number} direction the direction of the zoom rectangle. Acceptable
* values are Dygraph.HORIZONTAL and Dygraph.VERTICAL.
* @param {Number} startX The X position where the drag started, in canvas
for (var i in this.layout_.datasets) {
if (row < this.layout_.datasets[i].length) {
var point = this.layout_.points[pos+row];
-
+
if (this.attr_("stackedGraph")) {
point = this.layout_.unstackPointAtIndex(pos+row);
}
-
+
this.selPoints_.push(point);
}
pos += this.layout_.datasets[i].length;
// edge of the div, if we have two y-axes.
this.positionLabelsDiv_();
+ if (this.rangeSelector_) {
+ this.rangeSelector_.renderStaticLayer();
+ }
+
// If the data or options have changed, then we'd better redraw.
this.drawGraph_();
}
}
+ if (this.rangeSelector_) {
+ this.rangeSelector_.renderInteractiveLayer();
+ }
+
if (this.attr_("drawCallback") !== null) {
this.attr_("drawCallback")(this, is_initial_draw);
}
this.width_ = width;
this.height_ = height;
} else {
- this.width_ = this.maindiv_.offsetWidth;
- this.height_ = this.maindiv_.offsetHeight;
+ this.width_ = this.maindiv_.clientWidth;
+ this.height_ = this.maindiv_.clientHeight;
}
if (old_width != this.width_ || old_height != this.height_) {