Hi,
I'd like to have my charts run in a seprate thread from the main application. I'm using the JFreeChart to plot realtime data and sometimes the GUI becomes unresponsive whena chart is being redrawn, if the chart could be redrawn in a seprate thread I could give it lower priority and maintian responsiveness of my App's GUI.
My thoughts were to extend the XYPlot class and overload
public void draw(Graphics2D g2,
Rectangle2D area,
Point2D anchor,
PlotState parentState,
PlotRenderingInfo info)
And use a SwingWorker instance that calls the super's draw method.
Any advice? [/code]
How to make plots run in seperate thread?
I tried overloading draw and doing the swingworker thing and it failed. It never seemed to be able to completely draw the plot. It drew parts of it but never completely 
See below:


See below:
Code: Select all
private class ThreadedXYPlot extends XYPlot {
ThreadedXYPlot(XYDataset dataset,
ValueAxis domainAxis,
ValueAxis rangeAxis,
XYItemRenderer renderer) {
super(dataset, domainAxis, rangeAxis, renderer);
}
public void drawSuper(Graphics2D g2,
Rectangle2D area,
Point2D anchor,
PlotState parentState,
PlotRenderingInfo info) {
super.draw(g2, area, anchor, parentState, info);
}
public void draw(final Graphics2D g2,
final Rectangle2D area,
final Point2D anchor,
final PlotState parentState,
final PlotRenderingInfo info) {
final SwingWorker worker = new SwingWorker() {
public Object construct() {
System.out.println("drawing");
drawSuper(g2, area, anchor, parentState, info);
return null;
}
};
worker.start();
}
}







-
- Posts: 43
- Joined: Fri Mar 14, 2003 3:14 pm
- Location: Porto (Portugal)
- Contact:
Hi,be redrawn in a seprate thread I could give it lower priority and maintian responsiveness of my App's GUI.
In you realtime chart, do you have a hard requirement, that for each new sample, the chart should be refreshed?
I had once the same problem. What I did was collecting the samples in a buffer. I think I used a TimeSeries. This buffer was not used in the chart.
Then, I had a SwingTimer, that for each 5 sec, would copy the buffer, to the XYPlot internal buffer. The chart was automatically redraw at that time with the new samples received in that 5 sec interval.
Hope that helps,
Eduardo
Well I am doing that something like that, right now data can arrive at varying intervals the default being 125ms. I have two timeseries that I write to, one is bound to the plot and the other is a buffer that I write the readings to as they come in. I don't use a timer as I will be getting readings in a steady stream and will in effect be a timer itself. I keep track of when I last updated the plot's TimeSeries and make sure I update it after a fixed amount of time has passed (default 500 ms).
(Un)fortunately its part of the design of swing that all drawing MUST take place on the event dispatching thread.
JFreeChart isn't really designed to do this. As previously stated, the entire chart is redrawn whenever data changes. Most charts that have real time display capabilities only need to redraw the 2 most recent datapoints. a.k.a. "the hard-right-edge"
That being said, check to see how many times the chart is being repainted whenever you update anything. You might find that there are many more redundant repaints than you expect. My performance improved greatly when I bracketed the code that caused repaints to happen with the following:
You still need a timer,or at least some way to limit the frequency of updates. A Greenspan surprise rate hike can generate an amazing amount of data...
JFreeChart isn't really designed to do this. As previously stated, the entire chart is redrawn whenever data changes. Most charts that have real time display capabilities only need to redraw the 2 most recent datapoints. a.k.a. "the hard-right-edge"
That being said, check to see how many times the chart is being repainted whenever you update anything. You might find that there are many more redundant repaints than you expect. My performance improved greatly when I bracketed the code that caused repaints to happen with the following:
Code: Select all
chart.setNotify(false);
// update data
// update axes
// update legends
// etc etc etc
chart.setNotify(true);
Well, I was doing something like what you were doing but using two timeseries so that I would change the timeseries only once causing only one repaint, but your approach is better. I changed my code to handle updates like this.skunk wrote:(Un)fortunately its part of the design of swing that all drawing MUST take place on the event dispatching thread.
JFreeChart isn't really designed to do this. As previously stated, the entire chart is redrawn whenever data changes. Most charts that have real time display capabilities only need to redraw the 2 most recent datapoints. a.k.a. "the hard-right-edge"
That being said, check to see how many times the chart is being repainted whenever you update anything. You might find that there are many more redundant repaints than you expect. My performance improved greatly when I bracketed the code that caused repaints to happen with the following:
Code: Select all
chart.setNotify(false); // update data // update axes // update legends // etc etc etc chart.setNotify(true);
You still need a timer,or at least some way to limit the frequency of updates. A Greenspan surprise rate hike can generate an amazing amount of data...
Still, I'm updating the screen every 500 ms and at some points need to have 4 plot windows working and updating twice a second...
The program is reponsive but I'd like it to feel more fluid. Is there anyway of forcing the draw()'s to run in a seperate thread?