From 647f7496523a84b308b0218586663b9e4f71a021 Mon Sep 17 00:00:00 2001 From: Leon Sorokin Date: Wed, 27 Apr 2022 09:31:15 -0500 Subject: [PATCH] TimeSeries: properly stack series with missing datapoints (#48321) --- .../panel-graph/graph-ng-stacking2.json | 486 ++++++++++++++++- .../src/components/uPlot/utils.test.ts | 492 +++++++++++++++++- .../grafana-ui/src/components/uPlot/utils.ts | 34 +- 3 files changed, 1004 insertions(+), 8 deletions(-) diff --git a/devenv/dev-dashboards/panel-graph/graph-ng-stacking2.json b/devenv/dev-dashboards/panel-graph/graph-ng-stacking2.json index 410540966f0..60d9a661b9e 100644 --- a/devenv/dev-dashboards/panel-graph/graph-ng-stacking2.json +++ b/devenv/dev-dashboards/panel-graph/graph-ng-stacking2.json @@ -2512,7 +2512,7 @@ "axisPlacement": "auto", "barAlignment": 0, "drawStyle": "line", - "fillOpacity": 0, + "fillOpacity": 10, "gradientMode": "none", "hideFrom": { "legend": false, @@ -2648,7 +2648,7 @@ "axisPlacement": "auto", "barAlignment": 0, "drawStyle": "line", - "fillOpacity": 0, + "fillOpacity": 10, "gradientMode": "none", "hideFrom": { "legend": false, @@ -2784,7 +2784,7 @@ "axisPlacement": "auto", "barAlignment": 0, "drawStyle": "line", - "fillOpacity": 0, + "fillOpacity": 10, "gradientMode": "none", "hideFrom": { "legend": false, @@ -2904,6 +2904,484 @@ "title": "Connect null values = never", "transformations": [], "type": "timeseries" + }, + { + "datasource": { + "type": "testdata", + "uid": "PD8C576611E62080A" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "bars", + "fillOpacity": 100, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 0, + "pointSize": 4, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "normal" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 21, + "w": 12, + "x": 0, + "y": 44 + }, + "id": 36, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "targets": [ + { + "csvContent": "time,Label 1\n2021-12-20T05:09:05.832Z,1000", + "datasource": { + "type": "testdata", + "uid": "PD8C576611E62080A" + }, + "refId": "A", + "scenarioId": "csv_content" + }, + { + "csvContent": "time,Label 10\n2021-12-18T04:54:45.888Z,2500\n2021-12-20T05:09:05.832Z,600\n2021-12-22T05:23:25.776Z,350\n2022-01-03T06:49:25.440Z,500", + "datasource": { + "type": "testdata", + "uid": "PD8C576611E62080A" + }, + "refId": "B", + "scenarioId": "csv_content" + }, + { + "csvContent": "time,Label 11\n2021-12-18T04:54:45.888Z,28000\n2021-12-20T05:09:05.832Z,3100\n2021-12-22T05:23:25.776Z,36000\n2021-12-24T05:37:45.720Z,2800", + "datasource": { + "type": "testdata", + "uid": "PD8C576611E62080A" + }, + "refId": "C", + "scenarioId": "csv_content" + }, + { + "csvContent": "time,Label 12\n2021-12-20T05:09:05.832Z,255\n2021-12-24T05:37:45.720Z,651\n2021-12-26T05:52:05.664Z,50", + "datasource": { + "type": "testdata", + "uid": "PD8C576611E62080A" + }, + "refId": "D", + "scenarioId": "csv_content" + }, + { + "csvContent": "time,Label 13\n2021-12-18T04:54:45.888Z,5000\n2021-12-20T05:09:05.832Z,1231", + "datasource": { + "type": "testdata", + "uid": "PD8C576611E62080A" + }, + "refId": "E", + "scenarioId": "csv_content" + }, + { + "csvContent": "time,Label 14\n2021-12-14T04:26:06.000Z,122\n2021-12-16T04:40:25.944Z,123\n2021-12-18T04:54:45.888Z,12345\n2021-12-20T05:09:05.832Z,23456\n2021-12-22T05:23:25.776Z,34567\n2021-12-24T05:37:45.720Z,12345\n2021-12-26T05:52:05.664Z,8000\n2021-12-28T06:06:25.608Z,3000\n2021-12-30T06:20:45.552Z,1000\n2022-01-01T06:35:05.496Z,21", + "datasource": { + "type": "testdata", + "uid": "PD8C576611E62080A" + }, + "refId": "F", + "scenarioId": "csv_content" + }, + { + "csvContent": "time,Label 15\n2022-01-07T07:18:05.328Z,20", + "datasource": { + "type": "testdata", + "uid": "PD8C576611E62080A" + }, + "refId": "G", + "scenarioId": "csv_content" + }, + { + "csvContent": "time,Label 16\n2022-01-03T06:49:25.440Z,210\n2022-01-07T07:18:05.328Z,321", + "datasource": { + "type": "testdata", + "uid": "PD8C576611E62080A" + }, + "refId": "H", + "scenarioId": "csv_content" + }, + { + "csvContent": "time,Label 17\n2021-12-28T06:06:25.608Z,210\n2022-01-07T07:18:05.328Z,210", + "datasource": { + "type": "testdata", + "uid": "PD8C576611E62080A" + }, + "refId": "I", + "scenarioId": "csv_content" + }, + { + "csvContent": "time,Label 18\n2021-12-18T04:54:45.888Z,250\n2021-12-20T05:09:05.832Z,852\n2021-12-22T05:23:25.776Z,1234\n2021-12-26T05:52:05.664Z,321\n2021-12-30T06:20:45.552Z,432", + "datasource": { + "type": "testdata", + "uid": "PD8C576611E62080A" + }, + "refId": "J", + "scenarioId": "csv_content" + }, + { + "csvContent": "time,Label 2\n2021-12-24T05:37:45.720Z,543\n2021-12-26T05:52:05.664Z,18000\n2021-12-28T06:06:25.608Z,17000\n2021-12-30T06:20:45.552Z,12000\n2022-01-01T06:35:05.496Z,8500\n2022-01-03T06:49:25.440Z,8000\n2022-01-05T07:03:45.384Z,5000\n2022-01-07T07:18:05.328Z,3000\n2022-01-09T07:32:25.272Z,2500\n2022-01-11T07:46:45.216Z,2200\n2022-01-13T08:01:05.160Z,3000\n2022-01-15T08:15:25.104Z,1520\n2022-01-17T08:29:45.048Z,665.35", + "datasource": { + "type": "testdata", + "uid": "PD8C576611E62080A" + }, + "refId": "K", + "scenarioId": "csv_content" + }, + { + "csvContent": "time,Label 3\n2022-01-11T07:46:45.216Z,800", + "datasource": { + "type": "testdata", + "uid": "PD8C576611E62080A" + }, + "refId": "L", + "scenarioId": "csv_content" + }, + { + "csvContent": "time,Label 4\n2021-12-22T05:23:25.776Z,14173\n2021-12-24T05:37:45.720Z,14805\n2021-12-26T05:52:05.664Z,5600\n2021-12-28T06:06:25.608Z,5950\n2021-12-30T06:20:45.552Z,775\n2022-01-01T06:35:05.496Z,725\n2022-01-03T06:49:25.440Z,1450\n2022-01-05T07:03:45.384Z,3175\n2022-01-07T07:18:05.328Z,1850\n2022-01-09T07:32:25.272Z,1025\n2022-01-11T07:46:45.216Z,2700\n2022-01-13T08:01:05.160Z,4825\n2022-01-15T08:15:25.104Z,3600", + "datasource": { + "type": "testdata", + "uid": "PD8C576611E62080A" + }, + "refId": "M", + "scenarioId": "csv_content" + }, + { + "csvContent": "time,Label 5\n2022-01-15T08:15:25.104Z,1675", + "datasource": { + "type": "testdata", + "uid": "PD8C576611E62080A" + }, + "refId": "N", + "scenarioId": "csv_content" + }, + { + "csvContent": "time,Label 6\n2021-12-22T05:23:25.776Z,433.16", + "datasource": { + "type": "testdata", + "uid": "PD8C576611E62080A" + }, + "refId": "O", + "scenarioId": "csv_content" + }, + { + "csvContent": "time,Label 7\n2021-12-24T05:37:45.720Z,41250\n2021-12-26T05:52:05.664Z,45150\n2021-12-28T06:06:25.608Z,45870.16\n2021-12-30T06:20:45.552Z,38728.17\n2022-01-01T06:35:05.496Z,39931.77\n2022-01-03T06:49:25.440Z,39831.8\n2022-01-05T07:03:45.384Z,38252.06\n2022-01-07T07:18:05.328Z,44332.92\n2022-01-09T07:32:25.272Z,51359.74\n2022-01-11T07:46:45.216Z,56155.84\n2022-01-13T08:01:05.160Z,55676.92\n2022-01-15T08:15:25.104Z,55323.84\n2022-01-17T08:29:45.048Z,13830.96", + "datasource": { + "type": "testdata", + "uid": "PD8C576611E62080A" + }, + "refId": "P", + "scenarioId": "csv_content" + }, + { + "csvContent": "time,Label 8\n2021-12-30T06:20:45.552Z,52.89\n2022-01-01T06:35:05.496Z,569.57", + "datasource": { + "type": "testdata", + "uid": "PD8C576611E62080A" + }, + "refId": "Q", + "scenarioId": "csv_content" + }, + { + "csvContent": "time,Label 9\n2022-01-01T06:35:05.496Z,2140.34\n2022-01-03T06:49:25.440Z,4074.92\n2022-01-05T07:03:45.384Z,1557.85\n2022-01-07T07:18:05.328Z,1097.74\n2022-01-09T07:32:25.272Z,692.06\n2022-01-11T07:46:45.216Z,758.67\n2022-01-13T08:01:05.160Z,957.56\n2022-01-15T08:15:25.104Z,1470.49\n2022-01-17T08:29:45.048Z,198.18", + "datasource": { + "type": "testdata", + "uid": "PD8C576611E62080A" + }, + "refId": "R", + "scenarioId": "csv_content" + } + ], + "title": "'undefined' join artifacts (bars)", + "type": "timeseries" + }, + { + "datasource": { + "type": "testdata", + "uid": "PD8C576611E62080A" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 100, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 0, + "pointSize": 4, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "normal" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 21, + "w": 12, + "x": 12, + "y": 44 + }, + "id": 37, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "targets": [ + { + "csvContent": "time,Label 1\n2021-12-20T05:09:05.832Z,1000", + "datasource": { + "type": "testdata", + "uid": "PD8C576611E62080A" + }, + "refId": "A", + "scenarioId": "csv_content" + }, + { + "csvContent": "time,Label 10\n2021-12-18T04:54:45.888Z,2500\n2021-12-20T05:09:05.832Z,600\n2021-12-22T05:23:25.776Z,350\n2022-01-03T06:49:25.440Z,500", + "datasource": { + "type": "testdata", + "uid": "PD8C576611E62080A" + }, + "refId": "B", + "scenarioId": "csv_content" + }, + { + "csvContent": "time,Label 11\n2021-12-18T04:54:45.888Z,28000\n2021-12-20T05:09:05.832Z,3100\n2021-12-22T05:23:25.776Z,36000\n2021-12-24T05:37:45.720Z,2800", + "datasource": { + "type": "testdata", + "uid": "PD8C576611E62080A" + }, + "refId": "C", + "scenarioId": "csv_content" + }, + { + "csvContent": "time,Label 12\n2021-12-20T05:09:05.832Z,255\n2021-12-24T05:37:45.720Z,651\n2021-12-26T05:52:05.664Z,50", + "datasource": { + "type": "testdata", + "uid": "PD8C576611E62080A" + }, + "refId": "D", + "scenarioId": "csv_content" + }, + { + "csvContent": "time,Label 13\n2021-12-18T04:54:45.888Z,5000\n2021-12-20T05:09:05.832Z,1231", + "datasource": { + "type": "testdata", + "uid": "PD8C576611E62080A" + }, + "refId": "E", + "scenarioId": "csv_content" + }, + { + "csvContent": "time,Label 14\n2021-12-14T04:26:06.000Z,122\n2021-12-16T04:40:25.944Z,123\n2021-12-18T04:54:45.888Z,12345\n2021-12-20T05:09:05.832Z,23456\n2021-12-22T05:23:25.776Z,34567\n2021-12-24T05:37:45.720Z,12345\n2021-12-26T05:52:05.664Z,8000\n2021-12-28T06:06:25.608Z,3000\n2021-12-30T06:20:45.552Z,1000\n2022-01-01T06:35:05.496Z,21", + "datasource": { + "type": "testdata", + "uid": "PD8C576611E62080A" + }, + "refId": "F", + "scenarioId": "csv_content" + }, + { + "csvContent": "time,Label 15\n2022-01-07T07:18:05.328Z,20", + "datasource": { + "type": "testdata", + "uid": "PD8C576611E62080A" + }, + "refId": "G", + "scenarioId": "csv_content" + }, + { + "csvContent": "time,Label 16\n2022-01-03T06:49:25.440Z,210\n2022-01-07T07:18:05.328Z,321", + "datasource": { + "type": "testdata", + "uid": "PD8C576611E62080A" + }, + "refId": "H", + "scenarioId": "csv_content" + }, + { + "csvContent": "time,Label 17\n2021-12-28T06:06:25.608Z,210\n2022-01-07T07:18:05.328Z,210", + "datasource": { + "type": "testdata", + "uid": "PD8C576611E62080A" + }, + "refId": "I", + "scenarioId": "csv_content" + }, + { + "csvContent": "time,Label 18\n2021-12-18T04:54:45.888Z,250\n2021-12-20T05:09:05.832Z,852\n2021-12-22T05:23:25.776Z,1234\n2021-12-26T05:52:05.664Z,321\n2021-12-30T06:20:45.552Z,432", + "datasource": { + "type": "testdata", + "uid": "PD8C576611E62080A" + }, + "refId": "J", + "scenarioId": "csv_content" + }, + { + "csvContent": "time,Label 2\n2021-12-24T05:37:45.720Z,543\n2021-12-26T05:52:05.664Z,18000\n2021-12-28T06:06:25.608Z,17000\n2021-12-30T06:20:45.552Z,12000\n2022-01-01T06:35:05.496Z,8500\n2022-01-03T06:49:25.440Z,8000\n2022-01-05T07:03:45.384Z,5000\n2022-01-07T07:18:05.328Z,3000\n2022-01-09T07:32:25.272Z,2500\n2022-01-11T07:46:45.216Z,2200\n2022-01-13T08:01:05.160Z,3000\n2022-01-15T08:15:25.104Z,1520\n2022-01-17T08:29:45.048Z,665.35", + "datasource": { + "type": "testdata", + "uid": "PD8C576611E62080A" + }, + "refId": "K", + "scenarioId": "csv_content" + }, + { + "csvContent": "time,Label 3\n2022-01-11T07:46:45.216Z,800", + "datasource": { + "type": "testdata", + "uid": "PD8C576611E62080A" + }, + "refId": "L", + "scenarioId": "csv_content" + }, + { + "csvContent": "time,Label 4\n2021-12-22T05:23:25.776Z,14173\n2021-12-24T05:37:45.720Z,14805\n2021-12-26T05:52:05.664Z,5600\n2021-12-28T06:06:25.608Z,5950\n2021-12-30T06:20:45.552Z,775\n2022-01-01T06:35:05.496Z,725\n2022-01-03T06:49:25.440Z,1450\n2022-01-05T07:03:45.384Z,3175\n2022-01-07T07:18:05.328Z,1850\n2022-01-09T07:32:25.272Z,1025\n2022-01-11T07:46:45.216Z,2700\n2022-01-13T08:01:05.160Z,4825\n2022-01-15T08:15:25.104Z,3600", + "datasource": { + "type": "testdata", + "uid": "PD8C576611E62080A" + }, + "refId": "M", + "scenarioId": "csv_content" + }, + { + "csvContent": "time,Label 5\n2022-01-15T08:15:25.104Z,1675", + "datasource": { + "type": "testdata", + "uid": "PD8C576611E62080A" + }, + "refId": "N", + "scenarioId": "csv_content" + }, + { + "csvContent": "time,Label 6\n2021-12-22T05:23:25.776Z,433.16", + "datasource": { + "type": "testdata", + "uid": "PD8C576611E62080A" + }, + "refId": "O", + "scenarioId": "csv_content" + }, + { + "csvContent": "time,Label 7\n2021-12-24T05:37:45.720Z,41250\n2021-12-26T05:52:05.664Z,45150\n2021-12-28T06:06:25.608Z,45870.16\n2021-12-30T06:20:45.552Z,38728.17\n2022-01-01T06:35:05.496Z,39931.77\n2022-01-03T06:49:25.440Z,39831.8\n2022-01-05T07:03:45.384Z,38252.06\n2022-01-07T07:18:05.328Z,44332.92\n2022-01-09T07:32:25.272Z,51359.74\n2022-01-11T07:46:45.216Z,56155.84\n2022-01-13T08:01:05.160Z,55676.92\n2022-01-15T08:15:25.104Z,55323.84\n2022-01-17T08:29:45.048Z,13830.96", + "datasource": { + "type": "testdata", + "uid": "PD8C576611E62080A" + }, + "refId": "P", + "scenarioId": "csv_content" + }, + { + "csvContent": "time,Label 8\n2021-12-30T06:20:45.552Z,52.89\n2022-01-01T06:35:05.496Z,569.57", + "datasource": { + "type": "testdata", + "uid": "PD8C576611E62080A" + }, + "refId": "Q", + "scenarioId": "csv_content" + }, + { + "csvContent": "time,Label 9\n2022-01-01T06:35:05.496Z,2140.34\n2022-01-03T06:49:25.440Z,4074.92\n2022-01-05T07:03:45.384Z,1557.85\n2022-01-07T07:18:05.328Z,1097.74\n2022-01-09T07:32:25.272Z,692.06\n2022-01-11T07:46:45.216Z,758.67\n2022-01-13T08:01:05.160Z,957.56\n2022-01-15T08:15:25.104Z,1470.49\n2022-01-17T08:29:45.048Z,198.18", + "datasource": { + "type": "testdata", + "uid": "PD8C576611E62080A" + }, + "refId": "R", + "scenarioId": "csv_content" + } + ], + "title": "'undefined' join artifacts (lines)", + "type": "timeseries" } ], "refresh": false, @@ -2925,6 +3403,6 @@ "timezone": "", "title": "TimeSeries & BarChart Stacking", "uid": "1KxMUdE7k", - "version": 1, + "version": 5, "weekStart": "" } diff --git a/packages/grafana-ui/src/components/uPlot/utils.test.ts b/packages/grafana-ui/src/components/uPlot/utils.test.ts index 6075349a62d..56abf510014 100644 --- a/packages/grafana-ui/src/components/uPlot/utils.test.ts +++ b/packages/grafana-ui/src/components/uPlot/utils.test.ts @@ -1,8 +1,10 @@ import Units from 'ol/proj/Units'; -import { FieldType, MutableDataFrame } from '@grafana/data'; +import { FieldMatcherID, fieldMatchers, FieldType, MutableDataFrame } from '@grafana/data'; import { BarAlignment, GraphDrawStyle, GraphTransform, LineInterpolation, StackingMode } from '@grafana/schema'; +import { preparePlotFrame } from '../GraphNG/utils'; + import { getStackingGroups, preparePlotData2, timeFormatToTemplate } from './utils'; describe('timeFormatToTemplate', () => { @@ -511,6 +513,494 @@ describe('preparePlotData2', () => { `); }); }); + + it('accumulates stacks only at indices where stacking group has at least 1 value', () => { + // extracted data from plot in panel-graph/graph-ng-stacking2.json + const frameData = [ + [[1639976945832], [1000]], + [ + [1639803285888, 1639976945832, 1640150605776, 1641192565440], + [2500, 600, 350, 500], + ], + [ + [1639803285888, 1639976945832, 1640150605776, 1640324265720], + [28000, 3100, 36000, 2800], + ], + [ + [1639976945832, 1640324265720, 1640497925664], + [255, 651, 50], + ], + [ + [1639803285888, 1639976945832], + [5000, 1231], + ], + [ + [ + 1639455966000, 1639629625944, 1639803285888, 1639976945832, 1640150605776, 1640324265720, 1640497925664, + 1640671585608, 1640845245552, 1641018905496, + ], + [122, 123, 12345, 23456, 34567, 12345, 8000, 3000, 1000, 21], + ], + [[1641539885328], [20]], + [ + [1641192565440, 1641539885328], + [210, 321], + ], + [ + [1640671585608, 1641539885328], + [210, 210], + ], + [ + [1639803285888, 1639976945832, 1640150605776, 1640497925664, 1640845245552], + [250, 852, 1234, 321, 432], + ], + [ + [ + 1640324265720, 1640497925664, 1640671585608, 1640845245552, 1641018905496, 1641192565440, 1641366225384, + 1641539885328, 1641713545272, 1641887205216, 1642060865160, 1642234525104, 1642408185048, + ], + [543, 18000, 17000, 12000, 8500, 8000, 5000, 3000, 2500, 2200, 3000, 1520, 665.35], + ], + [[1641887205216], [800]], + [ + [ + 1640150605776, 1640324265720, 1640497925664, 1640671585608, 1640845245552, 1641018905496, 1641192565440, + 1641366225384, 1641539885328, 1641713545272, 1641887205216, 1642060865160, 1642234525104, + ], + [14173, 14805, 5600, 5950, 775, 725, 1450, 3175, 1850, 1025, 2700, 4825, 3600], + ], + [[1642234525104], [1675]], + [[1640150605776], [433.16]], + [ + [ + 1640324265720, 1640497925664, 1640671585608, 1640845245552, 1641018905496, 1641192565440, 1641366225384, + 1641539885328, 1641713545272, 1641887205216, 1642060865160, 1642234525104, 1642408185048, + ], + [ + 41250, 45150, 45870.16, 38728.17, 39931.77, 39831.8, 38252.06, 44332.92, 51359.74, 56155.84, 55676.92, + 55323.84, 13830.96, + ], + ], + [ + [1640845245552, 1641018905496], + [52.89, 569.57], + ], + [ + [ + 1641018905496, 1641192565440, 1641366225384, 1641539885328, 1641713545272, 1641887205216, 1642060865160, + 1642234525104, 1642408185048, + ], + [2140.34, 4074.92, 1557.85, 1097.74, 692.06, 758.67, 957.56, 1470.49, 198.18], + ], + ]; + + const names = 'abcdefghijklmnopqrstuvwxyz'.split('').reverse(); + + const dfs = frameData.map(([xs, ys]) => { + const df = new MutableDataFrame({ + fields: [ + { name: 'time', type: FieldType.time, values: xs }, + { + name: names.pop()!, + values: ys, + config: { custom: { stacking: { mode: StackingMode.Normal, group: 'A' } } }, + }, + ], + }); + + return df; + }); + + const df = preparePlotFrame(dfs, { + x: fieldMatchers.get(FieldMatcherID.firstTimeField).get({}), + y: fieldMatchers.get(FieldMatcherID.numeric).get({}), + })!; + + expect(preparePlotData2(df, getStackingGroups(df))).toMatchInlineSnapshot(` + Array [ + Array [ + 1639455966000, + 1639629625944, + 1639803285888, + 1639976945832, + 1640150605776, + 1640324265720, + 1640497925664, + 1640671585608, + 1640845245552, + 1641018905496, + 1641192565440, + 1641366225384, + 1641539885328, + 1641713545272, + 1641887205216, + 1642060865160, + 1642234525104, + 1642408185048, + ], + Array [ + 0, + 0, + 0, + 1000, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ], + Array [ + 0, + 0, + 2500, + 1600, + 350, + 0, + 0, + 0, + 0, + 0, + 500, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ], + Array [ + 0, + 0, + 30500, + 4700, + 36350, + 2800, + 0, + 0, + 0, + 0, + 500, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ], + Array [ + 0, + 0, + 30500, + 4955, + 36350, + 3451, + 50, + 0, + 0, + 0, + 500, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ], + Array [ + 0, + 0, + 35500, + 6186, + 36350, + 3451, + 50, + 0, + 0, + 0, + 500, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ], + Array [ + 122, + 123, + 47845, + 29642, + 70917, + 15796, + 8050, + 3000, + 1000, + 21, + 500, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ], + Array [ + 122, + 123, + 47845, + 29642, + 70917, + 15796, + 8050, + 3000, + 1000, + 21, + 500, + 0, + 20, + 0, + 0, + 0, + 0, + 0, + ], + Array [ + 122, + 123, + 47845, + 29642, + 70917, + 15796, + 8050, + 3000, + 1000, + 21, + 710, + 0, + 341, + 0, + 0, + 0, + 0, + 0, + ], + Array [ + 122, + 123, + 47845, + 29642, + 70917, + 15796, + 8050, + 3210, + 1000, + 21, + 710, + 0, + 551, + 0, + 0, + 0, + 0, + 0, + ], + Array [ + 122, + 123, + 48095, + 30494, + 72151, + 15796, + 8371, + 3210, + 1432, + 21, + 710, + 0, + 551, + 0, + 0, + 0, + 0, + 0, + ], + Array [ + 122, + 123, + 48095, + 30494, + 72151, + 16339, + 26371, + 20210, + 13432, + 8521, + 8710, + 5000, + 3551, + 2500, + 2200, + 3000, + 1520, + 665.35, + ], + Array [ + 122, + 123, + 48095, + 30494, + 72151, + 16339, + 26371, + 20210, + 13432, + 8521, + 8710, + 5000, + 3551, + 2500, + 3000, + 3000, + 1520, + 665.35, + ], + Array [ + 122, + 123, + 48095, + 30494, + 86324, + 31144, + 31971, + 26160, + 14207, + 9246, + 10160, + 8175, + 5401, + 3525, + 5700, + 7825, + 5120, + 665.35, + ], + Array [ + 122, + 123, + 48095, + 30494, + 86324, + 31144, + 31971, + 26160, + 14207, + 9246, + 10160, + 8175, + 5401, + 3525, + 5700, + 7825, + 6795, + 665.35, + ], + Array [ + 122, + 123, + 48095, + 30494, + 86757.16, + 31144, + 31971, + 26160, + 14207, + 9246, + 10160, + 8175, + 5401, + 3525, + 5700, + 7825, + 6795, + 665.35, + ], + Array [ + 122, + 123, + 48095, + 30494, + 86757.16, + 72394, + 77121, + 72030.16, + 52935.17, + 49177.77, + 49991.8, + 46427.06, + 49733.92, + 54884.74, + 61855.84, + 63501.92, + 62118.84, + 14496.31, + ], + Array [ + 122, + 123, + 48095, + 30494, + 86757.16, + 72394, + 77121, + 72030.16, + 52988.06, + 49747.34, + 49991.8, + 46427.06, + 49733.92, + 54884.74, + 61855.84, + 63501.92, + 62118.84, + 14496.31, + ], + Array [ + 122, + 123, + 48095, + 30494, + 86757.16, + 72394, + 77121, + 72030.16, + 52988.06, + 51887.67999999999, + 54066.72, + 47984.909999999996, + 50831.659999999996, + 55576.799999999996, + 62614.509999999995, + 64459.479999999996, + 63589.329999999994, + 14694.49, + ], + ] + `); + }); }); describe('auto stacking groups', () => { diff --git a/packages/grafana-ui/src/components/uPlot/utils.ts b/packages/grafana-ui/src/components/uPlot/utils.ts index 0e8923bb387..5e0254c7fee 100755 --- a/packages/grafana-ui/src/components/uPlot/utils.ts +++ b/packages/grafana-ui/src/components/uPlot/utils.ts @@ -164,9 +164,36 @@ export function preparePlotData2( ) { let data = Array(frame.fields.length) as AlignedData; + let stacksQty = stackingGroups.length; + let dataLen = frame.length; - let zeroArr = Array(dataLen).fill(0); - let accums = Array.from({ length: stackingGroups.length }, () => zeroArr.slice()); + let zeroArr = stacksQty > 0 ? Array(dataLen).fill(0) : []; + let falseArr = stacksQty > 0 ? Array(dataLen).fill(false) : []; + let accums = Array.from({ length: stacksQty }, () => zeroArr.slice()); + + let anyValsAtX = Array.from({ length: stacksQty }, () => falseArr.slice()); + + // figure out at which time indices each stacking group has any values + // (needed to avoid absorbing initial accum 0s at unrelated joined timestamps) + stackingGroups.forEach((group, groupIdx) => { + let groupValsAtX = anyValsAtX[groupIdx]; + + group.series.forEach((seriesIdx) => { + let field = frame.fields[seriesIdx]; + + if (field.config.custom?.hideFrom?.viz) { + return; + } + + let vals = field.values.toArray(); + + for (let i = 0; i < dataLen; i++) { + if (vals[i] != null) { + groupValsAtX[i] = true; + } + } + }); + }); frame.fields.forEach((field, i) => { let vals = field.values.toArray(); @@ -210,6 +237,7 @@ export function preparePlotData2( let stackIdx = stackingGroups.findIndex((group) => group.series.indexOf(i) > -1); let accum = accums[stackIdx]; + let groupValsAtX = anyValsAtX[stackIdx]; let stacked = (data[i] = Array(dataLen)); for (let i = 0; i < dataLen; i++) { @@ -218,7 +246,7 @@ export function preparePlotData2( if (v != null) { stacked[i] = accum[i] += v; } else { - stacked[i] = v; // we may want to coerce to 0 here + stacked[i] = groupValsAtX[i] ? accum[i] : v; } } }