dynamic XYBarChart

A discussion forum for JFreeChart (a 2D chart library for the Java platform).
Locked
Joern Muehlencord

dynamic XYBarChart

Post by Joern Muehlencord » Thu Apr 18, 2002 11:22 am

Hi out there,

I am trying to implement a dynamic barchart and had a look on the dynamic example in the demo. There "nottiyListeners" is called - I am calling fireSeriesChanged on my BasicTimeSeries. I cannont find any registerd listeners in the demo - so I think they are set in the "basic" classes like JFreeChart, CombinedDataset automaticaly. Is this correct?!

Any hints, why my chart is not beeing updated? I start with an empty chart - and it stays empty, even after some values are inserted into the BasicTimeSeries-Object.

Mfg
Joern

David Gilbert

Re: dynamic XYBarChart

Post by David Gilbert » Thu Apr 18, 2002 11:43 am

In the BasicTimeSeries class the add(...) and update(...) methods call fireSeriesChanged() automatically. This is picked up by the TimeSeriesCollection class, which responds by calling fireDatasetChanged() which sends a dataset change event to all registered listeners.

Whenever a dataset change event is generated, this is picked up by the JFreeChart object which (a) notifies the plot, so the axes can be updated and (b) notifies any other listeners (for example, the JFreeChartPanel if you are displaying a chart in an application).

The JFreeChartPanel is wired to redraw the chart every time it changes.

Without seeing the code you are using it is difficult to say if you have done something wrong or if there is a bug in JFreeChart.

Regards,

DG.

Joern Muehlencord

Re: dynamic XYBarChart

Post by Joern Muehlencord » Thu Apr 18, 2002 12:17 pm

Hi David,

ok, here is the code. First the initChart-Method, which creates the chart. It contains the still unsolved problem from http://www.object-refinery.com/phorum-3 ... 844&t=1844

/** liefert das Load-Chart für die Leitung */
private void initChart() {
String title = "Load-Chart";
//String subtitleStr ="der Leitung "+this;
String subtitleStr ="";
String domain = "Zeit";
String ranges[] = {"gleitender Durchschnitt", "Absolute Auslastung"};

load = new BasicTimeSeries("Auslastung", FixedMillisecond.class);
TimeSeriesCollection tsCollection = new TimeSeriesCollection(load);
LinearPlotFitAlgorithm lavg = new LinearPlotFitAlgorithm();
PlotFit pf1 = new PlotFit(tsCollection, lavg);
XYDataset tempDataset1 = pf1.getFit();

/*
MovingAveragePlotFitAlgorithm mavg = new MovingAveragePlotFitAlgorithm();
PlotFit pf2 = new PlotFit(tsCollection, mavg);
mavg.setPeriod(5);
XYDataset tempDataset2 = pf2.getFit();
*/

// Masterdatensatz erstellen
data = new CombinedDataset();
data.add (tempDataset1); // linearer durchschnitt + Daten!!
//data.add (tempDataset2); // linearer durchschnitt + Daten!!

// decompose data into its two dataset series
SeriesDataset series0 = new SubSeriesDataset(data, 0);
SeriesDataset series1 = new SubSeriesDataset(data, 1);
//SeriesDataset series2 = new SubSeriesDataset(data, 3);

// compose datasets for each sub-plot
CombinedDataset data0 = new CombinedDataset(new SeriesDataset[] {series0} ); // nur die Daten
CombinedDataset data1 = new CombinedDataset(new SeriesDataset[] {series1} ); // Durchschnitt

chart = null;
// make one shared horizintal axis
ValueAxis timeAxis = new HorizontalDateAxis(domain);
timeAxis.setCrosshairVisible(false);

// make one vertical axis for each sub-plot
NumberAxis[] valueAxis = new NumberAxis[2];
for (int i=0; i<valueAxis.length; i++) {
valueAxis = new VerticalNumberAxis(ranges);
valueAxis.setAutoRangeMinimumSize(new Integer(1));
valueAxis.setTickUnit(new NumberTickUnit(new Double(0.25), new DecimalFormat()));
valueAxis.setAutoRangeIncludesZero(false);
}

// Plots erstellen
CombinedPlot combinedPlot = new CombinedPlot(timeAxis, CombinedPlot.VERTICAL);
CombinedChart chartToCombine;

// XYChart hinzufuegen (absolute Auslastung und gleitender Durchschnitt)
chartToCombine = ChartFactory.createCombinableXYChart(timeAxis, valueAxis[0], data1);
combinedPlot.add(chartToCombine, 1);

// VerticalXYBarChar hinzufuegen (absolute Auslastung als Bar-Chart)
chartToCombine = ChartFactory.createCombinableVerticalXYBarChart(timeAxis, valueAxis[1], data0);
combinedPlot.add(chartToCombine, 1);

// die Plots auf die Größe anpassen und das Chart erzeugen
combinedPlot.adjustPlots();
chart = new JFreeChart(data, combinedPlot, "Load-Statistik", JFreeChart.DEFAULT_TITLE_FONT, true);
// Chart individualisieren und zurück geben
chart.setBackgroundPaint(new GradientPaint(0, 0, Color.white, 0, 1000, Color.orange));
TextTitle subtitle = new TextTitle(subtitleStr, new Font("SansSerif", Font.BOLD, 12));
chart.addTitle(subtitle);
}

and here is a insert-statement:

try {
load.add(new FixedMillisecond(now.getTime()+currentTime+k), new Double(1.0));
}
catch (Exception e) {
System.out.println (e);
}

private JFreeChart chart;
private BasicTimeSeries load;
private CombinedDataset data;

Hope, there is nothing missing.

Bye
Joern

Joern Muehlencord

Re: dynamic XYBarChart

Post by Joern Muehlencord » Thu Apr 18, 2002 12:23 pm

Uups, I missed one line. After the load.add(...)-block, a
load.fireSeriesChanged();
is missing.

Joern

David Gilbert

Re: dynamic XYBarChart

Post by David Gilbert » Thu Apr 18, 2002 2:01 pm

I think the problem is that the LinearPlotFitAlgorithm and MovingAveragePlotFitAlgorithm classes each calculate a completely new XYDataset based on the data you supply.

So your chart is not actually using the data in load...so even when you change it, the chart doesn't change because it is looking at a different dataset.

I think when these classes were originally written they were made for static charts, rather than dynamic ones. At some point, they'll need to be redesigned.

Regards,

DG.

Locked