I am drawing a line chart with monthly data points. However, I want the scale to display year strings only. So far, so easy. However, as far as I can see, Highcharts will always draw the xAxis labels relative to the ticks... and I am required to display them centered between ticks. Is there some simple way of doing this that I am missing, please...?
5 Answers
According to my understanding, the behavior you desire is:
http://jsfiddle.net/msjaiswal/U45Sr/2/
Let me break down the solution :
1. Monthly Data Points
One data point corresponding to one month :
var data = [
[Date.UTC(2003,1),0.872],
[Date.UTC(2003,2),0.8714],
[Date.UTC(2003,3),0.8638],
[Date.UTC(2003,4),0.8567],
[Date.UTC(2003,5),0.8536],
[Date.UTC(2003,6),0.8564],
..
]
2. Scale to display only yearly ticks
Use chart options like this:
xAxis: {
minRange : 30 * 24 * 3600 * 1000, //
minTickInterval: 12* 30 * 24 * 3600 * 1000 // An year
},

- 12,338
- 7
- 39
- 41
-
The problem is that the year label is under the "January", and that's not in the center of the year. – mirelon Jun 04 '13 at 07:49
There is no simple, out-of-the-box solution. You have to use events and reposition the labels accordingly. Here is a sample solution that also works when resizing the browser window (or otherwise forcing the chart to redraw), even when the tick count changes: http://jsfiddle.net/McNetic/eyyom2qg/3/
It works by attaching the same event handler to both the load
and the redraw
events:
$('#container').highcharts({
chart: {
events: {
load: fixLabels,
redraw: fixLabels
}
},
[...]
The handler itself looks like this:
var fixLabels = function() {
var labels = $('div.highcharts-xaxis-labels span', this.container).sort(function(a, b) {
return +parseInt($(a).css('left')) - +parseInt($(b).css('left'));
});
labels.css('margin-left',
(parseInt($(labels.get(1)).css('left')) - parseInt($(labels.get(0)).css('left'))) / 2
);
$(labels.get(this.xAxis[0].tickPositions.length - 1)).remove();
};
Basically, it works like this:
- Get all existing labels (when redrawn, this includes newly added ones). 2. Sort by css property 'left' (they are not sorted this way after some redrawing)
- Calculate offset between the first two labels (the offset is the same for all labels)
- Set half of the offset as margin-left of all labels, effectively shifting them half the offset to the right.
- Remove the rightmost label (moved outside of chart, by sometimes partly visible).

- 574
- 4
- 10
This can be done with a workaround by manually adjusting the label positioning via a callback (called on both load and redraw). Please see the fiddle linked to in my comment on this post: Highcharts - how can I center labels on a datetime x-axis?
There are several xAxis options which may help do what you want.
http://api.highcharts.com/highcharts#xAxis.labels
Take a look at 'align' which specifies whether the labels are to the left or right of the tick, and also 'x' which allows you to specify a x-offset for the label from the tick.

- 18,840
- 9
- 47
- 60
-
I'm doing that already. The data, however, is dynamic and as the gaps between ticks widen, the labels look more and more implausible glued to the ticks... I don't know if I can get hold of the number of ticks, so that I can calculate the distance between them and set the x-offset of centre-aligned labels on the fly... – user1617662 Apr 08 '13 at 13:02
Have you tried to use tick placement ? http://api.highcharts.com/highcharts#xAxis.tickmarkPlacement

- 37,348
- 3
- 49
- 75