views:

1049

answers:

8

I have an application which updates a variable about between 5 to 50 times a second and I am looking for some way of drawing a continuous XY plot of this change in real-time.

Though JFreeChart is not recommended for such a high update rate, many users still say that it works for them. I've tried using this demo and modified it to display a random variable, but it seems to use up 100% CPU usage all the time. Even if I ignore that, I do not want to be restricted to JFreeChart's ui class for constructing forms (though I'm not sure what its capabilities are exactly). Would it be possible to integrate it with Java's "forms" and drop-down menus? (as are available in VB) Otherwise, are there any alternatives I could look into?

EDIT: I'm new to Swing, so I've put together a code just to test the functionality of JFreeChart with it (while avoiding the use of the ApplicationFrame class of JFree since I'm not sure how that will work with Swing's combo boxes and buttons). Right now, the graph is being updated immediately and CPU usage is high. Would it be possible to buffer the value with new Millisecond() and update it maybe twice a second? Also, can I add other components to the rest of the JFrame without disrupting JFreeChart? How would I do that? frame.getContentPane().add(new Button("Click")) seems to overwrite the graph.

package graphtest;

import java.util.Random;
import javax.swing.JFrame;
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.Millisecond;
import org.jfree.data.time.TimeSeries;
import org.jfree.data.time.TimeSeriesCollection;

public class Main {
    static TimeSeries ts = new TimeSeries("data", Millisecond.class);

    public static void main(String[] args) throws InterruptedException {
        gen myGen = new gen();
        new Thread(myGen).start();

        TimeSeriesCollection dataset = new TimeSeriesCollection(ts);
        JFreeChart chart = ChartFactory.createTimeSeriesChart(
            "GraphTest",
            "Time",
            "Value",
            dataset,
            true,
            true,
            false
        );
        final XYPlot plot = chart.getXYPlot();
        ValueAxis axis = plot.getDomainAxis();
        axis.setAutoRange(true);
        axis.setFixedAutoRange(60000.0);

        JFrame frame = new JFrame("GraphTest");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        ChartPanel label = new ChartPanel(chart);
        frame.getContentPane().add(label);
        //Suppose I add combo boxes and buttons here later

        frame.pack();
        frame.setVisible(true);
    }

    static class gen implements Runnable {
        private Random randGen = new Random();

        public void run() {
            while(true) {
                int num = randGen.nextInt(1000);
                System.out.println(num);
                ts.addOrUpdate(new Millisecond(), num);
                try {
                    Thread.sleep(20);
                } catch (InterruptedException ex) {
                    System.out.println(ex);
                }
            }
        }
    }

}
+1  A: 

If your variable is updating that fast, there's no point in updating a chart every time.

Have you thought about buffering the variable changes, and refreshing the chart on a different thread, say, every 5s ? You should find that JFreeChart can handle such update rates well.

Since JFreeChart is a normal desktop library, you can integrate it with a standard Swing application very easily. Or, you can use it to chart via a web application (by rendering to a JPEG/PNG etc. JFreeChart can generate image maps automatically as well, so you can use mouseovers etc.)

Brian Agnew
That seems like a good idea, though I'd have to buffer some kind of timestamp as well. However, JFreeChart seems to take up 100% CPU usage whether I have 2 or 50 updates every second.
thodinc
Well, it's doing quite a lot - regenerating the graph from scratch every time. So I'd recommend a little less frequent updating (of course it depends on your machine and your additional load...)
Brian Agnew
A: 

Answered before here. Your variable changes up to 50 times per second, but in most cases you won't need to update every time a change is made. Instead you could update the graph at regular intervals (every 100ms for instance).

kgiannakakis
I've already looked at some of the other libraries mentioned in that thread, but there aren't too many that I can integrate with Java's drop-down boxes and other objects. They all seem to launch as separate applications. I'm currently looking at JRobin which might work, but is a little more complex to use.
thodinc
A: 
PanCrit
A: 

Maybe you can use two threads. One for the updating of your variable witch priority equals to 10. And a second thread who paints so fast as posible witch priority equals to 5.

I had to do the same in a game I'm writing.

It's possible I didn't understand your question. I'm a Belgian, 14 years old...

Martijn

Martijn Courteaux
A: 

Well I am also using JFreechart for high updates. JFreeChart updates up to 10 to 15 frame/second but using 100% CPU usage. But if I want to update it at a much higher frequency it wont be updated. If you find any any library which can be updated at abt 20 fps and can be used to develop a application in Java then please suggest me also. I have seen many library JFreeChart FAQ but I am not sure if anyone could be use for updates at about 20 fps.

A: 

According to this blog post:

http://jonathanwatmough.com/2008/02/prototyping-code-in-clojure/

its possible to implement 'real-ish time' display of audio spectrums using the KJ DSP library:

http://sirk.sytes.net/software/libs/kjdss/index.htm

so if you can get by with fairly simple charts it might be an alternative to JFreeChart.

tonys
A: 

Try KJDSS here!

sirk
A: 

Thanks for this post was lookin for this kind of real time graph!!!!! using JFree chart

Ashwin