Resync metasets array when indices change. (#6864)

* Resync metasets array when indices change.
* Make sure _metasets is initialized
This commit is contained in:
Jukka Kurkela 2019-12-28 16:49:34 +02:00 committed by Evert Timberg
parent e39970d494
commit 0b68786c04
2 changed files with 112 additions and 7 deletions

View File

@ -195,6 +195,7 @@ helpers.extend(Chart.prototype, /** @lends Chart */ {
me.options = config.options;
me._bufferedRender = false;
me._layers = [];
me._metasets = [];
// Add the chart instance to the global namespace
Chart.instances[me.id] = me;
@ -399,11 +400,45 @@ helpers.extend(Chart.prototype, /** @lends Chart */ {
scaleService.addScalesToLayout(this);
},
/**
* Updates the given metaset with the given dataset index. Ensures it's stored at that index
* in the _metasets array by swapping with the metaset at that index if necessary.
* @param {Object} meta - the dataset metadata
* @param {number} index - the dataset index
* @private
*/
_updateMetasetIndex: function(meta, index) {
const metasets = this._metasets;
const oldIndex = meta.index;
if (oldIndex !== index) {
metasets[oldIndex] = metasets[index];
metasets[index] = meta;
meta.index = index;
}
},
/**
* @private
*/
_updateMetasets: function() {
const me = this;
const metasets = me._metasets;
const numData = me.data.datasets.length;
const numMeta = metasets.length;
if (numMeta > numData) {
for (let i = numData; i < numMeta; ++i) {
me.destroyDatasetMeta(i);
}
metasets.splice(numData, numMeta - numData);
}
me._sortedMetasets = metasets.slice(0).sort(compare2Level('order', 'index'));
},
buildOrUpdateControllers: function() {
var me = this;
var newControllers = [];
var datasets = me.data.datasets;
var sorted = me._sortedMetasets = [];
var i, ilen;
for (i = 0, ilen = datasets.length; i < ilen; i++) {
@ -417,7 +452,7 @@ helpers.extend(Chart.prototype, /** @lends Chart */ {
}
meta.type = type;
meta.order = dataset.order || 0;
meta.index = i;
me._updateMetasetIndex(meta, i);
meta.label = '' + dataset.label;
meta.visible = me.isDatasetVisible(i);
@ -433,11 +468,9 @@ helpers.extend(Chart.prototype, /** @lends Chart */ {
meta.controller = new ControllerClass(me, i);
newControllers.push(meta.controller);
}
sorted.push(meta);
}
sorted.sort(compare2Level('order', 'index'));
me._updateMetasets();
return newControllers;
},
@ -768,8 +801,8 @@ helpers.extend(Chart.prototype, /** @lends Chart */ {
getDatasetMeta: function(datasetIndex) {
const me = this;
const dataset = me.data.datasets[datasetIndex];
const metasets = me._metasets = me._metasets || [];
let meta = metasets[datasetIndex];
const metasets = me._metasets;
let meta = metasets.filter(x => x._dataset === dataset).pop();
if (!meta) {
meta = metasets[datasetIndex] = {
@ -782,6 +815,7 @@ helpers.extend(Chart.prototype, /** @lends Chart */ {
yAxisID: null,
order: dataset.order || 0,
index: datasetIndex,
_dataset: dataset,
_parsed: []
};
}

View File

@ -1276,4 +1276,75 @@ describe('Chart', function() {
]);
});
});
describe('metasets', function() {
beforeEach(function() {
this.chart = acquireChart({
type: 'line',
data: {
datasets: [
{label: '1', order: 2},
{label: '2', order: 1},
{label: '3', order: 4},
{label: '4', order: 3},
]
}
});
});
afterEach(function() {
const metasets = this.chart._metasets;
expect(metasets.length).toEqual(this.chart.data.datasets.length);
for (let i = 0; i < metasets.length; i++) {
expect(metasets[i].index).toEqual(i);
expect(metasets[i]._dataset).toEqual(this.chart.data.datasets[i]);
}
});
it('should build metasets array in order', function() {
const metasets = this.chart._metasets;
expect(metasets[0].order).toEqual(2);
expect(metasets[1].order).toEqual(1);
expect(metasets[2].order).toEqual(4);
expect(metasets[3].order).toEqual(3);
});
it('should build sorted metasets array in correct order', function() {
const metasets = this.chart._sortedMetasets;
expect(metasets[0].order).toEqual(1);
expect(metasets[1].order).toEqual(2);
expect(metasets[2].order).toEqual(3);
expect(metasets[3].order).toEqual(4);
});
it('should be moved when datasets are removed from begining', function() {
this.chart.data.datasets.splice(0, 2);
this.chart.update();
const metasets = this.chart._metasets;
expect(metasets[0].order).toEqual(4);
expect(metasets[1].order).toEqual(3);
});
it('should be moved when datasets are removed from middle', function() {
this.chart.data.datasets.splice(1, 2);
this.chart.update();
const metasets = this.chart._metasets;
expect(metasets[0].order).toEqual(2);
expect(metasets[1].order).toEqual(3);
});
it('should be moved when datasets are inserted', function() {
this.chart.data.datasets.splice(1, 0, {label: '1.5', order: 5});
this.chart.update();
const metasets = this.chart._metasets;
expect(metasets[0].order).toEqual(2);
expect(metasets[1].order).toEqual(5);
expect(metasets[2].order).toEqual(1);
expect(metasets[3].order).toEqual(4);
expect(metasets[4].order).toEqual(3);
});
it('should be replaced when dataset is replaced', function() {
this.chart.data.datasets.splice(1, 1, {label: '1.5', order: 5});
this.chart.update();
const metasets = this.chart._metasets;
expect(metasets[0].order).toEqual(2);
expect(metasets[1].order).toEqual(5);
expect(metasets[2].order).toEqual(4);
expect(metasets[3].order).toEqual(3);
});
});
});