From 254159ad69584c2842edf1d54d8777a883303efa Mon Sep 17 00:00:00 2001 From: Leon Sorokin Date: Mon, 11 Jul 2022 12:45:42 -0500 Subject: [PATCH] BarChart: fix crash when checking bar value text overlap (#52061) --- public/app/plugins/panel/barchart/bars.ts | 36 +++++++++++++++++------ 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/public/app/plugins/panel/barchart/bars.ts b/public/app/plugins/panel/barchart/bars.ts index 032ae4df1b2..8074870c5f0 100644 --- a/public/app/plugins/panel/barchart/bars.ts +++ b/public/app/plugins/panel/barchart/bars.ts @@ -250,7 +250,7 @@ export function getConfig(opts: BarsOptions, theme: GrafanaTheme2) { let barsPctLayout: Array = []; let barsColors: Array; stroke: Array }> = []; let scaleFactor = 1; - let labels: ValueLabelTable = {}; + let labels: ValueLabelTable; let fontSize = opts.text?.valueSize ?? VALUE_MAX_FONT_SIZE; let labelOffset = LABEL_OFFSET_MAX; @@ -512,8 +512,12 @@ export function getConfig(opts: BarsOptions, theme: GrafanaTheme2) { curBaseline: CanvasTextBaseline | undefined = undefined; for (const didx in labels) { + // exclude first label from overlap testing + let first = true; + for (const sidx in labels[didx]) { - const { text, value, x = 0, y = 0, bbox = { x: 0, y: 0, w: 1, h: 1 } } = labels[didx][sidx]; + const label = labels[didx][sidx]; + const { text, value, x = 0, y = 0 } = label; let align: CanvasTextAlign = isXHorizontal ? 'center' : value !== null && value < 0 ? 'right' : 'left'; let baseline: CanvasTextBaseline = isXHorizontal @@ -533,19 +537,33 @@ export function getConfig(opts: BarsOptions, theme: GrafanaTheme2) { if (showValue === VisibilityMode.Always) { u.ctx.fillText(text, x, y); } else if (showValue === VisibilityMode.Auto) { + let { bbox } = label; + let intersectsLabel = false; - // Test for any collisions - for (const subsidx in labels[didx]) { - const r = labels[didx][subsidx].bbox!; + if (bbox == null) { + intersectsLabel = true; + label.hidden = true; + } else if (!first) { + // Test for any collisions + for (const subsidx in labels[didx]) { + if (subsidx === sidx) { + continue; + } - if (!labels[didx][subsidx].hidden && sidx !== subsidx && intersects(bbox, r)) { - intersectsLabel = true; - labels[didx][sidx].hidden = true; - break; + const label2 = labels[didx][subsidx]; + const { bbox: bbox2, hidden } = label2; + + if (!hidden && bbox2 && intersects(bbox, bbox2)) { + intersectsLabel = true; + label.hidden = true; + break; + } } } + first = false; + !intersectsLabel && u.ctx.fillText(text, x, y); } }