From 6cf97859f0f4950e0cfac27477220f781f8e6579 Mon Sep 17 00:00:00 2001 From: Jukka Kurkela Date: Fri, 19 Jun 2020 00:44:55 +0300 Subject: [PATCH] Consistently resolve element options (#7520) * Consistently resolve element options * Add tests --- src/core/core.datasetController.js | 107 +++++++++------------ test/specs/core.datasetController.tests.js | 79 +++++++++++++++ 2 files changed, 127 insertions(+), 59 deletions(-) diff --git a/src/core/core.datasetController.js b/src/core/core.datasetController.js index 517187154..d13447bf5 100644 --- a/src/core/core.datasetController.js +++ b/src/core/core.datasetController.js @@ -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 */ diff --git a/test/specs/core.datasetController.tests.js b/test/specs/core.datasetController.tests.js index 67aacaa3d..1da76a5d5 100644 --- a/test/specs/core.datasetController.tests.js +++ b/test/specs/core.datasetController.tests.js @@ -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; + }); }); -- 2.47.2