2017-07-18 37 views
0

我想顯示一段時間內的溫度曲線。我現在讀了一個類似CSV的文件,讓我知道時間和溫度。現在我想使用JFreeChart從這些值中顯示一個XY圖形。看起來 文件的原始數據如下:從CSV文件讀取數據到ArrayList並在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 

時間&溫度值的輸出(I已經從原始文件分開)看起來像:

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 

編輯: 現在我插入創建DateTimeFormatter在例如由trashgold: 它看起來像:

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

類似「CSV」的文件的第一行仍然顯示09:02:53,26.25 然後我得到一個DateTimeParseException:文本'2017-07-12T09:02:53 + 02:00'無法在索引處解析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) 

爲什麼文件的其餘部分不能被讀取和不顯示? (「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 

顯示在圖表中嗎?我認爲要像我一樣分裂並改造是好的,是不是?現在我在代碼中設置了DateFormatOverride(),但錯誤消息以及輸出保持不變。

回答

1

幾個問題是顯而易見的:

  • 你永遠不添加任何lines;至少,你需要這樣的事:

    lines.add(line); 
    
  • 相反的ChartFactory.createXYLineChart(),考慮創建一個時間序列:

    ChartFactory.createTimeSeriesChart(…) 
    
  • XYDataset通過createDataset()返回應該是一個TimeSeriesCollection到你添加一個TimeSeries

  • createDataset()中,通過lines迭代,解析數據字段,並將值添加到TimeSeriesTimeSeries鑑於LocalTime最密切建模

  • 的時間值,但是希望通過RegularTimePerioddouble定義add()座標;有關如下所示的轉換,請參閱Legacy Date-Time Code

  • 請注意,TimeSeries針對重複的域值引發SeriesException;結果,只有三條線在樣本輸入航空圖中繪製。

  • 取而代之的是替代工廠提供的XYLineAndShapeRenderer,請參考它以供日後修改。

  • 使用here所示方法之一改變圖表的尺寸。

  • 避免延伸頂級容器行ApplicationFrame

  • 構建和操作Swing GUI對象只有event dispatch thread上。

  • 使用try-with-resources statement確保每個資源在語句結束時關閉。

  • 由於您的actual data包含ISO 8601日期,所以可以直接使用ZonedDateTime.parse();使用setDateFormatOverride()來格式化日期軸標籤;以下示例指定了ISO 8601格式的UTC時區以便於比較;請撥打setDateFormatOverride()以查看您當地時區的時間。

image

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; 
    } 
} 
+0

謝謝你的建議。但現在問題是分裂。 「CSV」類似文件被拆分,最後它看起來像「時間和溫度」,看起來像這樣: 2017-07-12T07:02:53 + 00:00,2017-07-12T09:02: 53 + 02:00,26.25 隨着你的方法,在本地製作的時間我不會再來,程序也無法翻譯。是什麼讓我錯了? 如果直接輸出如何工作: 11:02:55,25.78 12:02:56,25.96 顯示在圖表中嗎?我認爲要像我一樣分裂並改造是好的,是不是? – LostInTranslate

+0

看起來你需要一個'DateTimeFormatter';所引用的教程有一節關於解析。現在您已經有了一個工作示例,請[編輯](https://stackoverflow.com/posts/45166365/edit)您的問題,以包含顯示_actual_數據和您的修訂方法的[mcve]。 – trashgod

+0

我有修改的問題,現在編輯添加了相應的錯誤消息 – LostInTranslate

相關問題