diff --git a/src/plugins/plugin.decimation.js b/src/plugins/plugin.decimation.js index 701d673c061..1deb0efd2e4 100644 --- a/src/plugins/plugin.decimation.js +++ b/src/plugins/plugin.decimation.js @@ -46,7 +46,7 @@ function lttbDecimation(data, start, count, availableWidth, options) { // Adding offset const rangeOffs = Math.floor(i * bucketWidth) + 1 + start; - const rangeTo = Math.floor((i + 1) * bucketWidth) + 1 + start; + const rangeTo = Math.min(Math.floor((i + 1) * bucketWidth) + 1, count) + start; const {x: pointAx, y: pointAy} = data[a]; // Note that this is changed from the original algorithm which initializes these diff --git a/test/specs/plugin.decimation.tests.js b/test/specs/plugin.decimation.tests.js index f9efbc29af7..9f8320b1e72 100644 --- a/test/specs/plugin.decimation.tests.js +++ b/test/specs/plugin.decimation.tests.js @@ -179,5 +179,41 @@ describe('Plugin.decimation', function() { expect(chart.data.datasets[0].data[3].x).toBe(originalData[5].x); expect(chart.data.datasets[0].data[4].x).toBe(originalData[6].x); }); + + it('should not crash with uneven points', function() { + const data = []; + for (let i = 0; i < 15552; i++) { + data.push({x: i, y: i}); + } + + function createChart() { + return window.acquireChart({ + type: 'line', + data: { + datasets: [{ + data + }] + }, + options: { + devicePixelRatio: 1.25, + parsing: false, + scales: { + x: { + type: 'linear' + } + }, + plugins: { + decimation: { + enabled: true, + algorithm: 'lttb' + } + } + } + }, { + canvas: {width: 511, height: 511}, + }); + } + expect(createChart).not.toThrow(); + }); }); });