From 2cdd097b3aeaf54b146bb1daf6ce6bb5d226eb14 Mon Sep 17 00:00:00 2001 From: benrubson Date: Sat, 15 Oct 2016 11:43:36 +0200 Subject: [PATCH 1/9] Missing values, correct timeStep --- public/app/plugins/panel/graph/graph.ts | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/public/app/plugins/panel/graph/graph.ts b/public/app/plugins/panel/graph/graph.ts index 6a3e49b8455..40ecfd4dfb2 100755 --- a/public/app/plugins/panel/graph/graph.ts +++ b/public/app/plugins/panel/graph/graph.ts @@ -271,8 +271,14 @@ module.directive('grafanaGraph', function($rootScope, timeSrv) { break; } default: { - if (data.length && data[0].stats.timeStep) { - options.series.bars.barWidth = data[0].stats.timeStep / 1.5; + var width; + for (let i = 0; i < data.length; i++) { + if (data[i].stats.timeStep && (width == null || (data[i].stats.timeStep / 1.5) < width)) { + width = data[i].stats.timeStep / 1.5; + } + } + if (width) { + options.series.bars.barWidth = width; } addTimeAxis(options); break; From c976448f6a7d5c41178643ae9baa8ff9a0d051ca Mon Sep 17 00:00:00 2001 From: benrubson Date: Sat, 15 Oct 2016 13:07:41 +0200 Subject: [PATCH 2/9] Missing values, stack null & missing values --- .../app/plugins/panel/graph/graph_tooltip.js | 7 +- public/vendor/flot/jquery.flot.js | 29 +++--- public/vendor/flot/jquery.flot.stack.js | 98 +++++++------------ 3 files changed, 51 insertions(+), 83 deletions(-) diff --git a/public/app/plugins/panel/graph/graph_tooltip.js b/public/app/plugins/panel/graph/graph_tooltip.js index 5ae03ccf813..dc573f96a58 100644 --- a/public/app/plugins/panel/graph/graph_tooltip.js +++ b/public/app/plugins/panel/graph/graph_tooltip.js @@ -78,10 +78,9 @@ function ($, _) { } // Highlighting multiple Points depending on the plot type - if (series.lines.steps || series.stack) { - // stacked and steppedLine plots can have series with different length. - // Stacked series can increase its length on each new stacked serie if null points found, - // to speed the index search we begin always on the last found hoverIndex. + if (series.lines.steps) { + // steppedLine plots can have series with different length. + // To speed the index search we begin always on the last found hoverIndex. hoverIndex = this.findHoverIndexFromDataPoints(pos.x, series, hoverIndex); } diff --git a/public/vendor/flot/jquery.flot.js b/public/vendor/flot/jquery.flot.js index ec91314c49d..8433ee26435 100644 --- a/public/vendor/flot/jquery.flot.js +++ b/public/vendor/flot/jquery.flot.js @@ -1201,24 +1201,21 @@ Licensed under the MIT license. points[k + m] = null; } } - else { - // a little bit of line specific stuff that - // perhaps shouldn't be here, but lacking - // better means... - if (insertSteps && k > 0 - && points[k - ps] != null - && points[k - ps] != points[k] - && points[k - ps + 1] != points[k + 1]) { - // copy the point to make room for a middle point - for (m = 0; m < ps; ++m) - points[k + ps + m] = points[k + m]; - // middle point has same y - points[k + 1] = points[k - ps + 1]; + if (insertSteps && k > 0 && (!nullify || points[k-ps] != null)) { + // copy the point to make room for a middle point + for (m = 0; m < ps; ++m) + points[k + ps + m] = points[k + m]; - // we've added a point, better reflect that - k += ps; - } + // middle point has same y + points[k + 1] = points[k - ps + 1] || 0; + + // if series has null values, let's give the last correct value a nice step + if(nullify) + points[k] = p[0]; + + // we've added a point, better reflect that + k += ps; } } } diff --git a/public/vendor/flot/jquery.flot.stack.js b/public/vendor/flot/jquery.flot.stack.js index ffb412ca2a0..22e6954f053 100644 --- a/public/vendor/flot/jquery.flot.stack.js +++ b/public/vendor/flot/jquery.flot.stack.js @@ -78,41 +78,41 @@ charts or filled areas). i = 0, j = 0, l, m; while (true) { - if (i >= points.length) + if (i >= points.length && j >= otherpoints.length) break; l = newpoints.length; + px = points[i + keyOffset]; + py = points[i + accumulateOffset]; + qx = otherpoints[j + keyOffset]; + qy = otherpoints[j + accumulateOffset]; + bottom = 0; - if (points[i] == null) { - // copy gaps + if (i < points.length && px == null) { + // ignore point + i += ps; + } + else if (j < otherpoints.length && qx == null && qy == null) { + // ignore point + j += otherps; + } + else if (i >= points.length) { + // take the remaining points from the previous series + for (m = 0; m < ps; ++m) + newpoints.push(otherpoints[j + m]); + bottom = qy; + j += otherps; + } + else if (j >= otherpoints.length) { + // take the remaining points from the current series for (m = 0; m < ps; ++m) newpoints.push(points[i + m]); i += ps; } - else if (j >= otherpoints.length) { - // for lines, we can't use the rest of the points - if (!withlines) { - for (m = 0; m < ps; ++m) - newpoints.push(points[i + m]); - } - i += ps; - } - else if (otherpoints[j] == null) { - // oops, got a gap - for (m = 0; m < ps; ++m) - newpoints.push(null); - fromgap = true; - j += otherps; - } else { // cases where we actually got two points - px = points[i + keyOffset]; - py = points[i + accumulateOffset]; - qx = otherpoints[j + keyOffset]; - qy = otherpoints[j + accumulateOffset]; - bottom = 0; - - if (px == qx) { + if (px == qx || qx == null) { + // take the point from the current series and skip the previous' one for (m = 0; m < ps; ++m) newpoints.push(points[i + m]); @@ -123,54 +123,26 @@ charts or filled areas). j += otherps; } else if (px > qx) { - // we got past point below, might need to - // insert interpolated extra point - if (withlines && i > 0 && points[i - ps] != null) { - intery = py + (points[i - ps + accumulateOffset] - py) * (qx - px) / (points[i - ps + keyOffset] - px); - newpoints.push(qx); - newpoints.push(intery + qy); - for (m = 2; m < ps; ++m) - newpoints.push(points[i + m]); - bottom = qy; - } + // take the point from the previous series so that the next series can stack over it + for (m = 0; m < ps; ++m) + newpoints.push(otherpoints[j + m]); + + newpoints[l]=null; + bottom = qy; j += otherps; } else { // px < qx - if (fromgap && withlines) { - // if we come from a gap, we just skip this point - i += ps; - continue; - } - + // take the point from the current series for (m = 0; m < ps; ++m) newpoints.push(points[i + m]); - // we might be able to interpolate a point below, - // this can give us a better y - if (withlines && j > 0 && otherpoints[j - otherps] != null) - bottom = qy + (otherpoints[j - otherps + accumulateOffset] - qy) * (px - qx) / (otherpoints[j - otherps + keyOffset] - qx); - - newpoints[l + accumulateOffset] += bottom; - i += ps; } + } - fromgap = false; - - if (l != newpoints.length && withbottom) - newpoints[l + 2] += bottom; - } - - // maintain the line steps invariant - if (withsteps && l != newpoints.length && l > 0 - && newpoints[l] != null - && newpoints[l] != newpoints[l - ps] - && newpoints[l + 1] != newpoints[l - ps + 1]) { - for (m = 0; m < ps; ++m) - newpoints[l + ps + m] = newpoints[l + m]; - newpoints[l + 1] = newpoints[l - ps + 1]; - } + if (l != newpoints.length && withbottom) + newpoints[l + 2] = bottom; } datapoints.points = newpoints; From 43129aa563551e64e720ee93d200c28559a97340 Mon Sep 17 00:00:00 2001 From: benrubson Date: Sat, 15 Oct 2016 13:10:19 +0200 Subject: [PATCH 3/9] Missing values, correct graph specs --- public/app/plugins/panel/graph/specs/graph_specs.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/app/plugins/panel/graph/specs/graph_specs.ts b/public/app/plugins/panel/graph/specs/graph_specs.ts index 9f8d91ca9de..046409b77b2 100644 --- a/public/app/plugins/panel/graph/specs/graph_specs.ts +++ b/public/app/plugins/panel/graph/specs/graph_specs.ts @@ -135,7 +135,7 @@ describe('grafanaGraph', function() { }); it('should set barWidth', function() { - expect(ctx.plotOptions.series.bars.barWidth).to.be(10/1.5); + expect(ctx.plotOptions.series.bars.barWidth).to.be(1/1.5); }); }); From 8d5269dea754a8eeb84f2711ddc2f7fe2e4f4e9b Mon Sep 17 00:00:00 2001 From: benrubson Date: Sat, 15 Oct 2016 13:17:11 +0200 Subject: [PATCH 4/9] Typo --- public/vendor/flot/jquery.flot.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/vendor/flot/jquery.flot.js b/public/vendor/flot/jquery.flot.js index 8433ee26435..e0941bb24c0 100644 --- a/public/vendor/flot/jquery.flot.js +++ b/public/vendor/flot/jquery.flot.js @@ -1202,7 +1202,7 @@ Licensed under the MIT license. } } - if (insertSteps && k > 0 && (!nullify || points[k-ps] != null)) { + if (insertSteps && k > 0 && (!nullify || points[k - ps] != null)) { // copy the point to make room for a middle point for (m = 0; m < ps; ++m) points[k + ps + m] = points[k + m]; From 04a276dc2cc566ec02906070cb93b4d854881aec Mon Sep 17 00:00:00 2001 From: benrubson Date: Sat, 15 Oct 2016 16:51:18 +0200 Subject: [PATCH 5/9] Missing values, correctly highlight last point --- public/app/plugins/panel/graph/graph_tooltip.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/public/app/plugins/panel/graph/graph_tooltip.js b/public/app/plugins/panel/graph/graph_tooltip.js index dc573f96a58..b901c2c8ed6 100644 --- a/public/app/plugins/panel/graph/graph_tooltip.js +++ b/public/app/plugins/panel/graph/graph_tooltip.js @@ -17,7 +17,7 @@ function ($, _) { var initial = last*ps; var len = series.datapoints.points.length; for (var j = initial; j < len; j += ps) { - if (series.datapoints.points[j] > posX) { + if ((series.datapoints.points[initial] != null && series.datapoints.points[j] == null) || series.datapoints.points[j] > posX) { return Math.max(j - ps, 0)/ps; } } @@ -78,9 +78,10 @@ function ($, _) { } // Highlighting multiple Points depending on the plot type - if (series.lines.steps) { - // steppedLine plots can have series with different length. - // To speed the index search we begin always on the last found hoverIndex. + if (series.lines.steps || series.stack) { + // stacked and steppedLine plots can have series with different length. + // Stacked series can increase its length on each new stacked serie if null points found, + // to speed the index search we begin always on the last found hoverIndex. hoverIndex = this.findHoverIndexFromDataPoints(pos.x, series, hoverIndex); } From 07bf4c0b825aa1e109f48376c8c26032e3eeb9fa Mon Sep 17 00:00:00 2001 From: benrubson Date: Sun, 16 Oct 2016 00:29:15 +0200 Subject: [PATCH 6/9] Missing values, keep interpolation --- public/vendor/flot/jquery.flot.stack.js | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/public/vendor/flot/jquery.flot.stack.js b/public/vendor/flot/jquery.flot.stack.js index 22e6954f053..ba2a6b86a2f 100644 --- a/public/vendor/flot/jquery.flot.stack.js +++ b/public/vendor/flot/jquery.flot.stack.js @@ -92,7 +92,7 @@ charts or filled areas). // ignore point i += ps; } - else if (j < otherpoints.length && qx == null && qy == null) { + else if (j < otherpoints.length && qx == null) { // ignore point j += otherps; } @@ -111,7 +111,7 @@ charts or filled areas). } else { // cases where we actually got two points - if (px == qx || qx == null) { + if (px == qx) { // take the point from the current series and skip the previous' one for (m = 0; m < ps; ++m) newpoints.push(points[i + m]); @@ -127,7 +127,10 @@ charts or filled areas). for (m = 0; m < ps; ++m) newpoints.push(otherpoints[j + m]); - newpoints[l]=null; + // we might be able to interpolate + if (i > 0 && points[i - ps] != null) + newpoints[l + accumulateOffset] += py + (points[i - ps + accumulateOffset] - py) * (qx - px) / (points[i - ps + keyOffset] - px); + bottom = qy; j += otherps; @@ -137,6 +140,13 @@ charts or filled areas). for (m = 0; m < ps; ++m) newpoints.push(points[i + m]); + // we might be able to interpolate a point below, + // this can give us a better y + if (j > 0 && otherpoints[j - otherps] != null) + bottom = qy + (otherpoints[j - otherps + accumulateOffset] - qy) * (px - qx) / (otherpoints[j - otherps + keyOffset] - qx); + + newpoints[l + accumulateOffset] += bottom; + i += ps; } } From 604dcbc6b245a42260350da25a8b1694e8f505ef Mon Sep 17 00:00:00 2001 From: benrubson Date: Sun, 16 Oct 2016 00:30:50 +0200 Subject: [PATCH 7/9] Missing values, corect tooltip --- public/app/plugins/panel/graph/graph_tooltip.js | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/public/app/plugins/panel/graph/graph_tooltip.js b/public/app/plugins/panel/graph/graph_tooltip.js index b901c2c8ed6..6477a4a46a9 100644 --- a/public/app/plugins/panel/graph/graph_tooltip.js +++ b/public/app/plugins/panel/graph/graph_tooltip.js @@ -17,7 +17,7 @@ function ($, _) { var initial = last*ps; var len = series.datapoints.points.length; for (var j = initial; j < len; j += ps) { - if ((series.datapoints.points[initial] != null && series.datapoints.points[j] == null) || series.datapoints.points[j] > posX) { + if ((series.datapoints.points[initial] != null && series.datapoints.points[j] == null && ! series.lines.steps) || series.datapoints.points[j] > posX) { return Math.max(j - ps, 0)/ps; } } @@ -61,7 +61,7 @@ function ($, _) { } hoverIndex = this.findHoverIndexFromData(pos.x, series); - hoverDistance = Math.abs(pos.x - series.data[hoverIndex][0]); + hoverDistance = pos.x - series.data[hoverIndex][0]; pointTime = series.data[hoverIndex][0]; if (series.stack) { @@ -102,9 +102,6 @@ function ($, _) { }); } - // Find point which closer to pointer - results.time = _.min(results, 'distance').time; - return results; }; @@ -174,7 +171,7 @@ function ($, _) { continue; } - if (! distance || hoverInfo.distance < distance) { + if (! distance || (hoverInfo.distance >=0 && (hoverInfo.distance < distance || distance < 0)) || (hoverInfo.distance < 0 && hoverInfo.distance > distance)) { distance = hoverInfo.distance; time = hoverInfo.time; } From 9792bd7b08ed21ed8dc7c2de1a1e89684e24aabf Mon Sep 17 00:00:00 2001 From: benrubson Date: Sun, 16 Oct 2016 00:46:56 +0200 Subject: [PATCH 8/9] Typo --- public/app/plugins/panel/graph/graph_tooltip.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/public/app/plugins/panel/graph/graph_tooltip.js b/public/app/plugins/panel/graph/graph_tooltip.js index 6477a4a46a9..f777ba15402 100644 --- a/public/app/plugins/panel/graph/graph_tooltip.js +++ b/public/app/plugins/panel/graph/graph_tooltip.js @@ -2,7 +2,7 @@ define([ 'jquery', 'lodash' ], -function ($, _) { +function ($) { 'use strict'; function GraphTooltip(elem, dashboard, scope, getSeriesFn) { @@ -17,7 +17,8 @@ function ($, _) { var initial = last*ps; var len = series.datapoints.points.length; for (var j = initial; j < len; j += ps) { - if ((series.datapoints.points[initial] != null && series.datapoints.points[j] == null && ! series.lines.steps) || series.datapoints.points[j] > posX) { + if ((series.datapoints.points[initial] != null && series.datapoints.points[j] == null && ! series.lines.steps) + || series.datapoints.points[j] > posX) { return Math.max(j - ps, 0)/ps; } } @@ -171,7 +172,9 @@ function ($, _) { continue; } - if (! distance || (hoverInfo.distance >=0 && (hoverInfo.distance < distance || distance < 0)) || (hoverInfo.distance < 0 && hoverInfo.distance > distance)) { + if (! distance + || (hoverInfo.distance >=0 && (hoverInfo.distance < distance || distance < 0)) + || (hoverInfo.distance < 0 && hoverInfo.distance > distance)) { distance = hoverInfo.distance; time = hoverInfo.time; } From 807bc5eb473eb0cc8d079c36a8de3733b6829731 Mon Sep 17 00:00:00 2001 From: benrubson Date: Sun, 16 Oct 2016 01:09:00 +0200 Subject: [PATCH 9/9] Add time back to result array --- .../app/plugins/panel/graph/graph_tooltip.js | 24 +++++++++++-------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/public/app/plugins/panel/graph/graph_tooltip.js b/public/app/plugins/panel/graph/graph_tooltip.js index f777ba15402..f160c55663f 100644 --- a/public/app/plugins/panel/graph/graph_tooltip.js +++ b/public/app/plugins/panel/graph/graph_tooltip.js @@ -48,6 +48,8 @@ function ($) { //now we know the current X (j) position for X and Y values var last_value = 0; //needed for stacked values + var minDistance, minTime; + for (i = 0; i < seriesList.length; i++) { series = seriesList[i]; @@ -65,6 +67,13 @@ function ($) { hoverDistance = pos.x - series.data[hoverIndex][0]; pointTime = series.data[hoverIndex][0]; + if (! minDistance + || (hoverDistance >=0 && (hoverDistance < minDistance || minDistance < 0)) + || (hoverDistance < 0 && hoverDistance > minDistance)) { + minDistance = hoverDistance; + minTime = pointTime; + } + if (series.stack) { if (panel.tooltip.value_type === 'individual') { value = series.data[hoverIndex][1]; @@ -103,6 +112,9 @@ function ($) { }); } + // Find point which closer to pointer + results.time = minTime; + return results; }; @@ -147,6 +159,8 @@ function ($) { seriesHtml = ''; + absoluteTime = dashboard.formatDate(seriesHoverInfo.time, tooltipFormat); + // Dynamically reorder the hovercard for the current time point if the // option is enabled, sort by yaxis by default. if (panel.tooltip.sort === 2) { @@ -163,8 +177,6 @@ function ($) { }); } - var distance, time; - for (i = 0; i < seriesHoverInfo.length; i++) { hoverInfo = seriesHoverInfo[i]; @@ -172,13 +184,6 @@ function ($) { continue; } - if (! distance - || (hoverInfo.distance >=0 && (hoverInfo.distance < distance || distance < 0)) - || (hoverInfo.distance < 0 && hoverInfo.distance > distance)) { - distance = hoverInfo.distance; - time = hoverInfo.time; - } - var highlightClass = ''; if (item && i === item.seriesIndex) { highlightClass = 'graph-tooltip-list-item--highlight'; @@ -194,7 +199,6 @@ function ($) { plot.highlight(hoverInfo.index, hoverInfo.hoverIndex); } - absoluteTime = dashboard.formatDate(time, tooltipFormat); self.showTooltip(absoluteTime, seriesHtml, pos); } // single series tooltip