问题描述
我想显示一段时间内的温度曲线.我现在已经阅读了一个类似于 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.25Then 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 图表中显示的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!