XChart
XChart copied to clipboard
Annotation for Date axis
XYChart.addSeries()
accepts a list of java.util.Date
, but Annotation*
constructor only accepts a double. I tried to convert Date to millis, but annotation is always rendered before the actual date. There's nothing similar in tests or examples, so could someone please tell me what is the proper way to calc annotation position for the Date axis type?
Ok, I think it's a bug. Chart labels should start from 2012, not from 2011.
List<LocalDate> x = new ArrayList<>();
List<Integer> y = new ArrayList<>();
x.add(LocalDate.of(2011, 12, 1));
y.add(10);
for (int year = 2012; year <= 2022; year++) {
var e = generate(year);
x.addAll(e.getKey());
y.addAll(e.getValue());
}
for (int i = 0; i < x.size(); i++) {
System.out.println(x.get(i) + " - " + y.get(i));
}
Collections.sort(x);
XYChart chart = new XYChartBuilder()
.width(1600)
.theme(Styler.ChartTheme.GGPlot2)
.xAxisTitle("Date")
.yAxisTitle("Message Count")
.build();
XYSeries series = chart.addSeries(
"s1",
x.stream().map(ld -> Date.from(ld.atStartOfDay(ZoneId.systemDefault()).toInstant())).collect(Collectors.toList()),
y
);
var aDate = LocalDate.of(2014, 6, 1).atStartOfDay().toInstant(ZoneOffset.UTC);
chart.addAnnotation(new AnnotationLine(aDate.toEpochMilli(), true, false));
static Map.Entry<List<LocalDate>, List<Integer>> generate(int year) {
var dates = new ArrayList<LocalDate>();
var values = new ArrayList<Integer>();
for (int month = 12; month >= 1; month--) {
dates.add(LocalDate.of(year, month, 10));
values.add(ThreadLocalRandom.current().nextInt(10, 50));
}
return Map.entry(dates, values);
}
Yup, definitely a bug. For this specific time scale it seems.