mirror of
https://github.com/chartjs/Chart.js.git
synced 2025-12-08 20:36:08 +00:00
Use global element hidden status for Pie charts (#7156)
Use global element hidden status for Pie / polarArea charts
This commit is contained in:
parent
3b915cbdd3
commit
a3dddb45d9
@ -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.
|
||||
|
||||
@ -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`
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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];
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -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);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user