From: Dan Vanderkam Date: Tue, 5 Apr 2011 14:35:42 +0000 (-0400) Subject: merge master X-Git-Tag: v1.0.0~536 X-Git-Url: https://adrianiainlam.tk/git/?a=commitdiff_plain;ds=inline;h=5bc3e265be640a29bc57d7d58c059322ab361d63;hp=-c;p=dygraphs.git merge master --- 5bc3e265be640a29bc57d7d58c059322ab361d63 diff --combined dygraph.js index 88ad4b8,00af051..fe677f2 --- a/dygraph.js +++ b/dygraph.js @@@ -193,11 -193,6 +193,11 @@@ Dygraph.DEFAULT_ATTRS = stepPlot: false, avoidMinZero: false, + // Sizes of the various chart labels. + titleHeight: 28, + xLabelHeight: 18, + yLabelWidth: 18, + interactionModel: null // will be set to Dygraph.defaultInteractionModel. }; @@@ -263,6 -258,10 +263,10 @@@ Dygraph.prototype.__init__ = function(d 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 -338,22 +343,22 @@@ 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 @@@ -944,9 -959,8 +964,9 @@@ Dygraph.prototype.createStatusMessage_ }; /** - * Position the labels div so that its right edge is flush with the right edge - * of the charting area. + * Position the labels div so that: + * - its right edge is flush with the right edge of the charting area + * - its top edge is flush with the top edge of the charting area */ Dygraph.prototype.positionLabelsDiv_ = function() { // Don't touch a user-specified labelsDiv. @@@ -955,7 -969,6 +975,7 @@@ var area = this.plotter_.area; var div = this.attr_("labelsDiv"); div.style.left = area.x + area.w - this.attr_("labelsDivWidth") - 1 + "px"; + div.style.top = area.y + "px"; }; /** @@@ -973,11 -986,10 +993,11 @@@ Dygraph.prototype.createRollInterface_ var display = this.attr_('showRoller') ? 'block' : 'none'; + var area = this.plotter_.area; var textAttr = { "position": "absolute", "zIndex": 10, - "top": (this.plotter_.area.h - 25) + "px", - "left": (this.plotter_.area.x + 1) + "px", + "top": (area.y + area.h - 25) + "px", + "left": (area.x + 1) + "px", "display": display }; this.roller_.size = "2"; @@@ -1503,6 -1515,7 +1523,7 @@@ Dygraph.prototype.doZoomX_ = function(l */ 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 -1543,11 +1551,11 @@@ Dygraph.prototype.doZoomY_ = function(l 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 -1575,8 +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 -2605,13 +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 -2639,15 +2647,15 @@@ * 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 -2724,13 +2732,13 @@@ 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 -2785,24 +2793,24 @@@ Dygraph.prototype.computeYAxisRanges_ 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 -3524,7 +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 -3534,12 +3542,12 @@@ } 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. @@@ -4110,7 -4164,7 +4172,7 @@@ Dygraph.OPTIONS_REFERENCE = // 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." } } ; // // NOTE: in addition to parsing as JS, this snippet is expected to be valid // JSON. This assumption cannot be checked in JS, but it will be checked when -// documentation is generated by the generate-documentation.py script. +// documentation is generated by the generate-documentation.py script. For the +// most part, this just means that you should always use double quotes. // Do a quick sanity check on the options reference. (function() { @@@ -4194,7 -4217,6 +4262,7 @@@ var valid_cats = [ 'Annotations', 'Axis display', + 'Chart labels', 'CSV parsing', 'Callbacks', 'Data Line display', @@@ -4205,7 -4227,8 +4273,8 @@@ '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;