将数据从CSV文件读取到ArrayList中并显示在XY图表中 [英] Read data from CSV file into ArrayList and display in XY Chart
问题描述
我想显示一段时间内的温度曲线。我现在已经阅读了一个类似于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 bycreateDataset()
should be aTimeSeriesCollection
to which you add aTimeSeries
.In
createDataset()
, iterate thoughlines
, parse the data fields, and add the values to theTimeSeries
.The time values given are most closely modeled by
LocalTime
, butTimeSeries
expects toadd()
coordinates defined by aRegularTimePeriod
and adouble
; see Legacy Date-Time Code concerning the conversion shown below.Note that
TimeSeries
throwsSeriesException
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; usesetDateFormatOverride()
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 tosetDateFormatOverride()
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屋!