Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using JFreeChart to display recent changes in a time series

How can I use JFreeChart to display just the most recent data in a continually updated time series?

Addenda: A complete, working example that incorporates the accepted answer is shown here. See also this variation having two series. See also this Q&A regarding setTimeBase().

like image 857
trashgod Avatar asked Feb 19 '11 04:02

trashgod


2 Answers

The JFreeChart class DynamicTimeSeriesCollection is a good choice.

Addendum: As noted by @Bahadır, the last point of the series was persistently zero. @Don helpfully suggests advancing the time and then appending the data.

dataset.advanceTime(); dataset.appendData(newData); 

enter image description here

import java.awt.BorderLayout; import java.awt.EventQueue; import java.awt.FlowLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.Random; import javax.swing.JButton; import javax.swing.JComboBox; import javax.swing.JPanel; import javax.swing.Timer; import org.jfree.chart.ChartFactory; import org.jfree.chart.ChartPanel; import org.jfree.chart.JFreeChart; import org.jfree.chart.axis.ValueAxis; import org.jfree.chart.plot.XYPlot; import org.jfree.data.time.DynamicTimeSeriesCollection; import org.jfree.data.time.Second; import org.jfree.data.xy.XYDataset; import org.jfree.chart.ui.ApplicationFrame; import org.jfree.chart.ui.UIUtils;  /**  * @see http://stackoverflow.com/a/15521956/230513  * @see http://stackoverflow.com/questions/5048852  */ public class DTSCTest 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 DTSCTest(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);          final JButton run = new JButton(STOP);         run.addActionListener(new ActionListener() {             @Override             public void actionPerformed(ActionEvent e) {                 String cmd = e.getActionCommand();                 if (STOP.equals(cmd)) {                     timer.stop();                     run.setText(START);                 } else {                     timer.start();                     run.setText(STOP);                 }             }         });          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) {             @Override             public Dimension getPreferredSize() {                 return new Dimension(640, 480);             }         }, BorderLayout.CENTER);         JPanel btnPanel = new JPanel(new FlowLayout());         btnPanel.add(run);         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.createTimeSeriesChart(             TITLE, "hh:mm:ss", "milliVolts", dataset, 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() {                 DTSCTest demo = new DTSCTest(TITLE);                 demo.pack();                 UIUtils.centerFrameOnScreen(demo);                 demo.setVisible(true);                 demo.start();             }         });     } } 
like image 119
trashgod Avatar answered Sep 19 '22 18:09

trashgod


You can also eliminate the zero by first advanceTime(), then appendData. (swap the way they are doing it in the example).

like image 26
Don Avatar answered Sep 21 '22 18:09

Don