From: Dan Onoshko Date: Sat, 24 Sep 2022 21:01:47 +0000 (+0700) Subject: fix: calc visible points on update (#10667) X-Git-Tag: v4.0.0~22 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=22f32af1bc497d1dd848b60a5d12bbff79265431;p=thirdparty%2FChart.js.git fix: calc visible points on update (#10667) --- diff --git a/src/controllers/controller.line.js b/src/controllers/controller.line.js index de391c3a7..18f0aa847 100644 --- a/src/controllers/controller.line.js +++ b/src/controllers/controller.line.js @@ -82,12 +82,20 @@ export default class LineController extends DatasetController { const {spanGaps, segment} = this.options; const maxGapLength = isNumber(spanGaps) ? spanGaps : Number.POSITIVE_INFINITY; const directUpdate = this.chart._animationsDisabled || reset || mode === 'none'; + const end = start + count; + const pointsCount = points.length; let prevParsed = start > 0 && this.getParsed(start - 1); - for (let i = start; i < start + count; ++i) { + for (let i = 0; i < pointsCount; ++i) { const point = points[i]; - const parsed = this.getParsed(i); const properties = directUpdate ? point : {}; + + if (i < start || i >= end) { + properties.skip = true; + continue; + } + + const parsed = this.getParsed(i); const nullData = isNullOrUndef(parsed[vAxis]); const iPixel = properties[iAxis] = iScale.getPixelForValue(parsed[iAxis], i); const vPixel = properties[vAxis] = reset || nullData ? vScale.getBasePixel() : vScale.getPixelForValue(_stacked ? this.applyStack(vScale, parsed, _stacked) : parsed[vAxis], i); diff --git a/src/helpers/helpers.collection.js b/src/helpers/helpers.collection.js index 5b2369808..8e77b06aa 100644 --- a/src/helpers/helpers.collection.js +++ b/src/helpers/helpers.collection.js @@ -35,7 +35,10 @@ export function _lookup(table, value, cmp) { */ export const _lookupByKey = (table, key, value, last) => _lookup(table, value, last - ? index => table[index][key] <= value + ? index => { + const ti = table[index][key]; + return ti < value || ti === value && table[index + 1][key] === value; + } : index => table[index][key] < value); /** diff --git a/test/specs/controller.line.tests.js b/test/specs/controller.line.tests.js index 2a758f649..368627d68 100644 --- a/test/specs/controller.line.tests.js +++ b/test/specs/controller.line.tests.js @@ -1051,6 +1051,9 @@ describe('Chart.controllers.line', function() { {x: 50, y: 9}, {x: 50, y: 9}, {x: 50, y: 9}, + {x: 51, y: 9}, + {x: 52, y: 9}, + {x: 52, y: 9}, ]; chart.update(); @@ -1062,6 +1065,10 @@ describe('Chart.controllers.line', function() { }; chart._handleEvent(event, false, true); + + const visiblePoints = chart.getSortedVisibleDatasetMetas()[0].data.filter(_ => !_.skip); + + expect(visiblePoints.length).toBe(6); }, 500); it('should not override tooltip title and label callbacks', async() => { diff --git a/test/specs/helpers.collection.tests.js b/test/specs/helpers.collection.tests.js index f6a1cbae5..432bfb542 100644 --- a/test/specs/helpers.collection.tests.js +++ b/test/specs/helpers.collection.tests.js @@ -19,6 +19,16 @@ describe('helpers.collection', function() { expect(_lookupByKey(data, 'x', 9)).toEqual({lo: 2, hi: 3}); }); + it('Should do binary search by key with last', () => { + expect(_lookupByKey([{x: 0}, {x: 2}, {x: 6}, {x: 9}], 'x', 25, true)).toEqual({lo: 2, hi: 3}); + expect(_lookupByKey([{x: 0}, {x: 2}, {x: 9}, {x: 9}], 'x', 25, true)).toEqual({lo: 2, hi: 3}); + expect(_lookupByKey([{x: 0}, {x: 2}, {x: 9}, {x: 9}, {x: 22}], 'x', 25, true)).toEqual({lo: 3, hi: 4}); + expect(_lookupByKey([{x: 0}, {x: 2}, {x: 25}, {x: 28}], 'x', 25, true)).toEqual({lo: 1, hi: 2}); + expect(_lookupByKey([{x: 0}, {x: 2}, {x: 25}, {x: 25}], 'x', 25, true)).toEqual({lo: 2, hi: 3}); + expect(_lookupByKey([{x: 0}, {x: 2}, {x: 25}, {x: 25}, {x: 28}], 'x', 25, true)).toEqual({lo: 2, hi: 3}); + expect(_lookupByKey([{x: 0}, {x: 2}, {x: 25}, {x: 25}, {x: 25}, {x: 28}, {x: 29}], 'x', 25, true)).toEqual({lo: 3, hi: 4}); + }); + it('Should do reverse binary search by key', function() { const data = [{x: 10}, {x: 7}, {x: 3}, {x: 0}]; expect(_rlookupByKey(data, 'x', 0)).toEqual({lo: 2, hi: 3});