Hi kimba,
there was somebody asking for something similar. See
http://www.jfree.org/phpBB2/viewtopic.php?t=23541
In general, if you already have your data structure, there are two ways in which you can use that as a data source in JFreeChart:
1. Put your data in one of the available dataset implementations. Drawback: you have to store your data in two places: in your custom structure and in the dataset. If your data structure changes you would have to do the entire data transport again.
2. Write your own class that implements/extends one of the available dataset interfaces/classes and exposes your data to JFreeChart in the right way. In this way you only have to store your data in one place. If the data in your data structure changes, you can simple fire an event.
Displaying a 2D number array in a plot is a situation somewhere in between an XYPlot and a CategoryPlot.
a) we have a discrete number of equally spaced x values (somehow like in a CategoryPlot). The number of the x values could e. g. stem from an analysis device that records data with a given frequency over a defined time span or that observes a given range in space with a given resolution in datapoints/length unit.
b) for each x-value we have a discrete number of equally spaced y-values. Each x-value has the same number of y-values (again somewhat like a CategoryPlot).
c) for each point in the chart given by the integer coordinates described in a) and b) we have a z-value that we want to show. That is a clear case of an XYZDataset and an XYBlockRenderer.
Let the number of x-values be columnCount and the number of y-values rowCount. Then we can design an XYZData implementation based on the following:
- The number of data points is columnCount*rowCount.
- For the first
rowCount data points the x-index is 0, for the next
rowCount data points the x-index is 1 an so forth.
- For x-index = 0, the y index is equal to the index of the data point in your value list. After we have displayed the first
rowCount data points we are resetting the y-index to zero. In general, the y-index of a data point is the modulus of its index in the data point list divided by the columns displayed so far
- The measurand can be retrieved from an array via [xindex][yindex].
Enough theory, here is a smaple program that will hopefully make the whole thing clearer.
Regards, paradoxoff
Code: Select all
package demo;
import java.awt.Color;
import java.awt.Font;
import javax.swing.JFrame;
import javax.swing.JPanel;
import org.jfree.chart.*;
import org.jfree.chart.plot.*;
import org.jfree.chart.renderer.LookupPaintScale;
import org.jfree.chart.renderer.xy.*;
import org.jfree.data.xy.*;
import org.jfree.chart.axis.*;
import org.jfree.chart.title.*;
import org.jfree.ui.*;
public class XYZChartDemo {
public XYZChartDemo(String title) {
JFrame frame = new JFrame(title);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JFreeChart chart = createXYZChart();
int width = 600;
int height = 600;
ChartPanel chartPanel = new ChartPanel(chart,width,height,16,16,width*10,height*10,true,true,true,true,true,true);
frame.setContentPane(chartPanel);
frame.pack();
frame.setVisible(true);
}
private JFreeChart createXYZChart() {
NumberAxis xAxis = new NumberAxis("x Axis");
NumberAxis yAxis = new NumberAxis("y Axis");
double[][] data = new double[][]{{10.0,15.0,20.0,25.0,30.0},{35.0,40.0,45.0,50.0,55.0},{60.0,65.0,70.0,75.0,80.0}};
XYZDataset xyzset = new XYZArrayDataset(data);
XYPlot plot = new XYPlot(xyzset, xAxis, yAxis, null);
XYBlockRenderer r = new XYBlockRenderer();
LookupPaintScale ps = new LookupPaintScale(0.0,100.0,Color.GRAY);
ps.add(10.0,new Color(255,192,192));
ps.add(15.0,new Color(255,128,128));
ps.add(20.0,new Color(255,0,0));
ps.add(25.0,new Color(192,0,0));
ps.add(30.0,new Color(128,0,0));
ps.add(35.0,new Color(128,255,128));
ps.add(40.0,new Color(64,255,64));
ps.add(45.0,new Color(0,224,0));
ps.add(50.0,new Color(0,160,0));
ps.add(55.0,new Color(0,96,0));
ps.add(60.0,new Color(192,192,255));
ps.add(65.0,new Color(128,128,255));
ps.add(70.0,new Color(0,0,255));
ps.add(75.0,new Color(0,0,192));
ps.add(80.0,new Color(0,0,128));
r.setPaintScale(ps);
r.setBlockHeight(1.0f);
r.setBlockWidth(1.0f);
plot.setRenderer(r);
JFreeChart chart = new JFreeChart("Chart Title",JFreeChart.DEFAULT_TITLE_FONT,plot,false);
NumberAxis scaleAxis = new NumberAxis("Scale");
scaleAxis.setUpperBound(100);
scaleAxis.setAxisLinePaint(Color.white);
scaleAxis.setTickMarkPaint(Color.white);
scaleAxis.setTickLabelFont(new Font("Dialog", Font.PLAIN, 12));
PaintScaleLegend legend = new PaintScaleLegend(ps,
scaleAxis);
legend.setAxisLocation(AxisLocation.BOTTOM_OR_LEFT);
legend.setPadding(new RectangleInsets(5, 5, 5, 5));
legend.setStripWidth(50);
legend.setPosition(RectangleEdge.RIGHT);
legend.setBackgroundPaint(Color.WHITE);
chart.addSubtitle(legend);
chart.setBackgroundPaint(Color.white);
return chart;
}
private static class XYZArrayDataset extends AbstractXYZDataset{
double[][] data;
int rowCount = 0;
int columnCount = 0;
XYZArrayDataset(double[][] data){
this.data = data;
rowCount = data.length;
columnCount = data[0].length;
}
public int getSeriesCount(){
return 1;
}
public Comparable getSeriesKey(int series){
return "serie";
}
public int getItemCount(int series){
return rowCount*columnCount;
}
public double getXValue(int series,int item){
return (int)(item/columnCount);
}
public double getYValue(int series,int item){
return item % columnCount;
}
public double getZValue(int series,int item){
return data[(int)(item/columnCount)][item % columnCount];
}
public Number getX(int series,int item){
return new Double((int)(item/columnCount));
}
public Number getY(int series,int item){
return new Double(item % columnCount);
}
public Number getZ(int series,int item){
return new Double(data[(int)(item/columnCount)][item % columnCount]);
}
}
public static void main(String[] args) {
XYZChartDemo demo = new XYZChartDemo(
"XYZ Demo");
}
}