Store parsed data more similarly to provided data (#6814)

* Store parsed data more similarly to provided data

* Add test
This commit is contained in:
Ben McCann 2019-12-08 05:52:11 -08:00 committed by Evert Timberg
parent c4483d1864
commit b7caa2410c
4 changed files with 91 additions and 30 deletions

View 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;
const meta = this._cachedMeta;
const metaData = meta.data;
let total = 0;
let i;
helpers.each(metaData, function(arc) {
value = arc ? arc._parsed : NaN;
if (!isNaN(value) && !arc.hidden) {
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;

View File

@ -850,7 +850,8 @@ helpers.extend(Chart.prototype, /** @lends Chart */ {
xAxisID: null,
yAxisID: null,
order: dataset.order || 0,
index: datasetIndex
index: datasetIndex,
_parsed: []
};
}

View 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);
}

View 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];