Hiding Small Pie Slices
Pie chart sizes its slices proportionally, based on the relative values. Sometimes that means that we end up with a chart that has a bunch of small-value slices that are barely visible, but clutter up the chart.
Here’s one chart like that:
Ewww. Let’s see what we can do about it.
Hiding labels
Section titled “Hiding labels”Let’s hide labels (and ticks) of the slices that are less than X percent of the whole slice.
We can hide or show any element in amCharts 4 using their hide() or show() methods respectively.
We also have a bunch of events at our disposal we can use to toggle element visibility.
Let’s build some to auto-hide labels and ticks.
pieSeries.ticks.template.events.on("ready", hideSmall);pieSeries.ticks.template.events.on("visibilitychanged", hideSmall);pieSeries.labels.template.events.on("ready", hideSmall);pieSeries.labels.template.events.on("visibilitychanged", hideSmall);
function hideSmall(ev) { if (ev.target.dataItem && (ev.target.dataItem.values.value.percent < 5)) { ev.target.hide(); } else { ev.target.show(); }}pieSeries.ticks.template.events.on("ready", hideSmall);pieSeries.ticks.template.events.on("visibilitychanged", hideSmall);pieSeries.labels.template.events.on("ready", hideSmall);pieSeries.labels.template.events.on("visibilitychanged", hideSmall);
function hideSmall(ev) { if (ev.target.dataItem && (ev.target.dataItem.values.value.percent < 5)) { ev.target.hide(); } else { ev.target.show(); }}{ // ... "series": [{ // ... "ticks": { "events": { "ready": function(ev) { if (ev.target.dataItem && (ev.target.dataItem.values.value.percent < 5)) { ev.target.hide(); } else { ev.target.show(); } }, "visibilitychanged": function(ev) { if (ev.target.dataItem && (ev.target.dataItem.values.value.percent < 5)) { ev.target.hide(); } else { ev.target.show(); } } } }, "labels": { "events": { "ready": function(ev) { if (ev.target.dataItem && (ev.target.dataItem.values.value.percent < 5)) { ev.target.hide(); } else { ev.target.show(); } }, "visibilitychanged": function(ev) { if (ev.target.dataItem && (ev.target.dataItem.values.value.percent < 5)) { ev.target.hide(); } else { ev.target.show(); } } } }, }]}Let’s check how we’re doing now.
Better. Now small irrelevant slices do not clutter up the interface, but still identifiable via hover or legend.
Hiding slices
Section titled “Hiding slices”But what about we don’t want to show those small slices at all?
We could use the same hidden adapter for slices template as well:
pieSeries.slices.template.adapter.add("hidden", hideSmall);pieSeries.slices.template.adapter.add("hidden", hideSmall);{ // ... "series": [{ // ... "slices": { "adapter": { "hidden": function hideSmall(hidden, target) { return target.dataItem.values.value.percent < 5 ? true : false; } } } }]}However, they would just be hidden, without the rest of the slices moving in to claim the freed up space.
While not faulty per se empty space indicates that we have removed something.
But what about if we want to completely eliminate hidden slices?
In this case simple adapter won’t do.
Removing slices
Section titled “Removing slices”For this to work, we will need to hide not just respective visual element of the slice, but whole “data item”.
In this case, Pie series will re-adjust itself so that remaining slices take up all of the pie.
For that we will utilize Pie series event datavalidated which happens right after data is being supplied to the series, because we will need it in order to check which slices to hide.
And, while we’re at it, we will also hide related legend items.
pieSeries.events.on("datavalidated", function(ev) { ev.target.slices.each(function(slice) { if (slice.dataItem.values.value.percent < 5) { slice.dataItem.hide(); slice.dataItem.legendDataItem.hide(); } });});pieSeries.events.on("datavalidated", function(ev) { ev.target.slices.each(function(slice) { if (slice.dataItem.values.value.percent < 5) { slice.dataItem.hide(); slice.dataItem.legendDataItem.hide(); } });});{ // ... "series": [{ // ... "events": { "datavalidated": function(ev) { ev.target.slices.each(function(slice) { if (slice.dataItem.values.value.percent < 5) { slice.dataItem.hide(); slice.dataItem.legendDataItem.hide(); } }); } } }]}Grouping small slices
Section titled “Grouping small slices”If you would rather not hide labels or slices themselves, you can use Slice Grouper plugin do dynamically group small slices into one “Other” slice.