javascripthighchartsoverlap

Annotations labels overlapping when using addAnnotation


I use Highcharts to render a scatter chart.

I'm having an issue when adding annotations on this chart. As I load my data from an asynchronous request based on user settings, I add my data and my annotations on a chart that is already rendered. However, when using addAnnotation function, I can't keep the labels from overlapping.

chart.addAnnotation({
  draggable: "",
  id: "chartAnnotations",
  labels: annotationsLabels,
  labelOptions: {
    align: "left",
    allowOverlap: false,
    borderColor: "#5c5c5c",
    shape: 'connector'
  }
}); 

Here is a sample adding series and annotation on a pre-rendered chart. https://jsfiddle.net/k29h6oqc/2/

Thank you for your help.


Solution

  • I managed to resolve your issue by simply adding annotations from a separate function on chart's load event:

    events: {
      load: function() {
        addAnnotations(this);
      }
    }
    

    const randomString = (length) =>
      Array(length)
      .fill('')
      .map(() => '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' [Math.floor(Math.random() * 62)])
      .join('');
    
    let chartData = [];
    
    for (i = 0; i < 20; i++) {
      chartData.push({
        id: String.fromCharCode(i + 65),
        name: randomString(20),
        x: Math.random() * 100,
        y: Math.random() * 100
      });
    }
    
    function createChartAndAnnotations() {
      let options = {
        chart: {
          renderTo: "container",
          type: 'scatter',
          plotBorderWidth: 1,
          events: {
            load: function() {
              addAnnotations(this);
            }
          }
        },
        xAxis: {
          gridLineWidth: 1
        },
        yAxis: {
          startOnTick: false,
          endOnTick: false
        },
        series: [{
          data: chartData,
          marker: {
            symbol: "square"
          }
        }]
      };
    
      let chart = new Highcharts.Chart(options);
    
      function addAnnotations(chart) {
        let annotationsLabels = chartData.map(el => ({
          allowOverlap: false,
          point: el.id.toString(),
          text: el.name
        }));
    
        chart.addAnnotation({
          draggable: "",
          id: "chartAnnotations",
          labels: annotationsLabels,
          labelOptions: {
            align: "left",
            allowOverlap: false,
            borderColor: "#5c5c5c",
            shape: 'connector'
          }
        });
      }
    }
    
    createChartAndAnnotations();
    #container {
        height: 400px;
    }
    
    .highcharts-figure,
    .highcharts-data-table table {
        min-width: 310px;
        max-width: 800px;
        margin: 1em auto;
    }
    
    .highcharts-data-table table {
        font-family: Verdana, sans-serif;
        border-collapse: collapse;
        border: 1px solid #ebebeb;
        margin: 10px auto;
        text-align: center;
        width: 100%;
        max-width: 500px;
    }
    
    .highcharts-data-table caption {
        padding: 1em 0;
        font-size: 1.2em;
        color: #555;
    }
    
    .highcharts-data-table th {
        font-weight: 600;
        padding: 0.5em;
    }
    
    .highcharts-data-table td,
    .highcharts-data-table th,
    .highcharts-data-table caption {
        padding: 0.5em;
    }
    
    .highcharts-data-table thead tr,
    .highcharts-data-table tr:nth-child(even) {
        background: #f8f8f8;
    }
    
    .highcharts-data-table tr:hover {
        background: #f1f7ff;
    }
    <script src="https://code.highcharts.com/stock/9/highstock.js"></script>
    <script src="https://code.highcharts.com/9/highcharts-more.js"></script>
    <script src="https://code.highcharts.com/9/modules/annotations.js"></script>
    
    <figure class="highcharts-figure">
        <div id="container"></div>
    </figure>

    To be honest, I'm not quite sure why it ignored the overlap in your original implementation. Something-something asynchronous execution I guess.