2014-08-31 84 views
0

這是我遇到的一個拐角案例。以下是SSCCE:帶有單個數據點的XYDataset:沒有任何繪圖

import java.util.*; 
import java.io.*; 
import java.awt.Color; 

import java.awt.image.BufferedImage; 
import javax.imageio.ImageIO; 

import org.jfree.chart.*; 
import org.jfree.chart.plot.*; 
import org.jfree.chart.axis.*; 
import org.jfree.data.time.*; 
import org.jfree.data.xy.XYDataset; 

public class FooMain { 

    public static void main(String args[]) throws Exception { 
     BufferedImage img = timeAxisSSEProcessionsChart(); 
     ImageIO.write(img, "png", new File("img.png")); 
     System.exit(0); 
    } 


    private static XYDataset createTimeSeriesDataset() { 
     TimeSeries timeSeries = new TimeSeries("series-a"); 
     timeSeries.add(RegularTimePeriod.createInstance(Millisecond.class, new java.util.Date(0) , TimeZone.getTimeZone("Zulu")), 100); 
     // if below line is commented out, nothing is plotted: 
     timeSeries.add(RegularTimePeriod.createInstance(Millisecond.class, new java.util.Date(1000), TimeZone.getTimeZone("Zulu")), 100); 
     TimeSeriesCollection rv = new TimeSeriesCollection(); 
     rv.addSeries(timeSeries); 
     return rv; 
    } 


    public static BufferedImage timeAxisSSEProcessionsChart() throws Exception { 
     XYDataset dataset = createTimeSeriesDataset(); 
     JFreeChart chart = ChartFactory.createTimeSeriesChart("title", "date", "series-a", dataset, true, true, false); 
     InputStream in = new ByteArrayInputStream(imageBytesFromChart(chart, 600, 400)); 
     return ImageIO.read(in); 
    } 

    private static byte[] imageBytesFromChart(JFreeChart chart, int width, int height) { 
     BufferedImage objBufferedImage = chart.createBufferedImage(width, height); 
     ByteArrayOutputStream bas = new ByteArrayOutputStream(); 
     try { 
      ImageIO.write(objBufferedImage, "png", bas); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
     byte[] byteArray=bas.toByteArray(); 
     return byteArray; 
    } 

} 

上面的代碼會按預期生成一個圖。

如果但是我們註釋掉createTimeSeriesDataset方法的指示線,再沒有什麼被畫在:

enter image description here

所以,問題是:我怎麼能保證至少一個點(或其他一些標記)被打印在角落的情況下XYDataset只包含一個數據點?

+0

(沒有測試它,只是一個簡單的問題:當您添加*同*點,會發生什麼*兩次*) – Marco13 2014-08-31 15:19:17

+0

@ Marco13 org.jfree.data.general.SeriesException:您正在嘗試在1970年1月1日01:00:00添加對時間段的觀察,但該系列已包含該時間段的觀察值。重複是不允許的。嘗試使用addOrUpdate()方法。 – 2014-08-31 15:22:39

回答

1

時間序列圖主要由連接各個數據點的組成。當只有一個數據元素時,沒有要連接的數據點。到目前爲止,如此明顯。

一個可能的解決辦法是使圖表的「滴答形狀」當僅存在一個條目。我不確定這是否適合您的情況。但是,這可能是與像

private static void showTickMarksForSingleElements(
    XYDataset dataset, JFreeChart chart) 
{ 
    TimeSeriesCollection timeSeriesCollection = 
     (TimeSeriesCollection)dataset; 
    List<?> series = timeSeriesCollection.getSeries(); 
    TimeSeries timeSeries = (TimeSeries) series.get(0); 
    if (timeSeries.getItemCount() == 1) 
    { 
     XYPlot plot = (XYPlot) chart.getPlot(); 
     XYLineAndShapeRenderer renderer 
      = (XYLineAndShapeRenderer) plot.getRenderer(); 
     renderer.setSeriesShapesVisible(0, true); 
    } 
} 

的方法來完成(注意,有明顯的對類型涉及給定對象的一些假設 - 毋庸置疑,在做石膏之前檢查類型!)

結果將被用於時間序列的單個刻度標記僅包含一個單一的元素:

ChartTick

在這裏作爲另一MVCE:

import java.awt.image.BufferedImage; 
import java.io.ByteArrayInputStream; 
import java.io.ByteArrayOutputStream; 
import java.io.IOException; 
import java.io.InputStream; 
import java.util.List; 
import java.util.TimeZone; 

import javax.imageio.ImageIO; 
import javax.swing.ImageIcon; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.SwingUtilities; 

import org.jfree.chart.ChartFactory; 
import org.jfree.chart.JFreeChart; 
import org.jfree.chart.plot.XYPlot; 
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer; 
import org.jfree.data.time.Millisecond; 
import org.jfree.data.time.RegularTimePeriod; 
import org.jfree.data.time.TimeSeries; 
import org.jfree.data.time.TimeSeriesCollection; 
import org.jfree.data.xy.XYDataset; 

public class SingleElementChart { 

    public static void main(String args[]) throws Exception { 
     BufferedImage img = timeAxisSSEProcessionsChart(); 
     show(img); 
    } 

    private static void show(final BufferedImage img) 
    { 
     SwingUtilities.invokeLater(new Runnable() 
     { 
      @Override 
      public void run() 
      { 
       JFrame f = new JFrame(); 
       f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       f.getContentPane().add(new JLabel(new ImageIcon(img))); 
       f.pack(); 
       f.setLocationRelativeTo(null); 
       f.setVisible(true); 
      } 
     }); 
    } 


    private static TimeSeriesCollection createTimeSeriesDataset() { 
     TimeSeries timeSeries = new TimeSeries("series-a"); 
     timeSeries.add(RegularTimePeriod.createInstance(
      Millisecond.class, new java.util.Date(0), 
      TimeZone.getTimeZone("Zulu")), 100); 
     // if below line is commented out, nothing is plotted: 
     //timeSeries.add(RegularTimePeriod.createInstance(
     // Millisecond.class, new java.util.Date(1000), 
     // TimeZone.getTimeZone("Zulu")), 100); 
     TimeSeriesCollection rv = new TimeSeriesCollection(); 
     rv.addSeries(timeSeries); 
     return rv; 
    } 


    public static BufferedImage timeAxisSSEProcessionsChart() throws Exception { 
     XYDataset dataset = createTimeSeriesDataset(); 
     JFreeChart chart = ChartFactory.createTimeSeriesChart(
      "title", "date", "series-a", dataset, true, true, false); 

     showTickMarksForSingleElements(dataset, chart); 

     InputStream in = new ByteArrayInputStream(
      imageBytesFromChart(chart, 600, 400)); 
     return ImageIO.read(in); 
    } 

    private static void showTickMarksForSingleElements(
     XYDataset dataset, JFreeChart chart) 
    { 
     TimeSeriesCollection timeSeriesCollection = 
      (TimeSeriesCollection)dataset; 
     List<?> series = timeSeriesCollection.getSeries(); 
     TimeSeries timeSeries = (TimeSeries) series.get(0); 
     if (timeSeries.getItemCount() == 1) 
     { 
      XYPlot plot = (XYPlot) chart.getPlot(); 
      XYLineAndShapeRenderer renderer 
       = (XYLineAndShapeRenderer) plot.getRenderer(); 
      renderer.setSeriesShapesVisible(0, true); 
     } 
    } 

    private static byte[] imageBytesFromChart(JFreeChart chart, int width, int height) { 
     BufferedImage objBufferedImage = 
      chart.createBufferedImage(width, height); 
     ByteArrayOutputStream bas = new ByteArrayOutputStream(); 
     try { 
      ImageIO.write(objBufferedImage, "png", bas); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
     byte[] byteArray=bas.toByteArray(); 
     return byteArray; 
    }