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

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

问题描述

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

  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

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

  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

编辑:
现在,我从Trashgod的示例中插入了DateTimeFormatter:
看起来像这样:

  public class Test {
public static void main(String [] args){
EventQueue.invokeLater(()-> {
ApplicationFrame frame = new ApplicationFrame( CSVTest);
Test test = new Test();
frame.add(test.createChart (温度配置文件));
frame.pack();
frame.setLocationRelativeTo(null);;
frame.setVisible(true);
});
}

私人ChartPanel createChart(String chartTitle){
JFreeChart chart = ChartFactory.createTimeSeriesChart(chartTitle,
Time, Temperature,createDataset(),正确,正确,错误);
ChartPanel chartPanel =新的ChartPanel(图表);
XYPlot plot = chart.getXYPlot();
DateAxis域=(DateAxis)plot.getDomainAxis();
domain.setDateFormatOverride(DateFormat.getDateInstance());
plot.setBackgroundPaint(Color.WHITE);
return chartPanel;
}


私有XYDataset createDataset(){
TimeSeries series = new TimeSeries( Temperature);
TimeSeriesCollection数据集=新的TimeSeriesCollection(系列);
try(FileReader fr = new FileReader( TestCSV.csv);
BufferedReader br = new 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);

Second second = new Second(Date.from(zdt.toInstant()));
series.add(second,Double.valueOf(split [1]));
}
} catch(IOException | SeriesException e){
System.err.println( Error: + e);
}
返回数据集;
}

类似于CSV的文件的第一行仍显示09: 02:53,26.25
然后我得到了DateTimeParseException:无法在索引2处解析文本'2017-07-12T09:02:53 + 02:00'

 线程 AWT-EventQueue-0中的异常java.time.format.DateTimeParseException:无法解析文本'2017-07-12T07:02:53 + 00:00'在索引2 
在java.time.format.DateTimeFormatter.parseResolved0(未知源)在
在java.time.format.DateTimeFormatter.parse(未知源)在Java.time.LocalTime处的
。在org.jfree.chart.demo.Test.createDataset(Test.java:63)处解析(未知源)java.time.LocalTime.parse(在未知源)
在组织内
.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.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

是否显示在图表中?我认为像我一样分裂和转变是可以的,不是吗?现在,我在代码中设置了setDateFormatOverride(),但错误消息以及输出仍然相同。

解决方案

几个问题显而易见:




  • 您绝不能在行中添加任何内容;至少需要这样的东西:

      lines.add(line); 


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

      ChartFactory.createTimeSeriesChart(…)


  • createDataset()返回的 XYDataset 应该是 TimeSeriesCollection ,在其中添加

      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 * /
    公共类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);
    });
    }

    私人ChartPanel createChart(String chartTitle){
    JFreeChart chart = ChartFactory.createTimeSeriesChart(chartTitle,
    Time, Temperature,createDataset(),正确,正确,错误);
    ChartPanel chartPanel =新的ChartPanel(图表);
    XYPlot plot = 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));
    axis.setDateFormatOverride(df);
    return chartPanel;
    }

    私有XYDataset createDataset(){
    TimeSeries series = new TimeSeries( Temperature);
    TimeSeriesCollection数据集=新的TimeSeriesCollection(系列);
    try(FileReader fr = new FileReader( temp.csv);
    BufferedReader br = new BufferedReader(fr)){
    字符串行;
    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);
    }
    返回数据集;
    }
    }


    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天全站免登陆