2014-03-13 34 views
2

我使用JFreeChart在java中使用netbeans繪製運行或移動正弦波。我爲它編寫代碼,但它不喜歡移動或運行正弦波圖形。所以,如果你對此有任何想法,那麼建議我。 我的代碼如下如何在java中使用JFree圖表繪製移動和正在運行的正弦波形圖?

import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import javax.swing.JButton; 
import javax.swing.JPanel; 
import org.jfree.chart.ChartFactory; 
import org.jfree.chart.ChartPanel; 
import org.jfree.chart.JFreeChart; 
import org.jfree.chart.plot.PlotOrientation; 
import org.jfree.chart.plot.XYPlot; 
import org.jfree.data.xy.XYDataset; 
import org.jfree.data.xy.XYSeries; 
import org.jfree.data.xy.XYSeriesCollection; 
import org.jfree.ui.ApplicationFrame; 


public class DrawChart extends ApplicationFrame implements ActionListener { 

    public XYSeries series; 

    public DrawChart(final String title) { 

     super(title); 
     series = new XYSeries("Sine", true, true); 
     XYSeriesCollection dataset = new XYSeriesCollection(series); 
     final JFreeChart chart = createChart(dataset); 

     final ChartPanel chartPanel = new ChartPanel(chart); 
     final JButton button = new JButton("Add New Data Item"); 
     button.setActionCommand("ADD_DATA"); 
     button.addActionListener(this); 

     final JPanel content = new JPanel(new BorderLayout()); 
     content.add(chartPanel); 
     content.add(button, BorderLayout.SOUTH); 
     chartPanel.setPreferredSize(new java.awt.Dimension(500, 270)); 
     setContentPane(content); 

    } 

    private JFreeChart createChart(final XYDataset dataset) { 
     JFreeChart jfreechart = ChartFactory.createXYLineChart("Sin Curve", "Angle (Deg)", "Value", dataset, PlotOrientation.VERTICAL, true, true, true); 
     jfreechart.setBackgroundPaint(Color.white); 
     XYPlot xyplot = (XYPlot) jfreechart.getPlot(); 
     xyplot.setBackgroundPaint(Color.lightGray); 
     xyplot.setDomainGridlinePaint(Color.white); 
     xyplot.setRangeGridlinePaint(Color.white); 
     return jfreechart; 
    } 

    public void actionPerformed(final ActionEvent e) { 
     if (e.getActionCommand().equals("ADD_DATA")) { 
      for (int i = 0; i < 100; i++) { 
       final double x = (i)/10.0 ; 
       final double y = Math.sin(x); 
       this.series.addOrUpdate(x, y); 
      } 
     } 
    } 

    public static void main(final String[] args) { 

     final DrawChart demo = new DrawChart("Dynamic Data view"); 
     demo.pack(); 
     RefineryUtilities.centerFrameOnScreen(demo); 
     demo.setVisible(true); 
    } 
} 

回答

5

example開始,用Math.sin()代替nextGaussian()產生了下面的圖示。 A javax.swing.Timer以1Hz步進動畫。

image

private ChartPanel createPane() { 
    final XYSeries series = new XYSeries("Data"); 
    for (int i = 0; i < random.nextInt(N) + N/2; i++) { 
     series.add(i, Math.sin(i)); 
    } 
    XYSeriesCollection dataset = new XYSeriesCollection(series); 
    new Timer(1000, new ActionListener() { 

     @Override 
     public void actionPerformed(ActionEvent e) { 
      series.add(series.getItemCount(), Math.sin(series.getItemCount())); 
     } 
    }).start(); 
    … 
} 
4

試試這個JavaFX。這更多靈活

1

這是我收集與使用JavaFX

import java.util.concurrent.ConcurrentLinkedQueue; 
import java.util.concurrent.ExecutorService; 
import java.util.concurrent.Executors; 

import javafx.animation.AnimationTimer; 
import javafx.animation.Timeline; 
import javafx.application.Application; 
import javafx.scene.Scene; 
import javafx.scene.chart.LineChart; 
import javafx.scene.chart.NumberAxis; 
import javafx.scene.chart.XYChart.Series; 
import javafx.stage.Stage; 

public class ACS extends Application 
{ 
    private static final int MAX_DATA_POINTS = 200; 

    private Series series; 
    private float xSeriesData = 0; 
    private final ConcurrentLinkedQueue<Number> dataQ = new ConcurrentLinkedQueue<Number>(); 
    private ExecutorService executor; 
    private AddToQueue addToQueue; 
    private Timeline timeline2; 
    private NumberAxis xAxis; 

    private void init(final Stage primaryStage) 
    { 
     xAxis = new NumberAxis(0, MAX_DATA_POINTS, 1); 
     xAxis.setForceZeroInRange(false); 
     xAxis.setAutoRanging(false); 

     final NumberAxis yAxis = new NumberAxis(0, 200, 1); 
     yAxis.setAutoRanging(false); 

     // -- Chart 
     final LineChart<Number, Number> sc = new LineChart<Number, Number>(xAxis, yAxis) { 
      // Override to remove symbols on each data point 
      @Override 
      protected void dataItemAdded(final Series<Number, Number> series, final int itemIndex, final Data<Number, Number> item) 
      {} 
     }; 
     sc.setAnimated(false); 
     sc.setId("liveAreaChart"); 
     sc.setTitle("Animated Area Chart"); 
     // -- Chart Series 
     series = new LineChart.Series<Number, Number>(); 
     series.setName("Area Chart Series"); 
     sc.getData().add(series); 

     final Scene scene = new Scene(sc, 800, 800); 
     scene.getStylesheets().add("site.css"); 
     sc.getStyleClass().add("thick-chart"); 

     primaryStage.setScene(scene); 
    } 

    @Override 
    public void start(final Stage primaryStage) throws Exception 
    { 
     init(primaryStage); 
     primaryStage.show(); 

     // -- Prepare Executor Services 
     executor = Executors.newCachedThreadPool(); 
     addToQueue = new AddToQueue(); 
     executor.execute(addToQueue); 
     // -- Prepare Timeline 
     prepareTimeline(); 
    } 

    public static void main(final String[] args) 
    { 
     launch(args); 
    } 

    private class AddToQueue implements Runnable 
    { 
     double PERIOD = 20; 
     double SCALE = 20; 
     int pos = 0; 

     @Override 
     public void run() 
     { 
      try { 
       final double Min = 20; 
       final double Max = 55; 
       // add a item of random data to queue 
//uncomment the line below to generate a normal graph 
       // dataQ.add(Min + (Math.random() * ((Max - Min)))); 
       dataQ.add(((Math.sin((++pos * 2 * Math.PI)/PERIOD) * (SCALE/2)) + (SCALE/2))); 
       Thread.sleep(1000); 
       executor.execute(this); 
      } 
      catch (final InterruptedException ex) { 
       // Logger.getLogger(ACS.class.getName()).log(Level.SEVERE, null, ex); 
      } 
     } 
    } 

    // -- Timeline gets called in the JavaFX Main thread 
    private void prepareTimeline() 
    { 
     // Every frame to take any data from queue and add to chart 
     new AnimationTimer() { 
      @Override 
      public void handle(final long now) 
      { 
       addDataToSeries(); 
      } 
     }.start(); 
    } 

    private void addDataToSeries() 
    { 
     for (int i = 0; i < 20; i++) { // -- add 20 numbers to the plot+ 
      if (dataQ.isEmpty()) { 
       break; 
      } 
      // series.getData().add(new LineChart.Data(xSeriesData++, dataQ.remove())); 

      final Number datapoint = dataQ.remove(); 
      xSeriesData = xSeriesData + 1; 
      System.out.println(xSeriesData + " " + datapoint); 
      series.getData().add(new LineChart.Data(xSeriesData, datapoint)); 
     } 
     // remove points to keep us at no more than MAX_DATA_POINTS 
     if (series.getData().size() > (MAX_DATA_POINTS * 10)) { 
      series.getData().remove(0, series.getData().size() - (MAX_DATA_POINTS * 10)); 
     } 
     // update 
     xAxis.setLowerBound(xSeriesData - (MAX_DATA_POINTS)); 
     xAxis.setUpperBound(xSeriesData - 1); 
    } 
} 
上來