this.dateWindow_ = attrs.dateWindow || null;
this.valueRange_ = attrs.valueRange || null;
this.wilsonInterval_ = attrs.wilsonInterval || true;
+ this.is_initial_draw_ = true;
// Clear the div. This ensure that, if multiple dygraphs are passed the same
// div, then only one will be drawn.
}
};
+Dygraph.clipCanvas_ = function(cnv, clip) {
+ var ctx = cnv.getContext("2d");
+ ctx.beginPath();
+ ctx.rect(clip.left, clip.top, clip.width, clip.height);
+ ctx.clip();
+};
+
/**
* Generates interface elements for the Dygraph: a containing div, a div to
* display the current point, and a textbox to adjust the rolling average
this.graphDiv.style.height = this.height_ + "px";
enclosing.appendChild(this.graphDiv);
+ var clip = {
+ top: 0,
+ left: this.attr_("yAxisLabelWidth") + 2 * this.attr_("axisTickSize")
+ };
+ clip.width = this.width_ - clip.left - this.attr_("rightGap");
+ clip.height = this.height_ - this.attr_("axisLabelFontSize")
+ - 2 * this.attr_("axisTickSize");
+ this.clippingArea_ = clip;
+
// Create the canvas for interactive parts of the chart.
- // this.canvas_ = document.createElement("canvas");
this.canvas_ = Dygraph.createCanvas();
this.canvas_.style.position = "absolute";
this.canvas_.width = this.width_;
// ... and for static parts of the chart.
this.hidden_ = this.createPlotKitCanvas_(this.canvas_);
+ // Make sure we don't overdraw.
+ Dygraph.clipCanvas_(this.hidden_, this.clippingArea_);
+ Dygraph.clipCanvas_(this.canvas_, this.clippingArea_);
+
var dygraph = this;
Dygraph.addEvent(this.hidden_, 'mousemove', function(e) {
dygraph.mouseMove_(e);
this.createStatusMessage_();
this.createRollInterface_();
this.createDragInterface_();
-}
+};
+
+/**
+ * Detach DOM elements in the dygraph and null out all data references.
+ * Calling this when you're done with a dygraph can dramatically reduce memory
+ * usage. See, e.g., the tests/perf.html example.
+ */
+Dygraph.prototype.destroy = function() {
+ var removeRecursive = function(node) {
+ while (node.hasChildNodes()) {
+ removeRecursive(node.firstChild);
+ node.removeChild(node.firstChild);
+ }
+ };
+ removeRecursive(this.maindiv_);
+
+ var nullOut = function(obj) {
+ for (var n in obj) {
+ if (typeof(obj[n]) === 'object') {
+ obj[n] = null;
+ }
+ }
+ };
+
+ // These may not all be necessary, but it can't hurt...
+ nullOut(this.layout_);
+ nullOut(this.plotter_);
+ nullOut(this);
+};
/**
* Creates the canvas containing the PlotKit graph. Only plotkit ever draws on
* @private
*/
Dygraph.prototype.drawGraph_ = function(data) {
+ // This is used to set the second parameter to drawCallback, below.
+ var is_initial_draw = this.is_initial_draw_;
+ this.is_initial_draw_ = false;
+
var minY = null, maxY = null;
this.layout_.removeAllDatasets();
this.setColors_();
this.canvas_.height);
if (this.attr_("drawCallback") !== null) {
- this.attr_("drawCallback")(this);
+ this.attr_("drawCallback")(this, is_initial_draw);
}
};