【发布时间】:2021-03-19 09:21:04
【问题描述】:
java.util.Date 非常容易出错。它已经死了。万岁java.time.*。
给定一个Map<LocalDate, Integer> dateToCountMap,我如何创建一个显示每个日期计数的JFreeChart 图表?
【问题讨论】:
标签: java jfreechart java-time
java.util.Date 非常容易出错。它已经死了。万岁java.time.*。
给定一个Map<LocalDate, Integer> dateToCountMap,我如何创建一个显示每个日期计数的JFreeChart 图表?
【问题讨论】:
标签: java jfreechart java-time
以LocalDate为例,可以通过构造对应的Day来创建时序图,如下图。
LocalDate ld = entry.getKey();
Day d = new Day(ld.getDayOfMonth(), ld.getMonthValue(), ld.getYear());
series.add(d, entry.getValue());
如果你有相关的时区数据,可以在构造Day时使用。类似的方法可用于LocalDateTime 和任何所需的具体RegularTimePeriod。另请参阅here 和here 显示的方法,给定Instant。此外,XYDataset 的自定义实现,见here,可以简单地将toEpochMilli() 的结果转换并从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);
}
}
【讨论】:
RegularTimePeriod 测试现在使用java.time。