Skip to content

Commit 0b68786

Browse files
kurkleetimberg
authored andcommitted
Resync metasets array when indices change. (#6864)
* Resync metasets array when indices change. * Make sure _metasets is initialized
1 parent e39970d commit 0b68786

File tree

2 files changed

+112
-7
lines changed

2 files changed

+112
-7
lines changed

src/core/core.controller.js

Lines changed: 41 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,7 @@ helpers.extend(Chart.prototype, /** @lends Chart */ {
195195
me.options = config.options;
196196
me._bufferedRender = false;
197197
me._layers = [];
198+
me._metasets = [];
198199

199200
// Add the chart instance to the global namespace
200201
Chart.instances[me.id] = me;
@@ -399,11 +400,45 @@ helpers.extend(Chart.prototype, /** @lends Chart */ {
399400
scaleService.addScalesToLayout(this);
400401
},
401402

403+
/**
404+
* Updates the given metaset with the given dataset index. Ensures it's stored at that index
405+
* in the _metasets array by swapping with the metaset at that index if necessary.
406+
* @param {Object} meta - the dataset metadata
407+
* @param {number} index - the dataset index
408+
* @private
409+
*/
410+
_updateMetasetIndex: function(meta, index) {
411+
const metasets = this._metasets;
412+
const oldIndex = meta.index;
413+
if (oldIndex !== index) {
414+
metasets[oldIndex] = metasets[index];
415+
metasets[index] = meta;
416+
meta.index = index;
417+
}
418+
},
419+
420+
/**
421+
* @private
422+
*/
423+
_updateMetasets: function() {
424+
const me = this;
425+
const metasets = me._metasets;
426+
const numData = me.data.datasets.length;
427+
const numMeta = metasets.length;
428+
429+
if (numMeta > numData) {
430+
for (let i = numData; i < numMeta; ++i) {
431+
me.destroyDatasetMeta(i);
432+
}
433+
metasets.splice(numData, numMeta - numData);
434+
}
435+
me._sortedMetasets = metasets.slice(0).sort(compare2Level('order', 'index'));
436+
},
437+
402438
buildOrUpdateControllers: function() {
403439
var me = this;
404440
var newControllers = [];
405441
var datasets = me.data.datasets;
406-
var sorted = me._sortedMetasets = [];
407442
var i, ilen;
408443

409444
for (i = 0, ilen = datasets.length; i < ilen; i++) {
@@ -417,7 +452,7 @@ helpers.extend(Chart.prototype, /** @lends Chart */ {
417452
}
418453
meta.type = type;
419454
meta.order = dataset.order || 0;
420-
meta.index = i;
455+
me._updateMetasetIndex(meta, i);
421456
meta.label = '' + dataset.label;
422457
meta.visible = me.isDatasetVisible(i);
423458

@@ -433,11 +468,9 @@ helpers.extend(Chart.prototype, /** @lends Chart */ {
433468
meta.controller = new ControllerClass(me, i);
434469
newControllers.push(meta.controller);
435470
}
436-
sorted.push(meta);
437471
}
438472

439-
sorted.sort(compare2Level('order', 'index'));
440-
473+
me._updateMetasets();
441474
return newControllers;
442475
},
443476

@@ -768,8 +801,8 @@ helpers.extend(Chart.prototype, /** @lends Chart */ {
768801
getDatasetMeta: function(datasetIndex) {
769802
const me = this;
770803
const dataset = me.data.datasets[datasetIndex];
771-
const metasets = me._metasets = me._metasets || [];
772-
let meta = metasets[datasetIndex];
804+
const metasets = me._metasets;
805+
let meta = metasets.filter(x => x._dataset === dataset).pop();
773806

774807
if (!meta) {
775808
meta = metasets[datasetIndex] = {
@@ -782,6 +815,7 @@ helpers.extend(Chart.prototype, /** @lends Chart */ {
782815
yAxisID: null,
783816
order: dataset.order || 0,
784817
index: datasetIndex,
818+
_dataset: dataset,
785819
_parsed: []
786820
};
787821
}

test/specs/core.controller.tests.js

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1276,4 +1276,75 @@ describe('Chart', function() {
12761276
]);
12771277
});
12781278
});
1279+
1280+
describe('metasets', function() {
1281+
beforeEach(function() {
1282+
this.chart = acquireChart({
1283+
type: 'line',
1284+
data: {
1285+
datasets: [
1286+
{label: '1', order: 2},
1287+
{label: '2', order: 1},
1288+
{label: '3', order: 4},
1289+
{label: '4', order: 3},
1290+
]
1291+
}
1292+
});
1293+
});
1294+
afterEach(function() {
1295+
const metasets = this.chart._metasets;
1296+
expect(metasets.length).toEqual(this.chart.data.datasets.length);
1297+
for (let i = 0; i < metasets.length; i++) {
1298+
expect(metasets[i].index).toEqual(i);
1299+
expect(metasets[i]._dataset).toEqual(this.chart.data.datasets[i]);
1300+
}
1301+
});
1302+
it('should build metasets array in order', function() {
1303+
const metasets = this.chart._metasets;
1304+
expect(metasets[0].order).toEqual(2);
1305+
expect(metasets[1].order).toEqual(1);
1306+
expect(metasets[2].order).toEqual(4);
1307+
expect(metasets[3].order).toEqual(3);
1308+
});
1309+
it('should build sorted metasets array in correct order', function() {
1310+
const metasets = this.chart._sortedMetasets;
1311+
expect(metasets[0].order).toEqual(1);
1312+
expect(metasets[1].order).toEqual(2);
1313+
expect(metasets[2].order).toEqual(3);
1314+
expect(metasets[3].order).toEqual(4);
1315+
});
1316+
it('should be moved when datasets are removed from begining', function() {
1317+
this.chart.data.datasets.splice(0, 2);
1318+
this.chart.update();
1319+
const metasets = this.chart._metasets;
1320+
expect(metasets[0].order).toEqual(4);
1321+
expect(metasets[1].order).toEqual(3);
1322+
});
1323+
it('should be moved when datasets are removed from middle', function() {
1324+
this.chart.data.datasets.splice(1, 2);
1325+
this.chart.update();
1326+
const metasets = this.chart._metasets;
1327+
expect(metasets[0].order).toEqual(2);
1328+
expect(metasets[1].order).toEqual(3);
1329+
});
1330+
it('should be moved when datasets are inserted', function() {
1331+
this.chart.data.datasets.splice(1, 0, {label: '1.5', order: 5});
1332+
this.chart.update();
1333+
const metasets = this.chart._metasets;
1334+
expect(metasets[0].order).toEqual(2);
1335+
expect(metasets[1].order).toEqual(5);
1336+
expect(metasets[2].order).toEqual(1);
1337+
expect(metasets[3].order).toEqual(4);
1338+
expect(metasets[4].order).toEqual(3);
1339+
});
1340+
it('should be replaced when dataset is replaced', function() {
1341+
this.chart.data.datasets.splice(1, 1, {label: '1.5', order: 5});
1342+
this.chart.update();
1343+
const metasets = this.chart._metasets;
1344+
expect(metasets[0].order).toEqual(2);
1345+
expect(metasets[1].order).toEqual(5);
1346+
expect(metasets[2].order).toEqual(4);
1347+
expect(metasets[3].order).toEqual(3);
1348+
});
1349+
});
12791350
});

0 commit comments

Comments
 (0)