Question

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.

 3  38  3
1 Jan 1970

Solution

 2

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.

2024-07-02
loremus