package ch.psi.plot.xyz; import java.util.Arrays; import java.util.logging.Logger; import org.jfree.data.xy.DefaultXYZDataset; import org.jfree.data.xy.XYZDataset; /** * PlotData implementation optimized for matrix data. * ... */ public class MatrixPlotData implements JFreeMatrixPlotData{ private static Logger logger = Logger.getLogger(MatrixPlotData.class.getName()); private int numberOfXBins; private int numberOfYBins; private double[][] dataArray; Boolean[] occupiedBin; private XYZDataset data; private JFreeMatrixPlotMetadata metadata; public MatrixPlotData(){ this(new JFreeMatrixPlotMetadata()); } public MatrixPlotData(JFreeMatrixPlotMetadata metadata) { this.metadata = metadata; numberOfXBins = metadata.getNumberOfBinsX(); numberOfYBins = metadata.getNumberOfBinsY(); int arraylength = numberOfXBins*numberOfYBins; double[] xvalues = new double[arraylength]; double[] yvalues = new double[arraylength]; double[] zvalues = new double[arraylength]; Arrays.fill(xvalues, Double.NEGATIVE_INFINITY); Arrays.fill(yvalues, Double.NEGATIVE_INFINITY); Arrays.fill(zvalues, Double.NEGATIVE_INFINITY); logger.fine("Number of X values: "+numberOfXBins+" Number of Y values: "+numberOfYBins+" Array size: "+arraylength); dataArray = new double[][] {xvalues, yvalues, zvalues}; occupiedBin = new Boolean[arraylength]; Arrays.fill(occupiedBin, false); //Create the XYDataset (org.jfree), not to be confused with the ch.psi dataSet) data = new DefaultXYZDataset(); ((DefaultXYZDataset)data).addSeries("Series Name" , dataArray); } @Override public void addData(Number x, Number y, Number z) { int xBin = getXBin(x.doubleValue()); int yBin = getYBin(y.doubleValue()); //x Value is column, y value is row dataArray[0][yBin * numberOfXBins + xBin] = x.doubleValue(); dataArray[1][yBin * numberOfXBins + xBin] = y.doubleValue(); dataArray[2][yBin * numberOfXBins + xBin] = z.doubleValue(); } @Override public void addDataBinned(Number x, Number y, Number z) { int xBin = getXBin(x.doubleValue()); int yBin = getYBin(y.doubleValue()); dataArray[0][yBin * numberOfXBins + xBin] = getXValueBinned(xBin, yBin); dataArray[1][yBin * numberOfXBins + xBin] = getYValueBinned(xBin, yBin); dataArray[2][yBin * numberOfXBins + xBin] = z.doubleValue(); if (occupiedBin[yBin * numberOfXBins + xBin]){ logger.finest("Bin (" + xBin + " " + yBin + ") is allready filled" ); } else{ occupiedBin[yBin * numberOfXBins + xBin] = true; } } //Not part of interface public double getXValueBinned(int i, int j){ return metadata.getMinX() + i*metadata.getBinWidthX(); } //Not part of interface public double getYValueBinned(int i, int j){ return metadata.getMinY() + j*metadata.getBinWidthY(); } @Override public void addData(int i, int j, Number x, Number y, Number z) { //The array is filled 'horizontally' (row (=yAxis) kept constant, columns++ , //then row++ etc) dataArray[0][i * numberOfXBins + j] = x.doubleValue(); dataArray[1][i * numberOfXBins + j] = y.doubleValue(); dataArray[2][i * numberOfXBins + j] = z.doubleValue(); } @Override public XYZDataset getData() { return data; } @Override public JFreeMatrixPlotMetadata getMetadata() { return metadata; } @Override public void setMetadata(JFreeMatrixPlotMetadata metadata) { this.metadata = metadata; } @Override public double getXValue(int i, int j){ return dataArray[0][i * numberOfXBins + j]; } @Override public double getYValue(int i, int j){ return dataArray[1][i * numberOfXBins + j]; } @Override public double getXValueBinned(double x){ return metadata.getMinX() + getXBin(x)*metadata.getBinWidthX(); } @Override public double getYValueBinned(double y){ return metadata.getMinY() + getYBin(y)*metadata.getBinWidthY(); } @Override public double getValue(double x, double y){ int column = getXBin(x); int row = getYBin(y); //int column = (int)x; //int row = (int)y; return dataArray[2][row * numberOfXBins + column]; } @Override public double getValue(int i, int j) { return dataArray[2][i * numberOfXBins + j]; } /** * The array is filled 'horizontally' (row kept constant, columns++ , * then row++ etc. where row = i = yAxis and column = j = xAxis) */ @Override public void setValue(int i, int j, double value) { dataArray[2][i * numberOfXBins + j] = value; } /** * get the bin in which x lies * maxX and minX values are the values in the middle of the first and last bin * therefore we need to subtract 1/2 of binWidth * @return */ @Override public int getXBin(double x) { return ((int) ((x - ( metadata.getMinX() - 0.5*metadata.getBinWidthX()))/metadata.getBinWidthX())); } /** * get the bin in which y lies * maxY and minY values are the values in the middle of the first and last bin * therefore we need to subtract 1/2 of binWidth * @return */ @Override public int getYBin(double y) { return ((int) ((y - (metadata.getMinY() - 0.5*metadata.getBinWidthY()))/metadata.getBinWidthY())); } /* (non-Javadoc) * @see ch.psi.plot.xyz.JFreeMatrixPlotData#getDataArray() */ @Override public double[] getDataArray() { return dataArray[2]; } /* (non-Javadoc) * @see ch.psi.plot.xyz.JFreeMatrixPlotData#getXSize() */ @Override public int getXSize() { // TODO Auto-generated method stub return numberOfXBins; } /* (non-Javadoc) * @see ch.psi.plot.xyz.JFreeMatrixPlotData#getYSize() */ @Override public int getYSize() { // TODO Auto-generated method stub return numberOfYBins; } public void clear(){ Arrays.fill(dataArray[0], Double.NEGATIVE_INFINITY); Arrays.fill(dataArray[1], Double.NEGATIVE_INFINITY); Arrays.fill(dataArray[2], Double.NEGATIVE_INFINITY); } }