X-Git-Url: https://adrianiainlam.tk/git/?a=blobdiff_plain;f=dygraph.js;h=fe677f29688d874c74b06319cff267ae9d6d6108;hb=5bc3e265be640a29bc57d7d58c059322ab361d63;hp=88ad4b85b555c45302670cd50463abb5959cf421;hpb=fe45f9720a20702b0217404e1b80144b47c01653;p=dygraphs.git diff --git a/dygraph.js b/dygraph.js index 88ad4b8..fe677f2 100644 --- a/dygraph.js +++ b/dygraph.js @@ -263,6 +263,10 @@ Dygraph.prototype.__init__ = function(div, file, attrs) { this.is_initial_draw_ = true; this.annotations_ = []; + // Zoomed indicators - These indicate when the graph has been zoomed and on what axis. + this.zoomed_x_ = false; + this.zoomed_y_ = false; + // Number of digits to use when labeling the x (if numeric) and y axis // ticks. this.numXDigits_ = 2; @@ -339,6 +343,22 @@ Dygraph.prototype.__init__ = function(div, file, attrs) { this.start_(); }; +/** + * Returns the zoomed status of the chart for one or both axes. + * + * Axis is an optional parameter. Can be set to 'x' or 'y'. + * + * The zoomed status for an axis is set whenever a user zooms using the mouse + * or when the dateWindow or valueRange are updated (unless the isZoomedIgnoreProgrammaticZoom + * option is also specified). + */ +Dygraph.prototype.isZoomed = function(axis) { + if (axis == null) return this.zoomed_x_ || this.zoomed_y_; + if (axis == 'x') return this.zoomed_x_; + if (axis == 'y') return this.zoomed_y_; + throw "axis parameter to Dygraph.isZoomed must be missing, 'x' or 'y'."; +}; + Dygraph.prototype.toString = function() { var maindiv = this.maindiv_; var id = (maindiv && maindiv.id) ? maindiv.id : maindiv @@ -1503,6 +1523,7 @@ Dygraph.prototype.doZoomX_ = function(lowX, highX) { */ Dygraph.prototype.doZoomXDates_ = function(minDate, maxDate) { this.dateWindow_ = [minDate, maxDate]; + this.zoomed_x_ = true; this.drawGraph_(); if (this.attr_("zoomCallback")) { this.attr_("zoomCallback")(minDate, maxDate, this.yAxisRanges()); @@ -1530,9 +1551,11 @@ Dygraph.prototype.doZoomY_ = function(lowY, highY) { valueRanges.push([low, hi]); } + this.zoomed_y_ = true; this.drawGraph_(); if (this.attr_("zoomCallback")) { var xRange = this.xAxisRange(); + var yRange = this.yAxisRange(); this.attr_("zoomCallback")(xRange[0], xRange[1], this.yAxisRanges()); } }; @@ -1560,6 +1583,8 @@ Dygraph.prototype.doUnzoom_ = function() { if (dirty) { // Putting the drawing operation before the callback because it resets // yAxisRange. + this.zoomed_x_ = false; + this.zoomed_y_ = false; this.drawGraph_(); if (this.attr_("zoomCallback")) { var minDate = this.rawData_[0][0]; @@ -2588,11 +2613,13 @@ Dygraph.prototype.drawGraph_ = function() { this.layout_.updateOptions( { yAxes: this.axes_, seriesToAxisMap: this.seriesToAxisMap_ } ); - this.addXTicks_(); + // Save the X axis zoomed status as the updateOptions call will tend to set it errorneously + var tmp_zoomed_x = this.zoomed_x_; // Tell PlotKit to use this new data and render itself this.layout_.updateOptions({dateWindow: this.dateWindow_}); + this.zoomed_x_ = tmp_zoomed_x; this.layout_.evaluateWithError(); this.plotter_.clear(); this.plotter_.render(); @@ -2620,6 +2647,15 @@ Dygraph.prototype.drawGraph_ = function() { * indices are into the axes_ array. */ Dygraph.prototype.computeYAxes_ = function() { + var valueWindows; + if (this.axes_ != undefined) { + // Preserve valueWindow settings. + valueWindows = []; + for (var index = 0; index < this.axes_.length; index++) { + valueWindows.push(this.axes_[index].valueWindow); + } + } + this.axes_ = [{ yAxisId : 0, g : this }]; // always have at least one y-axis. this.seriesToAxisMap_ = {}; @@ -2696,6 +2732,13 @@ Dygraph.prototype.computeYAxes_ = function() { if (vis[i - 1]) seriesToAxisFiltered[s] = this.seriesToAxisMap_[s]; } this.seriesToAxisMap_ = seriesToAxisFiltered; + + if (valueWindows != undefined) { + // Restore valueWindow settings. + for (var index = 0; index < valueWindows.length; index++) { + this.axes_[index].valueWindow = valueWindows[index]; + } + } }; /** @@ -2750,12 +2793,24 @@ Dygraph.prototype.computeYAxisRanges_ = function(extremes) { var series = seriesForAxis[i]; var minY = Infinity; // extremes[series[0]][0]; var maxY = -Infinity; // extremes[series[0]][1]; + var extremeMinY, extremeMaxY; for (var j = 0; j < series.length; j++) { - minY = Math.min(extremes[series[j]][0], minY); - maxY = Math.max(extremes[series[j]][1], maxY); + // Only use valid extremes to stop null data series' from corrupting the scale. + extremeMinY = extremes[series[j]][0]; + if (extremeMinY != null) { + minY = Math.min(extremeMinY, minY); + } + extremeMaxY = extremes[series[j]][1]; + if (extremeMaxY != null) { + maxY = Math.max(extremeMaxY, maxY); + } } if (axis.includeZero && minY > 0) minY = 0; + // Ensure we have a valid scale, otherwise defualt to zero for safety. + if (minY == Infinity) minY = 0; + if (maxY == -Infinity) maxY = 0; + // Add some padding and round up to an integer to be human-friendly. var span = maxY - minY; // special case: if we have no sense of scale, use +/-10% of the sole value. @@ -3477,6 +3532,7 @@ Dygraph.prototype.start_ = function() { *
  • file: changes the source data for the graph
  • *
  • errorBars: changes whether the data contains stddev
  • * + * * @param {Object} attrs The new properties and values */ Dygraph.prototype.updateOptions = function(attrs) { @@ -3486,6 +3542,12 @@ Dygraph.prototype.updateOptions = function(attrs) { } if ('dateWindow' in attrs) { this.dateWindow_ = attrs.dateWindow; + if (!('isZoomedIgnoreProgrammaticZoom' in attrs)) { + this.zoomed_x_ = attrs.dateWindow != null; + } + } + if ('valueRange' in attrs && !('isZoomedIgnoreProgrammaticZoom' in attrs)) { + this.zoomed_y_ = attrs.valueRange != null; } // TODO(danvk): validate per-series options. @@ -4179,6 +4241,12 @@ Dygraph.OPTIONS_REFERENCE = // "type": "integer", "default": "18", "description": "Width of the div which contains the y-axis label. Since the y-axis label appears rotated 90 degrees, this actually affects the height of its div." + }, + "isZoomedIgnoreProgrammaticZoom" : { + "default": "false", + "labels": ["Zooming"], + "type": "boolean", + "description" : "When this option is passed to updateOptions() along with either the dateWindow or valueRange options, the zoom flags are not changed to reflect a zoomed state. This is primarily useful for when the display area of a chart is changed programmatically and also where manual zooming is allowed and use is made of the isZoomed method to determine this." } } ; // @@ -4205,7 +4273,8 @@ Dygraph.OPTIONS_REFERENCE = // 'Legend', 'Overall display', 'Rolling Averages', - 'Value display/formatting' + 'Value display/formatting', + 'Zooming' ]; var cats = {}; for (var i = 0; i < valid_cats.length; i++) cats[valid_cats[i]] = true;