mirror of
https://github.com/chartjs/Chart.js.git
synced 2026-03-13 03:36:50 +01:00
Category: Track automatically added labels (#9921)
* Category: Track automatically added labels * Use correct yAxisKey (does not change anything)
This commit is contained in:
@@ -1,14 +1,20 @@
|
||||
import Scale from '../core/core.scale';
|
||||
import {isNullOrUndef, valueOrDefault, _limitValue} from '../helpers';
|
||||
|
||||
const addIfString = (labels, raw, index) => typeof raw === 'string'
|
||||
? labels.push(raw) - 1
|
||||
: isNaN(raw) ? null : index;
|
||||
const addIfString = (labels, raw, index, addedLabels) => {
|
||||
if (typeof raw === 'string') {
|
||||
index = labels.push(raw) - 1;
|
||||
addedLabels.unshift({index, label: raw});
|
||||
} else if (isNaN(raw)) {
|
||||
index = null;
|
||||
}
|
||||
return index;
|
||||
};
|
||||
|
||||
function findOrAddLabel(labels, raw, index) {
|
||||
function findOrAddLabel(labels, raw, index, addedLabels) {
|
||||
const first = labels.indexOf(raw);
|
||||
if (first === -1) {
|
||||
return addIfString(labels, raw, index);
|
||||
return addIfString(labels, raw, index, addedLabels);
|
||||
}
|
||||
const last = labels.lastIndexOf(raw);
|
||||
return first !== last ? index : first;
|
||||
@@ -24,6 +30,21 @@ export default class CategoryScale extends Scale {
|
||||
/** @type {number} */
|
||||
this._startValue = undefined;
|
||||
this._valueRange = 0;
|
||||
this._addedLabels = [];
|
||||
}
|
||||
|
||||
init(scaleOptions) {
|
||||
const added = this._addedLabels;
|
||||
if (added.length) {
|
||||
const labels = this.getLabels();
|
||||
for (const {index, label} of added) {
|
||||
if (labels[index] === label) {
|
||||
labels.splice(index, 1);
|
||||
}
|
||||
}
|
||||
this._addedLabels = [];
|
||||
}
|
||||
super.init(scaleOptions);
|
||||
}
|
||||
|
||||
parse(raw, index) {
|
||||
@@ -32,7 +53,7 @@ export default class CategoryScale extends Scale {
|
||||
}
|
||||
const labels = this.getLabels();
|
||||
index = isFinite(index) && labels[index] === raw ? index
|
||||
: findOrAddLabel(labels, raw, valueOrDefault(index, raw));
|
||||
: findOrAddLabel(labels, raw, valueOrDefault(index, raw), this._addedLabels);
|
||||
return validIndex(index, labels.length - 1);
|
||||
}
|
||||
|
||||
|
||||
@@ -249,6 +249,124 @@ describe('Chart.DatasetController', function() {
|
||||
expect(parsedYValues).toEqual([20, 30]);
|
||||
});
|
||||
|
||||
describe('labels array synchronization', function() {
|
||||
const data1 = [
|
||||
{x: 'One', name: 'One', y: 1, value: 1},
|
||||
{x: 'Two', name: 'Two', y: 2, value: 2}
|
||||
];
|
||||
const data2 = [
|
||||
{x: 'Three', name: 'Three', y: 3, value: 3},
|
||||
{x: 'Four', name: 'Four', y: 4, value: 4},
|
||||
{x: 'Five', name: 'Five', y: 5, value: 5}
|
||||
];
|
||||
[
|
||||
true,
|
||||
false,
|
||||
{
|
||||
xAxisKey: 'name',
|
||||
yAxisKey: 'value'
|
||||
}
|
||||
].forEach(function(parsing) {
|
||||
describe('when parsing is ' + JSON.stringify(parsing), function() {
|
||||
it('should remove old labels when data is updated', function() {
|
||||
const chart = acquireChart({
|
||||
type: 'line',
|
||||
data: {
|
||||
datasets: [{
|
||||
data: data1
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
parsing
|
||||
}
|
||||
});
|
||||
|
||||
chart.data.datasets[0].data = data2;
|
||||
chart.update();
|
||||
|
||||
const meta = chart.getDatasetMeta(0);
|
||||
const labels = meta.iScale.getLabels();
|
||||
expect(labels).toEqual(data2.map(n => n.x));
|
||||
});
|
||||
|
||||
it('should not remove any user added labels', function() {
|
||||
const chart = acquireChart({
|
||||
type: 'line',
|
||||
data: {
|
||||
datasets: [{
|
||||
data: data1
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
parsing
|
||||
}
|
||||
});
|
||||
|
||||
chart.data.labels.push('user-added');
|
||||
chart.data.datasets[0].data = [];
|
||||
chart.update();
|
||||
|
||||
const meta = chart.getDatasetMeta(0);
|
||||
const labels = meta.iScale.getLabels();
|
||||
expect(labels).toEqual(['user-added']);
|
||||
});
|
||||
|
||||
it('should not remove any user defined labels', function() {
|
||||
const chart = acquireChart({
|
||||
type: 'line',
|
||||
data: {
|
||||
datasets: [{
|
||||
data: data1
|
||||
}],
|
||||
labels: ['user1', 'user2']
|
||||
},
|
||||
options: {
|
||||
parsing
|
||||
}
|
||||
});
|
||||
|
||||
const meta = chart.getDatasetMeta(0);
|
||||
|
||||
expect(meta.iScale.getLabels()).toEqual(['user1', 'user2'].concat(data1.map(n => n.x)));
|
||||
|
||||
chart.data.datasets[0].data = data2;
|
||||
chart.update();
|
||||
|
||||
expect(meta.iScale.getLabels()).toEqual(['user1', 'user2'].concat(data2.map(n => n.x)));
|
||||
});
|
||||
|
||||
it('should keep up with multiple datasets', function() {
|
||||
const chart = acquireChart({
|
||||
type: 'line',
|
||||
data: {
|
||||
datasets: [{
|
||||
data: data1
|
||||
}, {
|
||||
data: data2
|
||||
}],
|
||||
labels: ['One', 'Three']
|
||||
},
|
||||
options: {
|
||||
parsing
|
||||
}
|
||||
});
|
||||
|
||||
const scale = chart.scales.x;
|
||||
|
||||
expect(scale.getLabels()).toEqual(['One', 'Three', 'Two', 'Four', 'Five']);
|
||||
|
||||
chart.data.datasets[0].data = data2;
|
||||
chart.data.datasets[1].data = data1;
|
||||
chart.update();
|
||||
|
||||
expect(scale.getLabels()).toEqual(['One', 'Three', 'Four', 'Five', 'Two']);
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
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({
|
||||
|
||||
Reference in New Issue
Block a user