Skip to content

Labeling under a bubble in a bubble chart in amcharts4

I was trying to figure out how to label a bubble underneath it in amcharts 4 in a bubble chart like this:

bubble chart example

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.

Answer

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.