I was trying to figure out how to label a bubble underneath it in amcharts 4 in a bubble chart like this:
But I'm not finding anything official about it.
If you push a LabelBullet onto the series, the labels are centered on the data point, then you can use dx/dy to adjust their position, but the problem is on a bubble chart the bubbles change size relative to a data point.
This is what I've come up with so far, but I was hoping somebody might have something more official:
const bulletLabel = series.bullets.push(new am4charts.LabelBullet());
bulletLabel.label.text = options.bubbleLabelText;
bulletLabel.label.paddingTop = 20;
bulletLabel.label.fontSize = 12;
series.heatRules.push(
{
target: bulletLabel,
min: options.minRadius || 5,
max: options.maxRadius || 60,
property: 'dy'
}
);
This also only works when labeling underneath the bubble and I can't think of a way to make it work above the bubble instead.
You'll want to use an adapter for the LabelBullet
's dy
. When that comes in, check the bullet's dataItem.bullets
to grab a reference to its CircleBullet
(used for bubbles), check its radius, then use that for your dy
. You can also provide logic if you want it to go above or under the CircleBullet
, e.g. if a value is less than 10
, go above, otherwise go below.
// Sample data
{
"date": "2015-01-08",
"ay": 8,
"by": 12.3,
"aValue": 5,
"bValue": 13,
bubbleLabelText: "test"
}
const bulletLabel = series.bullets.push(new am4charts.LabelBullet());
bulletLabel.label.text = "{bubbleLabelText}";
bulletLabel.label.fontSize = 12;
bulletLabel.adapter.add('dy', (dy, bullet) => {
let radiusDy = dy;
bullet.dataItem.bullets.iterator()(firstBullet => {
const circleBullet = firstBullet[1];
if (bullet.dataItem.dataContext.bubbleLabelText) {
radiusDy = circleBullet.circle.radius;
if(bullet.dataItem.values.valueY.value >= 10) {
radiusDy += 12;
} else {
radiusDy = -1 * radiusDy - 12;
}
}
})
return radiusDy;
});
Here's a fork of our Bubble XY chart with date-based axis demo with the above code:
https://codepen.io/team/amcharts/pen/a86361c54a4c369e8c49bdd931f8d0f5
You could try doing something similar with having a Label
inside the CircleBullet
(as a child of it), tinker with its valign
and/or the CircleBullet
's contentValign
, but you'd still have to dynamically adjust their dy
so they go a bit above/below the circle.
Hope this helps.