【问题标题】:JFreeChart: create a chart with java.time.LocalDate or java.time.LocalDateTimeJFreeChart:使用 java.time.LocalDate 或 java.time.LocalDateTime 创建图表
【发布时间】:2021-03-19 09:21:04
【问题描述】:

java.util.Date 非常容易出错。它已经死了。万岁java.time.*。

给定一个Map<LocalDate, Integer> dateToCountMap,我如何创建一个显示每个日期计数的JFreeChart 图表?

【问题讨论】:

    标签: java jfreechart java-time


    【解决方案1】:

    以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);
        }
    }
    

    【讨论】:

    • 完美!我希望 JFreeChart 在未来的版本中也能直接支持它。
    • 我看到RegularTimePeriod 测试现在使用java.time。
    猜你喜欢
    • 1970-01-01
    • 2016-12-14
    • 2012-04-15
    • 1970-01-01
    • 2017-09-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-06
    相关资源
    最近更新 更多