diff --git a/src/plugins/plugin.legend.js b/src/plugins/plugin.legend.js index 6ed99413536..9fb47f441ab 100644 --- a/src/plugins/plugin.legend.js +++ b/src/plugins/plugin.legend.js @@ -392,6 +392,7 @@ export class Legend extends Element { const lineHeight = itemHeight + padding; this.legendItems.forEach((legendItem, i) => { + const legendHitBox = this.legendHitBoxes[i]; ctx.strokeStyle = legendItem.fontColor; // for strikethrough effect ctx.fillStyle = legendItem.fontColor; // render in correct colour @@ -409,10 +410,17 @@ export class Legend extends Element { cursor.line++; x = cursor.x = _alignStartEnd(align, this.left + padding, this.right - lineWidths[cursor.line]); } - } else if (i > 0 && y + lineHeight > this.bottom) { - x = cursor.x = x + columnSizes[cursor.line].width + padding; - cursor.line++; - y = cursor.y = _alignStartEnd(align, this.top + titleHeight + padding, this.bottom - columnSizes[cursor.line].height); + } else if (i > 0 && legendHitBox && legendHitBox.col !== cursor.line) { + const previousColSize = columnSizes[cursor.line]; + const columnSize = columnSizes[legendHitBox.col]; + + if (!previousColSize || !columnSize) { + return; + } + + x = cursor.x = x + previousColSize.width + padding; + cursor.line = legendHitBox.col; + y = cursor.y = _alignStartEnd(align, this.top + titleHeight + padding, this.bottom - columnSize.height); } const realX = rtlHelper.x(x); diff --git a/test/specs/plugin.legend.tests.js b/test/specs/plugin.legend.tests.js index e0bed42c263..68cdd703891 100644 --- a/test/specs/plugin.legend.tests.js +++ b/test/specs/plugin.legend.tests.js @@ -956,6 +956,49 @@ describe('Legend block tests', function() { expect(chart.legend.options.title.color).toBe('green'); }); + it('should not crash when defaults font changes before a render', function() { + const defaultFont = Object.assign({}, Chart.defaults.font); + const labels = Array.from({length: 8}, (_, i) => `L${i}`); + const datasets = labels.map((_, i) => ({ + label: `dataset${i}`, + data: [i + 1] + })); + + const chart = acquireChart({ + type: 'bar', + data: { + labels: ['A'], + datasets + }, + options: { + responsive: false, + maintainAspectRatio: false, + plugins: { + legend: { + position: 'right' + } + } + } + }, { + canvas: { + width: 256, + height: 180 + } + }); + + try { + Object.assign(Chart.defaults.font, { + size: 42 + }); + + expect(function() { + chart.render(); + }).not.toThrow(); + } finally { + Object.assign(Chart.defaults.font, defaultFont); + } + }); + describe('config update', function() { it('should update the options', function() {