From ed68557a99cb2e28b032f4a1c376dc24a9a0837c Mon Sep 17 00:00:00 2001 From: Jacco van den Berg <39033624+LeeLenaleee@users.noreply.github.com> Date: Sat, 12 Feb 2022 16:23:31 +0100 Subject: [PATCH] Make object notation usable for polarArea and radar (#10088) * start to make object notation usable for polarArea * enable object notation also for radar chart, test default key --- docs/general/data-structures.md | 7 ++++- src/controllers/controller.polarArea.js | 13 +++++---- src/controllers/controller.radar.js | 8 ++++-- src/helpers/helpers.config.js | 16 +++++++++++ .../parse-object-data.json | 27 ++++++++++++++++++ .../parse-object-data.png | Bin 0 -> 21734 bytes test/specs/controller.radar.tests.js | 26 +++++++++++++++++ 7 files changed, 88 insertions(+), 9 deletions(-) create mode 100644 test/fixtures/controller.polarArea/parse-object-data.json create mode 100644 test/fixtures/controller.polarArea/parse-object-data.png diff --git a/docs/general/data-structures.md b/docs/general/data-structures.md index 65b877551..6f3c808f2 100644 --- a/docs/general/data-structures.md +++ b/docs/general/data-structures.md @@ -69,7 +69,7 @@ options: { } ``` -When using the pie/doughnut chart type, the `parsing` object should have a `key` item that points to the value to look at. In this example, the doughnut chart will show two items with values 1500 and 500. +When using the pie/doughnut, radar or polarArea chart type, the `parsing` object should have a `key` item that points to the value to look at. In this example, the doughnut chart will show two items with values 1500 and 500. ```javascript type: 'doughnut', @@ -85,6 +85,11 @@ options: { } ``` +:::warning +When using object notation in a radar chart you still need a labels array with labels for the chart to show correctly. +::: + + ## Object ```javascript diff --git a/src/controllers/controller.polarArea.js b/src/controllers/controller.polarArea.js index 84a9568a4..92642a32f 100644 --- a/src/controllers/controller.polarArea.js +++ b/src/controllers/controller.polarArea.js @@ -1,6 +1,5 @@ import DatasetController from '../core/core.datasetController'; -import {toRadians, PI} from '../helpers/index'; -import {formatNumber} from '../helpers/helpers.intl'; +import {toRadians, PI, formatNumber, _parseObjectDataRadialScale} from '../helpers/index'; export default class PolarAreaController extends DatasetController { @@ -23,6 +22,10 @@ export default class PolarAreaController extends DatasetController { }; } + parseObjectData(meta, data, start, count) { + return _parseObjectDataRadialScale.bind(this)(meta, data, start, count); + } + update(mode) { const arcs = this._cachedMeta.data; @@ -50,7 +53,6 @@ export default class PolarAreaController extends DatasetController { updateElements(arcs, start, count, mode) { const reset = mode === 'reset'; const chart = this.chart; - const dataset = this.getDataset(); const opts = chart.options; const animationOpts = opts.animation; const scale = this._cachedMeta.rScale; @@ -69,7 +71,7 @@ export default class PolarAreaController extends DatasetController { const arc = arcs[i]; let startAngle = angle; let endAngle = angle + this._computeAngle(i, mode, defaultAngle); - let outerRadius = chart.getDataVisibility(i) ? scale.getDistanceFromCenterForValue(dataset.data[i]) : 0; + let outerRadius = chart.getDataVisibility(i) ? scale.getDistanceFromCenterForValue(this.getParsed(i).r) : 0; angle = endAngle; if (reset) { @@ -96,12 +98,11 @@ export default class PolarAreaController extends DatasetController { } countVisibleElements() { - const dataset = this.getDataset(); const meta = this._cachedMeta; let count = 0; meta.data.forEach((element, index) => { - if (!isNaN(dataset.data[index]) && this.chart.getDataVisibility(index)) { + if (!isNaN(this.getParsed(index).r) && this.chart.getDataVisibility(index)) { count++; } }); diff --git a/src/controllers/controller.radar.js b/src/controllers/controller.radar.js index 36d53b030..e1a525f31 100644 --- a/src/controllers/controller.radar.js +++ b/src/controllers/controller.radar.js @@ -1,4 +1,5 @@ import DatasetController from '../core/core.datasetController'; +import {_parseObjectDataRadialScale} from '../helpers/index'; export default class RadarController extends DatasetController { @@ -15,6 +16,10 @@ export default class RadarController extends DatasetController { }; } + parseObjectData(meta, data, start, count) { + return _parseObjectDataRadialScale.bind(this)(meta, data, start, count); + } + update(mode) { const meta = this._cachedMeta; const line = meta.dataset; @@ -44,14 +49,13 @@ export default class RadarController extends DatasetController { } updateElements(points, start, count, mode) { - const dataset = this.getDataset(); const scale = this._cachedMeta.rScale; const reset = mode === 'reset'; for (let i = start; i < start + count; i++) { const point = points[i]; const options = this.resolveDataElementOptions(i, point.active ? 'active' : mode); - const pointPosition = scale.getPointPositionForValue(i, dataset.data[i]); + const pointPosition = scale.getPointPositionForValue(i, this.getParsed(i).r); const x = reset ? scale.xCenter : pointPosition.x; const y = reset ? scale.yCenter : pointPosition.y; diff --git a/src/helpers/helpers.config.js b/src/helpers/helpers.config.js index e6b30b732..058739d94 100644 --- a/src/helpers/helpers.config.js +++ b/src/helpers/helpers.config.js @@ -351,3 +351,19 @@ function resolveKeysFromAllScopes(scopes) { } return Array.from(set); } + +export function _parseObjectDataRadialScale(meta, data, start, count) { + const {iScale} = meta; + const {key = 'r'} = this._parsing; + const parsed = new Array(count); + let i, ilen, index, item; + + for (i = 0, ilen = count; i < ilen; ++i) { + index = i + start; + item = data[index]; + parsed[i] = { + r: iScale.parse(resolveObjectKey(item, key), index) + }; + } + return parsed; +} diff --git a/test/fixtures/controller.polarArea/parse-object-data.json b/test/fixtures/controller.polarArea/parse-object-data.json new file mode 100644 index 000000000..17b8ebe59 --- /dev/null +++ b/test/fixtures/controller.polarArea/parse-object-data.json @@ -0,0 +1,27 @@ +{ + "config": { + "type": "polarArea", + "data": { + "datasets": [ + { + "data": [{"id": "Sales", "nested": {"value": 10}}, {"id": "Purchases", "nested": {"value": 20}}], + "backgroundColor": ["red", "blue"] + } + ] + }, + "options": { + "responsive": false, + "plugins": { + "legend": false + }, + "parsing": { + "key": "nested.value" + }, + "scales": { + "r": { + "display": false + } + } + } + } +} diff --git a/test/fixtures/controller.polarArea/parse-object-data.png b/test/fixtures/controller.polarArea/parse-object-data.png new file mode 100644 index 0000000000000000000000000000000000000000..dc24813095933a5a9b06dc97ef74f9b5cbe343fc GIT binary patch literal 21734 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