开发者

Enabling/Disabling drawing of a JFreeChart

开发者 https://www.devze.com 2023-02-24 02:42 出处:网络
I have a chart cr开发者_开发知识库eated as shown below, and I am adding values to the TimeSeries (in a different location in my program). The ChartPanel is actually contained within a JTabbedPane, and

I have a chart cr开发者_开发知识库eated as shown below, and I am adding values to the TimeSeries (in a different location in my program). The ChartPanel is actually contained within a JTabbedPane, and I would like to not redraw the chart unless it's tab is being displayed. Is there any way for me to signal that rendering should not occur when new data comes into the TimeSeries unless that tab is the one currently being shown? I'm guessing there is some call that signals the data has been updated and a new rendering is needed, so basically I want to intercept that call and do nothing if the tab is not being shown, let the call through if the tab is being shown, and call it once manually when the user switches to that tab. This isn't a major issue with one ChartPanel in the background, but I have a few on different tabs and it's starting to eat CPU like nasty to update 4-5 charts constantly.

    sAccuracy = new TimeSeries("a");
    TimeSeriesCollection dataset = new TimeSeriesCollection(sAccuracy);
    JFreeChart c = ChartFactory.createTimeSeriesChart("Accuracy",
            "", "Percent", dataset, false, false, false);

    ChartPanel cp = new ChartPanel(c);


I've faced the same problem whereby the JFreechart API is fairly clunky and simply repaints the entire chart whenever a single datapoint is added resulting in a large rendering overhead.

The way I've solved this is to implement my own underlying model (e.g. XYDataset implementation) that is aware of when the chart containing it is being displayed, and to only propagate events when that chart is visible - If the chart is not visible then the model should defer the firing of events until later; e.g.

public class MyXYDataset extends AbstractXYDataset {
  private boolean shown;
  private boolean pendingEvent;

  /**
   * Called when the chart containing this dataset is being displayed
   * (e.g. hook this into a selection listener that listens to tab selection events).
   */
  public void setShown(boolean shown) {
    this.shown = shown;

    if (this.shown && this.pendingEvent) {
      this.pendingEvent = false;
      fireDatasetChanged();
    }
  }

  public void addDatapoint(double x, double y) {
    // TODO: Add to underlying collection.

    if (this.shown) {
      // Chart is currently displayed so propagate event immediately.
      fireDatasetChanged();
    } else {
      // Chart is hidden so delay firing of event but record that we need to fire one.
      this.pendingEvent = true;
    }
  }
}


Another possibility is to set c.setNotify(false);, which will prevent the chart to listen to the ChartChangeEvent:

http://www.jfree.org/jfreechart/api/javadoc/org/jfree/chart/JFreeChart.html#setNotify(boolean)

0

精彩评论

暂无评论...
验证码 换一张
取 消