return axis === indexAxis ? '_index_' : '_value_';
}
+function idMatchesAxis(id) {
+ if (id === 'x' || id === 'y' || id === 'r') {
+ return id;
+ }
+}
+
function axisFromPosition(position) {
if (position === 'top' || position === 'bottom') {
return 'x';
}
}
-export function determineAxis(id, scaleOptions) {
- if (id === 'x' || id === 'y' || id === 'r') {
+export function determineAxis(id, ...scaleOptions) {
+ if (idMatchesAxis(id)) {
return id;
}
+ for (const opts of scaleOptions) {
+ const axis = opts.axis
+ || axisFromPosition(opts.position)
+ || id.length > 1 && idMatchesAxis(id[0].toLowerCase());
+ if (axis) {
+ return axis;
+ }
+ }
+ throw new Error(`Cannot determine type of '${id}' axis. Please provide 'axis' or 'position' option.`);
+}
- id = scaleOptions.axis
- || axisFromPosition(scaleOptions.position)
- || id.length > 1 && determineAxis(id[0].toLowerCase(), scaleOptions);
-
- if (id) {
- return id;
+function getAxisFromDataset(id, axis, dataset) {
+ if (dataset[axis + 'AxisID'] === id) {
+ return {axis};
}
+}
- throw new Error(`Cannot determine type of '${name}' axis. Please provide 'axis' or 'position' option.`);
+function retrieveAxisFromDatasets(id, config) {
+ if (config.data && config.data.datasets) {
+ const boundDs = config.data.datasets.filter((d) => d.xAxisID === id || d.yAxisID === id);
+ if (boundDs.length) {
+ return getAxisFromDataset(id, 'x', boundDs[0]) || getAxisFromDataset(id, 'y', boundDs[0]);
+ }
+ }
+ return {};
}
function mergeScaleConfig(config, options) {
if (scaleConf._proxy) {
return console.warn(`Ignoring resolver passed as options for scale: ${id}`);
}
- const axis = determineAxis(id, scaleConf);
+ const axis = determineAxis(id, scaleConf, retrieveAxisFromDatasets(id, config), defaults.scales[scaleConf.type]);
const defaultId = getDefaultScaleIDFromAxis(axis, chartIndexAxis);
const defaultScaleOptions = chartDefaults.scales || {};
scales[id] = mergeIf(Object.create(null), [{axis}, scaleConf, defaultScaleOptions[axis], defaultScaleOptions[defaultId]]);
expect(scale._layers().length).toEqual(3);
});
+ it('should create the chart with custom scale ids without axis or position options', function() {
+ function createChart() {
+ return window.acquireChart({
+ type: 'scatter',
+ data: {
+ datasets: [{
+ data: [{x: 0, y: 0}, {x: 1, y: 1}, {x: 2, y: 2}],
+ xAxisID: 'customIDx',
+ yAxisID: 'customIDy'
+ }]
+ },
+ options: {
+ scales: {
+ customIDx: {
+ type: 'linear',
+ display: false
+ },
+ customIDy: {
+ type: 'linear',
+ display: false
+ }
+ }
+ }
+ });
+ }
+
+ expect(createChart).not.toThrow();
+ });
+
it('should default to one layer for custom scales', function() {
class CustomScale extends Chart.Scale {
draw() {}
expect(scale._layers()[0].z).toEqual(20);
});
+ it('should default to one layer for custom scales for axis', function() {
+ class CustomScale1 extends Chart.Scale {
+ draw() {}
+ convertTicksToLabels() {
+ return ['tick'];
+ }
+ }
+ CustomScale1.id = 'customScale1';
+ CustomScale1.defaults = {axis: 'x'};
+ Chart.register(CustomScale1);
+
+ var chart = window.acquireChart({
+ type: 'line',
+ options: {
+ scales: {
+ my: {
+ type: 'customScale1',
+ grid: {
+ z: 10
+ },
+ ticks: {
+ z: 20
+ }
+ }
+ }
+ }
+ });
+
+ var scale = chart.scales.my;
+ expect(scale._layers().length).toEqual(1);
+ expect(scale._layers()[0].z).toEqual(20);
+ });
+
+ it('should fail for custom scales without any axis or position', function() {
+ class CustomScale2 extends Chart.Scale {
+ draw() {}
+ }
+ CustomScale2.id = 'customScale2';
+ CustomScale2.defaults = {};
+ Chart.register(CustomScale2);
+
+ function createChart() {
+ return window.acquireChart({
+ type: 'line',
+ options: {
+ scales: {
+ my: {
+ type: 'customScale2'
+ }
+ }
+ }
+ });
+ }
+
+ expect(createChart).toThrow(new Error('Cannot determine type of \'my\' axis. Please provide \'axis\' or \'position\' option.'));
+ });
+
it('should return 3 layers when z is not equal between ticks and grid', function() {
var chart = window.acquireChart({
type: 'line',