Redrawing chart after dataset changed. How ?
Redrawing chart after dataset changed. How ?
It has been a long day and if anyone can help I would be most grateful.
I have extended ChartPanel to enable me to implement KeyPressed events on the chart. I have got that working and I am incrementing / decrementing the value that was mouse clicked by using the up / down arrow. Having changed the dataset I was wondering how I can get the chart to redraw ?
Thanks
I have extended ChartPanel to enable me to implement KeyPressed events on the chart. I have got that working and I am incrementing / decrementing the value that was mouse clicked by using the up / down arrow. Having changed the dataset I was wondering how I can get the chart to redraw ?
Thanks
Re: Redrawing chart after dataset changed. How ?
org.jfree.chart.JFreeChart defines this method
Code: Select all
public void fireChartChanged()
Re: Redrawing chart after dataset changed. How ?
I don't quite get this.
This is the code where I create my chart
final XYSeries altitudeSeries = new XYSeries("Altitude");
final XYSeries slopeSeries = new XYSeries("Slope");
for(GraphableObject.GraphPoint point : graphObject.getGraphPoints()) {
altitudeSeries.add(point.getDistancePoint(), point.getAltitudePoint());
slopeSeries.add(point.getDistancePoint(), point.getSlopePoint());
}
the points highlighted in red are references to Double / Float objects that I am updating. Given they are object references I would expect the chart to update with the new value when I call the fireChartChanged() method on the associated JFreeChart instance.
I am missing something simple here ?
Thanks
This is the code where I create my chart
final XYSeries altitudeSeries = new XYSeries("Altitude");
final XYSeries slopeSeries = new XYSeries("Slope");
for(GraphableObject.GraphPoint point : graphObject.getGraphPoints()) {
altitudeSeries.add(point.getDistancePoint(), point.getAltitudePoint());
slopeSeries.add(point.getDistancePoint(), point.getSlopePoint());
}
the points highlighted in red are references to Double / Float objects that I am updating. Given they are object references I would expect the chart to update with the new value when I call the fireChartChanged() method on the associated JFreeChart instance.
I am missing something simple here ?
Thanks
Re: Redrawing chart after dataset changed. How ?
In your example you create new Datasets! Did you set those datasets to be used by the chart (plot.setDataset())?
A ChartChanged event should than IMHO occur automatically and redraw your chart.
- martin
A ChartChanged event should than IMHO occur automatically and redraw your chart.
- martin
Re: Redrawing chart after dataset changed. How ?
Here is the full source code of the create combined chart
public static JFreeChart createCombinedChart(GraphableObject graphObject) {
final XYSeries altitudeSeries = new XYSeries("Altitude");
final XYSeries slopeSeries = new XYSeries("Slope");
for(GraphableObject.GraphPoint point : graphObject.getGraphPoints()) {
altitudeSeries.add(point.getDistancePoint(), point.getAltitudePoint());
slopeSeries.add(point.getDistancePoint(), point.getSlopePoint());
}
final XYDataset altitudeCollection = new XYSeriesCollection(altitudeSeries);
final XYDataset slopeCollection = new XYSeriesCollection(slopeSeries);
final XYLineAndShapeRenderer renderer1 = new XYLineAndShapeRenderer(true, true);
renderer1.setBaseToolTipGenerator(new StandardXYToolTipGenerator());
final NumberAxis rangeAxis1 = new NumberAxis("Altitude(M)");
final XYPlot subplot1 = new XYPlot(altitudeCollection, null, rangeAxis1, renderer1);
subplot1.setRangeAxisLocation(AxisLocation.BOTTOM_OR_LEFT);
final XYLineAndShapeRenderer renderer2 = new XYLineAndShapeRenderer(false, true);
renderer2.setBaseToolTipGenerator(new StandardXYToolTipGenerator());
final NumberAxis rangeAxis2 = new NumberAxis("Slope(%)");
rangeAxis2.setMinorTickMarksVisible(true);
rangeAxis2.setAutoRangeIncludesZero(true);
final XYPlot subplot2 = new XYPlot(slopeCollection, null, rangeAxis2, renderer2);
subplot1.setRangeAxisLocation(AxisLocation.TOP_OR_LEFT);
final CombinedDomainXYPlot plot = new CombinedDomainXYPlot(new NumberAxis("Distance(Metres)"));
plot.setGap(5.0);
plot.add(subplot1, 2);
plot.add(subplot2, 1);
plot.setOrientation(PlotOrientation.VERTICAL);
final JFreeChart chart = new JFreeChart("Combined Altitude/Slope", plot);
// result.getLegend().setAnchor(Legend.SOUTH);
return chart;
}
Edit - I only create the chart once, so no I am not creating new datasets each time.
public static JFreeChart createCombinedChart(GraphableObject graphObject) {
final XYSeries altitudeSeries = new XYSeries("Altitude");
final XYSeries slopeSeries = new XYSeries("Slope");
for(GraphableObject.GraphPoint point : graphObject.getGraphPoints()) {
altitudeSeries.add(point.getDistancePoint(), point.getAltitudePoint());
slopeSeries.add(point.getDistancePoint(), point.getSlopePoint());
}
final XYDataset altitudeCollection = new XYSeriesCollection(altitudeSeries);
final XYDataset slopeCollection = new XYSeriesCollection(slopeSeries);
final XYLineAndShapeRenderer renderer1 = new XYLineAndShapeRenderer(true, true);
renderer1.setBaseToolTipGenerator(new StandardXYToolTipGenerator());
final NumberAxis rangeAxis1 = new NumberAxis("Altitude(M)");
final XYPlot subplot1 = new XYPlot(altitudeCollection, null, rangeAxis1, renderer1);
subplot1.setRangeAxisLocation(AxisLocation.BOTTOM_OR_LEFT);
final XYLineAndShapeRenderer renderer2 = new XYLineAndShapeRenderer(false, true);
renderer2.setBaseToolTipGenerator(new StandardXYToolTipGenerator());
final NumberAxis rangeAxis2 = new NumberAxis("Slope(%)");
rangeAxis2.setMinorTickMarksVisible(true);
rangeAxis2.setAutoRangeIncludesZero(true);
final XYPlot subplot2 = new XYPlot(slopeCollection, null, rangeAxis2, renderer2);
subplot1.setRangeAxisLocation(AxisLocation.TOP_OR_LEFT);
final CombinedDomainXYPlot plot = new CombinedDomainXYPlot(new NumberAxis("Distance(Metres)"));
plot.setGap(5.0);
plot.add(subplot1, 2);
plot.add(subplot2, 1);
plot.setOrientation(PlotOrientation.VERTICAL);
final JFreeChart chart = new JFreeChart("Combined Altitude/Slope", plot);
// result.getLegend().setAnchor(Legend.SOUTH);
return chart;
}
Edit - I only create the chart once, so no I am not creating new datasets each time.
Re: Redrawing chart after dataset changed. How ?
When you add values to your dataset, ie :
Are you sure there is object reference ?
Did you check if your dataset values change when you click on the arrows ?
Code: Select all
altitudeSeries.add(point.getDistancePoint(), point.getAltitudePoint());
slopeSeries.add(point.getDistancePoint(), point.getSlopePoint());
Did you check if your dataset values change when you click on the arrows ?
Re: Redrawing chart after dataset changed. How ?
Sorry, I misunderstood your previous posting. Double/Float is immutable, so your references change, rather than the objects themselves. What you really want to do, is update your dataset. Either re-create the dataset and set it via plot.setDataset(), or get a reference to the used dataset and update the values in question.
hth,
- martin
hth,
- martin
Re: Redrawing chart after dataset changed. How ?
The reference does change, but I would just have expected the reference to point to another Double on the heapmatinh wrote:Sorry, I misunderstood your previous posting. Double/Float is immutable, so your references change, rather than the objects themselves. What you really want to do, is update your dataset. Either re-create the dataset and set it via plot.setDataset(), or get a reference to the used dataset and update the values in question.
hth,
- martin
eg
public void add(Number x, Number y) {
// argument checking delegated...
add(x, y, true);
}
Does that make sense ?
Re: Redrawing chart after dataset changed. How ?
A simple example:
What do you think is the value of d after the last statement? It's still 1.0, even though d1 (to which it was refering) changed.
hth,
- martin
Code: Select all
Double d1 = Double.valueOf(1.0d);
Double d2 = Double.valueOf(2.0d);
Double d = d1;
d1 = d2;
hth,
- martin
Re: Redrawing chart after dataset changed. How ?
Thanks for that. What is the easiest option for updating the dataset ?
Once I have created my chart I don't what the hassle of having to traverse the object of the chart to locate the point that I want to update?
Once I have created my chart I don't what the hassle of having to traverse the object of the chart to locate the point that I want to update?
Re: Redrawing chart after dataset changed. How ?
XYSeries defines these methodsflanajb wrote:Thanks for that. What is the easiest option for updating the dataset ?
Code: Select all
public void update(java.lang.Number x, java.lang.Number y)
public void updateByIndex(int index, java.lang.Number y)
Re: Redrawing chart after dataset changed. How ?
stupid question, but how do I get a handle on the underlying xyseries from the actual chart instance ?
I have been using eclipse, but there seems to be so many associations with the chart that I can't see the woods for the trees.
Thanks for your help, by the way.
I have been using eclipse, but there seems to be so many associations with the chart that I can't see the woods for the trees.
Thanks for your help, by the way.
Re: Redrawing chart after dataset changed. How ?
Instead of using XYSeries and XYSeriesCollection, perhaps the easiest way to achieve what you are looking for is to define your own dataset. This way nothing needs to be copied and there is only one location in memory to update.
Assuming that graphObject.getGraphPoints() returns an instance of java.util.List<GraphableObject.GraphPoint>, you could try something like this
Create another class exactly the same except it should be called MySlopeDataset and getSeriesKey/getYValue should read
To use these classes change your creation code to this
Whenever the source data changes, simply call
and the charts will repaint with the new data values.
This is off the top of my head so it *might* not compile
Assuming that graphObject.getGraphPoints() returns an instance of java.util.List<GraphableObject.GraphPoint>, you could try something like this
Code: Select all
class MyAltitudeDataset extends AbstractXYDataset {
private GraphableObject graphObject;
MyAltitudeDataset(GraphableObject go) {
graphObject = go;
}
public int getSeriesCount() {
return 1;
}
public Comparable getSeriesKey(int series) {
return "Altitude";
}
public DomainOrder getDomainOrder() {
return DomainOrder.NONE; // change to ASCENDING if your data is sorted
}
public double getXValue(int series, int item) {
return graphObject.getGraphPoints().get(item).getDistancePoint();
}
public double getYValue(int series, int item) {
return graphObject.getGraphPoints().get(item).getAltitudePoint();
}
}
Code: Select all
class MySlopeDataset extends AbstractXYDataset {
.
.
.
public Comparable getSeriesKey(int series) {
return "Slope";
}
public double getYValue(int series, int item) {
return graphObject.getGraphPoints().get(item).getSlopePoint();
}
}
Code: Select all
public static JFreeChart createCombinedChart(GraphableObject graphObject) {
final XYLineAndShapeRenderer renderer1 = new XYLineAndShapeRenderer(true, true);
renderer1.setBaseToolTipGenerator(new StandardXYToolTipGenerator());
final NumberAxis rangeAxis1 = new NumberAxis("Altitude(M)");
final XYPlot subplot1 = new XYPlot(new MyAltitudeDataset(graphObject), null, rangeAxis1, renderer1);
subplot1.setRangeAxisLocation(AxisLocation.BOTTOM_OR_LEFT);
final XYLineAndShapeRenderer renderer2 = new XYLineAndShapeRenderer(false, true);
renderer2.setBaseToolTipGenerator(new StandardXYToolTipGenerator());
final NumberAxis rangeAxis2 = new NumberAxis("Slope(%)");
rangeAxis2.setMinorTickMarksVisible(true);
rangeAxis2.setAutoRangeIncludesZero(true);
final XYPlot subplot2 = new XYPlot(new MySlopeDataset(graphObject), null, rangeAxis2, renderer2);
subplot2.setRangeAxisLocation(AxisLocation.TOP_OR_LEFT);
final CombinedDomainXYPlot plot = new CombinedDomainXYPlot(new NumberAxis("Distance(Metres)"));
plot.setGap(5.0);
plot.add(subplot1, 2);
plot.add(subplot2, 1);
plot.setOrientation(PlotOrientation.VERTICAL);
final JFreeChart chart = new JFreeChart("Combined Altitude/Slope", plot);
// result.getLegend().setAnchor(Legend.SOUTH);
return chart;
}
Code: Select all
CombinedDomainXYPlot cdplot = (CombinedDomainXYPlot)chart.getPlot();
XYPlot subplot1 = (XYPlot)cdplot.getSubplots().get(0);
((AbstractSeriesDataset)subplot1.getDataset(0)).seriesChanged(null); // will cause plot 1 to redraw
XYPlot subplot2 = (XYPlot)plot.getSubplots().get(1);
((AbstractSeriesDataset)subplot2.getDataset(0)).seriesChanged(null); // will cause plot 2 to redraw
This is off the top of my head so it *might* not compile

Re: Redrawing chart after dataset changed. How ?
Thanks for that. I will have a good luck at it tomorrow