-
Notifications
You must be signed in to change notification settings - Fork 6
Description
I want to be able to create linked time series charts with Charba, where zooming and panning in one zooms in the other.
The previous issue #88 derived into a discussion about this, so I wanted to properly continue it here.
When doing my tests to synchronize charts, I realized that it wasn't working because of the random dataset example I was working with.
With the following code:
private TimeSeriesLineChartWidget createLineChart() {
TimeSeriesLineChartWidget chart = new TimeSeriesLineChartWidget();
TimeSeriesLineOptions chartOptions = chart.getOptions();
chartOptions.setResponsive(true);
chartOptions.setAspectRatio(3.5);
chartOptions.setMaintainAspectRatio(true);
chartOptions.getLegend().setDisplay(true);
chartOptions.getTitle().setDisplay(true);
chartOptions.getTitle().setText("oui");
chartOptions.getTooltips().setEnabled(true);
chartOptions.setAnimationEnabled(false);
chartOptions.getDecimation().setEnabled(true);
chartOptions.getDecimation().setAlgorithm(DecimationAlgorithm.MIN_MAX);
// tooltip interaction options
Interaction interaction = chartOptions.getInteraction();
interaction.setMode(InteractionMode.NEAREST);
interaction.setAxis(InteractionAxis.X);
interaction.setIntersect(false);
// axes options
CartesianTimeSeriesAxis xAxis = chartOptions.getScales().getTimeAxis();
xAxis.getTitle().setDisplay(true);
xAxis.getTitle().setText("Time");
xAxis.getTicks().setSource(TickSource.DATA);
xAxis.getTime().setUnit(TimeUnit.SECOND);
xAxis.getTime().getDisplayFormats().setDisplayFormat(TimeUnit.SECOND, "m’ss”");
xAxis.getTime().getDisplayFormats().setDisplayFormat(TimeUnit.MINUTE, "H:mm:ss");
xAxis.getTime().getDisplayFormats().setDisplayFormat(TimeUnit.HOUR, "H:mm:ss");
xAxis.setMin((ScaleContext context) -> {
return _minDate;
});
xAxis.setMax((ScaleContext context) -> {
return _maxDate;
});
CartesianLinearAxis yAxis = chartOptions.getScales().getLinearAxis();
yAxis.getTitle().setDisplay(true);
yAxis.getTitle().setText("Fromage");
yAxis.setDisplay(true);
yAxis.setBeginAtZero(true);
// zoom options
ZoomOptions zoomOptions = new ZoomOptions();
zoomOptions.getPan().setEnabled(true);
zoomOptions.getPan().setModifierKey(ModifierKey.ALT);
zoomOptions.getPan().setMode(Mode.X);
zoomOptions.getZoom().setMode(Mode.X);
zoomOptions.getZoom().getDrag().setEnabled(true);
zoomOptions.getZoom().getWheel().setEnabled(true);
zoomOptions.getZoom().getWheel().setSpeed(0.3);
zoomOptions.getZoom().getWheel().setModifierKey(ModifierKey.ALT);
zoomOptions.getZoom().getPinch().setEnabled(true);
zoomOptions.store(chart);
zoomOptions.getZoom().setCompletedCallback((ZoomContext context) -> {
CartesianTimeSeriesAxis timeAxis = chartOptions.getScales().getTimeAxis();
ScaleItem scaleAxis = chart.getNode().getScales().getItems().get(timeAxis.getId().value());
for (TimeSeriesLineChartWidget rawChart : _rawCharts) {
if (rawChart == chart)
continue;
_minDate = scaleAxis.getMinAsDate();
_maxDate = scaleAxis.getMaxAsDate();
rawChart.update();
}
});
long start = new Date().getTime();
TimeSeriesItem[] data = new TimeSeriesItem[20];
for (int i = 0; i < data.length; i++)
data[i] = new TimeSeriesItem(new Date((long) i + start), Random.nextDouble());
// dataset
TimeSeriesLineDataset dataset = chart.newDataset();
dataset.setLabel("fromage");
dataset.setBorderColor(Color.CHARBA);
dataset.setBorderWidth(1);
dataset.setPointRadius(0);
dataset.setParsing(false);
dataset.setTimeSeriesData(data);
chart.getData().setDatasets(dataset);
_rawCharts.add(chart);
return chart;
}
as soon as I try to zoom, the synchronization completely breaks and the second graph shows nothing (the actual graph is there, but hidden far to the right).
I realized after hours of debugging, with the help of a coworker, that the dataset may have been too short and too compact - maybe I was losing precision on the dates?
And so I tried the code above, with these modifications:
TimeSeriesItem[] data = new TimeSeriesItem[20];
for (int i = 0; i < data.length; i++)
- data[i] = new TimeSeriesItem(new Date((long) i + start), Random.nextDouble());
+ data[i] = new TimeSeriesItem(new Date(((long) i) * 17271 + start), Random.nextDouble());
I'm glad I managed to fix my problem, but I was wondering why the dates I generated created this problem in the first place. For our use-case, it will probably not be relevant, but it's probably important to mention here that such a thing is happening.