From e8213058dad8825f79b4466fea7215116b4c46ff Mon Sep 17 00:00:00 2001 From: Dimitris - Rafail Katsampas Date: Mon, 30 Aug 2021 13:31:35 +0300 Subject: [PATCH 1/8] fix: Old labels were not destroyed on data update when data was not primitive. --- src/core/core.datasetController.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/core/core.datasetController.js b/src/core/core.datasetController.js index 1794c7031b9..9bb1348c838 100644 --- a/src/core/core.datasetController.js +++ b/src/core/core.datasetController.js @@ -416,15 +416,18 @@ export default class DatasetController { let prev = start > 0 && meta._parsed[start - 1]; let i, cur, parsed; - if (this._parsing === false) { + if (me._parsing === false) { + iScale.getLabels().splice(0); meta._parsed = data; meta._sorted = true; parsed = data; } else { if (isArray(data[start])) { - parsed = this.parseArrayData(meta, data, start, count); + iScale.getLabels().splice(0); + parsed = me.parseArrayData(meta, data, start, count); } else if (isObject(data[start])) { - parsed = this.parseObjectData(meta, data, start, count); + iScale.getLabels().splice(0); + parsed = me.parseObjectData(meta, data, start, count); } else { parsed = this.parsePrimitiveData(meta, data, start, count); } From d5cb9e67577f2472974b3746c613bb6de0b7a62d Mon Sep 17 00:00:00 2001 From: Dimitris - Rafail Katsampas Date: Mon, 30 Aug 2021 14:03:12 +0300 Subject: [PATCH 2/8] fix: This will only destroy labels when parsing data is not primitive. --- src/core/core.datasetController.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/core/core.datasetController.js b/src/core/core.datasetController.js index 9bb1348c838..40c72ebd59d 100644 --- a/src/core/core.datasetController.js +++ b/src/core/core.datasetController.js @@ -422,11 +422,12 @@ export default class DatasetController { meta._sorted = true; parsed = data; } else { - if (isArray(data[start])) { + if (isObject(me._parsing)) { iScale.getLabels().splice(0); + } + if (isArray(data[start])) { parsed = me.parseArrayData(meta, data, start, count); } else if (isObject(data[start])) { - iScale.getLabels().splice(0); parsed = me.parseObjectData(meta, data, start, count); } else { parsed = this.parsePrimitiveData(meta, data, start, count); From 6cc882da15e1241e33fcd05bf4436bfbed8a6b7f Mon Sep 17 00:00:00 2001 From: Dimitris - Rafail Katsampas Date: Mon, 30 Aug 2021 19:04:57 +0300 Subject: [PATCH 3/8] ref: Added labels cleanup earlier since old way caused issues. --- src/core/core.datasetController.js | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/core/core.datasetController.js b/src/core/core.datasetController.js index 40c72ebd59d..1794c7031b9 100644 --- a/src/core/core.datasetController.js +++ b/src/core/core.datasetController.js @@ -416,19 +416,15 @@ export default class DatasetController { let prev = start > 0 && meta._parsed[start - 1]; let i, cur, parsed; - if (me._parsing === false) { - iScale.getLabels().splice(0); + if (this._parsing === false) { meta._parsed = data; meta._sorted = true; parsed = data; } else { - if (isObject(me._parsing)) { - iScale.getLabels().splice(0); - } if (isArray(data[start])) { - parsed = me.parseArrayData(meta, data, start, count); + parsed = this.parseArrayData(meta, data, start, count); } else if (isObject(data[start])) { - parsed = me.parseObjectData(meta, data, start, count); + parsed = this.parseObjectData(meta, data, start, count); } else { parsed = this.parsePrimitiveData(meta, data, start, count); } From 633a52b288778fdfc886007372231baab0e7e7c5 Mon Sep 17 00:00:00 2001 From: Dimitris - Rafail Katsampas Date: Mon, 30 Aug 2021 19:23:29 +0300 Subject: [PATCH 4/8] chore: Check if `labels` is defined. --- src/core/core.datasetController.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/core/core.datasetController.js b/src/core/core.datasetController.js index 1794c7031b9..e0f2de93d7b 100644 --- a/src/core/core.datasetController.js +++ b/src/core/core.datasetController.js @@ -367,7 +367,12 @@ export default class DatasetController { const dataset = this.getDataset(); let stackChanged = false; - this._dataCheck(); + let labels = me.chart.data.labels; + if (labels && labels.length && (me._parsing === false || isObject(me._parsing))) { + labels.splice(0); + } + + me._dataCheck(); // make sure cached _stacked status is current const oldStacked = meta._stacked; From 7994da3a5675a72ad47418c6b795f9427d716c61 Mon Sep 17 00:00:00 2001 From: Dimitris - Rafail Katsampas Date: Thu, 28 Oct 2021 17:53:25 +0300 Subject: [PATCH 5/8] chore: Clean iScale labels instead. --- src/core/core.datasetController.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/core.datasetController.js b/src/core/core.datasetController.js index e0f2de93d7b..f65f9cf11ad 100644 --- a/src/core/core.datasetController.js +++ b/src/core/core.datasetController.js @@ -367,7 +367,7 @@ export default class DatasetController { const dataset = this.getDataset(); let stackChanged = false; - let labels = me.chart.data.labels; + let labels = meta.iScale ? meta.iScale.getLabels() : null; if (labels && labels.length && (me._parsing === false || isObject(me._parsing))) { labels.splice(0); } From 5a788f351a776dfdf6b7b87180802487ba7fed40 Mon Sep 17 00:00:00 2001 From: Dimitris - Rafail Katsampas Date: Sun, 7 Nov 2021 19:26:38 +0000 Subject: [PATCH 6/8] fix: Replaced undefined `me` references with `this`. --- src/core/core.datasetController.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/core.datasetController.js b/src/core/core.datasetController.js index f65f9cf11ad..ad83157839f 100644 --- a/src/core/core.datasetController.js +++ b/src/core/core.datasetController.js @@ -368,11 +368,11 @@ export default class DatasetController { let stackChanged = false; let labels = meta.iScale ? meta.iScale.getLabels() : null; - if (labels && labels.length && (me._parsing === false || isObject(me._parsing))) { + if (labels && labels.length && (this._parsing === false || isObject(this._parsing))) { labels.splice(0); } - me._dataCheck(); + this._dataCheck(); // make sure cached _stacked status is current const oldStacked = meta._stacked; From ab13a9f665db02e2bf0286e149730c10ec2e6bdf Mon Sep 17 00:00:00 2001 From: Dimitris - Rafail Katsampas Date: Sun, 7 Nov 2021 19:30:41 +0000 Subject: [PATCH 7/8] chore: Changed `labels` variable into constant. --- src/core/core.datasetController.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/core.datasetController.js b/src/core/core.datasetController.js index ad83157839f..b8cb4e2d27f 100644 --- a/src/core/core.datasetController.js +++ b/src/core/core.datasetController.js @@ -367,7 +367,7 @@ export default class DatasetController { const dataset = this.getDataset(); let stackChanged = false; - let labels = meta.iScale ? meta.iScale.getLabels() : null; + const labels = meta.iScale ? meta.iScale.getLabels() : null; if (labels && labels.length && (this._parsing === false || isObject(this._parsing))) { labels.splice(0); } From 88ea094cf0a8de4ea873b7628a992a08f6da3937 Mon Sep 17 00:00:00 2001 From: Dimitris - Rafail Katsampas Date: Sun, 7 Nov 2021 23:00:51 +0200 Subject: [PATCH 8/8] test: Added tests for parsing-related labels bug fix. --- test/specs/core.datasetController.tests.js | 63 ++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/test/specs/core.datasetController.tests.js b/test/specs/core.datasetController.tests.js index 05bef5b65b6..38664b10b03 100644 --- a/test/specs/core.datasetController.tests.js +++ b/test/specs/core.datasetController.tests.js @@ -249,6 +249,69 @@ describe('Chart.DatasetController', function() { expect(parsedYValues).toEqual([20, 30]); }); + it('should synchronize labels array with X values when chart existing dataset is updated and parsing is off', function() { + const chart = acquireChart({ + type: 'line', + data: { + datasets: [{ + data: [ + {x: 'One', y: 1}, + {x: 'Two', y: 2} + ] + }] + }, + options: { + parsing: false + } + }); + + const newData = [ + {x: 'Three', y: 3}, + {x: 'Four', y: 4}, + {x: 'Five', y: 5} + ]; + + chart.data.datasets[0].data = newData; + chart.update(); + + const meta = chart.getDatasetMeta(0); + const labels = meta.iScale.getLabels(); + expect(labels).toEqual(newData.map(n => n.x)); + }); + + it('should synchronize labels array with X values when chart existing dataset is updated and parsing has provided keys', function() { + const chart = acquireChart({ + type: 'line', + data: { + datasets: [{ + data: [ + {name: 'One', num: 1}, + {name: 'Two', num: 2} + ] + }] + }, + options: { + parsing: { + xAxisKey: 'name', + yAxisKey: 'num' + } + } + }); + + const newData = [ + {name: 'Three', num: 3}, + {name: 'Four', num: 4}, + {name: 'Five', num: 5} + ]; + + chart.data.datasets[0].data = newData; + chart.update(); + + const meta = chart.getDatasetMeta(0); + const labels = meta.iScale.getLabels(); + expect(labels).toEqual(newData.map(n => n.name)); + }); + it('should synchronize metadata when data are inserted or removed and parsing is on', function() { const data = [0, 1, 2, 3, 4, 5]; const chart = acquireChart({