heshjse
heshjse

Reputation: 910

how to limit the label size only for bubble diameter in high charts

In my high charts some bubbles have long labels.I need to limit that label only for diameter size of of that bubble. (As a example flowing graph XIMT-DL should be XIMT...). Do you know the way to do that?

code example: code example

enter image description here

Upvotes: 0

Views: 670

Answers (1)

Wojciech Chmiel
Wojciech Chmiel

Reputation: 7372

Unfortunately, this behavior is not implemented in the core. However, it can be achieved easily by implementing your custom logic. In the chart.events.render callback check the width of each point and width of its data label. When data label is wider than the point just trim it and add dots if necessary. Check the code and demo posted below:

Code:

  chart: {
    type: 'packedbubble',
    height: '100%',
    events: {
      render: function() {
        const chart = this;

        chart.series.forEach(series => {
          series.points.forEach(point => {

            if (point.graphic.width > 1) {
              if (point.dataLabel.width > point.graphic.width) {
                let indic = (
                    (point.dataLabel.width - point.graphic.width) /
                    point.dataLabel.width
                  ),
                  text = point.series.name,
                  textLen = text.length,
                  maxTextLen = Math.floor(textLen * (1 - indic)),
                  newText,
                  dotted,
                  substringLen;

                dotted = maxTextLen > 2 ? '..' : '.';
                substringLen = maxTextLen > 2 ? 2 : 1;
                newText = text.substring(0, maxTextLen - substringLen) + dotted;

                point.dataLabel.text.element.innerHTML =
                  '<tspan>' + newText + '</tspan>';

                point.dataLabel.text.translate(
                  (point.dataLabel.width - point.graphic.width) / 2,
                  0
                );
              }
            }

          });
        })
      }
    }
  }

Demo:

API reference:


Another approach is to add an event listener afterRender and modify labels there so that chart options are defined separately.

Code:

(function(H) {
  H.addEvent(H.Series, 'afterRender', function() {
    console.log(this);

    const chart = this.chart;

    chart.series.forEach(series => {
      if (series.points && series.points.length) {
        series.points.forEach(point => {

          if (point.graphic.width > 1) {
            if (point.dataLabel.width > point.graphic.width) {
              let indic = (
                  (point.dataLabel.width - point.graphic.width) /
                  point.dataLabel.width
                ),
                text = point.series.name,
                textLen = text.length,
                maxTextLen = Math.floor(textLen * (1 - indic)),
                newText,
                dotted,
                substringLen;

              dotted = maxTextLen > 2 ? '..' : '.';
              substringLen = maxTextLen > 2 ? 2 : 1;
              newText = text.substring(0, maxTextLen - substringLen) + dotted;

              point.dataLabel.text.element.innerHTML =
                '<tspan>' + newText + '</tspan>';

              point.dataLabel.text.translate(
                (point.dataLabel.width - point.graphic.width) / 2,
                0
              );
            }
          }

        });
      }
    })
  });
})(Highcharts);

Demo:

Upvotes: 1

Related Questions