Reputation: 27312
java.util.Date
is very error prone. It is dead. Long live java.time.*
.
Given a Map<LocalDate, Integer> dateToCountMap
, how do I create a JFreeChart
chart that shows the count per date?
Upvotes: 3
Views: 766
Reputation: 205785
In the case of LocalDate
, you can create a time series chart by constructing the corresponding Day
, as shown below.
LocalDate ld = entry.getKey();
Day d = new Day(ld.getDayOfMonth(), ld.getMonthValue(), ld.getYear());
series.add(d, entry.getValue());
If you have relevant time zone data, you can use it when constructing the Day
. A similar approach can be used for LocalDateTime
and any desired concrete RegularTimePeriod
. See also the approach shown here and here, given an Instant
. Moreover, a custom implementation of XYDataset
, seen here, can simply convert the result of toEpochMilli()
and return it from getX()
.
import java.awt.Dimension;
import java.awt.EventQueue;
import java.text.DateFormat;
import java.time.LocalDate;
import java.util.HashMap;
import java.util.Map;
import javax.swing.JFrame;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.DateAxis;
import org.jfree.chart.plot.XYPlot;
import org.jfree.data.time.Day;
import org.jfree.data.time.TimeSeries;
import org.jfree.data.time.TimeSeriesCollection;
import org.jfree.data.xy.XYDataset;
/**
* @see https://stackoverflow.com/a/66713994/230513
* @see https://stackoverflow.com/a/12481509/230513
*/
public class XYTest {
private static final int N = 16;
private XYDataset createDataset() {
long t = LocalDate.now().toEpochDay();
Map<LocalDate, Integer> dateToCountMap = new HashMap<>();
for (int i = 0; i < N; i++) {
dateToCountMap.put(LocalDate.ofEpochDay(t + i), (int) Math.pow(i, 1.61));
}
TimeSeries series = new TimeSeries("Data)");
for (Map.Entry<LocalDate, Integer> entry : dateToCountMap.entrySet()) {
LocalDate ld = entry.getKey();
Day d = new Day(ld.getDayOfMonth(), ld.getMonthValue(), ld.getYear());
series.add(d, entry.getValue());
}
return new TimeSeriesCollection(series);
}
private JFreeChart createChart(final XYDataset dataset) {
JFreeChart chart = ChartFactory.createTimeSeriesChart(
"Test", "Day", "Value", dataset, false, false, false);
XYPlot plot = (XYPlot) chart.getPlot();
DateAxis domain = (DateAxis) plot.getDomainAxis();
domain.setDateFormatOverride(DateFormat.getDateInstance());
return chart;
}
static void create() {
JFrame frame = new JFrame("Bar Chart");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
XYTest xyTest = new XYTest();
XYDataset dataset = xyTest.createDataset();
JFreeChart chart = xyTest.createChart(dataset);
ChartPanel chartPanel = new ChartPanel(chart) {
@Override
public Dimension getPreferredSize() {
return new Dimension(800, 300);
}
};
frame.add(chartPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(XYTest::create);
}
}
Upvotes: 4