2013-12-13 113 views
3

我有一個動態的面積圖,我想在顯示圖表的最後一點(我的圖表上的最近值)上添加一個綠色點。例如,顯示我想要的線邊界一個很大的綠色點將顯示在我的面積圖上?我正在使用示例shown here面積圖上的圖形點JFreechart

如何做到這一點?有我的代碼:

public class essaijfree2 extends ApplicationFrame { 

private static final String TITLE = "Dynamic Series"; 
private static final String START = "Start"; 
private static final String STOP = "Stop"; 
private static final float MINMAX = 100; 
private static final int COUNT = 2 * 60; 
private static final int FAST = 100; 
private static final int SLOW = FAST * 5; 
private static final Random random = new Random(); 
private Timer timer; 

public essaijfree2(final String title) { 
    super(title); 
    final DynamicTimeSeriesCollection dataset = 
     new DynamicTimeSeriesCollection(1, COUNT, new Second()); 
    dataset.setTimeBase(new Second(0, 0, 0, 1, 1, 2011)); 
    dataset.addSeries(gaussianData(), 0, "Gaussian data"); 
    JFreeChart chart = createChart(dataset); 
    XYPlot xyPlot = (XYPlot) chart.getPlot(); 
    XYDifferenceRenderer r = new XYDifferenceRenderer(Color.green,Color.red, true); 
    xyPlot.setRenderer(r); 



    final JComboBox combo = new JComboBox(); 
    combo.addItem("Fast"); 
    combo.addItem("Slow"); 
    combo.addActionListener(new ActionListener() { 

     @Override 
     public void actionPerformed(ActionEvent e) { 
      if ("Fast".equals(combo.getSelectedItem())) { 
       timer.setDelay(FAST); 
      } else { 
       timer.setDelay(SLOW); 
      } 
     } 
    }); 

    this.add(new ChartPanel(chart), BorderLayout.CENTER); 
    JPanel btnPanel = new JPanel(new FlowLayout()); 

    btnPanel.add(combo); 
    this.add(btnPanel, BorderLayout.SOUTH); 

    timer = new Timer(FAST, new ActionListener() { 

     float[] newData = new float[1]; 

     @Override 
     public void actionPerformed(ActionEvent e) { 
      newData[0] = randomValue(); 
      dataset.advanceTime(); 
      dataset.appendData(newData); 
     } 
    }); 
} 

private float randomValue() { 

    return (float) (random.nextGaussian() * MINMAX/3); 
} 

private float[] gaussianData() { 
    float[] a = new float[COUNT]; 
    for (int i = 0; i < a.length; i++) { 
     a[i] = randomValue(); 
    } 
    return a; 
} 

private JFreeChart createChart(final XYDataset dataset) { 
    final JFreeChart result = ChartFactory.createXYAreaChart(
     TITLE, "hh:mm:ss", "milliVolts", dataset,PlotOrientation.VERTICAL, true, true, false); 
    final XYPlot plot = result.getXYPlot(); 
    ValueAxis domain = plot.getDomainAxis(); 
    domain.setAutoRange(true); 

    ValueAxis range = plot.getRangeAxis(); 
    range.setRange(-MINMAX, MINMAX); 
    return result; 
} 

public void start() { 
    timer.start(); 
} 

public static void main(final String[] args) { 
    EventQueue.invokeLater(new Runnable() { 

     @Override 
     public void run() { 
      essaijfree2 demo = new essaijfree2(TITLE); 
      demo.pack(); 
      RefineryUtilities.centerFrameOnScreen(demo); 
      demo.setVisible(true); 
      demo.start(); 
     } 
    }); 
} 
+0

你可能會用'org.jfree.chart.annotations'實驗。 – trashgod

+0

交叉發佈[這裏](http://www.jfree.org/forum/viewtopic.php?f=3&t=116745)。 – trashgod

+0

因此跨發佈問題在哪裏? –

回答

1

我建議創建您自己的XYAnnotation,它不使用預定義的x和y值,而是從數據集中選取它們,並且b)使用在Java2D空間中定義邊界的形狀,以使形狀大小保持不變當你放大常數 下面是一個例子:

Item Annotation Demo

public class ItemAnnotationDemo { 

    public static void main(String[] args) { 
     int count = 20; 
     double[][] data = new double[2][count]; 
     for(int i = 0; i < count; i++){ 
      data[0][i] = i; 
      data[1][i] = i; 
     } 
     DefaultXYDataset dataset = new DefaultXYDataset(); 
     dataset.addSeries("Values", data); 
     NumberAxis xAxis = new NumberAxis("x axis"); 
     NumberAxis yAxis = new NumberAxis("y axis"); 
     XYItemRenderer renderer = new XYLineAndShapeRenderer(true, true); 
     renderer.addAnnotation(new XYItemAnnotation(
      new Rectangle2D.Double(-10, -8, 20, 16), 
      new Color(128,128,128,128), 
      new BasicStroke(3.0f), 
      Color.RED,0,Integer.MAX_VALUE)); 
     XYPlot plot = new XYPlot(dataset, xAxis, yAxis, renderer); 
     JFreeChart chart = new JFreeChart(plot); 
     JFrame frame = new JFrame(); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.getContentPane().add(new ChartPanel(chart)); 
     frame.pack(); 
     frame.setVisible(true); 

    } 
} 
class XYItemAnnotation extends AbstractXYAnnotation{ 
    private Shape shape; 
    private Paint outline; 
    private Paint fill; 
    private Stroke stroke; 
    private int si; 
    private int ii; 
    public XYItemAnnotation(Shape shape, Paint fillPaint, Stroke outlineStroke, Paint outlinePaint, int seriesIndex, int itemIndex){ 
     super(); 
     this.shape = shape; 
     this.fill = fillPaint; 
     this.stroke = outlineStroke; 
     this.outline = outlinePaint; 
     this.si = seriesIndex; 
     this.ii = itemIndex; 
    } 
    public void draw(Graphics2D g2, XYPlot plot, Rectangle2D dataArea, ValueAxis domainAxis, ValueAxis rangeAxis, int datasetIndex, PlotRenderingInfo info){ 
     XYDataset dataset = plot.getDataset(datasetIndex); 
     if(dataset == null) return; 
     if(si > dataset.getSeriesCount() - 1) return; 
     int item = Math.max(0, ii); 
     item = Math.min(item, dataset.getItemCount(si) - 1); 
     double dx = dataset.getXValue(si, item); 
     double dy = dataset.getYValue(si, item); 
     if(Double.isNaN(dx) || Double.isNaN(dy)) return; 
     if(!domainAxis.getRange().contains(dx) || !rangeAxis.getRange().contains(dy)) return; 
     PlotOrientation orientation = plot.getOrientation(); 
     RectangleEdge domainEdge = Plot.resolveDomainAxisLocation(
       plot.getDomainAxisLocation(), orientation); 
     RectangleEdge rangeEdge = Plot.resolveRangeAxisLocation(
       plot.getRangeAxisLocation(), orientation); 

     double jx = domainAxis.valueToJava2D(dx, dataArea, domainEdge); 
     double jy = rangeAxis.valueToJava2D(dy, dataArea, rangeEdge); 
     if (orientation == PlotOrientation.HORIZONTAL) { 
      double temp = jx; 
      jx = jy; 
      jy = temp; 
     } 
     Shape trans = ShapeUtilities.createTranslatedShape(shape, jx, jy); 
     g2.setPaint(fill); 
     g2.fill(trans); 
     g2.setPaint(outline); 
     g2.setStroke(stroke); 
     g2.draw(trans); 

    } 
} 
+0

我遵循你的例子,它爲我工作,謝謝! –

4

我看看位於最後添加的基準座標的XYShapeAnnotation。一些例子見here。您可以使用RadialGradientPaint以及變化的alpha來獲得暈輪效果。我從來沒有試過動態地做,但XYPlot包括方法addAnnotation()removeAnnotation();都通知所有註冊的聽衆。

+0

好吧我會嘗試一下 –

+1

XYShapeAnnotation是一個不錯的選擇,但是由於這個綠色點總是在最後一個數據點上繪製,所以對我來說,渲染器繪製它是有意義的(顯然你需要子類化或複製和修改現有的渲染器,但在本地製作應該不會有困難)。 –