2014-08-31 72 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; 
    }