将 CSV 文件中的数据读入 ArrayList 并在 XY 图表中显示 [英] Read data from CSV file into ArrayList and display in XY Chart

查看:16
本文介绍了将 CSV 文件中的数据读入 ArrayList 并在 XY 图表中显示的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想显示一段时间内的温度曲线.我现在已经阅读了一个类似于 CSV 的文件,它让我知道指示的时间和温度.现在我想使用 JFreeChart 从值中显示 XY 图.文件的原始数据如下所示:

utc,local,celsius2017-07-12T07:02:53+00:00,2017-07-12T09:02:53+02:00,26.252017-07-12T08:02:54+00:00,2017-07-12T10:02:54+02:00,26.082017-07-12T09:02:55+00:00,2017-07-12T11:02:55+02:00,25.782017-07-12T10:02:56+00:00,2017-07-12T12:02:56+02:00,25.962017-07-12T10:51:02+00:00,2017-07-12T12:51:02+02:00,26.142017-07-12T10:51:02+00:00,2017-07-12T12:51:02+02:00,26.14

输出时间&温度值(我已经从原始文件中分离出来)看起来像:

09:02:53,26.2510:02:54,26.0811:02:55,25.7812:02:56,25.9612:51:02,26.1412:51:02,26.14

现在我在 Trashgod 的例子中插入了一个 DateTimeFormatter:看起来像:

公共类测试{公共静态无效主(字符串 [] args){EventQueue.invokeLater(() -> {ApplicationFrame frame = new ApplicationFrame("CSVTest");测试测试=新测试();frame.add(test.createChart("温度曲线"));框架.pack();frame.setLocationRelativeTo(null);;frame.setVisible(true);});}私人 ChartPanel createChart(String chartTitle) {JFreeChart 图表 = ChartFactory.createTimeSeriesChart(chartTitle,"时间", "温度", createDataset(), true, true, false);ChartPanel chartPanel = new ChartPanel(chart);XYPlot 图 = chart.getXYPlot();DateAxis domain = (DateAxis) plot.getDomainAxis();domain.setDateFormatOverride(DateFormat.getDateInstance());plot.setBackgroundPaint(Color.WHITE);返回图表面板;}私人 XYDataset createDataset() {TimeSeries 系列 = new TimeSeries("Temperature");TimeSeriesCollection 数据集 = new TimeSeriesCollection(series);试试 (FileReader fr = new FileReader("TestCSV.csv");BufferedReader br = 新的 BufferedReader(fr)) {字符串线;br.readLine();while ((line = br.readLine()) != null) {String[] split = line.split(",");System.out.println(ZonedDateTime.parse(split[1]).format(DateTimeFormatter.ISO_LOCAL_TIME) + "," +split[2]);ZonedDateTime zdt = ZonedDateTime.of(LocalDate.now(),LocalTime.parse(split[0]), ZoneId.systemDefault());String s = ZonedDateTime.parse(split[0]).format(DateTimeFormatter.ISO_LOCAL_TIME);第二秒 = new Second(Date.from(zdt.toInstant()));series.add(second, Double.valueOf(split[1]));}} catch (IOException | SeriesException e) {System.err.println("错误:" + e);}返回数据集;}

CSV"类文件的第一行仍然显示 09:02:53,26.25然后我得到一个 DateTimeParseException: Text '2017-07-12T09:02:53+02:00' could not be parsed at index 2

线程AWT-EventQueue-0"中的异常java.time.format.DateTimeParseException:无法在索引2处解析文本2017-07-12T07:02:53+00:00"在 java.time.format.DateTimeFormatter.parseResolved0(来源不明)在 java.time.format.DateTimeFormatter.parse(Unknown Source)在 java.time.LocalTime.parse(来源不明)在 java.time.LocalTime.parse(来源不明)在 org.jfree.chart.demo.Test.createDataset(Test.java:63)在 org.jfree.chart.demo.Test.createChart(Test.java:43)在 org.jfree.chart.demo.Test.lambda$0(Test.java:34)

为什么不能读取或显示文件的其余部分?(System.out.println()"应该只作为最后的控制).DateTimeFomatter 是正确的,不是吗?

根据你的方法,我在本地制作的时间不多了&该程序无法翻译.我做错了什么?直接输出怎么用

09:02:53,26.2510:02:54,26.0811:02:55,25.7812:02:56,25.9612:51:02,26.1412:51:02,26.14

显示在图表中?我认为像我一样分裂和转变是可以的,不是吗?现在我在代码中设置了 setDateFormatOverride(),但错误信息以及输出保持不变.

解决方案

几个问题很明显:

  • 你从不向添加任何东西;至少,你需要这样的东西:

    lines.add(line);

  • 考虑创建时间序列,而不是 ChartFactory.createXYLineChart():

    ChartFactory.createTimeSeriesChart(…)

  • createDataset() 返回的 XYDataset 应该是您添加

    import java.awt.Color;导入 java.awt.EventQueue;导入 java.io.BufferedReader;导入 java.io.FileReader;导入 java.io.IOException;导入 java.text.SimpleDateFormat;导入 java.time.ZonedDateTime;导入 java.util.Date;导入 java.util.TimeZone;导入 org.jfree.chart.ChartFactory;导入 org.jfree.chart.ChartPanel;导入 org.jfree.chart.JFreeChart;导入 org.jfree.chart.axis.DateAxis;导入 org.jfree.chart.plot.XYPlot;导入 org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;导入 org.jfree.data.general.SeriesException;导入 org.jfree.data.time.Second;导入 org.jfree.data.time.TimeSeries;导入 org.jfree.data.time.TimeSeriesCollection;导入 org.jfree.data.xy.XY 数据集;导入 org.jfree.ui.ApplicationFrame;/** @see https://stackoverflow.com/a/45173688/230513 */公共类 CSVTest {公共静态无效主(字符串 [] args){EventQueue.invokeLater(() -> {ApplicationFrame frame = new ApplicationFrame("CSVTest");CSVTest 测试 = 新的 CSVTest();frame.add(test.createChart("温度曲线"));框架.pack();frame.setLocationRelativeTo(null);;frame.setVisible(true);});}私人 ChartPanel createChart(String chartTitle) {JFreeChart 图表 = ChartFactory.createTimeSeriesChart(chartTitle,"时间", "温度", createDataset(), true, true, false);ChartPanel chartPanel = new ChartPanel(chart);XYPlot 图 = chart.getXYPlot();plot.setBackgroundPaint(Color.WHITE);XYLineAndShapeRenderer r = (XYLineAndShapeRenderer) plot.getRenderer();r.setBaseShapesVisible(true);DateAxis 轴 = (DateAxis) plot.getDomainAxis();SimpleDateFormat df = new SimpleDateFormat("HH:mm:ssX");df.setTimeZone(TimeZone.getTimeZone("UTC"));轴.setDateFormatOverride(df);返回图表面板;}私人 XYDataset createDataset() {TimeSeries 系列 = new TimeSeries("Temperature");TimeSeriesCollection 数据集 = new TimeSeriesCollection(series);试试 (FileReader fr = new FileReader("temp.csv");BufferedReader br = 新的 BufferedReader(fr)) {字符串线;while ((line = br.readLine()) != null) {String[] s = line.split(",");ZonedDateTime zdt = ZonedDateTime.parse(s[0]);第二秒 = new Second(Date.from(zdt.toInstant()));series.add(second, Double.valueOf(s[2]));}} catch (IOException | SeriesException e) {System.err.println("错误:" + e);}返回数据集;}}

    I would like to display a temperature curve over time. I have now read a file, which is CSV-similar, that let me know the time and the temperature indicated. Now I want to use JFreeChart to display an XY graph from the values. The original data of the file looks as follows:

    utc,local,celsius
    2017-07-12T07:02:53+00:00,2017-07-12T09:02:53+02:00,26.25
    2017-07-12T08:02:54+00:00,2017-07-12T10:02:54+02:00,26.08
    2017-07-12T09:02:55+00:00,2017-07-12T11:02:55+02:00,25.78
    2017-07-12T10:02:56+00:00,2017-07-12T12:02:56+02:00,25.96
    2017-07-12T10:51:02+00:00,2017-07-12T12:51:02+02:00,26.14
    2017-07-12T10:51:02+00:00,2017-07-12T12:51:02+02:00,26.14
    

    The output of time & temperature values (I have separated from the original file) looks like:

    09:02:53,26.25
    10:02:54,26.08
    11:02:55,25.78
    12:02:56,25.96
    12:51:02,26.14
    12:51:02,26.14
    

    EDIT: Now I have inserted a DateTimeFormatter in the example from Trashgod: It looks like:

    public class Test {
    public static void main(String[] args) {
        EventQueue.invokeLater(() -> {
            ApplicationFrame frame = new ApplicationFrame("CSVTest");
            Test test = new Test();
            frame.add(test.createChart("Temperature profile"));
            frame.pack();
            frame.setLocationRelativeTo(null);;
            frame.setVisible(true);
        });
    }
    
    private ChartPanel createChart(String chartTitle) {
        JFreeChart chart = ChartFactory.createTimeSeriesChart(chartTitle,
            "Time", "Temperature", createDataset(), true, true, false);
        ChartPanel chartPanel = new ChartPanel(chart);
        XYPlot plot = chart.getXYPlot();
        DateAxis domain = (DateAxis) plot.getDomainAxis();
        domain.setDateFormatOverride(DateFormat.getDateInstance());
        plot.setBackgroundPaint(Color.WHITE);
        return chartPanel;
    }
    
    
        private XYDataset createDataset() {
        TimeSeries series = new TimeSeries("Temperature");
        TimeSeriesCollection dataset = new TimeSeriesCollection(series);
        try (FileReader fr = new FileReader("TestCSV.csv");
            BufferedReader br = new BufferedReader(fr)) {
            String line;
            br.readLine();
            while ((line = br.readLine()) != null) {
                String[] split = line.split(",");
    
               System.out.println(ZonedDateTime.parse(split[1]).format(DateTimeFormatter.ISO_LOCAL_TIME)  + "," +split[2]);
               ZonedDateTime zdt = ZonedDateTime.of(LocalDate.now(),LocalTime.parse(split[0]), ZoneId.systemDefault());
               String s = ZonedDateTime.parse(split[0]).format(DateTimeFormatter.ISO_LOCAL_TIME);
    
               Second second =  new Second(Date.from(zdt.toInstant()));
               series.add(second, Double.valueOf(split[1]));
            }
        } catch (IOException | SeriesException e) {
            System.err.println("Error: " + e);
        }
        return dataset;
    }
    

    The first line of the "CSV" -like file is still displayed 09:02:53,26.25 Then I get a DateTimeParseException: Text '2017-07-12T09:02:53+02:00' could not be parsed at index 2

    Exception in thread "AWT-EventQueue-0" java.time.format.DateTimeParseException: Text '2017-07-12T07:02:53+00:00' could not be parsed at index 2
    at java.time.format.DateTimeFormatter.parseResolved0(Unknown Source)
    at java.time.format.DateTimeFormatter.parse(Unknown Source)
    at java.time.LocalTime.parse(Unknown Source)
    at java.time.LocalTime.parse(Unknown Source)
    at org.jfree.chart.demo.Test.createDataset(Test.java:63)
    at org.jfree.chart.demo.Test.createChart(Test.java:43)
    at org.jfree.chart.demo.Test.lambda$0(Test.java:34)
    

    Why can not the rest of the file be read nor displayed? ("System.out.println()" should only serve as a control at the end). The DateTimeFomatter is correct, isn´t it?

    With your approach, the time to make locally I come no further & the program can not translate. What did I do wrong? How could it work if the direct output

    09:02:53,26.25
    10:02:54,26.08
    11:02:55,25.78
    12:02:56,25.96
    12:51:02,26.14
    12:51:02,26.14
    

    is displayed in a chart? I think to split and to transform like I did is okay, isn´t it? Now I have setDateFormatOverride () in the code, but the error message, as well as the output remain the same.

    解决方案

    Several problems are evident:

    • You never add anything to lines; at a minimum, you'll need something like this:

      lines.add(line);
      

    • Instead of ChartFactory.createXYLineChart(), consider creating a time series:

      ChartFactory.createTimeSeriesChart(…)
      

    • The XYDataset returned by createDataset() should be a TimeSeriesCollection to which you add a TimeSeries.

    • In createDataset(), iterate though lines, parse the data fields, and add the values to the TimeSeries.

    • The time values given are most closely modeled by LocalTime, but TimeSeries expects to add() coordinates defined by a RegularTimePeriod and a double; see Legacy Date-Time Code concerning the conversion shown below.

    • Note that TimeSeries throws SeriesException for duplicate domain values; as a result, only three of the four lines int eh sample input air charted.

    • Instead of replacing the factory supplied XYLineAndShapeRenderer, get a reference to it for later modification.

    • Alter the chart's size using one of the approaches shown here.

    • Avoid extending top-level containers line ApplicationFrame.

    • Construct and manipulate Swing GUI objects only on the event dispatch thread.

    • Use a try-with-resources statement to ensure that each resource is closed at the end of the statement.

    • As your actual data contains ISO 8601 dates, ZonedDateTime.parse() can be used directly; use setDateFormatOverride() to format the date axis labels; the example below specifies a UTC time zone in ISO 8601 format for easy comparison; comment out the call to setDateFormatOverride() to see the times in your local time zone.

    import java.awt.Color;
    import java.awt.EventQueue;
    import java.io.BufferedReader;
    import java.io.FileReader;
    import java.io.IOException;
    import java.text.SimpleDateFormat;
    import java.time.ZonedDateTime;
    import java.util.Date;
    import java.util.TimeZone;
    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.chart.renderer.xy.XYLineAndShapeRenderer;
    import org.jfree.data.general.SeriesException;
    import org.jfree.data.time.Second;
    import org.jfree.data.time.TimeSeries;
    import org.jfree.data.time.TimeSeriesCollection;
    import org.jfree.data.xy.XYDataset;
    import org.jfree.ui.ApplicationFrame;
    
    /** @see https://stackoverflow.com/a/45173688/230513 */
    public class CSVTest {
    
        public static void main(String[] args) {
            EventQueue.invokeLater(() -> {
                ApplicationFrame frame = new ApplicationFrame("CSVTest");
                CSVTest test = new CSVTest();
                frame.add(test.createChart("Temperature profile"));
                frame.pack();
                frame.setLocationRelativeTo(null);;
                frame.setVisible(true);
            });
        }
    
        private ChartPanel createChart(String chartTitle) {
            JFreeChart chart = ChartFactory.createTimeSeriesChart(chartTitle,
                "Time", "Temperature", createDataset(), true, true, false);
            ChartPanel chartPanel = new ChartPanel(chart);
            XYPlot plot = chart.getXYPlot();
            plot.setBackgroundPaint(Color.WHITE);
            XYLineAndShapeRenderer r = (XYLineAndShapeRenderer) plot.getRenderer();
            r.setBaseShapesVisible(true);
            DateAxis axis = (DateAxis) plot.getDomainAxis();
            SimpleDateFormat df = new SimpleDateFormat("HH:mm:ssX");
            df.setTimeZone(TimeZone.getTimeZone("UTC"));
            axis.setDateFormatOverride(df);
            return chartPanel;
        }
    
        private XYDataset createDataset() {
            TimeSeries series = new TimeSeries("Temperature");
            TimeSeriesCollection dataset = new TimeSeriesCollection(series);
            try (FileReader fr = new FileReader("temp.csv");
                BufferedReader br = new BufferedReader(fr)) {
                String line;
                while ((line = br.readLine()) != null) {
                    String[] s = line.split(",");
                    ZonedDateTime zdt = ZonedDateTime.parse(s[0]);
                    Second second = new Second(Date.from(zdt.toInstant()));
                    series.add(second, Double.valueOf(s[2]));
                }
            } catch (IOException | SeriesException e) {
                System.err.println("Error: " + e);
            }
            return dataset;
        }
    }
    

    这篇关于将 CSV 文件中的数据读入 ArrayList 并在 XY 图表中显示的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆