From 5011e7a1a4764f7ae0b8703e319d635ab6e4abc8 Mon Sep 17 00:00:00 2001 From: Dan Vanderkam Date: Sat, 28 Nov 2009 15:53:49 -0500 Subject: [PATCH] fix some range calculation bugs with error bars, gaps with error bars --- dygraph-canvas.js | 4 ++ dygraph.js | 112 ++++++++++++++++++++++++++++++----------------- tests/label-div.html | 2 +- tests/missing-data.html | 22 ++++++++++ tests/native-format.html | 2 +- 5 files changed, 99 insertions(+), 43 deletions(-) diff --git a/dygraph-canvas.js b/dygraph-canvas.js index 1c5b502..9bf7512 100644 --- a/dygraph-canvas.js +++ b/dygraph-canvas.js @@ -204,6 +204,10 @@ DygraphCanvasRenderer.prototype._renderLineChart = function() { var errorTrapezoid = function(ctx_,point) { count++; if (point.name == setName) { + if (!point.y || isNaN(point.y)) { + prevX = -1; + return; + } var newYs = [ point.y - point.errorPlus * yscale, point.y + point.errorMinus * yscale ]; newYs[0] = this.area.h * newYs[0] + this.area.y; diff --git a/dygraph.js b/dygraph.js index 30ea8f6..ef06082 100644 --- a/dygraph.js +++ b/dygraph.js @@ -962,6 +962,46 @@ Dygraph.prototype.addYTicks_ = function(minY, maxY) { yTicks: ticks } ); }; +// Computes the range of the data series (including confidence intervals). +// series is either [ [x1, y1], [x2, y2], ... ] or +// [ [x1, [y1, dev_low, dev_high]], [x2, [y2, dev_low, dev_high]], ... +// Returns [low, high] +Dygraph.prototype.extremeValues_ = function(series) { + var minY = null, maxY = null; + + var bars = this.attr_("errorBars") || this.customBars_; + if (bars) { + // With custom bars, maxY is the max of the high values. + for (var j = 0; j < series.length; j++) { + var y = series[j][1][0]; + if (!y) continue; + var low = y - series[j][1][1]; + var high = y + series[j][1][2]; + if (low > y) low = y; // this can happen with custom bars, + if (high < y) high = y; // e.g. in tests/custom-bars.html + if (maxY == null || high > maxY) { + maxY = high; + } + if (minY == null || low < minY) { + minY = low; + } + } + } else { + for (var j = 0; j < series.length; j++) { + var y = series[j][1]; + if (!y) continue; + if (maxY == null || y > maxY) { + maxY = y; + } + if (minY == null || y < minY) { + minY = y; + } + } + } + + return [minY, maxY]; +}; + /** * Update the graph with new data. Data is in the format * [ [date1, val1, val2, ...], [date2, val1, val2, ...] if errorBars=false @@ -993,41 +1033,15 @@ Dygraph.prototype.drawGraph_ = function(data) { for (var k = 0; k < series.length; k++) { if (series[k][0] >= low && series[k][0] <= high) { pruned.push(series[k]); - var y = bars ? series[k][1][0] : series[k][1]; - if (!y) continue; - if (maxY == null || y > maxY) maxY = y; - if (minY == null || y < minY) minY = y; } } series = pruned; - } else { - if (!this.customBars_) { - for (var j = 0; j < series.length; j++) { - var y = bars ? series[j][1][0] : series[j][1]; - if (!y) continue; - if (maxY == null || y > maxY) { - maxY = bars ? y + series[j][1][1] : y; - } - if (minY == null || y < minY) { - minY = bars ? y + series[j][1][1] : y; - } - } - } else { - // With custom bars, maxY is the max of the high values. - for (var j = 0; j < series.length; j++) { - var y = series[j][1][0]; - var high = series[j][1][2]; - if (high > y) y = high; - if (maxY == null || y > maxY) { - maxY = y; - } - if (minY == null || y < minY) { - minY = y; - } - } - } } + [thisMinY, thisMaxY] = this.extremeValues_(series); + if (!minY || thisMinY < minY) minY = thisMinY; + if (!maxY || thisMaxY > maxY) maxY = thisMaxY; + if (bars) { var vals = []; for (var j=0; j diff --git a/tests/missing-data.html b/tests/missing-data.html index 0206852..e6eb648 100644 --- a/tests/missing-data.html +++ b/tests/missing-data.html @@ -10,9 +10,14 @@ + + +
+
+
diff --git a/tests/native-format.html b/tests/native-format.html index 09a5235..16bd9f1 100644 --- a/tests/native-format.html +++ b/tests/native-format.html @@ -32,7 +32,7 @@ [4,70,80], ], { - labels: [ "A", "B" ] + labels: [ "x", "A", "B" ] }); -- 2.7.4