skip to Main Content

I’m adjusting some values for dataLabels in a render function, but I need to redraw a chart to apply these changes. Here’s my render function:

render: function () {
  const points = this.series[0].points;
          
  for (var i = 0; i < points.length; i++) {

    if (i < points.length - 1) {
      const dataLabel1 = (points[i] as any).dataLabel
      const dataLabel2 = (points[i + 1] as any).dataLabel

      if ((dataLabel1.x + dataLabel1.width) >= dataLabel2.x) {

        dataLabel1.attr({
          y: dataLabel1.y - (dataLabel1.height + 2),
          fill: points[i].color
        });
 
      }
    }
  }
}

But nothing changes until, for example, the width of a chart is changed. So, I suppose that changes needs the chart to be rendered again to be applied.

I tried to redraw my chart like this:

render: function () {
  const points = this.series[0].points;
          
  for (var i = 0; i < points.length; i++) {

    if (i < points.length - 1) {
      const dataLabel1 = (points[i] as any).dataLabel
      const dataLabel2 = (points[i + 1] as any).dataLabel

      if ((dataLabel1.x + dataLabel1.width) >= dataLabel2.x) {

        dataLabel1.attr({
          y: dataLabel1.y - (dataLabel1.height + 2),
          fill: points[i].color
        });
 
      }
    }
  }

  this.redraw();
}

But this leads to the infinite render loop. How can I redraw a chart here or is there any other way to apply the changes?

2

Answers


  1. I think you don’t need to call this.redraw() in your render function. You can use the update method for data labels to adjust the position and fill color of data labels in a chart and have those changes immediately reflected. Something like this should work,

    render: function () {
      const points = this.series[0].points;
              
      for (var i = 0; i < points.length; i++) {
    
        if (i < points.length - 1) {
          const dataLabel1 = (points[i] as any).dataLabel
          const dataLabel2 = (points[i + 1] as any).dataLabel
    
          if ((dataLabel1.x + dataLabel1.width) >= dataLabel2.x) {
            dataLabel1.update({
              y: dataLabel1.y - (dataLabel1.height + 2),
              color: points[i].color // Use 'color' instead of 'fill' to set the text color
            });
          }
        }
      }
    }
    
    Login or Signup to reply.
  2. You can conditionally redraw the chart, for example:

    let allowChartRedraw = true;
    
    Highcharts.chart('container', {
      chart: {
        events: {
          render: function() {
            if (allowChartRedraw) {
              allowChartRedraw = false;
    
              this.redraw();
    
              allowChartRedraw = true;
            }
          }
        }
      },
      ...
    });
    

    However, you probably don’t need to do that. Using the attr method for data labels should be enough, please check this live example: https://jsfiddle.net/BlackLabel/tyL96pxd/

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search