]> git.ipfire.org Git - thirdparty/Chart.js.git/commitdiff
Store parsed data more similarly to provided data (#6814)
authorBen McCann <322311+benmccann@users.noreply.github.com>
Sun, 8 Dec 2019 13:52:11 +0000 (05:52 -0800)
committerEvert Timberg <evert.timberg+github@gmail.com>
Sun, 8 Dec 2019 13:52:11 +0000 (08:52 -0500)
* Store parsed data more similarly to provided data

* Add test

src/controllers/controller.doughnut.js
src/core/core.controller.js
src/core/core.datasetController.js
test/specs/core.datasetController.tests.js

index 2fcb7d272f94cf1889e2af1701419cd6d2a85c7b..ad5fa86ea8e74f6aebc8db5339266d303899f9a3 100644 (file)
@@ -140,10 +140,10 @@ module.exports = DatasetController.extend({
         */
        _parse: function(start, count) {
                var data = this.getDataset().data;
-               var metaData = this._cachedMeta.data;
+               var meta = this._cachedMeta;
                var i, ilen;
                for (i = start, ilen = start + count; i < ilen; ++i) {
-                       metaData[i]._parsed = +data[i];
+                       meta._parsed[i] = +data[i];
                }
        },
 
@@ -220,7 +220,6 @@ module.exports = DatasetController.extend({
                me.updateElements(arcs, 0, arcs.length, reset);
        },
 
-
        updateElements: function(arcs, start, count, reset) {
                const me = this;
                const chart = me.chart;
@@ -231,13 +230,14 @@ module.exports = DatasetController.extend({
                const centerY = (chartArea.top + chartArea.bottom) / 2;
                const startAngle = opts.rotation; // non reset case handled later
                const endAngle = opts.rotation; // non reset case handled later
+               const meta = me.getMeta();
                const innerRadius = reset && animationOpts.animateScale ? 0 : me.innerRadius;
                const outerRadius = reset && animationOpts.animateScale ? 0 : me.outerRadius;
-               var i;
+               let i;
 
                for (i = 0; i < start + count; ++i) {
                        const arc = arcs[i];
-                       const circumference = reset && animationOpts.animateRotate ? 0 : arc.hidden ? 0 : me.calculateCircumference(arc._parsed * opts.circumference / DOUBLE_PI);
+                       const circumference = reset && animationOpts.animateRotate ? 0 : arc.hidden ? 0 : me.calculateCircumference(meta._parsed[i] * opts.circumference / DOUBLE_PI);
                        const options = arc._options || {};
                        const model = {
                                // Desired view properties
@@ -272,16 +272,17 @@ module.exports = DatasetController.extend({
        },
 
        calculateTotal: function() {
-               var metaData = this._cachedMeta.data;
-               var total = 0;
-               var value;
-
-               helpers.each(metaData, function(arc) {
-                       value = arc ? arc._parsed : NaN;
-                       if (!isNaN(value) && !arc.hidden) {
+               const meta = this._cachedMeta;
+               const metaData = meta.data;
+               let total = 0;
+               let i;
+
+               for (i = 0; i < metaData.length; i++) {
+                       const value = meta._parsed[i];
+                       if (!isNaN(value) && !metaData[i].hidden) {
                                total += Math.abs(value);
                        }
-               });
+               }
 
                /* if (total === 0) {
                        total = NaN;
index 5fadf0fde1d2e365435ce20ac4d6553b5c8f7b99..d2977d12bb50e0606f829c30cbffe9513fc8243b 100644 (file)
@@ -850,7 +850,8 @@ helpers.extend(Chart.prototype, /** @lends Chart */ {
                                xAxisID: null,
                                yAxisID: null,
                                order: dataset.order || 0,
-                               index: datasetIndex
+                               index: datasetIndex,
+                               _parsed: []
                        };
                }
 
index a2a93b56a3f099c4695964dcdde91e8a726b766a..73658bb06b08352ec558a3582ffdedf6d06704ec 100644 (file)
@@ -478,18 +478,19 @@ helpers.extend(DatasetController.prototype, {
                let i, parsed;
 
                if (parsing === false) {
-                       parsed = data;
-                       offset = start;
-               } else if (helpers.isArray(data[start])) {
-                       parsed = me._parseArrayData(meta, data, start, count);
-               } else if (helpers.isObject(data[start])) {
-                       parsed = me._parseObjectData(meta, data, start, count);
+                       meta._parsed = data;
                } else {
-                       parsed = me._parsePrimitiveData(meta, data, start, count);
-               }
+                       if (helpers.isArray(data[start])) {
+                               parsed = me._parseArrayData(meta, data, start, count);
+                       } else if (helpers.isObject(data[start])) {
+                               parsed = me._parseObjectData(meta, data, start, count);
+                       } else {
+                               parsed = me._parsePrimitiveData(meta, data, start, count);
+                       }
 
-               for (i = 0; i < count; ++i) {
-                       meta.data[i + start]._parsed = parsed[i + offset];
+                       for (i = 0; i < count; ++i) {
+                               meta._parsed[i + start] = parsed[i + offset];
+                       }
                }
 
                if (_stacked) {
@@ -594,11 +595,11 @@ helpers.extend(DatasetController.prototype, {
         * @private
         */
        _getParsed: function(index) {
-               const data = this._cachedMeta.data;
+               const data = this._cachedMeta._parsed;
                if (index < 0 || index >= data.length) {
                        return;
                }
-               return data[index]._parsed;
+               return data[index];
        },
 
        /**
@@ -634,7 +635,7 @@ helpers.extend(DatasetController.prototype, {
 
                for (i = 0; i < ilen; ++i) {
                        item = metaData[i];
-                       parsed = item._parsed;
+                       parsed = meta._parsed[i];
                        value = parsed[scale.id];
                        otherValue = parsed[otherScale.id];
                        if (item.hidden || isNaN(value) ||
@@ -665,13 +666,12 @@ helpers.extend(DatasetController.prototype, {
         * @private
         */
        _getAllParsedValues: function(scale) {
-               const meta = this._cachedMeta;
-               const metaData = meta.data;
+               const parsed = this._cachedMeta._parsed;
                const values = [];
                let i, ilen, value;
 
-               for (i = 0, ilen = metaData.length; i < ilen; ++i) {
-                       value = metaData[i]._parsed[scale.id];
+               for (i = 0, ilen = parsed.length; i < ilen; ++i) {
+                       value = parsed[i][scale.id];
                        if (!isNaN(value)) {
                                values.push(value);
                        }
index c03f6de94902a7cb0f734888da39857dce8bf816..d80d16bd8d2fdfe4d9ddff8de8ad396ecd5b9dd4 100644 (file)
@@ -170,6 +170,65 @@ describe('Chart.DatasetController', function() {
                expect(meta.data[9]).toBe(last);
        });
 
+       it('should synchronize metadata when data are inserted or removed and parsing is off', function() {
+               var data = [{x: 0, y: 0}, {x: 1, y: 1}, {x: 2, y: 2}, {x: 3, y: 3}, {x: 4, y: 4}, {x: 5, y: 5}];
+               var chart = acquireChart({
+                       type: 'line',
+                       data: {
+                               datasets: [{
+                                       data: data
+                               }]
+                       },
+                       options: {
+                               parsing: false,
+                               scales: {
+                                       x: {type: 'linear'},
+                                       y: {type: 'linear'}
+                               }
+                       }
+               });
+
+               var meta = chart.getDatasetMeta(0);
+               var controller = meta.controller;
+               var first, last;
+
+               first = controller._getParsed(0);
+               last = controller._getParsed(5);
+               data.push({x: 6, y: 6}, {x: 7, y: 7}, {x: 8, y: 8});
+               data.push({x: 9, y: 9});
+               expect(meta.data.length).toBe(10);
+               expect(controller._getParsed(0)).toBe(first);
+               expect(controller._getParsed(5)).toBe(last);
+
+               last = controller._getParsed(9);
+               data.pop();
+               expect(meta.data.length).toBe(9);
+               expect(controller._getParsed(0)).toBe(first);
+               expect(controller._getParsed(9)).toBe(undefined);
+               expect(controller._getParsed(8)).toEqual({x: 8, y: 8});
+
+               last = controller._getParsed(8);
+               data.shift();
+               data.shift();
+               data.shift();
+               expect(meta.data.length).toBe(6);
+               expect(controller._getParsed(5)).toBe(last);
+
+               first = controller._getParsed(0);
+               last = controller._getParsed(5);
+               data.splice(1, 4, {x: 10, y: 10}, {x: 11, y: 11});
+               expect(meta.data.length).toBe(4);
+               expect(controller._getParsed(0)).toBe(first);
+               expect(controller._getParsed(3)).toBe(last);
+               expect(controller._getParsed(1)).toEqual({x: 10, y: 10});
+
+               data.unshift({x: 12, y: 12}, {x: 13, y: 13}, {x: 14, y: 14}, {x: 15, y: 15});
+               data.unshift({x: 16, y: 16}, {x: 17, y: 17});
+               expect(meta.data.length).toBe(10);
+               expect(controller._getParsed(6)).toBe(first);
+               expect(controller._getParsed(9)).toBe(last);
+       });
+
        it('should re-synchronize metadata when the data object reference changes', function() {
                var data0 = [0, 1, 2, 3, 4, 5];
                var data1 = [6, 7, 8];