X-Git-Url: https://adrianiainlam.tk/git/?a=blobdiff_plain;ds=sidebyside;f=dygraph.js;h=045c394ebbe3b379061ba61f5368c5ab28827f89;hb=e0ff43a1c387a0ef9ee01ab52a61fbb698f413a5;hp=8162d8e6b3b4c291eadf1ea7cc30ae1bef1e74c5;hpb=e7e949c8743a252cbd77e60db8bef4d112d6f166;p=dygraphs.git diff --git a/dygraph.js b/dygraph.js index 8162d8e..045c394 100644 --- a/dygraph.js +++ b/dygraph.js @@ -1509,15 +1509,15 @@ Dygraph.prototype.eventToDomCoords = function(event) { * @private */ Dygraph.prototype.findClosestRow = function(domX) { - var minDistX = null; + var minDistX = Infinity; var idx = -1; var points = this.layout_.points; var l = points.length; for (var i = 0; i < l; i++) { var point = points[i]; - if (point === null) continue; + if (!Dygraph.isValidPoint(point, true)) continue; var dist = Math.abs(point.canvasx - domX); - if (minDistX === null || dist < minDistX) { + if (dist < minDistX) { minDistX = dist; idx = i; } @@ -1538,7 +1538,7 @@ Dygraph.prototype.findClosestRow = function(domX) { * @private */ Dygraph.prototype.findClosestPoint = function(domX, domY) { - var minDist = null; + var minDist = Infinity; var idx = -1; var points = this.layout_.points; var dist, dx, dy, point, closestPoint, closestSeries; @@ -1547,13 +1547,12 @@ Dygraph.prototype.findClosestPoint = function(domX, domY) { var len = this.layout_.setPointsLengths[setIdx]; for (var i = 0; i < len; ++i) { var point = points[first + i]; - if (point === null) continue; + if (!Dygraph.isValidPoint(point)) continue; dx = point.canvasx - domX; dy = point.canvasy - domY; dist = dx * dx + dy * dy; - if (minDist === null || dist < minDist) { - if (!isNaN(dist)) - minDist = dist; + if (dist < minDist) { + minDist = dist; closestPoint = point; closestSeries = setIdx; idx = i; @@ -1562,7 +1561,7 @@ Dygraph.prototype.findClosestPoint = function(domX, domY) { } var name = this.layout_.setNames[closestSeries]; return { - row: idx, + row: idx + this.getLeftBoundary_(), seriesName: name, point: closestPoint }; @@ -1582,29 +1581,36 @@ Dygraph.prototype.findClosestPoint = function(domX, domY) { */ Dygraph.prototype.findStackedPoint = function(domX, domY) { var row = this.findClosestRow(domX); + var boundary = this.getLeftBoundary_(); + var rowIdx = row - boundary; var points = this.layout_.points; var closestPoint, closestSeries; for (var setIdx = 0; setIdx < this.layout_.datasets.length; ++setIdx) { var first = this.layout_.setPointsOffsets[setIdx]; var len = this.layout_.setPointsLengths[setIdx]; - if (row >= len) continue; - var p1 = points[first + row]; + if (rowIdx >= len) continue; + var p1 = points[first + rowIdx]; + if (!Dygraph.isValidPoint(p1)) continue; var py = p1.canvasy; - if (domX > p1.canvasx && row + 1 < len) { + if (domX > p1.canvasx && rowIdx + 1 < len) { // interpolate series Y value using next point - var p2 = points[first + row + 1]; - var dx = p2.canvasx - p1.canvasx; - if (dx > 0) { - var r = (domX - p1.canvasx) / dx; - py += r * (p2.canvasy - p1.canvasy); + var p2 = points[first + rowIdx + 1]; + if (Dygraph.isValidPoint(p2)) { + var dx = p2.canvasx - p1.canvasx; + if (dx > 0) { + var r = (domX - p1.canvasx) / dx; + py += r * (p2.canvasy - p1.canvasy); + } } - } else if (domX < p1.canvasx && row > 0) { + } else if (domX < p1.canvasx && rowIdx > 0) { // interpolate series Y value using previous point - var p0 = points[first + row - 1]; - var dx = p1.canvasx - p0.canvasx; - if (dx > 0) { - var r = (p1.canvasx - domX) / dx; - py += r * (p0.canvasy - p1.canvasy); + var p0 = points[first + rowIdx - 1]; + if (Dygraph.isValidPoint(p0)) { + var dx = p1.canvasx - p0.canvasx; + if (dx > 0) { + var r = (p1.canvasx - domX) / dx; + py += r * (p0.canvasy - p1.canvasy); + } } } // Stop if the point (domX, py) is above this series' upper edge @@ -1659,6 +1665,18 @@ Dygraph.prototype.mouseMove_ = function(event) { }; /** + * Fetch left offset from first defined boundaryIds record (see bug #236). + */ +Dygraph.prototype.getLeftBoundary_ = function() { + for (var i = 0; i < this.boundaryIds_.length; i++) { + if (this.boundaryIds_[i] !== undefined) { + return this.boundaryIds_[i][0]; + } + } + return 0; +}; + +/** * Transforms layout_.points index into data row number. * @param int layout_.points index * @return int row number, or -1 if none could be found. @@ -1667,19 +1685,11 @@ Dygraph.prototype.mouseMove_ = function(event) { Dygraph.prototype.idxToRow_ = function(idx) { if (idx < 0) return -1; - // make sure that you get the boundaryIds record which is also defined (see bug #236) - var boundaryIdx = -1; - for (var i = 0; i < this.boundaryIds_.length; i++) { - if (this.boundaryIds_[i] !== undefined) { - boundaryIdx = i; - break; - } - } - if (boundaryIdx < 0) return -1; + var boundary = this.getLeftBoundary_(); for (var setIdx = 0; setIdx < this.layout_.datasets.length; ++setIdx) { var set = this.layout_.datasets[setIdx]; if (idx < set.length) { - return this.boundaryIds_[boundaryIdx][0] + idx; + return boundary + idx; } idx -= set.length; } @@ -1832,6 +1842,8 @@ Dygraph.prototype.generateLegendHTML_ = function(x, sel_points, oneEmWidth) { */ Dygraph.prototype.setLegendHTML_ = function(x, sel_points) { var labelsDiv = this.attr_("labelsDiv"); + if (!labelsDiv) return; + var sizeSpan = document.createElement('span'); // Calculates the width of 1em in pixels for the legend. sizeSpan.setAttribute('style', 'margin: 0; padding: 0 0 0 1em; border: 0;'); @@ -1973,12 +1985,7 @@ Dygraph.prototype.setSelection = function(row, opt_seriesName) { var pos = 0; if (row !== false) { - for (var i = 0; i < this.boundaryIds_.length; i++) { - if (this.boundaryIds_[i] !== undefined) { - row -= this.boundaryIds_[i][0]; - break; - } - } + row -= this.getLeftBoundary_(); } var changed = false; @@ -1994,7 +2001,7 @@ Dygraph.prototype.setSelection = function(row, opt_seriesName) { point = this.layout_.unstackPointAtIndex(pos+row); } - this.selPoints_.push(point); + if (!(point.yval === null)) this.selPoints_.push(point); } pos += set.length; } @@ -2066,7 +2073,7 @@ Dygraph.prototype.getSelection = function() { for (var row=0; row= 0; --k) { + // Use the first nonempty dataset to get X values. + if (!datasets[k]) continue; + for (j = 0; j < datasets[k].length; j++) { + var x = datasets[k][j][0]; + if (isNaN(cumulative_y[x])) { + // Set all Y values to NaN at that X value. + for (i = datasets.length - 1; i >= 0; i--) { + if (!datasets[i]) continue; + datasets[i][j][1] = NaN; + } + } + } + break; + } + } + return [ datasets, extremes, boundaryIds ]; }; @@ -2677,24 +2708,19 @@ Dygraph.prototype.computeYAxisRanges_ = function(extremes) { * * @private */ -Dygraph.prototype.extractSeries_ = function(rawData, i, logScale, connectSeparatedPoints) { +Dygraph.prototype.extractSeries_ = function(rawData, i, logScale) { var series = []; for (var j = 0; j < rawData.length; j++) { var x = rawData[j][0]; var point = rawData[j][i]; if (logScale) { // On the log scale, points less than zero do not exist. - // This will create a gap in the chart. Note that this ignores - // connectSeparatedPoints. + // This will create a gap in the chart. if (point <= 0) { point = null; } - series.push([x, point]); - } else { - if (point !== null || !connectSeparatedPoints) { - series.push([x, point]); - } } + series.push([x, point]); } return series; }; @@ -2869,7 +2895,7 @@ Dygraph.prototype.detectTypeFromString_ = function(str) { // TODO(danvk): use Dygraph.numberValueFormatter here? /** @private (shut up, jsdoc!) */ this.attrs_.axes.x.valueFormatter = function(x) { return x; }; - this.attrs_.axes.x.ticker = Dygraph.numericTicks; + this.attrs_.axes.x.ticker = Dygraph.numericLinearTicks; this.attrs_.axes.x.axisLabelFormatter = this.attrs_.axes.x.valueFormatter; } }; @@ -3108,7 +3134,7 @@ Dygraph.prototype.parseArray_ = function(data) { /** @private (shut up, jsdoc!) */ this.attrs_.axes.x.valueFormatter = function(x) { return x; }; this.attrs_.axes.x.axisLabelFormatter = Dygraph.numberAxisLabelFormatter; - this.attrs_.axes.x.ticker = Dygraph.numericTicks; + this.attrs_.axes.x.ticker = Dygraph.numericLinearTicks; return data; } }; @@ -3148,7 +3174,7 @@ Dygraph.prototype.parseDataTable_ = function(data) { } else if (indepType == 'number') { this.attrs_.xValueParser = function(x) { return parseFloat(x); }; this.attrs_.axes.x.valueFormatter = function(x) { return x; }; - this.attrs_.axes.x.ticker = Dygraph.numericTicks; + this.attrs_.axes.x.ticker = Dygraph.numericLinearTicks; this.attrs_.axes.x.axisLabelFormatter = this.attrs_.axes.x.valueFormatter; } else { this.error("only 'date', 'datetime' and 'number' types are supported for " +