8

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...?

user1617662
  • 81
  • 1
  • 2

5 Answers5

3

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
    },
Mayank Jaiswal
  • 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
2

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).
Nicolai Ehemann
  • 574
  • 4
  • 10
0

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?

Community
  • 1
  • 1
Ian
  • 590
  • 2
  • 19
-1

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.

SteveP
  • 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
-1

Have you tried to use tick placement ? http://api.highcharts.com/highcharts#xAxis.tickmarkPlacement

Sebastian Bochan
  • 37,348
  • 3
  • 49
  • 75