From daf0e3cb4ebfc78221aff906d86ea9040dc2db5a Mon Sep 17 00:00:00 2001 From: Dominik Prokop Date: Tue, 28 Jun 2022 16:21:18 +0200 Subject: [PATCH] Bar chart: Fix stacking bug when data produces 0 accumulators (#51450) * Don't divide by 0 ... * Add test panel to gdev dashboard --- .betterer.results | 16 ++-- .../panel-graph/graph-ng-stacking2.json | 86 ++++++++++++++++++- .../grafana-ui/src/components/uPlot/utils.ts | 2 +- public/app/plugins/panel/barchart/bars.ts | 13 ++- 4 files changed, 103 insertions(+), 14 deletions(-) diff --git a/.betterer.results b/.betterer.results index e4534e05a0b..751df3a8192 100644 --- a/.betterer.results +++ b/.betterer.results @@ -2328,7 +2328,7 @@ exports[`better eslint`] = { "packages/grafana-ui/src/components/uPlot/types.ts:1918909040": [ [16, 26, 3, "Unexpected any. Specify a different type.", "193409811"] ], - "packages/grafana-ui/src/components/uPlot/utils.ts:1200596632": [ + "packages/grafana-ui/src/components/uPlot/utils.ts:1283022966": [ [70, 13, 20, "Do not use any type assertions.", "1571376654"], [131, 20, 34, "Do not use any type assertions.", "1148863494"], [134, 11, 35, "Do not use any type assertions.", "2376372234"], @@ -10875,15 +10875,15 @@ exports[`better eslint`] = { "public/app/plugins/panel/barchart/TickSpacingEditor.tsx:335508426": [ [28, 69, 3, "Unexpected any. Specify a different type.", "193409811"] ], - "public/app/plugins/panel/barchart/bars.ts:4025264055": [ + "public/app/plugins/panel/barchart/bars.ts:3843272290": [ [51, 58, 3, "Unexpected any. Specify a different type.", "193409811"], [53, 42, 3, "Unexpected any. Specify a different type.", "193409811"], - [409, 7, 17, "Do not use any type assertions.", "3632921021"], - [464, 23, 11, "Do not use any type assertions.", "319541530"], - [464, 31, 3, "Unexpected any. Specify a different type.", "193409811"], - [466, 23, 11, "Do not use any type assertions.", "319541530"], - [466, 31, 3, "Unexpected any. Specify a different type.", "193409811"], - [474, 22, 33, "Do not use any type assertions.", "3146060940"] + [414, 7, 17, "Do not use any type assertions.", "3632921021"], + [469, 23, 11, "Do not use any type assertions.", "319541530"], + [469, 31, 3, "Unexpected any. Specify a different type.", "193409811"], + [471, 23, 11, "Do not use any type assertions.", "319541530"], + [471, 31, 3, "Unexpected any. Specify a different type.", "193409811"], + [479, 22, 33, "Do not use any type assertions.", "3146060940"] ], "public/app/plugins/panel/barchart/module.tsx:780565076": [ [70, 95, 9, "Do not use any type assertions.", "3692209159"], diff --git a/devenv/dev-dashboards/panel-graph/graph-ng-stacking2.json b/devenv/dev-dashboards/panel-graph/graph-ng-stacking2.json index 60d9a661b9e..85593916d32 100644 --- a/devenv/dev-dashboards/panel-graph/graph-ng-stacking2.json +++ b/devenv/dev-dashboards/panel-graph/graph-ng-stacking2.json @@ -3382,6 +3382,90 @@ ], "title": "'undefined' join artifacts (lines)", "type": "timeseries" + }, + { + "datasource": { + "type": "testdata", + "uid": "PD8C576611E62080A" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "axisSoftMin": 0, + "fillOpacity": 80, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineWidth": 1, + "scaleDistribution": { + "type": "linear" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 65 + }, + "id": 39, + "options": { + "barRadius": 0, + "barWidth": 0.97, + "groupWidth": 0.7, + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom" + }, + "orientation": "auto", + "showValue": "auto", + "stacking": "percent", + "tooltip": { + "mode": "single", + "sort": "none" + }, + "xTickLabelRotation": 0, + "xTickLabelSpacing": 0 + }, + "pluginVersion": "9.1.0-pre", + "targets": [ + { + "csvContent": "name, number, number2, number3, number4\nName1, 40, 5, 20, 10\nName2, 0,0,0,0\nName3, 6, 3, 5, 1\nName4, 1, 1, 1, 2", + "datasource": { + "type": "testdata", + "uid": "PD8C576611E62080A" + }, + "refId": "A", + "scenarioId": "csv_content" + } + ], + "title": "Bar chart stack with 0 only series", + "type": "barchart" } ], "refresh": false, @@ -3405,4 +3489,4 @@ "uid": "1KxMUdE7k", "version": 5, "weekStart": "" -} +} \ No newline at end of file diff --git a/packages/grafana-ui/src/components/uPlot/utils.ts b/packages/grafana-ui/src/components/uPlot/utils.ts index 0b8e86fbed9..6684d0e4952 100644 --- a/packages/grafana-ui/src/components/uPlot/utils.ts +++ b/packages/grafana-ui/src/components/uPlot/utils.ts @@ -286,7 +286,7 @@ export function preparePlotData2( if (v != null) { // v / accum will always be pos, so properly (re)sign by group stacking dir - stacked[i] = group.dir * (v / accum[i]); + stacked[i] = accum[i] === 0 ? 0 : group.dir * (v / accum[i]); } } } diff --git a/public/app/plugins/panel/barchart/bars.ts b/public/app/plugins/panel/barchart/bars.ts index 65e17fbe0eb..032ae4df1b2 100644 --- a/public/app/plugins/panel/barchart/bars.ts +++ b/public/app/plugins/panel/barchart/bars.ts @@ -307,11 +307,16 @@ export function getConfig(opts: BarsOptions, theme: GrafanaTheme2) { qt.add(barRect); if (showValue !== VisibilityMode.Never) { + const raw = rawValue(seriesIdx, dataIdx)!; + let divider = 1; + + if (pctStacked && alignedTotals![seriesIdx][dataIdx]!) { + divider = alignedTotals![seriesIdx][dataIdx]!; + } + + const v = divider === 0 ? 0 : raw / divider; // Format Values and calculate label offsets - const text = formatValue( - seriesIdx, - rawValue(seriesIdx, dataIdx)! / (pctStacked ? alignedTotals![seriesIdx][dataIdx]! : 1) - ); + const text = formatValue(seriesIdx, v); labelOffset = Math.min(labelOffset, Math.round(LABEL_OFFSET_FACTOR * (isXHorizontal ? wid : hgt))); if (labels[dataIdx] === undefined) {