I'm generating a Highcharts graph, but some details I can't solve.
- The labels are confused with each other.
- The labels of the 2 red splines show them horizontally, not vertically, and only at position 0 on the left.
I should leave the graph as similar as possible to:
This is the code:
Highcharts.chart('container', {
chart: {
zoomType: 'x'
// ,styledMode: true
},
title: {
text: 'Indicador'
},
subtitle: {
text: 'Subtitulo'
},
xAxis: {
title: {
text: 'Titulo 1'
}
/*,
min: 20,
max: 40,
scrollbar: {
enabled: true
},*/
},
yAxis: {
title: {
text: 'Titulo 2'
}
},
legend: {
layout: 'vertical',
align: 'right',
verticalAlign: 'middle'
},
plotOptions: {
spline: {
dataLabels: {
enabled: true,
formatter: function() {
return 1;
},
y: -30 //separacion del indicador
}
},
series: {
label: {
connectorAllowed: false
},
dataLabels: {
enabled: true,
formatter: function() {
var color = '';
var serie = this.series.name;
if (serie == '2017-Rendimiento') {
color = 'purple';
} else if (serie == '2018-Rendimiento') {
color = 'green';
} else if (serie == '2017-RendimientoF') {
color = 'Blue';
} else if (serie == '2018-RendimientoF') {
color = 'Brown';
} else {
if (this.x == 0) { //si posicion es 0 muestre spline con color
color = 'red'; //color spline
} else {
color = 'white';
}
}
return '<span style="color:' + color + '">' + this.y + '</span>';
},
align: 'center',
color: 'black',
rotation: -90
}
/*,
pointStart: 2010*/
}
},
series: [{
name: '2017-Rendimiento',
data: [275, 270, 276, 265, 271, null, 270, 271, 255, 260, 255, 262],
color: 'purple'
}, {
name: '2018-Rendimiento',
data: [260, 265, null, 270, 263, 266, 264, 264, 254, 264, 254, 264],
color: 'green',
lineWidth: 4
}, {
name: '2017-RendimientoF',
data: [210, 222, null, 222, 220, 210, 210, 210, 223, 210, 218, 225],
color: 'blue',
height: 5
}, {
name: '2018-RendimientoF',
data: [null, 225, 225, 225, 225, 225, 235, 245, 225, 215, 215, 229],
color: 'brown',
lineWidth: 4
}, {
type: 'spline',
name: '2018-Meta Core',
data: [267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267],
marker: {
lineWidth: 2,
lineColor: 'red',
fillColor: 'red',
symbol: 'circle'
},
color: 'red'
}, {
type: 'spline',
name: '2017-Meta Core',
data: [220, 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, 220],
marker: {
lineWidth: 2,
lineColor: 'red',
fillColor: 'red',
symbol: 'circle'
},
color: 'red'
}],
responsive: {
rules: [{
condition: {
maxWidth: 500
},
chartOptions: {
legend: {
layout: 'horizontal',
align: 'center',
verticalAlign: 'bottom'
}
}
}]
}
});
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script src="https://code.highcharts.com/stock/highstock.js"></script>
<script src="https://code.highcharts.com/stock/modules/exporting.js"></script>
<script src="https://code.highcharts.com/stock/modules/export-data.js"></script>
<div id="container" class="chart"></div>
Highcharts does not have a built-in function to "split" labels when they overlap. The only thing left to do is place them dynamically. I prepared an example where the labels are added dynamically after the chart is loaded, here it is:
The event
load
is executed after graphic is loaded, calling the functionloadLabels
that iterates through the series and inserts the labels (see this part of the code to understand it). The first thing I do is identify the series through the color (for greater efficiency you could add aid
to the series and switch them by this attribute), if the series is red I add the label only in the first point (point.x == 0
). If the series is purple or green, I ask for the value of each point (point.y > 267
). If it's bigger, I put the label above the line, if it's smaller, it's below. In the case of the brown and blue series, the logic is the same, except that I take the value 220 as a reference.As you can see, some labels also overlap. I can't do anything else here, it's up to you to decide what criteria to use in these specific cases.
I leave you the script working: https://jsfiddle.net/ZottoSL/xdekn8h4/97/
And the documentation on how to dynamically load labels: https://api.highcharts.com/class-reference/Highcharts.SVGRenderer#label
PS: I removed the attribute
plotOptions
as it is obviously not needed.