Skip to content

Commit 8ff853c

Browse files
authored
feat: remove default axis override when custom id is given (#10643)
* feat: remove default axis override when custom id is given * docs: add info into migration guide * test: fix tests for the feat * docs: add info into migration guide * test: fix tests for the feat * feat: review fixes * feat: review fixes
1 parent 0edb2ac commit 8ff853c

File tree

9 files changed

+125
-18
lines changed

9 files changed

+125
-18
lines changed

docs/migration/v4-migration.md

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ Chart.js 4.0 introduces a number of breaking changes. We tried keeping the amoun
77
### Charts
88

99
* Charts don't override the default tooltip callbacks, so all chart types have the same-looking tooltips.
10+
* Default scale override has been removed if the configured scale starts with `x`/`y`. Defining `xAxes` in your config will now create a second scale instead of overriding the default `x` axis.
1011

1112
### Options
1213

src/core/core.config.js

+12-5
Original file line numberDiff line numberDiff line change
@@ -32,17 +32,25 @@ function axisFromPosition(position) {
3232
}
3333

3434
export function determineAxis(id, scaleOptions) {
35-
if (id === 'x' || id === 'y') {
35+
if (id === 'x' || id === 'y' || id === 'r') {
3636
return id;
3737
}
38-
return scaleOptions.axis || axisFromPosition(scaleOptions.position) || id.charAt(0).toLowerCase();
38+
39+
id = scaleOptions.axis
40+
|| axisFromPosition(scaleOptions.position)
41+
|| id.length > 1 && determineAxis(id[0].toLowerCase(), scaleOptions);
42+
43+
if (id) {
44+
return id;
45+
}
46+
47+
throw new Error(`Cannot determine type of '${name}' axis. Please provide 'axis' or 'position' option.`);
3948
}
4049

4150
function mergeScaleConfig(config, options) {
4251
const chartDefaults = overrides[config.type] || {scales: {}};
4352
const configScales = options.scales || {};
4453
const chartIndexAxis = getIndexAxis(config.type, options);
45-
const firstIDs = Object.create(null);
4654
const scales = Object.create(null);
4755

4856
// First figure out first scale id's per axis.
@@ -57,7 +65,6 @@ function mergeScaleConfig(config, options) {
5765
const axis = determineAxis(id, scaleConf);
5866
const defaultId = getDefaultScaleIDFromAxis(axis, chartIndexAxis);
5967
const defaultScaleOptions = chartDefaults.scales || {};
60-
firstIDs[axis] = firstIDs[axis] || id;
6168
scales[id] = mergeIf(Object.create(null), [{axis}, scaleConf, defaultScaleOptions[axis], defaultScaleOptions[defaultId]]);
6269
});
6370

@@ -69,7 +76,7 @@ function mergeScaleConfig(config, options) {
6976
const defaultScaleOptions = datasetDefaults.scales || {};
7077
Object.keys(defaultScaleOptions).forEach(defaultID => {
7178
const axis = getAxisFromDefaultScaleID(defaultID, indexAxis);
72-
const id = dataset[axis + 'AxisID'] || firstIDs[axis] || axis;
79+
const id = dataset[axis + 'AxisID'] || axis;
7380
scales[id] = scales[id] || Object.create(null);
7481
mergeIf(scales[id], [{axis}, configScales[id], defaultScaleOptions[defaultID]]);
7582
});

test/fixtures/controller.bar/stacking/issue-9105.js

+5-5
Original file line numberDiff line numberDiff line change
@@ -10,31 +10,31 @@ module.exports = {
1010
label: 'Dataset 1',
1111
data: [12, 19, 3, 5, 2, 3],
1212
stack: '0',
13-
yAxisID: 'y-axis-1'
13+
yAxisID: 'y'
1414
},
1515
{
1616
backgroundColor: 'rgba(54,162,235,0.8)',
1717
label: 'Dataset 2',
1818
data: [13, 19, 3, 5, 8, 3],
1919
stack: '0',
20-
yAxisID: 'y-axis-1'
20+
yAxisID: 'y'
2121
},
2222
{
2323
backgroundColor: 'rgba(75,192,192,0.8)',
2424
label: 'Dataset 3',
2525
data: [13, 19, 3, 5, 8, 3],
2626
stack: '0',
27-
yAxisID: 'y-axis-1'
27+
yAxisID: 'y'
2828
}
2929
]
3030
},
3131
options: {
3232
plugins: false,
3333
scales: {
34-
xaxis: {
34+
x: {
3535
display: false,
3636
},
37-
'y-axis-1': {
37+
y: {
3838
display: false
3939
}
4040
}

test/fixtures/core.scale/ticks/rotated-long.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,11 @@ module.exports = {
1717
title: false
1818
},
1919
scales: {
20-
bottom: {
20+
x: {
2121
type: 'category',
2222
position: 'bottom'
2323
},
24-
top: {
24+
x2: {
2525
type: 'category',
2626
position: 'top'
2727
}

test/fixtures/core.scale/ticks/rotated-multi-line.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,11 @@ module.exports = {
1717
title: false
1818
},
1919
scales: {
20-
bottom: {
20+
x: {
2121
type: 'category',
2222
position: 'bottom'
2323
},
24-
top: {
24+
x2: {
2525
type: 'category',
2626
position: 'top'
2727
}

test/fixtures/mixed/bar+line.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,10 @@ module.exports = {
1919
options: {
2020
indexAxis: 'y',
2121
scales: {
22-
horz: {
22+
x: {
2323
position: 'top'
2424
},
25-
vert: {
25+
y: {
2626
axis: 'y',
2727
labels: ['a', 'b', 'c', 'd']
2828
}

test/specs/core.controller.tests.js

+1
Original file line numberDiff line numberDiff line change
@@ -443,6 +443,7 @@ describe('Chart', function() {
443443
options: {
444444
scales: {
445445
foo: {
446+
axis: 'x',
446447
type: 'logarithmic',
447448
_jasmineCheckC: 'c2',
448449
_jasmineCheckD: 'd2'

test/specs/core.scale.tests.js

+98
Original file line numberDiff line numberDiff line change
@@ -571,4 +571,102 @@ describe('Core.scale', function() {
571571
expect(chart.scales.y.max).toEqual(10);
572572
});
573573
});
574+
575+
describe('overrides', () => {
576+
it('should create new scale', () => {
577+
const chart = window.acquireChart({
578+
type: 'scatter',
579+
data: {
580+
datasets: [{
581+
data: [{x: 100, y: 100}, {x: -100, y: -100}]
582+
}, {
583+
data: [{x: 10, y: 10}, {x: -10, y: -10}]
584+
}]
585+
},
586+
options: {
587+
scales: {
588+
x2: {
589+
type: 'linear',
590+
min: -20,
591+
max: 20
592+
}
593+
}
594+
}
595+
});
596+
597+
expect(Object.keys(chart.scales).sort()).toEqual(['x', 'x2', 'y']);
598+
});
599+
600+
it('should create new scale with custom name', () => {
601+
const chart = window.acquireChart({
602+
type: 'scatter',
603+
data: {
604+
datasets: [{
605+
data: [{x: 100, y: 100}, {x: -100, y: -100}]
606+
}, {
607+
data: [{x: 10, y: 10}, {x: -10, y: -10}]
608+
}]
609+
},
610+
options: {
611+
scales: {
612+
scaleX: {
613+
axis: 'x',
614+
type: 'linear',
615+
min: -20,
616+
max: 20
617+
}
618+
}
619+
}
620+
});
621+
622+
expect(Object.keys(chart.scales).sort()).toEqual(['scaleX', 'x', 'y']);
623+
});
624+
625+
it('should throw error on scale with custom name without axis type', () => {
626+
expect(() => window.acquireChart({
627+
type: 'scatter',
628+
data: {
629+
datasets: [{
630+
data: [{x: 100, y: 100}, {x: -100, y: -100}]
631+
}, {
632+
data: [{x: 10, y: 10}, {x: -10, y: -10}]
633+
}]
634+
},
635+
options: {
636+
scales: {
637+
scaleX: {
638+
type: 'linear',
639+
min: -20,
640+
max: 20
641+
}
642+
}
643+
}
644+
})).toThrow();
645+
});
646+
647+
it('should read options first to determine axis', () => {
648+
const chart = window.acquireChart({
649+
type: 'scatter',
650+
data: {
651+
datasets: [{
652+
data: [{x: 100, y: 100}, {x: -100, y: -100}]
653+
}, {
654+
data: [{x: 10, y: 10}, {x: -10, y: -10}]
655+
}]
656+
},
657+
options: {
658+
scales: {
659+
xavier: {
660+
axis: 'y',
661+
type: 'linear',
662+
min: -20,
663+
max: 20
664+
}
665+
}
666+
}
667+
});
668+
669+
expect(chart.scales.xavier.axis).toBe('y');
670+
});
671+
});
574672
});

types/index.d.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -3039,9 +3039,9 @@ export interface CartesianScaleOptions extends CoreScaleOptions {
30393039
stackWeight?: number;
30403040

30413041
/**
3042-
* Which type of axis this is. Possible values are: 'x', 'y'. If not set, this is inferred from the first character of the ID which should be 'x' or 'y'.
3042+
* Which type of axis this is. Possible values are: 'x', 'y', 'r'. If not set, this is inferred from the first character of the ID which should be 'x', 'y' or 'r'.
30433043
*/
3044-
axis: 'x' | 'y';
3044+
axis: 'x' | 'y' | 'r';
30453045

30463046
/**
30473047
* User defined minimum value for the scale, overrides minimum value from data.

0 commit comments

Comments
 (0)