I'm using GWT Highcharts api in my application. this is how it looks:
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.
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);
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;
};
}-*/;
}