Graphical Analysis Using JFreeChart

I am working with JFreeChart to plot multiple TimeSeries charts. It seemed to be working fine, but as of today, all graphs seem to flicker and shrink randomly, making them impossible. If I minify and maximize, the problem is fixed within a few seconds before the next update or click. Does anyone have any idea what the problem might be?

alt text

The code is pretty simple:

TimeSeries ts = new TimeSeries("Graph", Millisecond.class);
TimeSeriesCollection dataset = new TimeSeriesCollection(ts);
JFreeChart Graph = createChart(dataset);
ChartPanel panel_Graph = new ChartPanel(Graph);

....

JFrame newWindow = new JFrame("Graph");
newWindow.setLayout(new GridLayout());
newWindow.setContentPane(panel_Graph);
newWindow.setMinimumSize(new Dimension(600, 480));
newWindow.setLocationRelativeTo(null);
newWindow.setVisible(true);


static private JFreeChart createChart(TimeSeriesCollection dataset) {
        JFreeChart chart = ChartFactory.createTimeSeriesChart(
            "Graph",
            "Time",
            "Value",
            dataset,
            false,
            true,
            false
        );
        final XYPlot plot = chart.getXYPlot();
        ValueAxis timeaxis = plot.getDomainAxis();
        timeaxis.setAutoRange(true);
        timeaxis.setFixedAutoRange(60000.0);
        return chart;
}

      

+2


source to share


2 answers


If you see an inconsistent / corrupted image, it sometimes indicates a dataset update on a non-Thread Dispatch Thread. I suggest you add some statements to test this:

assert SwingUtilities.isEventDispatchThread ();

Also note that JFreeChart is not particularly efficient as it re-renders the entire chart whenever a new data point is added. You can do one optimization:

  • If your application consists of multiple diagrams, then only the DatasetChangeEvent

    diagram currently displayed is distributed . If the chart is hidden (in another tab, for example), just register the fact that it is out of date and needs to be reinstalled when the tab is selected.


EDIT

Based on your comment on Dan's answer, it looks like your posts about the I / O stream are also updating the JFreeChart dataset, when in fact the update should be done on the event dispatch thread (and the messages should be done on a separate I / O). To do this, I suggest you use a throttle based approach where the I / O events are combined together. You can use BlockingQueue

to achieve this; eg.

// Message definition containing update information.
public interface Message { ... }

// BlockingQueue implementation used to enqueue updates received on I/O thread.
BlockingQueue<Message> msgQ = ...

// Method called by I/O thread when a new Message is received.
public void msgReceived(Message msg) {
  boolean wasEmpty = msgQ.isEmpty();

  msgQ.add(msg);

  // Queue was empty so need to re-invoke Swing thread to process queue.
  if (wasEmpty) {
    // processUpdates is a re-useable Runnable defined below.
    SwingUtilities.invokeLater(processUpdates);
  }
}

// Runnable that processes all enqueued events.  Much more efficient than:
// a) Creating a new Runnable each time.
// b) Processing one Message per call to run().
private final Runnable processUpdates = new Runnable() {
  public void run() {
    Message msg;

    while ((msg = msgQ.poll) != null) {
      // Add msg to dataset within Event Dispatch thread.
    }
  }
}

      

+1


source


How do you add data points to a chart? Are you doing this on the AWT event dispatch thread? You should probably be using SwingUtilities.invokeAndWait . You can use invokeLater, but if your program is busy with other things, the GUI may not update quickly.



Also, how much data do you have? I found that the code for the fixed auto-range was rather ineffective for a lot of data points. This may have been fixed in the most recent version (I don't know).

0


source







All Articles