This tutorial will show how we can add labels inside a Donut series, make them display dynamic info, such as sum of values of all slices, as well resize dynamically to comfortably fit within inner section of a chart.
Adding a label
We can add Label
element directly as a child of a PieSeries
and it will automatically be placed right in the center of the series.
series.children.push(am5.Label.new(root, { text: "Hi there!", centerX: am5.p50, centerY: am5.p50, fontSize: 40, fontWeight: "500", fill: am5.color(0x555555) }));
series.children.push(am5.Label.new(root, { text: "Hi there!", centerX: am5.p50, centerY: am5.p50, fontSize: 40, fontWeight: "500", fill: am5.color(0x555555) }));
Positioning
The label will be placed with its X and Y coordinates directly in the center of the pie/donut. This is why we used centerX
and centerY
settings so that the label is placed by its center, rather than tips top-left corner. This way it will be centered perfectly in the middle.
If we have a multi-line text, we might also use textAlign: "center"
setting:
series.children.push(am5.Label.new(root, { text: "Hi there!\nššš", centerX: am5.p50, centerY: am5.p50, textAlign: "center", fontSize: 40, fontWeight: "500", fill: am5.color(0x555555) }));
series.children.push(am5.Label.new(root, { text: "Hi there!\nššš", centerX: am5.p50, centerY: am5.p50, textAlign: "center", fontSize: 40, fontWeight: "500", fill: am5.color(0x555555) }));
And finally, should we need to micro-adjust vertical position of the label, we can use dy
setting, which moves an element up (negative value) or down by X pixels:
series.children.push(am5.Label.new(root, {
text: "Hi there!",
centerX: am5.p50,
centerY: am5.p50,
fontSize: 40,
fontWeight: "500",
fill: am5.color(0x555555)
}));
Positioning
The label will be placed with its X and Y coordinates directly in the center of the pie/donut. This is why we used centerX
and centerY
settings so that the label is placed by its center, rather than tips top-left corner. This way it will be centered perfectly in the middle.
If we have a multi-line text, we might also use textAlign: "center"
setting:
series.children.push(am5.Label.new(root, { text: "Hi there!\nššš", centerX: am5.p50, centerY: am5.p50, textAlign: "center", fontSize: 40, fontWeight: "500", fill: am5.color(0x555555), dy: -10 }));
series.children.push(am5.Label.new(root, { text: "Hi there!\nššš", centerX: am5.p50, centerY: am5.p50, textAlign: "center", fontSize: 40, fontWeight: "500", fill: am5.color(0x555555), dy: -10 }));
Displaying series data
Having a label as child of the series comes with another advantage: we can use data placeholders to tap into any public or private setting or property of the parent series.
Among other values, PieSeries
holds sum of all its labels in its private setting valueSum
. Let's use that in a label:
series.children.push(am5.Label.new(root, { text: "[fontSize: 20px; #999]TOTAL[/]\n{valueSum.formatNumber()}", textAlign: "center", centerX: am5.p50, centerY: am5.p50, fontSize: 40, fontWeight: "500", populateText: true, fill: am5.color(0x555555) }));
series.children.push(am5.Label.new(root, { text: "[fontSize: 20px; #999]TOTAL[/]\n{valueSum.formatNumber()}", textAlign: "center", centerX: am5.p50, centerY: am5.p50, fontSize: 40, fontWeight: "500", populateText: true, fill: am5.color(0x555555) }));
A few notes about the code above:
- In order for
Label
to populate its data placeholders, thepopulateText: true
setting needs to be set. - We used in-line text styles to format our label.
- We also used an in-line formatting function to apply number formatting to the sum placeholder.
Fitting within donut
Finally, let's make sure our label never bleeds out outside of the inner circle, by employing a series event which kicks in when radius of the series changes, to apply maxWidth
setting to the label.
We will also set oversizedBehavior: "fit"
setting, which will make the label shrink in size, to always fit withing the dynamically-maintained maxWidth
:
series.children.push(am5.Label.new(root, {
text: "Hi there!\nššš",
centerX: am5.p50,
centerY: am5.p50,
textAlign: "center",
fontSize: 40,
fontWeight: "500",
fill: am5.color(0x555555),
dy: -10
}));
Displaying series data
Having a label as child of the series comes with another advantage: we can use data placeholders to tap into any public or private setting or property of the parent series.
Among other values, PieSeries
holds sum of all its labels in its private setting valueSum
. Let's use that in a label:
let label = series.children.push(am5.Label.new(root, { text: "[fontSize: 20px; #999]TOTAL[/]\n{valueSum.formatNumber()}", textAlign: "center", centerX: am5.p50, centerY: am5.p50, fontSize: 40, fontWeight: "500", populateText: true, fill: am5.color(0x555555), oversizedBehavior: "fit" })); // Resize label to fit series series.onPrivate("radius", function(radius) { label.set("maxWidth", radius * 1.5) });
var label = series.children.push(am5.Label.new(root, { text: "[fontSize: 20px; #999]TOTAL[/]\n{valueSum.formatNumber()}", textAlign: "center", centerX: am5.p50, centerY: am5.p50, fontSize: 40, fontWeight: "500", populateText: true, fill: am5.color(0x555555), oversizedBehavior: "fit" })); // Resize label to fit series series.onPrivate("radius", function(radius) { label.set("maxWidth", radius * 1.5) });NOTE
For more stuff available in a PieSeries
, refer to the related class reference: settings, private settings.
Example
See the Pen Sum label inside Pie Chart by amCharts team (@amcharts) on CodePen.