BarChart: fix crash when checking bar value text overlap (#52061)

pull/52115/head
Leon Sorokin 3 years ago committed by GitHub
parent 28dd413c1d
commit 254159ad69
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 38
      public/app/plugins/panel/barchart/bars.ts

@ -250,7 +250,7 @@ export function getConfig(opts: BarsOptions, theme: GrafanaTheme2) {
let barsPctLayout: Array<null | { offs: number[]; size: number[] }> = [];
let barsColors: Array<null | { fill: Array<string | null>; stroke: Array<string | null> }> = [];
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 intersectsLabel = false;
let { bbox } = label;
// Test for any collisions
for (const subsidx in labels[didx]) {
const r = labels[didx][subsidx].bbox!;
let intersectsLabel = false;
if (!labels[didx][subsidx].hidden && sidx !== subsidx && intersects(bbox, r)) {
intersectsLabel = true;
labels[didx][sidx].hidden = true;
break;
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;
}
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);
}
}

Loading…
Cancel
Save