Setting tick interval dynamically in highstock chart

2.2k views Asked by At

I'm using GWT Highcharts api in my application. this is how it looks:enter image description here

as you can see there is a small shift between the columns and labels on the x axis. To fix this I wrote the following code:

chart.getXAxis().setTickInterval(7 * 24 * 3600 * 1000);

No shift, but after that the zoom mechnizm of the x axis not works, and there are labels for each week of the year on the x axis(screenshot below). It looks unreadable when the time period is large. So, I want x axis zoom mechanism to work even if the tick interval is set. enter image description here

I've tryed to fix it by adding AxisSetExtremesEventHandler(code below) but it didn't help. Thanks!

chart = new StockChart();
    chart.getXAxis().setTickInterval(7 * 24 * 3600 * 1000);
    chart.setOption("/plotOptions/column/stacking", "normal");
    chart.getNavigator().setEnabled(true);
    DateTimeLabelFormats dateFormat = new DateTimeLabelFormats().setWeek("%e. %b").setYear("%Y");
    chart.getNavigator().getXAxis().setDateTimeLabelFormats(dateFormat);

    chart.getXAxis().setAxisSetExtremesEventHandler(new AxisSetExtremesEventHandler() {

      @Override
      public boolean onSetExtremes(AxisSetExtremesEvent axisSetExtremesEvent) {
        long week = 7 * 24 * 3600 * 1000;
        double max = axisSetExtremesEvent.getMax().doubleValue();
        double min = 0;
        try {
          min = axisSetExtremesEvent.getMin().doubleValue();
        } catch (Exception e) {
          min = axisSetExtremesEvent.getAxis().getExtremes().getDataMin().doubleValue();
          System.out.println(e.getLocalizedMessage());
        }
        double delta = max - min;
        if (delta >= 52 * week) {
          chart.getXAxis().setTickInterval(12 * week);
        } else if (delta >= 26 * week) {
          chart.getXAxis().setTickInterval(4 * week);
        } else {
          chart.getXAxis().setTickInterval(week);
        }
        chart.redraw();
        return true;
      }
    });

    chart.getXAxis().setType(Axis.Type.DATE_TIME).setDateTimeLabelFormats(dateFormat);
    String currentYearWeek = convertToYearWeek(getTimestampFromDate(null));
    chart.setChartTitleText("Historical chart");
    chart.setSize("auto", "100%");

    XAxisLabels xLabel = new XAxisLabels().setColor("#555555").setRotation(-90)
        .setAlign(Align.RIGHT).setY(10).setFormatter(new AxisLabelsFormatter() {
          @Override
          public String format(AxisLabelsData axisLabelsData) {
            String yw = convertToYearWeek(String.valueOf(axisLabelsData.getValueAsLong()));
            return yw;
          }
        });
    chart.getXAxis().setLabels(xLabel);
1

There are 1 answers

0
Mihail On BEST ANSWER

finally I've found solution: ...

chart.getXAxis().setOption("tickPositioner", NativeHelper.getTickPositioner());

...

public class NativeHelper {
public static native JavaScriptObject getTickPositioner() /*-{
    return function(min, max) {
        var pos, week = 7 * 24 * 3600 * 1000, delta = max - min, shift, tickPositions = [];
        if (delta >= 52 * week) {
            shift = 5 * week;
        } else if (delta >= 26 * week) {
            shift = 2 * week;
        } else {
            shift = week;
        }
        roundedMin = Math.floor(min / shift) * shift;
        var minYearWeek = @com.project.NativeHelper::convertToYearWeek(Ljava/lang/String;)(roundedMin +"");
        roundedMin = parseInt(@com.project.NativeHelper::getTimestampFromDate(Ljava/lang/String;)(minYearWeek));
        pos = roundedMin;
        var lastPosition;
        while (pos <= max) {
            tickPositions.push(pos);
            pos += shift;
            if (pos === lastPosition) {
                break;
            }
            lastPosition = pos;
        }
        return tickPositions;
    };
  }-*/;
}