]> git.ipfire.org Git - thirdparty/Chart.js.git/commitdiff
Add ability to hide specific data element (#9450)
authorJukka Kurkela <jukka.kurkela@gmail.com>
Wed, 21 Jul 2021 11:08:02 +0000 (14:08 +0300)
committerGitHub <noreply@github.com>
Wed, 21 Jul 2021 11:08:02 +0000 (07:08 -0400)
docs/developers/api.md
docs/samples/other-charts/doughnut.md
src/controllers/controller.doughnut.js
src/core/core.controller.js
src/core/core.datasetController.js
test/fixtures/controller.doughnut/doughnut-hidden-single.js [new file with mode: 0644]
test/fixtures/controller.doughnut/doughnut-hidden-single.png [new file with mode: 0644]
types/index.esm.d.ts

index 4494dfebb9ba8b776a276394a04865bbf62e53aa..a17b2a5d6b771a23b74b3b6d3974b548a9b8e7ab 100644 (file)
@@ -152,20 +152,26 @@ Returns the stored visibility state of an data index for all datasets. Set by [t
 var visible = chart.getDataVisibility(2);
 ```
 
-## hide(datasetIndex)
+## hide(datasetIndex, dataIndex?)
 
-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.
+If dataIndex is not specified, 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.
+
+If dataIndex is specified, sets the hidden flag of that element to true and updates the chart.
 
 ```javascript
 chart.hide(1); // hides dataset at index 1 and does 'hide' animation.
+chart.hide(0, 2); // hides the data element at index 2 of the first dataset.
 ```
 
-## show(datasetIndex)
+## show(datasetIndex, dataIndex?)
+
+If dataIndex is not specified, sets the visibility for the given dataset to true. Updates the chart and animates the dataset with `'show'` mode. This animation can be configured under the `show` key in animation options. Please see [animations](../configuration/animations.md) docs for more details.
 
-Sets the visibility for the given dataset to true. Updates the chart and animates the dataset with `'show'` mode. This animation can be configured under the `show` key in animation options. Please see [animations](../configuration/animations.md) docs for more details.
+If dataIndex is specified, sets the hidden flag of that element to false and updates the chart.
 
 ```javascript
 chart.show(1); // shows dataset at index 1 and does 'show' animation.
+chart.show(0, 2); // shows the data element at index 2 of the first dataset.
 ```
 
 ## setActiveElements(activeElements)
index bbe7d9f894a751f839cc74da9bf6119524ea4d8c..21e98c68e48f8d408be83d421077a2fdbd80d064 100644 (file)
@@ -48,6 +48,30 @@ const actions = [
       }
     }
   },
+  {
+    name: 'Hide(0)',
+    handler(chart) {
+      chart.hide(0);
+    }
+  },
+  {
+    name: 'Show(0)',
+    handler(chart) {
+      chart.show(0);
+    }
+  },
+  {
+    name: 'Hide (0, 1)',
+    handler(chart) {
+      chart.hide(0, 1);
+    }
+  },
+  {
+    name: 'Show (0, 1)',
+    handler(chart) {
+      chart.show(0, 1);
+    }
+  },
   {
     name: 'Remove Dataset',
     handler(chart) {
index 20929bbe1f6f7d4be9784298b2e48c3dd47648d7..91c4756cf91f47891488f6414a7182b79dbd64cc 100644 (file)
@@ -145,7 +145,7 @@ export default class DoughnutController extends DatasetController {
     const opts = me.options;
     const meta = me._cachedMeta;
     const circumference = me._getCircumference();
-    if ((reset && opts.animation.animateRotate) || !this.chart.getDataVisibility(i) || meta._parsed[i] === null) {
+    if ((reset && opts.animation.animateRotate) || !this.chart.getDataVisibility(i) || meta._parsed[i] === null || meta.data[i].hidden) {
       return 0;
     }
     return me.calculateCircumference(meta._parsed[i] * circumference / TAU);
@@ -203,7 +203,7 @@ export default class DoughnutController extends DatasetController {
 
     for (i = 0; i < metaData.length; i++) {
       const value = meta._parsed[i];
-      if (value !== null && !isNaN(value) && this.chart.getDataVisibility(i)) {
+      if (value !== null && !isNaN(value) && this.chart.getDataVisibility(i) && !metaData[i].hidden) {
         total += Math.abs(value);
       }
     }
index 16c98cd97ffc3b6552f86bf01be23ba7ede67a72..96bce6b4ce71ea5d4ddc866c459922ecaa79105f 100644 (file)
@@ -7,7 +7,7 @@ import PluginService from './core.plugins';
 import registry from './core.registry';
 import Config, {determineAxis, getIndexAxis} from './core.config';
 import {retinaScale, _isDomSupported} from '../helpers/helpers.dom';
-import {each, callback as callCallback, uid, valueOrDefault, _elementsEqual, isNullOrUndef, setsEqual} from '../helpers/helpers.core';
+import {each, callback as callCallback, uid, valueOrDefault, _elementsEqual, isNullOrUndef, setsEqual, defined} from '../helpers/helpers.core';
 import {clearCanvas, clipArea, unclipArea, _isPointInArea} from '../helpers/helpers.canvas';
 // @ts-ignore
 import {version} from '../../package.json';
@@ -794,25 +794,29 @@ class Chart {
   /**
         * @private
         */
-  _updateDatasetVisibility(datasetIndex, visible) {
+  _updateVisibility(datasetIndex, dataIndex, visible) {
     const me = this;
     const mode = visible ? 'show' : 'hide';
     const meta = me.getDatasetMeta(datasetIndex);
     const anims = meta.controller._resolveAnimations(undefined, mode);
-    me.setDatasetVisibility(datasetIndex, visible);
 
-    // Animate visible state, so hide animation can be seen. This could be handled better if update / updateDataset returned a Promise.
-    anims.update(meta, {visible});
-
-    me.update((ctx) => ctx.datasetIndex === datasetIndex ? mode : undefined);
+    if (defined(dataIndex)) {
+      meta.data[dataIndex].hidden = !visible;
+      me.update();
+    } else {
+      me.setDatasetVisibility(datasetIndex, visible);
+      // Animate visible state, so hide animation can be seen. This could be handled better if update / updateDataset returned a Promise.
+      anims.update(meta, {visible});
+      me.update((ctx) => ctx.datasetIndex === datasetIndex ? mode : undefined);
+    }
   }
 
-  hide(datasetIndex) {
-    this._updateDatasetVisibility(datasetIndex, false);
+  hide(datasetIndex, dataIndex) {
+    this._updateVisibility(datasetIndex, dataIndex, false);
   }
 
-  show(datasetIndex) {
-    this._updateDatasetVisibility(datasetIndex, true);
+  show(datasetIndex, dataIndex) {
+    this._updateVisibility(datasetIndex, dataIndex, true);
   }
 
   /**
index 048073a84007f2660fb233499ef38d28c23f1463..f504d3f5cbf0232516bb6a24e8184029e821be66 100644 (file)
@@ -701,6 +701,9 @@ export default class DatasetController {
 
     for (i = start; i < start + count; ++i) {
       const element = elements[i];
+      if (element.hidden) {
+        continue;
+      }
       if (element.active) {
         active.push(element);
       } else {
diff --git a/test/fixtures/controller.doughnut/doughnut-hidden-single.js b/test/fixtures/controller.doughnut/doughnut-hidden-single.js
new file mode 100644 (file)
index 0000000..80f0ee9
--- /dev/null
@@ -0,0 +1,42 @@
+module.exports = {
+  config: {
+    type: 'doughnut',
+    data: {
+      labels: ['A', 'B', 'C', 'D', 'E'],
+      datasets: [{
+        data: [1, 5, 10, 50, 100],
+        backgroundColor: [
+          'rgba(255, 99, 132, 0.8)',
+          'rgba(54, 162, 235, 0.8)',
+          'rgba(255, 206, 86, 0.8)',
+          'rgba(75, 192, 192, 0.8)',
+          'rgba(153, 102, 255, 0.8)'
+        ],
+      }, {
+        data: [1, 5, 10, 50, 100],
+        backgroundColor: [
+          'rgba(255, 99, 132, 0.8)',
+          'rgba(54, 162, 235, 0.8)',
+          'rgba(255, 206, 86, 0.8)',
+          'rgba(75, 192, 192, 0.8)',
+          'rgba(153, 102, 255, 0.8)'
+        ],
+      }]
+    },
+    options: {
+      responsive: false,
+      plugins: {
+        legend: false,
+        title: false,
+        tooltip: false,
+        filler: false
+      }
+    },
+  },
+  options: {
+    run(chart) {
+      chart.hide(0, 4);
+      chart.hide(1, 2);
+    }
+  }
+};
diff --git a/test/fixtures/controller.doughnut/doughnut-hidden-single.png b/test/fixtures/controller.doughnut/doughnut-hidden-single.png
new file mode 100644 (file)
index 0000000..5cfbe2c
Binary files /dev/null and b/test/fixtures/controller.doughnut/doughnut-hidden-single.png differ
index ccd1838cdb9a8c40de69c0500e40ac84b8006286..155b5330f567541ae7294395a114d674d3cd3edd 100644 (file)
@@ -508,8 +508,8 @@ export declare class Chart<
   setDatasetVisibility(datasetIndex: number, visible: boolean): void;
   toggleDataVisibility(index: number): void;
   getDataVisibility(index: number): boolean;
-  hide(datasetIndex: number): void;
-  show(datasetIndex: number): void;
+  hide(datasetIndex: number, dataIndex?: number): void;
+  show(datasetIndex: number, dataIndex?: number): void;
 
   getActiveElements(): ActiveElement[];
   setActiveElements(active: ActiveDataPoint[]): void;