Delay data to elements synchronization to update (#9105)

This commit is contained in:
Jukka Kurkela
2021-05-15 15:22:15 +03:00
committed by GitHub
parent e344c75eb8
commit d1a243efec
2 changed files with 50 additions and 17 deletions

View File

@@ -228,6 +228,7 @@ export default class DatasetController {
this._drawCount = undefined;
this.enableOptionSharing = false;
this.$context = undefined;
this._syncList = [];
this.initialize();
}
@@ -242,6 +243,9 @@ export default class DatasetController {
}
updateIndex(datasetIndex) {
if (this.index !== datasetIndex) {
clearStacks(this._cachedMeta);
}
this.index = datasetIndex;
}
@@ -316,6 +320,7 @@ export default class DatasetController {
const me = this;
const dataset = me.getDataset();
const data = dataset.data || (dataset.data = []);
const _data = me._data;
// In order to correctly handle data addition/deletion animation (an thus simulate
// real-time charts), we need to monitor these data modifications and synchronize
@@ -323,14 +328,19 @@ export default class DatasetController {
if (isObject(data)) {
me._data = convertObjectDataToArray(data);
} else if (me._data !== data) {
if (me._data) {
} else if (_data !== data) {
if (_data) {
// This case happens when the user replaced the data array instance.
unlistenArrayEvents(me._data, me);
clearStacks(me._cachedMeta);
unlistenArrayEvents(_data, me);
// Discard old elements, parsed data and stacks
const meta = me._cachedMeta;
clearStacks(meta);
meta._parsed = [];
meta.data = [];
}
if (data && Object.isExtensible(data)) {
listenArrayEvents(data, me);
me._syncList = [];
}
me._data = data;
}
@@ -356,6 +366,7 @@ export default class DatasetController {
me._dataCheck();
// make sure cached _stacked status is current
const oldStacked = meta._stacked;
meta._stacked = isStacked(meta.vScale, meta);
// detect change in stack option
@@ -371,7 +382,7 @@ export default class DatasetController {
me._resyncElements(resetNewElements);
// if stack changed, update stack values for the whole dataset
if (stackChanged) {
if (stackChanged || oldStacked !== meta._stacked) {
updateStacks(me, meta._parsed);
}
}
@@ -905,17 +916,28 @@ export default class DatasetController {
*/
_resyncElements(resetNewElements) {
const me = this;
const numMeta = me._cachedMeta.data.length;
const numData = me._data.length;
const data = me._data;
const elements = me._cachedMeta.data;
// Apply changes detected through array listeners
for (const [method, arg1, arg2] of me._syncList) {
me[method](arg1, arg2);
}
me._syncList = [];
const numMeta = elements.length;
const numData = data.length;
const count = Math.min(numData, numMeta);
if (numData > numMeta) {
me._insertElements(numMeta, numData - numMeta, resetNewElements);
} else if (numData < numMeta) {
me._removeElements(numData, numMeta - numData);
}
// Re-parse the old elements (new elements are parsed in _insertElements)
const count = Math.min(numData, numMeta);
if (count) {
} else if (count) {
// TODO: It is not optimal to always parse the old data
// This is done because we are not detecting direct assignments:
// chart.data.datasets[0].data[5] = 10;
// chart.data.datasets[0].data[5].y = 10;
me.parse(0, count);
}
}
@@ -975,36 +997,36 @@ export default class DatasetController {
*/
_onDataPush() {
const count = arguments.length;
this._insertElements(this.getDataset().data.length - count, count);
this._syncList.push(['_insertElements', this.getDataset().data.length - count, count]);
}
/**
* @private
*/
_onDataPop() {
this._removeElements(this._cachedMeta.data.length - 1, 1);
this._syncList.push(['_removeElements', this._cachedMeta.data.length - 1, 1]);
}
/**
* @private
*/
_onDataShift() {
this._removeElements(0, 1);
this._syncList.push(['_removeElements', 0, 1]);
}
/**
* @private
*/
_onDataSplice(start, count) {
this._removeElements(start, count);
this._insertElements(start, arguments.length - 2);
this._syncList.push(['_removeElements', start, count]);
this._syncList.push(['_insertElements', start, arguments.length - 2]);
}
/**
* @private
*/
_onDataUnshift() {
this._insertElements(0, arguments.length);
this._syncList.push(['_insertElements', 0, arguments.length]);
}
}

View File

@@ -268,6 +268,7 @@ describe('Chart.DatasetController', function() {
last = meta.data[5];
data.push(6, 7, 8);
data.push(9);
chart.update();
expect(meta.data.length).toBe(10);
expect(meta.data[0]).toBe(first);
expect(meta.data[5]).toBe(last);
@@ -275,6 +276,7 @@ describe('Chart.DatasetController', function() {
last = meta.data[9];
data.pop();
chart.update();
expect(meta.data.length).toBe(9);
expect(meta.data[0]).toBe(first);
expect(meta.data.indexOf(last)).toBe(-1);
@@ -284,6 +286,7 @@ describe('Chart.DatasetController', function() {
data.shift();
data.shift();
data.shift();
chart.update();
expect(meta.data.length).toBe(6);
expect(meta.data.indexOf(first)).toBe(-1);
expect(meta.data[5]).toBe(last);
@@ -293,6 +296,7 @@ describe('Chart.DatasetController', function() {
second = meta.data[1];
last = meta.data[5];
data.splice(1, 4, 10, 11);
chart.update();
expect(meta.data.length).toBe(4);
expect(meta.data[0]).toBe(first);
expect(meta.data[3]).toBe(last);
@@ -301,6 +305,7 @@ describe('Chart.DatasetController', function() {
data.unshift(12, 13, 14, 15);
data.unshift(16, 17);
chart.update();
expect(meta.data.length).toBe(10);
expect(meta.data[6]).toBe(first);
expect(meta.data[9]).toBe(last);
@@ -333,12 +338,14 @@ describe('Chart.DatasetController', function() {
last = controller.getParsed(5);
data.push({x: 6, y: 6}, {x: 7, y: 7}, {x: 8, y: 8});
data.push({x: 9, y: 9});
chart.update();
expect(meta.data.length).toBe(10);
expect(controller.getParsed(0)).toBe(first);
expect(controller.getParsed(5)).toBe(last);
last = controller.getParsed(9);
data.pop();
chart.update();
expect(meta.data.length).toBe(9);
expect(controller.getParsed(0)).toBe(first);
expect(controller.getParsed(9)).toBe(undefined);
@@ -348,12 +355,14 @@ describe('Chart.DatasetController', function() {
data.shift();
data.shift();
data.shift();
chart.update();
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});
chart.update();
expect(meta.data.length).toBe(4);
expect(controller.getParsed(0)).toBe(first);
expect(controller.getParsed(3)).toBe(last);
@@ -361,6 +370,7 @@ describe('Chart.DatasetController', function() {
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});
chart.update();
expect(meta.data.length).toBe(10);
expect(controller.getParsed(6)).toBe(first);
expect(controller.getParsed(9)).toBe(last);
@@ -390,6 +400,7 @@ describe('Chart.DatasetController', function() {
expect(meta._parsed.map(p => p.y)).toEqual(data1);
data1.push(9);
chart.update();
expect(meta.data.length).toBe(4);
chart.data.datasets[0].data = data0;