]> git.ipfire.org Git - thirdparty/Chart.js.git/commitdiff
Use custom scale defaults and dataset axis ID options to determine the axis (#11134)
authorstockiNail <stocki.nail@gmail.com>
Wed, 15 Feb 2023 14:27:13 +0000 (15:27 +0100)
committerGitHub <noreply@github.com>
Wed, 15 Feb 2023 14:27:13 +0000 (09:27 -0500)
Use custom scale defaults to determine the axis

.size-limit.cjs
src/core/core.config.js
test/specs/core.scale.tests.js

index 2f4e5e4c67d3fc43c6e39ce2027ff2a360d4a8a2..2b421ffcb090d10bec746a80bd4591a1336a859e 100644 (file)
@@ -13,7 +13,7 @@ module.exports = [
   },
   {
     path: 'dist/chart.js',
-    limit: '34 KB',
+    limit: '34.5 KB',
     import: '{ Chart }',
     running: false,
     modifyWebpackConfig
index b7362b328c49e84cab7e566a2e98172ffc0ab212..209e87291ab36a27d2de205a5621415640120389 100644 (file)
@@ -22,6 +22,12 @@ function getDefaultScaleIDFromAxis(axis, indexAxis) {
   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';
@@ -31,20 +37,35 @@ function axisFromPosition(position) {
   }
 }
 
-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) {
@@ -62,7 +83,7 @@ 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]]);
index d0aa77f60adee74d8dc44dbe150fa9eb6d3aef88..caa3c8f32ea789154b88df5881ce3572c7e9ce19 100644 (file)
@@ -481,6 +481,35 @@ describe('Core.scale', function() {
       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() {}
@@ -514,6 +543,63 @@ describe('Core.scale', function() {
       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',