mirror of
https://github.com/chartjs/Chart.js.git
synced 2026-03-13 19:56:49 +01:00
Delay data to elements synchronization to update (#9105)
This commit is contained in:
@@ -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]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user