]> git.ipfire.org Git - thirdparty/Chart.js.git/commitdiff
Use global element hidden status for Pie charts (#7156)
authorJukka Kurkela <jukka.kurkela@gmail.com>
Sun, 1 Mar 2020 14:07:39 +0000 (16:07 +0200)
committerGitHub <noreply@github.com>
Sun, 1 Mar 2020 14:07:39 +0000 (09:07 -0500)
Use global element hidden status for Pie / polarArea charts

docs/developers/api.md
docs/getting-started/v3-migration.md
src/controllers/controller.doughnut.js
src/controllers/controller.polarArea.js
src/core/core.controller.js
src/core/core.datasetController.js
src/core/core.element.js
test/specs/core.controller.tests.js
test/specs/global.defaults.tests.js

index 77f184d2412c8815bf7c81d72c84769dbab96198..b60ed19282bcba0a8281c3ad312d01cdfc3cb7cf 100644 (file)
@@ -166,6 +166,23 @@ chart.setDataVisibility(0, 2, false); // hides the item in dataset 0, at index 2
 chart.update(); // chart now renders with item hidden
 ```
 
+## toggleDataVisibility(index)
+
+Toggles the visibility of an item in all datasets. A dataset needs to explicitly support this feature for it to have an effect. From internal chart types, doughnut / pie and polar area use this.
+
+```javascript
+chart.toggleDataVisibility(2); // toggles the item in all datasets, at index 2
+chart.update(); // chart now renders with item hidden
+```
+
+## getDataVisibility(index)
+
+Returns the stored visibility state of an data index for all datasets. Set by [toggleDataVisibility](#toggleDataVisibility). A dataset controller should use this method to determine if an item should not be visible.
+
+```javascript
+var visible = chart.getDataVisibility(2);
+```
+
 ## hide(datasetIndex)
 
 Sets the visibility for the given dataset to false. Updates the chart and animates the dataset with `'hide'` mode. This animation can be configured under the `hide` key in animation options. Please see [animations](../configuration/animations.md) docs for more details.
index 1df1a319271acf461c363fc5d77bb262e1dc3009..73c27c065f3f7b7254b277a818cc7885bb4ecaef 100644 (file)
@@ -104,6 +104,7 @@ Animation system was completely rewritten in Chart.js v3. Each property can now
 * `DatasetController.createMetaDataset`
 * `Element.getArea`
 * `Element.height`
+* `Element.hidden` was replaced by chart level status, usable with `getDataVisibility(index)` / `toggleDataVisibility(index)`
 * `Element.initialize`
 * `Element.inLabelRange`
 * `helpers.addEvent`
index 362125447c480c7a4419d789aa97d3ba7002d21b..361322de960179b9b31487b6e69646c1eea752d4 100644 (file)
@@ -36,7 +36,7 @@ defaults.set('doughnut', {
                                                        fillStyle: style.backgroundColor,
                                                        strokeStyle: style.borderColor,
                                                        lineWidth: style.borderWidth,
-                                                       hidden: isNaN(data.datasets[0].data[i]) || meta.data[i].hidden,
+                                                       hidden: !chart.getDataVisibility(i),
 
                                                        // Extra data used for toggling the correct item
                                                        index: i
@@ -48,19 +48,8 @@ defaults.set('doughnut', {
                },
 
                onClick(e, legendItem) {
-                       const index = legendItem.index;
-                       const chart = this.chart;
-                       let i, ilen, meta;
-
-                       for (i = 0, ilen = (chart.data.datasets || []).length; i < ilen; ++i) {
-                               meta = chart.getDatasetMeta(i);
-                               // toggle visibility of index if exists
-                               if (meta.data[index]) {
-                                       meta.data[index].hidden = !meta.data[index].hidden;
-                               }
-                       }
-
-                       chart.update();
+                       this.chart.toggleDataVisibility(legendItem.index);
+                       this.chart.update();
                }
        },
 
@@ -202,7 +191,7 @@ export default class DoughnutController extends DatasetController {
                const me = this;
                const opts = me.chart.options;
                const meta = me._cachedMeta;
-               return reset && opts.animation.animateRotate ? 0 : meta.data[i].hidden ? 0 : me.calculateCircumference(meta._parsed[i] * opts.circumference / DOUBLE_PI);
+               return reset && opts.animation.animateRotate ? 0 : this.chart.getDataVisibility(i) ? me.calculateCircumference(meta._parsed[i] * opts.circumference / DOUBLE_PI) : 0;
        }
 
        updateElements(arcs, start, mode) {
@@ -258,7 +247,7 @@ export default class DoughnutController extends DatasetController {
 
                for (i = 0; i < metaData.length; i++) {
                        const value = meta._parsed[i];
-                       if (!isNaN(value) && !metaData[i].hidden) {
+                       if (!isNaN(value) && this.chart.getDataVisibility(i)) {
                                total += Math.abs(value);
                        }
                }
index 28a92fbedd7c1e4fdbbdc7449cd7d4ddd0cbe48a..8d6475530935d2df6b243c1c4ab611ac1142a8ea 100644 (file)
@@ -44,7 +44,7 @@ defaults.set('polarArea', {
                                                        fillStyle: style.backgroundColor,
                                                        strokeStyle: style.borderColor,
                                                        lineWidth: style.borderWidth,
-                                                       hidden: isNaN(data.datasets[0].data[i]) || meta.data[i].hidden,
+                                                       hidden: !chart.getDataVisibility(i),
 
                                                        // Extra data used for toggling the correct item
                                                        index: i
@@ -56,16 +56,8 @@ defaults.set('polarArea', {
                },
 
                onClick(e, legendItem) {
-                       const index = legendItem.index;
-                       const chart = this.chart;
-                       let i, ilen, meta;
-
-                       for (i = 0, ilen = (chart.data.datasets || []).length; i < ilen; ++i) {
-                               meta = chart.getDatasetMeta(i);
-                               meta.data[index].hidden = !meta.data[index].hidden;
-                       }
-
-                       chart.update();
+                       this.chart.toggleDataVisibility(legendItem.index);
+                       this.chart.update();
                }
        },
 
@@ -160,7 +152,7 @@ export default class PolarAreaController extends DatasetController {
                        const index = start + i;
                        let startAngle = angle;
                        let endAngle = angle + me._computeAngle(index);
-                       let outerRadius = arc.hidden ? 0 : scale.getDistanceFromCenterForValue(dataset.data[index]);
+                       let outerRadius = this.chart.getDataVisibility(index) ? scale.getDistanceFromCenterForValue(dataset.data[index]) : 0;
                        angle = endAngle;
 
                        if (reset) {
@@ -193,7 +185,7 @@ export default class PolarAreaController extends DatasetController {
                let count = 0;
 
                meta.data.forEach((element, index) => {
-                       if (!isNaN(dataset.data[index]) && !element.hidden) {
+                       if (!isNaN(dataset.data[index]) && this.chart.getDataVisibility(index)) {
                                count++;
                        }
                });
@@ -210,7 +202,7 @@ export default class PolarAreaController extends DatasetController {
                const count = meta.count;
                const dataset = me.getDataset();
 
-               if (isNaN(dataset.data[index]) || meta.data[index].hidden) {
+               if (isNaN(dataset.data[index]) || !this.chart.getDataVisibility(index)) {
                        return 0;
                }
 
index 5f8ef2f814a10721109d7d7990cbbaca415f671c..731888b8c7e9d17a0484a593cd014a8033542d0b 100644 (file)
@@ -222,6 +222,7 @@ export default class Chart {
                this.scale = undefined;
                this.$plugins = undefined;
                this.$proxies = {};
+               this._hiddenIndices = {};
 
                // Add the chart instance to the global namespace
                Chart.instances[me.id] = me;
@@ -864,12 +865,12 @@ export default class Chart {
                meta.hidden = !visible;
        }
 
-       setDataVisibility(datasetIndex, index, visible) {
-               const meta = this.getDatasetMeta(datasetIndex);
+       toggleDataVisibility(index) {
+               this._hiddenIndices[index] = !this._hiddenIndices[index];
+       }
 
-               if (meta.data[index]) {
-                       meta.data[index].hidden = !visible;
-               }
+       getDataVisibility(index) {
+               return !this._hiddenIndices[index];
        }
 
        /**
index 752bb5b279547d310d0fb7ab2b37189ca86df674..02f6ab03a3c568b81249807a1c73ac8f35c96861 100644 (file)
@@ -624,7 +624,7 @@ export default class DatasetController {
         */
        getMinMax(scale, canStack) {
                const meta = this._cachedMeta;
-               const {data, _parsed} = meta;
+               const _parsed = meta._parsed;
                const sorted = meta._sorted && scale === meta.iScale;
                const ilen = _parsed.length;
                const otherScale = this._getOtherScale(scale);
@@ -632,7 +632,7 @@ export default class DatasetController {
                let min = Number.POSITIVE_INFINITY;
                let max = Number.NEGATIVE_INFINITY;
                const {min: otherMin, max: otherMax} = getUserBounds(otherScale);
-               let i, item, value, parsed, otherValue;
+               let i, value, parsed, otherValue;
 
                function _compute() {
                        if (stack) {
@@ -648,11 +648,10 @@ export default class DatasetController {
                }
 
                function _skip() {
-                       item = data[i];
                        parsed = _parsed[i];
                        value = parsed[scale.axis];
                        otherValue = parsed[otherScale.axis];
-                       return ((item && item.hidden) || isNaN(value) || otherMin > otherValue || otherMax < otherValue);
+                       return (isNaN(value) || otherMin > otherValue || otherMax < otherValue);
                }
 
                for (i = 0; i < ilen; ++i) {
index db4ebaa639bf3c3959827a2480238848d757f8ee..5e4aa7934f0dcc59542c29b724f36612e3438180 100644 (file)
@@ -8,7 +8,6 @@ export default class Element {
        constructor(cfg) {
                this.x = undefined;
                this.y = undefined;
-               this.hidden = false;
                this.active = false;
                this.options = undefined;
                this.$animations = undefined;
index e234862db6ce4fe2be594f504cd4c8a8bce3d0f8..42832301cfb3131ce448672ae1c1014f2e640878 100644 (file)
@@ -1365,9 +1365,9 @@ describe('Chart', function() {
                        expect(meta.hidden).toBe(true);
                });
 
-               it('should hide a single data item', function() {
+               it('should toggle data visibility by index', function() {
                        var chart = acquireChart({
-                               type: 'polarArea',
+                               type: 'pie',
                                data: {
                                        datasets: [{
                                                data: [1, 2, 3]
@@ -1375,10 +1375,13 @@ describe('Chart', function() {
                                }
                        });
 
-                       chart.setDataVisibility(0, 1, false);
+                       expect(chart.getDataVisibility(1)).toBe(true);
 
-                       var meta = chart.getDatasetMeta(0);
-                       expect(meta.data[1].hidden).toBe(true);
+                       chart.toggleDataVisibility(1);
+                       expect(chart.getDataVisibility(1)).toBe(false);
+
+                       chart.update();
+                       expect(chart.getDataVisibility(1)).toBe(false);
                });
        });
 });
index bf9e589d1a21636a83d2fb5792d5a5199b04073b..30652473ae7aec21c5b21e9398aa6d1688dccf76 100644 (file)
@@ -121,7 +121,7 @@ describe('Default Configs', function() {
                        }, {
                                text: 'label3',
                                fillStyle: 'blue',
-                               hidden: true,
+                               hidden: false,
                                index: 2,
                                strokeStyle: '#000',
                                lineWidth: 2
@@ -144,18 +144,16 @@ describe('Default Configs', function() {
                                },
                                options: config
                        });
-                       var meta = chart.getDatasetMeta(0);
-
                        spyOn(chart, 'update').and.callThrough();
 
                        var legendItem = chart.legend.legendItems[0];
                        config.legend.onClick.call(chart.legend, null, legendItem);
 
-                       expect(meta.data[0].hidden).toBe(true);
+                       expect(chart.getDataVisibility(0)).toBe(false);
                        expect(chart.update).toHaveBeenCalled();
 
                        config.legend.onClick.call(chart.legend, null, legendItem);
-                       expect(meta.data[0].hidden).toBe(false);
+                       expect(chart.getDataVisibility(0)).toBe(true);
                });
        });
 
@@ -219,7 +217,7 @@ describe('Default Configs', function() {
                        }, {
                                text: 'label3',
                                fillStyle: 'blue',
-                               hidden: true,
+                               hidden: false,
                                index: 2,
                                strokeStyle: '#000',
                                lineWidth: 2
@@ -242,18 +240,16 @@ describe('Default Configs', function() {
                                },
                                options: config
                        });
-                       var meta = chart.getDatasetMeta(0);
-
                        spyOn(chart, 'update').and.callThrough();
 
                        var legendItem = chart.legend.legendItems[0];
                        config.legend.onClick.call(chart.legend, null, legendItem);
 
-                       expect(meta.data[0].hidden).toBe(true);
+                       expect(chart.getDataVisibility(0)).toBe(false);
                        expect(chart.update).toHaveBeenCalled();
 
                        config.legend.onClick.call(chart.legend, null, legendItem);
-                       expect(meta.data[0].hidden).toBe(false);
+                       expect(chart.getDataVisibility(0)).toBe(true);
                });
        });
 });