8
votes

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

5 Answers

3
votes

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
    },
2
votes

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:

  1. 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)
  2. Calculate offset between the first two labels (the offset is the same for all labels)
  3. Set half of the offset as margin-left of all labels, effectively shifting them half the offset to the right.
  4. Remove the rightmost label (moved outside of chart, by sometimes partly visible).
0
votes

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?

-1
votes

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.