/*
* Open Source Physics software is free software as described near the bottom of this code file.
*
* For additional information and documentation on Open Source Physics please see:
* <http://www.opensourcephysics.org/>
*/
package org.opensourcephysics.display;
import org.opensourcephysics.controls.XML;
import org.opensourcephysics.controls.XMLControl;
/**
* HistogramDataset creates a histogram of appended data points.
*
* @author Wolfgang Christian
* @version 1.0
*/
public class HistogramDataset extends Dataset {
double min, max;
double binSize = 1;
int n;
double[] binVals;
double[] xVals;
int counts;
int missedCounts;
/**
* Constructor HistogramDataset
* @param binMin
* @param binMax
* @param binSize
*/
public HistogramDataset(double binMin, double binMax, double binSize) {
super();
setMarkerShape(Dataset.POST);
setBinWidth(binMin, binMax, binSize);
}
/**
* Constructs a HistogramDataset for values from 0 through 100.
*/
protected HistogramDataset() {
this(0, 100, 1);
}
/**
* Appends an (x,y) datum to the Stipchart.
*
* @param x
* @param y
*/
public void append(double x, double y) {
int index = (int) ((x-min)/binSize);
if((index<0)||(index>=n)) {
missedCounts++;
} else {
counts++;
binVals[index] += y;
ymax = Math.max(binVals[index], ymax);
ymin = Math.min(binVals[index], ymin);
// xpoints do not change; ypoints has been set so just copy the new data
System.arraycopy(binVals, 0, ypoints, 0, n);
if(isConnected()) {
recalculatePath();
}
}
}
/**
* Appends (x,y) data-arrays to the Stipchart.
*
* @param xpoints
* @param ypoints
*/
public void append(double[] xpoints, double[] ypoints) {
for(int j = 0, nj = xpoints.length; j<nj; j++) { // bin all the points
int index = (int) ((xpoints[j]-min)/binSize);
if((index<0)||(index>=n)) {
missedCounts++;
} else {
counts++;
binVals[index] += ypoints[j];
ymax = Math.max(binVals[index], ymax);
ymin = Math.min(binVals[index], ymin);
}
}
// xpoints do not change; ypoints has been set so just copy the new data
System.arraycopy(binVals, 0, this.ypoints, 0, n);
if(isConnected()) {
recalculatePath();
}
}
/**
* Gets the x world coordinate for the left hand side of the panel.
*
* @return xmin
*/
public double getXMin() {
return min;
}
/**
* Gets the x world coordinate for the right hand side of the panel.
*
* @return xmax
*/
public double getXMax() {
return max;
}
public void setBinWidth(double binMin, double binMax, double binSize) {
counts = 0;
missedCounts = 0;
min = binMin;
max = binMax;
this.binSize = binSize;
n = (int) ((binMax-binMin)/binSize);
binVals = new double[n];
xVals = new double[n];
double x = min+binSize/2;
for(int i = 0; i<n; i++) {
xVals[i] = x;
x += this.binSize;
}
super.clear();
super.append(xVals, binVals);
}
/**
* Clears data from the histogram.
*/
public void clear() {
for(int i = 0; i<n; i++) {
binVals[i] = 0;
}
counts = 0;
missedCounts = 0;
// xpoints do not change; ypoints has been set so just copy the new data
ymax = 0;
ymin = 0;
if(n==0) {
return;
}
System.arraycopy(binVals, 0, ypoints, 0, n);
if(isConnected()) {
recalculatePath();
}
}
/**
* Returns the XML.ObjectLoader for this class.
*
* @return the object loader
*/
public static XML.ObjectLoader getLoader() {
return new HistogramDatasetLoader();
}
protected static class HistogramDatasetLoader extends Loader {
public void saveObject(XMLControl control, Object obj) {
super.saveObject(control, obj);
HistogramDataset dataset = (HistogramDataset) obj;
control.setValue("min", dataset.min); //$NON-NLS-1$
control.setValue("max", dataset.max); //$NON-NLS-1$
control.setValue("bin_size", dataset.binSize); //$NON-NLS-1$
control.setValue("number_of_bins", dataset.n); //$NON-NLS-1$
control.setValue("bin_vals", dataset.binVals); //$NON-NLS-1$
control.setValue("x_vals", dataset.xVals); //$NON-NLS-1$
control.setValue("counts", dataset.counts); //$NON-NLS-1$
control.setValue("missed_counts", dataset.missedCounts); //$NON-NLS-1$
}
public Object loadObject(XMLControl control, Object obj) {
super.loadObject(control, obj);
HistogramDataset dataset = (HistogramDataset) obj;
dataset.setBinWidth(control.getDouble("min"), control.getDouble("max"), control.getDouble("bin_size")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
dataset.binVals = (double[]) control.getObject("bin_vals"); //$NON-NLS-1$
dataset.xVals = (double[]) control.getObject("x_vals"); //$NON-NLS-1$
dataset.counts = control.getInt("counts"); //$NON-NLS-1$
dataset.missedCounts = control.getInt("missed_counts"); //$NON-NLS-1$
if(dataset.n==0) {
return obj;
}
System.arraycopy(dataset.xVals, 0, dataset.xpoints, 0, dataset.n);
System.arraycopy(dataset.binVals, 0, dataset.ypoints, 0, dataset.n);
if(dataset.isConnected()) {
dataset.recalculatePath();
}
return obj;
}
}
}
/*
* Open Source Physics software is free software; you can redistribute
* it and/or modify it under the terms of the GNU General Public License (GPL) as
* published by the Free Software Foundation; either version 2 of the License,
* or(at your option) any later version.
* Code that uses any portion of the code in the org.opensourcephysics package
* or any subpackage (subdirectory) of this package must must also be be released
* under the GNU GPL license.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston MA 02111-1307 USA
* or view the license online at http://www.gnu.org/copyleft/gpl.html
*
* Copyright (c) 2007 The Open Source Physics project
* http://www.opensourcephysics.org
*/