]> git.ipfire.org Git - thirdparty/Chart.js.git/commitdiff
Consistently resolve element options (#7520)
authorJukka Kurkela <jukka.kurkela@gmail.com>
Thu, 18 Jun 2020 21:44:55 +0000 (00:44 +0300)
committerGitHub <noreply@github.com>
Thu, 18 Jun 2020 21:44:55 +0000 (17:44 -0400)
* Consistently resolve element options
* Add tests

src/core/core.datasetController.js
test/specs/core.datasetController.tests.js

index 517187154e6af075217a6418e27f8c46fd11f683..d13447bf530d2da685cf8b79bf04cd90db82db32 100644 (file)
@@ -147,6 +147,14 @@ function getFirstScaleId(chart, axis) {
        return Object.keys(scales).filter(key => scales[key].axis === axis).shift();
 }
 
+function optionKeys(optionNames) {
+       return isArray(optionNames) ? optionNames : Object.keys(optionNames);
+}
+
+function optionKey(key, active) {
+       return active ? 'hover' + key.charAt(0).toUpperCase() + key.slice(1) : key;
+}
+
 export default class DatasetController {
 
        /**
@@ -685,29 +693,10 @@ export default class DatasetController {
         * @protected
         */
        resolveDatasetElementOptions(active) {
-               const me = this;
-               const chart = me.chart;
-               const datasetOpts = me._config;
-               // @ts-ignore
-               const options = chart.options.elements[me.datasetElementType._type] || {};
-               const elementOptions = me.datasetElementOptions;
-               const values = {};
-               const context = me._getContext(undefined, active);
-               let i, ilen, key, readKey, value;
-
-               for (i = 0, ilen = elementOptions.length; i < ilen; ++i) {
-                       key = elementOptions[i];
-                       readKey = active ? 'hover' + key.charAt(0).toUpperCase() + key.slice(1) : key;
-                       value = resolve([
-                               datasetOpts[readKey],
-                               options[readKey]
-                       ], context);
-                       if (value !== undefined) {
-                               values[key] = value;
-                       }
-               }
-
-               return values;
+               return this._resolveOptions(this.datasetElementOptions, {
+                       active,
+                       type: this.datasetElementType._type
+               });
        }
 
        /**
@@ -722,43 +711,14 @@ export default class DatasetController {
                if (cached[mode]) {
                        return cached[mode];
                }
-               const chart = me.chart;
-               const datasetOpts = me._config;
-               // @ts-ignore
-               const options = chart.options.elements[me.dataElementType._type] || {};
-               const elementOptions = me.dataElementOptions;
-               const values = {};
-               const context = me._getContext(index, active);
                const info = {cacheable: !active};
-               let keys, i, ilen, key, value, readKey;
-
-               if (isArray(elementOptions)) {
-                       for (i = 0, ilen = elementOptions.length; i < ilen; ++i) {
-                               key = elementOptions[i];
-                               readKey = active ? 'hover' + key.charAt(0).toUpperCase() + key.slice(1) : key;
-                               value = resolve([
-                                       datasetOpts[readKey],
-                                       options[readKey]
-                               ], context, index, info);
-                               if (value !== undefined) {
-                                       values[key] = value;
-                               }
-                       }
-               } else {
-                       keys = Object.keys(elementOptions);
-                       for (i = 0, ilen = keys.length; i < ilen; ++i) {
-                               key = keys[i];
-                               readKey = active ? 'hover' + key.charAt(0).toUpperCase() + key.slice(1) : key;
-                               value = resolve([
-                                       datasetOpts[elementOptions[readKey]],
-                                       datasetOpts[readKey],
-                                       options[readKey]
-                               ], context, index, info);
-                               if (value !== undefined) {
-                                       values[key] = value;
-                               }
-                       }
-               }
+
+               const values = me._resolveOptions(me.dataElementOptions, {
+                       index,
+                       active,
+                       info,
+                       type: me.dataElementType._type
+               });
 
                if (info.cacheable) {
                        // `$shared` indicades this set of options can be shared between multiple elements.
@@ -774,6 +734,35 @@ export default class DatasetController {
                return values;
        }
 
+       /**
+        * @private
+        */
+       _resolveOptions(optionNames, args) {
+               const me = this;
+               const {index, active, type, info} = args;
+               const datasetOpts = me._config;
+               const options = me.chart.options.elements[type] || {};
+               const values = {};
+               const context = me._getContext(index, active);
+               const keys = optionKeys(optionNames);
+
+               for (let i = 0, ilen = keys.length; i < ilen; ++i) {
+                       const key = keys[i];
+                       const readKey = optionKey(key, active);
+                       const value = resolve([
+                               datasetOpts[optionNames[readKey]],
+                               datasetOpts[readKey],
+                               options[readKey]
+                       ], context, index, info);
+
+                       if (value !== undefined) {
+                               values[key] = value;
+                       }
+               }
+
+               return values;
+       }
+
        /**
         * @private
         */
index 67aacaa3dbbd607b2b2ada198c9847d73e0bca5f..1da76a5d5d8175f5c4d61e8d9285005fbcaded9d 100644 (file)
@@ -584,4 +584,83 @@ describe('Chart.DatasetController', function() {
                // Reset old shared state
                Chart.defaults.color = oldColor;
        });
+
+       describe('_resolveOptions', function() {
+               it('should resove names in array notation', function() {
+                       Chart.defaults.elements.line.globalTest = 'global';
+
+                       const chart = acquireChart({
+                               type: 'line',
+                               data: {
+                                       datasets: [{
+                                               data: [1],
+                                               datasetTest: 'dataset'
+                                       }]
+                               },
+                               options: {
+                                       elements: {
+                                               line: {
+                                                       elementTest: 'element'
+                                               }
+                                       }
+                               }
+                       });
+
+                       const controller = chart.getDatasetMeta(0).controller;
+
+                       expect(controller._resolveOptions(
+                               [
+                                       'datasetTest',
+                                       'elementTest',
+                                       'globalTest'
+                               ],
+                               {type: 'line'})
+                       ).toEqual({
+                               datasetTest: 'dataset',
+                               elementTest: 'element',
+                               globalTest: 'global'
+                       });
+
+                       // Remove test from global defaults
+                       delete Chart.defaults.elements.line.globalTest;
+               });
+       });
+
+       it('should resove names in object notation', function() {
+               Chart.defaults.elements.line.global = 'global';
+
+               const chart = acquireChart({
+                       type: 'line',
+                       data: {
+                               datasets: [{
+                                       data: [1],
+                                       datasetTest: 'dataset'
+                               }]
+                       },
+                       options: {
+                               elements: {
+                                       line: {
+                                               element: 'element'
+                                       }
+                               }
+                       }
+               });
+
+               const controller = chart.getDatasetMeta(0).controller;
+
+               expect(controller._resolveOptions(
+                       {
+                               dataset: 'datasetTest',
+                               element: 'elementTest',
+                               global: 'globalTest'},
+                       {type: 'line'})
+               ).toEqual({
+                       dataset: 'dataset',
+                       element: 'element',
+                       global: 'global'
+               });
+
+               // Remove test from global defaults
+               delete Chart.defaults.elements.line.global;
+       });
 });