]> git.ipfire.org Git - thirdparty/Chart.js.git/commitdiff
Detect data modifications with equal values (#7350)
authorJukka Kurkela <jukka.kurkela@gmail.com>
Tue, 19 May 2020 21:58:53 +0000 (00:58 +0300)
committerGitHub <noreply@github.com>
Tue, 19 May 2020 21:58:53 +0000 (17:58 -0400)
Fix data shift-push with identical values

src/core/core.datasetController.js
test/specs/core.datasetController.tests.js

index 110a6ca354e4667b78e9ca1aa4dd3a03b982f165..371c8436063f5ebbb66ee795664b00964eac9342 100644 (file)
@@ -235,6 +235,7 @@ export default class DatasetController {
                this._parsing = false;
                this._data = undefined;
                this._dataCopy = undefined;
+               this._dataModified = false;
                this._objectData = undefined;
                this._labels = undefined;
                this._scaleStacked = {};
@@ -359,7 +360,7 @@ export default class DatasetController {
                        me._data = convertObjectDataToArray(data);
                        me._objectData = data;
                } else {
-                       if (me._data === data && helpers.arrayEquals(data, me._dataCopy)) {
+                       if (me._data === data && !me._dataModified && helpers.arrayEquals(data, me._dataCopy)) {
                                return false;
                        }
 
@@ -372,6 +373,8 @@ export default class DatasetController {
                        // Note: This is suboptimal, but better than always parsing the data
                        me._dataCopy = data.slice(0);
 
+                       me._dataModified = false;
+
                        if (data && Object.isExtensible(data)) {
                                listenArrayEvents(data, me);
                        }
@@ -1111,6 +1114,7 @@ export default class DatasetController {
        _onDataPush() {
                const count = arguments.length;
                this._insertElements(this.getDataset().data.length - count, count);
+               this._dataModified = true;
        }
 
        /**
@@ -1118,6 +1122,7 @@ export default class DatasetController {
         */
        _onDataPop() {
                this._removeElements(this._cachedMeta.data.length - 1, 1);
+               this._dataModified = true;
        }
 
        /**
@@ -1125,6 +1130,7 @@ export default class DatasetController {
         */
        _onDataShift() {
                this._removeElements(0, 1);
+               this._dataModified = true;
        }
 
        /**
@@ -1133,6 +1139,7 @@ export default class DatasetController {
        _onDataSplice(start, count) {
                this._removeElements(start, count);
                this._insertElements(start, arguments.length - 2);
+               this._dataModified = true;
        }
 
        /**
@@ -1140,6 +1147,7 @@ export default class DatasetController {
         */
        _onDataUnshift() {
                this._insertElements(0, arguments.length);
+               this._dataModified = true;
        }
 }
 
index d2bd407d5d3e181d197a0af475742766218f4236..4c21f1a0a9627b54fd6ea0058adcf32f20c8a574 100644 (file)
@@ -343,6 +343,32 @@ describe('Chart.DatasetController', function() {
                expect(meta.data.length).toBe(42);
        });
 
+       // https://github.com/chartjs/Chart.js/issues/7243
+       it('should re-synchronize metadata when data is moved and values are equal', function() {
+               var data = [10, 10, 10, 10, 10, 10];
+               var chart = acquireChart({
+                       type: 'line',
+                       data: {
+                               labels: ['a', 'b', 'c', 'd', 'e', 'f'],
+                               datasets: [{
+                                       data,
+                                       fill: true
+                               }]
+                       }
+               });
+
+               var meta = chart.getDatasetMeta(0);
+
+               expect(meta.data.length).toBe(6);
+               const firstX = meta.data[0].x;
+
+               data.push(data.shift());
+               chart.update();
+
+               expect(meta.data.length).toBe(6);
+               expect(meta.data[0].x).toEqual(firstX);
+       });
+
        it('should re-synchronize metadata when scaleID changes', function() {
                var chart = acquireChart({
                        type: 'line',