]> git.ipfire.org Git - thirdparty/Chart.js.git/commitdiff
Fix: Update/draw only visible -regression (#7808)
authorJukka Kurkela <jukka.kurkela@gmail.com>
Sun, 20 Sep 2020 20:46:55 +0000 (23:46 +0300)
committerGitHub <noreply@github.com>
Sun, 20 Sep 2020 20:46:55 +0000 (16:46 -0400)
src/controllers/controller.line.js

index e5dbc588335ec40d661ebdfb5241349773b9464b..669b602319f4387d8cbb16895de06dee0bdc761b 100644 (file)
@@ -1,6 +1,6 @@
 import DatasetController from '../core/core.datasetController';
 import {valueOrDefault} from '../helpers/helpers.core';
-import {isNumber} from '../helpers/helpers.math';
+import {isNumber, _limitValue} from '../helpers/helpers.math';
 import {resolve} from '../helpers/helpers.options';
 import {_lookupByKey} from '../helpers/helpers.collection';
 
@@ -15,11 +15,18 @@ export default class LineController extends DatasetController {
                const me = this;
                const meta = me._cachedMeta;
                const {dataset: line, data: points = []} = meta;
-               const {start, count} = getStartAndCountOfVisiblePoints(meta, points);
+               // @ts-ignore
+               const animationsDisabled = me.chart._animationsDisabled;
+               let {start, count} = getStartAndCountOfVisiblePoints(meta, points, animationsDisabled);
 
                me._drawStart = start;
                me._drawCount = count;
 
+               if (scaleRangesChanged(meta) && !animationsDisabled) {
+                       start = 0;
+                       count = points.length;
+               }
+
                // Update Line
                // In resize mode only point locations change, so no need to set the points or options.
                if (mode !== 'resize') {
@@ -171,7 +178,7 @@ LineController.defaults = {
        }
 };
 
-function getStartAndCountOfVisiblePoints(meta, points) {
+function getStartAndCountOfVisiblePoints(meta, points, animationsDisabled) {
        const pointCount = points.length;
 
        let start = 0;
@@ -179,10 +186,44 @@ function getStartAndCountOfVisiblePoints(meta, points) {
 
        if (meta._sorted) {
                const {iScale, _parsed} = meta;
+               const axis = iScale.axis;
                const {min, max, minDefined, maxDefined} = iScale.getUserBounds();
-               start = minDefined ? Math.max(0, _lookupByKey(_parsed, iScale.axis, min).lo) : 0;
-               count = (maxDefined ? Math.min(pointCount, _lookupByKey(_parsed, iScale.axis, max).hi + 1) : pointCount) - start;
+               if (minDefined) {
+                       start = _limitValue(Math.min(
+                               _lookupByKey(_parsed, iScale.axis, min).lo,
+                               animationsDisabled ? pointCount : _lookupByKey(points, axis, iScale.getPixelForValue(min)).lo),
+                       0, pointCount - 1);
+               }
+               if (maxDefined) {
+                       count = _limitValue(Math.max(
+                               _lookupByKey(_parsed, iScale.axis, max).hi + 1,
+                               animationsDisabled ? 0 : _lookupByKey(points, axis, iScale.getPixelForValue(max)).hi + 1),
+                       start, pointCount) - start;
+               } else {
+                       count = pointCount - start;
+               }
        }
 
        return {start, count};
 }
+
+function scaleRangesChanged(meta) {
+       const {xScale, yScale, _scaleRanges} = meta;
+       const newRanges = {
+               xmin: xScale.min,
+               xmax: xScale.max,
+               ymin: yScale.min,
+               ymax: yScale.max
+       };
+       if (!_scaleRanges) {
+               meta._scaleRanges = newRanges;
+               return true;
+       }
+       const changed = _scaleRanges.xmin !== xScale.min
+               || _scaleRanges.xmax !== xScale.max
+               || _scaleRanges.ymin !== yScale.min
+               || _scaleRanges.ymax !== yScale.max;
+
+       Object.assign(_scaleRanges, newRanges);
+       return changed;
+}