/*
* 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 java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import javax.swing.table.AbstractTableModel;
import org.opensourcephysics.controls.XML;
import org.opensourcephysics.controls.XMLControl;
import org.opensourcephysics.controls.XMLLoader;
/**
* Histogram maps bin number to occurrences. Histogram is Drawable and can be
* rendered on a DrawingPanel. Histogram also implements TableModel and can be
* displayed in a JTable. By default, bins consist of (notation: [ inclusive, )
* exclusive): ..., [-1,0), [0,1), [1,2), ...
*
* @author Joshua Gould
* @author Wolfgang Christian
* @created June 26, 2002
* @version 1.1
*/
public class Histogram extends AbstractTableModel implements Measurable, LogMeasurable, Data {
HistogramDataset histogramDataset;
/** draw point at top of bin */
public final static int DRAW_POINT = 0;
/** draw bin from y min to top of bin */
public final static int DRAW_BIN = 1;
/**
* Should histogram be drawn on a log scale? Default is false.
*/
public boolean logScale = false;
/**
* Should the height be adjusted by bin width? Default is false.
*/
public boolean adjustForWidth = false;
/**
* The visibility of the histogram
*/
private boolean visible=true; // Paco
/**
* Force the measured condition
*/
private boolean measured = true; // Paco
/** color of bins */
protected Color binFillColor = Color.red;
/** color of bins */
protected Color binEdgeColor = Color.red;
/** style for drawing bins */
protected int binStyle = DRAW_BIN;
/** maps bin number to occurrences */
HashMap<Integer, Double> bins;
/** width of a bin */
double binWidth = 1;
/** offset of the bins */
double binOffset = 0;
/** false if the bins are continuous */
boolean discrete = true;
/** binNumber*binWidth + binOffset */
double xmin;
/** binNumber*binWidth + binWidth + binOffset */
double xmax;
/** min number of occurrences for all bins */
final int YMIN = 0;
/** max number of occurrences for all bins */
double ymax;
/** the name of the histogram */
String name;
/** the name of the bin */
String binColumnName;
/** the name of the x column */
String xColumnName;
/** the name of the occurrences */
String yColumnName;
/**
* bin number-occurrences pairs in histogram, used for table model
* implementation
*/
Map.Entry<?, ?>[] entries = new Map.Entry<?, ?>[0];
/** whether the data has changed since the last time the entries were retrieved */
boolean dataChanged;
/** total occurrences in histogram */
double sum;
/** whether occurrences are normalized to one */
boolean normalizedToOne = false;
/**
* amount by which this histogram is shifted to the right, so that it peeks
* out from behind other histograms.
*/
double barOffset;
/** an integer ID that identifies this object */
protected int datasetID = hashCode();
/** Histogram constructor. */
public Histogram() {
binColumnName = DisplayRes.getString("Histogram.Column.BinNumber"); //$NON-NLS-1$
xColumnName = "x"; //$NON-NLS-1$
yColumnName = DisplayRes.getString("Histogram.Column.Occurrences"); //$NON-NLS-1$
name = DisplayRes.getString("Histogram.Title"); //$NON-NLS-1$
clear();
}
/**
* Reads a file and appends the data contained in the file to this Histogram.
* The format of the file is bins \t occurrences. Lines beginning with # and
* empty lines are ignored.
*
* @param inputPathName A pathname string.
* @exception java.io.IOException Description of the Exception
*/
public void read(String inputPathName) throws java.io.IOException {
java.io.BufferedReader reader = new java.io.BufferedReader(new java.io.FileReader(inputPathName));
String s = null;
while((s = reader.readLine())!=null) {
s = s.trim();
if(s.equals("")||(s.length()==0)||(s.charAt(0)=='#')) { // ignore empty lines and lines beginning with # //$NON-NLS-1$
continue;
}
try {
java.util.StringTokenizer st = new java.util.StringTokenizer(s, "\t"); //$NON-NLS-1$
int binNumber = Integer.parseInt(st.nextToken());
double numberOfoccurrences = Double.parseDouble(st.nextToken());
Double prioroccurrences = bins.get(new Integer(binNumber));
if(prioroccurrences==null) { // first occurence for this bin
bins.put(new Integer(binNumber), new Double(numberOfoccurrences));
} else {
numberOfoccurrences += prioroccurrences.doubleValue(); // increase occurrences for bin by prioroccurrences
bins.put(new Integer(binNumber), new Double(numberOfoccurrences));
}
ymax = Math.max(numberOfoccurrences, ymax);
xmin = Math.min(binNumber*binWidth+binOffset, xmin);
xmax = Math.max(binNumber*binWidth+binWidth+binOffset, xmax);
} catch(java.util.NoSuchElementException nsee) {
nsee.printStackTrace();
} catch(NumberFormatException nfe) {
nfe.printStackTrace();
}
}
reader.close();
dataChanged = true;
}
/**
* Creates a string representation of this Histogram. The bins are displayed
* in ascending order. The format of this string is bin number \t occurrences.
* Each bin starts on a new line.
*
* @return A String with the number of occurrences for each bin.
* @see #toString
*/
public String toSortedString() {
Set<Integer> keySet = bins.keySet();
Object[] keys = keySet.toArray();
Arrays.sort(keys);
String s = "x\tx"; //$NON-NLS-1$
StringBuffer buf = new StringBuffer(s.length()*keys.length);
for(int i = 0; i<keys.length; i++) {
Object key = keys[i];
buf.append(key);
buf.append("\t"); //$NON-NLS-1$
buf.append(bins.get(keys[i]));
buf.append("\n"); //$NON-NLS-1$
}
return buf.toString();
}
/**
* Creates a string representation of this Histogram. The format is bin
* number\t occurrences. Each new bin starts on a new line.
*
* @return A String with the number of occurrences for each bin.
*/
public String toString() {
Set<Integer> set = bins.keySet();
Iterator<Integer> keys = set.iterator();
String s = "x\tx"; //$NON-NLS-1$
StringBuffer buf = new StringBuffer(s.length()*set.size());
while(keys.hasNext()) {
Integer binNumber = keys.next();
Double occurrences = bins.get(binNumber);
buf.append(binNumber);
buf.append("\t"); //$NON-NLS-1$
buf.append(occurrences);
buf.append("\n"); //$NON-NLS-1$
}
return buf.toString();
}
/**
* Computes the hash code (bin number) for the specified value
*
* @param value
* @return the hash code
*/
public int hashCode(double value) {
return(int) (Math.floor((value-binOffset)/binWidth));
}
/**
* Append a value with number of occurrences to the Histogram.
*
* @param value
* @param numberOfoccurrences
*/
public synchronized void append(double value, double numberOfoccurrences) {
sum += numberOfoccurrences;
int binNumber = hashCode(value);
// Determine if there have previously been any occurrences for this bin
Double occurrences = bins.get(new Integer(binNumber));
if(occurrences==null) { // first occurence for this bin
bins.put(new Integer(binNumber), new Double(numberOfoccurrences));
} else {
// need to put Objects in HashMap, but can only add doubles
numberOfoccurrences += occurrences.doubleValue(); // increase occurrences for bin by numberOfoccurrences
bins.put(new Integer(binNumber), new Double(numberOfoccurrences));
}
ymax = Math.max(numberOfoccurrences, ymax);
xmin = Math.min(binNumber*binWidth+binOffset, xmin);
xmax = Math.max(binNumber*binWidth+binWidth+binOffset, xmax);
dataChanged = true;
}
/**
* Appends a value with 1 occurence.
*
* @param value
*/
public void append(double value) {
append(value, 1);
}
/**
* Appends values from an input file. Each value is separated by a \n
*
* @param inputPathName A pathname string.
* @exception IOException Description of the Exception
*/
public void append(String inputPathName) throws IOException {
BufferedReader br = new java.io.BufferedReader(new java.io.FileReader(inputPathName));
String s = null;
while((s = br.readLine())!=null) {
s = s.trim();
if(s.equals("")||(s.length()==0)||(s.charAt(0)=='#')) { //$NON-NLS-1$
continue;
}
try {
double d = Double.parseDouble(s);
append(d, 1);
} catch(NumberFormatException nfe) {
nfe.printStackTrace();
}
}
br.close();
}
/**
* Appends an array of values with 1 occurence.
*
* @param values
*/
public void append(double[] values) {
for(int i = 0; i<values.length; i++) {
append(values[i], 1);
}
}
/**
* Sets the visibility of the histogram
* @param visibility
*/
public void setVisible(boolean visibility) {
this.visible = visibility;
}
/**
* Draws this histogram in the drawing panel.
*
* @param drawingPanel
* @param g
*/
public synchronized void draw(DrawingPanel drawingPanel, Graphics g) {
if(bins.size()==0 || !visible) {
return;
}
Shape oldClip = g.getClip();
g.setColor(binFillColor);
g.clipRect(0, 0, drawingPanel.getWidth(), drawingPanel.getHeight());
for(Iterator<Integer> keys = bins.keySet().iterator(); keys.hasNext(); ) {
Integer binNumber = keys.next();
Double d = (bins.get(binNumber));
if(d==null) {
return;
}
double occurrences = d.doubleValue();
if(normalizedToOne) {
occurrences /= sum;
}
if(binStyle==DRAW_BIN) {
drawBin(drawingPanel, g, binNumber.intValue(), occurrences);
} else {
drawPoint(drawingPanel, g, binNumber.intValue(), occurrences);
}
}
g.setClip(oldClip);
}
/** Clears all data from this histogram and resets min and max values. */
public synchronized void clear() {
bins = new HashMap<Integer, Double>();
xmin = Integer.MAX_VALUE;
xmax = Integer.MIN_VALUE;
ymax = Integer.MIN_VALUE;
sum = 0;
dataChanged = true;
}
/**
* Gets an array of bin number-occurrences pairs
*
* @return The entries.
*/
public Map.Entry<?, ?>[] entries() {
updateEntries();
return entries;
}
/**
* Sets the style for drawing this histogram. Options are DRAW_POINT, which
* draws a point at the top of the bin, and DRAW_BIN which draws the entire
* bin down to the x axis. Default is DRAW_BIN.
*
* @param style
*/
public void setBinStyle(int style) {
binStyle = style;
}
/**
* Sets the discrete flag.
*
* @param _discrete <code>true<\code> if bins are discrete, <code>false<\code> if bins are continuous.
*/
public void setDiscrete(boolean _discrete) {
discrete = _discrete;
}
/**
* Sets the offset of the bins. Default is 0.
*
* @param _binOffset
*/
public void setBinOffset(double _binOffset) {
binOffset = _binOffset;
}
/**
* Set the offset of the bars as a fraction of a bin width. The offset is the
* amount by which this histogram is shifted to the right, so that it peeks
* out from behind later histograms when displayed in a DrawingPanel.
*
* @param _barOffset The new barOffset value
*/
public void setBarOffset(double _barOffset) {
barOffset = _barOffset;
}
/**
* Line color to use for this data
* @return
*/
public java.awt.Color getLineColor() {
return binEdgeColor;
}
/**
* Line colors for Data interface.
* @return
*/
public java.awt.Color[] getLineColors() {
return new Color[] {binEdgeColor, binEdgeColor};
}
/**
* Fill color to use for this data
* @return
*/
public java.awt.Color getFillColor() {
return binFillColor;
}
/**
* Fill colors for Data interface.
* @return
*/
public java.awt.Color[] getFillColors() {
return new Color[] {binFillColor, binFillColor};
}
/**
* Sets the bin color.
*
* @param binColor
*/
public void setBinColor(Color binColor) {
binFillColor = binColor;
binEdgeColor = binColor;
}
/**
* Sets the bin's fill and edge colors. If the fill color is null the bin is not filled.
*
* @param fillColor
* @param edgeColor
*/
public void setBinColor(Color fillColor, Color edgeColor) {
binFillColor = fillColor;
binEdgeColor = edgeColor;
}
/**
* Sets the width of a bin.
*
* @param _binWidth
*/
public void setBinWidth(double _binWidth) {
binWidth = _binWidth;
}
/**
* Sets a name that can be used to identify the dataset.
*
* @param name String
*/
public void setName(String name) {
this.name = TeXParser.parseTeX(name);
}
/**
* Gets the dataset name.
*
* @return String
*/
public String getName() {
return name;
}
/**
* The column names to be used in the data display tool
* @return
*/
public String[] getColumnNames() {
return new String[] {xColumnName, yColumnName};
}
/**
* Some elements (a Group, for instance) do not contain data, but a list of subelements which do.
* This method is used by Data displaying tools to create as many pages as needed.
* @return A list of DataInformation elements, null if the element itself is a DataInformation
*/
public java.util.List<Data> getDataList() {
return null;
}
/**
* Sets the column names when rendering this histogram in a JTable.
*
* @param _binColumnName
* @param _yColumnName
*/
public void setXYColumnNames(String _xColumnName, String _yColumnName) {
xColumnName = TeXParser.parseTeX(_xColumnName);
yColumnName = TeXParser.parseTeX(_yColumnName);
}
/**
* Sets the column names when rendering this histogram in a JTable.
*
* @param _binColumnName
* @param _yColumnName
* @param _name String the name of the histogram
*/
public void setXYColumnNames(String _xColumnName, String _yColumnName, String _name) {
xColumnName = TeXParser.parseTeX(_xColumnName);
yColumnName = TeXParser.parseTeX(_yColumnName);
name = TeXParser.parseTeX(_name);
}
/**
* Normalizes the occurrences in this histogram to one.
*
* @param b
*/
public void setNormalizedToOne(boolean b) {
normalizedToOne = b;
}
/**
* Gets the width of a bin.
*
* @return The bin width.
*/
public double getBinWidth() {
return binWidth;
}
/**
* Gets the offset of the bins.
*
* @return The bin offset.
*/
public double getBinOffset() {
return binOffset;
}
/**
* Gets the x world coordinate for the left hand side of this histogram.
*
* @return xmin
*/
public double getXMin() {
return(discrete&&(bins.size()>1)) ? xmin-binWidth : xmin;
}
/**
* Gets the x world coordinate for the right hand side of this histogram.
*
* @return xmax
*/
public double getXMax() {
return xmax;
}
/**
* Gets the y world coordinate for the bottom of this histogram.
*
* @return minimum y value
*/
public double getYMin() {
return YMIN;
}
/**
* Gets the y world coordinate for the top of this histogram.
*
* @return xmax
*/
public double getYMax() {
double max = (normalizedToOne ? ymax/sum : ymax);
if(adjustForWidth) {
max = max/getBinWidth();
}
if(logScale) {
max = Math.log(max);
}
return max;
}
/**
* Gets the minimum x needed to draw this object on a log scale.
* @return minimum
*/
public double getXMinLogscale() {
double xmin = getXMin();
if(xmin>0) {
return xmin;
}
return binOffset;
}
/**
* Gets the maximum x needed to draw this object on a log scale.
* @return maximum
*/
public double getXMaxLogscale() {
double xmax = getXMax();
if(xmax>0) {
return xmax;
}
return binOffset+10;
}
/**
* Gets the minimum y needed to draw this object on a log scale.
* @return minimum
*/
public double getYMinLogscale() {
return 1;
}
/**
* Gets the maximum y needed to draw this object on a log scale on a log scale.
* @return maximum
*/
public double getYMaxLogscale() {
return Math.max(10, getYMax()); // make sure we have at least one decade on log scale
}
/**
* Gets the valid measure flag. The measure is valid if this histogram is not
* empty.
*
* @return <code>true<\code> if measure is valid.
*/
public boolean isMeasured() {
return bins.size()>0 && measured; // Paco
}
/**
* Forces the measured condition of the histogram
* @param visibility
*/
public void setMeasured(boolean measure) { // Paco
this.measured = measure;
}
/**
* Gets the name of the column for rendering in a JTable
*
* @param column the column whose value is to be queried
* @return the name
*/
public String getColumnName(int column) {
if(column==0) {
return binColumnName;
} else if(column==1) {
return xColumnName;
} else {
return yColumnName;
}
}
/**
* Gets the number of rows for rendering in a JTable.
*
* @return the count
*/
public int getRowCount() {
return bins.size();
}
/**
* Gets the name of the colummn for rendering in a JTable
*
* @return the name
*/
public int getColumnCount() {
return 3;
}
/**
* Gets a bin number or occurrences for bin number for rendering in a JTable.
*
* @param row the row whose value is to be queried
* @param column the column whose value is to be queried
* @return the datum
*/
public Object getValueAt(int row, int column) {
updateEntries();
Map.Entry<?, ?> entry = entries[row];
if(column==0) {
return entry.getKey();
}
if(column==1) {
return new Double(((Integer) entry.getKey()).doubleValue()*binWidth+binWidth/2.0+binOffset);
}
if(normalizedToOne) {
Double d = (Double) entry.getValue();
return new Double(d.doubleValue()/sum);
}
return entry.getValue();
}
/**
* Gets the type of object for JTable entry.
*
* @param columnIndex the column whose value is to be queried
* @return the class
*/
public Class<?> getColumnClass(int columnIndex) {
return((columnIndex==0) ? Integer.class : Double.class);
}
/**
* Sets the ID number of this Data.
*
* @param id the ID number
*/
public void setID(int id) {
datasetID = id;
}
/**
* Returns a unique identifier for this Data.
*
* @return the ID number
*/
public int getID() {
return datasetID;
}
/**
* Draws a point at the top of a bin.
*
* @param drawingPanel
* @param g
* @param binNumber
* @param occurrences
*/
protected void drawPoint(DrawingPanel drawingPanel, Graphics g, int binNumber, double occurrences) {
int px = drawingPanel.xToPix(getLeftMostBinPosition(binNumber)); // leftmost position of bin
int py = drawingPanel.yToPix(occurrences);
int pointRadius = 2;
if(discrete) {
g.fillRect(px-pointRadius, py-pointRadius, pointRadius*2, pointRadius*2);
} else { // continous, draw entire bin
int px2 = drawingPanel.xToPix(getRightMostBinPosition(binNumber));
int pWidth = px2-px;
g.fillRect(px, py, pWidth, pointRadius*2);
}
}
/**
* Draws a filled bin.
*
* @param drawingPanel
* @param g
* @param binNumber
* @param occurrences
*/
protected void drawBin(DrawingPanel drawingPanel, Graphics g, int binNumber, double occurrences) {
if(adjustForWidth) {
occurrences = occurrences/getBinWidth();
}
if(logScale) {
occurrences = Math.max(0, Math.log(occurrences));
}
int binlx = drawingPanel.xToPix(getLeftMostBinPosition(binNumber));
if(discrete) {
if(binEdgeColor!=null) {
g.setColor(binEdgeColor);
g.drawLine(binlx, drawingPanel.yToPix(YMIN), binlx, drawingPanel.yToPix(occurrences));
}
} else { // continous, draw entire bin
int binrx = drawingPanel.xToPix(getRightMostBinPosition(binNumber));
int pWidth = binrx-binlx;
double pHeight = drawingPanel.getYPixPerUnit()*occurrences;
java.awt.geom.Rectangle2D.Double rect = new java.awt.geom.Rectangle2D.Double(binlx, drawingPanel.yToPix(occurrences), pWidth, pHeight);
Graphics2D g2 = (Graphics2D) g;
if(binFillColor!=null) {
g.setColor(binFillColor);
g2.fill(rect);
}
if(binEdgeColor!=null) {
g.setColor(binEdgeColor);
g2.draw(rect);
}
}
}
/**
* Gets an array containing the bin centers.
*
* @return the bins
*/
public double[] getXPoints() {
int nbins = 1+(int) ((xmax-xmin)/binWidth);
if(nbins<1) {
return new double[0];
}
double[] xdata = new double[nbins];
for(int i = 0; i<nbins; i++) {
xdata[i] = xmin+i*binWidth+binOffset+binWidth/2;
//System.out.println("number="+i+" x="+xdata[i]);
}
return xdata;
}
/**
* Gets an array containing the values within the bins.
*
* @return the values of the bins
*/
public double[] getYPoints() {
int nbins = 1+(int) ((xmax-xmin)/binWidth);
if(nbins<1) {
return new double[0];
}
double[] ydata = new double[nbins];
for(int i = 0; i<nbins; i++) {
Integer binNumber = new Integer(i);
Double bin = bins.get(binNumber);
ydata[i] = (bin==null) ? 0 : bin.doubleValue();
//System.out.println("number"+binNumber.intValue()+" x="+data[0][i]+ " occurrences="+data[1][i]);
}
return ydata;
}
/**
* Gets a data array containing both the bin centers and the values within the bins.
*
* @return a double[index][2] array of data
*/
public double[][] getPoints() {
int nbins = 1+(int) ((xmax-xmin)/binWidth);
if(nbins<1) {
return new double[2][0];
}
double[][] data = new double[2][nbins];
int iStart = (int) (xmin/binWidth);
for(int i = 0; i<nbins; i++) {
Integer binNumber = new Integer(i+iStart);
Double bin = bins.get(binNumber);
data[0][i] = xmin+i*binWidth+binOffset+binWidth/2;
data[1][i] = (bin==null) ? 0 : bin.doubleValue();
// System.out.println("number"+binNumber.intValue()+" x="+data[0][i]+ " occurances="+data[1][i]);
}
return data;
}
/**
* Gets a data array containing both the bin centers and the values within the bins.
*
* @return a double[index][2] array of data
*/
public double[][] getLogPoints() {
int nbins = (int) Math.round((xmax-xmin)/binWidth);
if(nbins<1) {
return new double[2][0];
}
double[][] data = new double[2][nbins];
int iStart = (int) (xmin/binWidth);
for(int i = 0; i<nbins; i++) {
Integer binNumber = new Integer(i+iStart);
Double bin = bins.get(binNumber);
data[0][i] = xmin+i*binWidth+binOffset+binWidth/2;
data[1][i] = (bin==null) ? 0 : bin.doubleValue();
data[1][i] = (data[1][i]>0) ? Math.log(data[1][i]) : 0;
}
return data;
}
/**
* Method getLeftMostBinPosition
*
* @param binNumber
*
* @return position
*/
public double getLeftMostBinPosition(int binNumber) {
return binNumber*binWidth+binOffset+binWidth*barOffset;
}
/**
* Method getRightMostBinPosition
*
* @param binNumber
*
* @return position
*/
public double getRightMostBinPosition(int binNumber) {
return binNumber*binWidth+binWidth+binOffset+binWidth*barOffset;
}
/**
* Updates the bin number-occurrences array if data has changed since the last
* update
*/
private synchronized void updateEntries() {
if(dataChanged) {
entries = bins.entrySet().toArray(entries);
dataChanged = false;
}
}
public double[][] getData2D() {
double[][] data = (logScale) ? getLogPoints() : getPoints();
return data;
}
public double[][][] getData3D() {
return null;
}
public ArrayList<Dataset> getDatasets() {
double[][] data = (logScale) ? getLogPoints() : getPoints();
double[] bins = data[0];
double[] vals = data[1];
//double start=bins[0]-getBinWidth()/2;
//double stop=bins[bins.length-1]+getBinWidth()/2;
double start = 0;
double stop = getBinWidth();
if((bins!=null)&&(bins.length>0)) {
start = bins[0]-getBinWidth()/2;
stop = bins[bins.length-1]+getBinWidth()/2;
}
if(histogramDataset==null) {
histogramDataset = new HistogramDataset(start, stop, getBinWidth());
} else {
histogramDataset.clear();
histogramDataset.setBinWidth(start, stop, getBinWidth());
}
histogramDataset.setXYColumnNames(xColumnName, yColumnName, name);
histogramDataset.append(bins, vals);
histogramDataset.setMarkerColor(binFillColor, binEdgeColor);
ArrayList<Dataset> list = new ArrayList<Dataset>();
list.add(histogramDataset);
return list;
}
/**
* Returns the XML.ObjectLoader for this class.
*
* @return the object loader
*/
public static XML.ObjectLoader getLoader() {
return new HistogramLoader();
}
/**
* A class to save and load Dataset data in an XMLControl.
*/
protected static class HistogramLoader extends XMLLoader {
public void saveObject(XMLControl control, Object obj) {
Histogram his = (Histogram) obj;
double[][] points = (his.logScale) ? his.getLogPoints() : his.getPoints();
double[] bins = points[0];
double[] vals = points[1];
control.setValue("log_scale", his.logScale); //$NON-NLS-1$
control.setValue("discrete", his.discrete); //$NON-NLS-1$
control.setValue("adjust_for_width", his.adjustForWidth); //$NON-NLS-1$
control.setValue("bin_fill_color", his.binFillColor); //$NON-NLS-1$
control.setValue("bin_edge_color", his.binEdgeColor); //$NON-NLS-1$
control.setValue("bin_style", his.binStyle); //$NON-NLS-1$
control.setValue("bin_width", his.binWidth); //$NON-NLS-1$
control.setValue("bin_offset", his.binOffset); //$NON-NLS-1$
control.setValue("name", his.name); //$NON-NLS-1$
control.setValue("x_column_name", his.xColumnName); //$NON-NLS-1$
control.setValue("y_column_name", his.yColumnName); //$NON-NLS-1$
control.setValue("bin_column_name", his.binColumnName); //$NON-NLS-1$
control.setValue("bins", bins); //$NON-NLS-1$
control.setValue("vals", vals); //$NON-NLS-1$
}
public Object createObject(XMLControl control) {
return new Histogram();
}
public Object loadObject(XMLControl control, Object obj) {
Histogram his = (Histogram) obj;
double[] bins = (double[]) control.getObject("bins"); //$NON-NLS-1$
double[] vals = (double[]) control.getObject("vals"); //$NON-NLS-1$
his.name = control.getString("name"); //$NON-NLS-1$
his.xColumnName = control.getString("x_column_name"); //$NON-NLS-1$
his.yColumnName = control.getString("y_column_name"); //$NON-NLS-1$
his.binColumnName = control.getString("bin_column_name"); //$NON-NLS-1$
his.logScale = control.getBoolean("log_scale"); //$NON-NLS-1$
his.discrete = control.getBoolean("discrete"); //$NON-NLS-1$
his.adjustForWidth = control.getBoolean("adjust_for_width"); //$NON-NLS-1$
his.binFillColor = (Color) control.getObject("bin_fill_color"); //$NON-NLS-1$
his.binEdgeColor = (Color) control.getObject("bin_edge_color"); //$NON-NLS-1$
his.binStyle = control.getInt("bin_style"); //$NON-NLS-1$
his.binWidth = control.getDouble("bin_width"); //$NON-NLS-1$
his.binOffset = control.getDouble("bin_offset"); //$NON-NLS-1$
his.adjustForWidth = control.getBoolean("adjust_for_width"); //$NON-NLS-1$
if((bins!=null)&&(vals!=null)) {
for(int i = 0, n = bins.length; i<n; i++) {
his.append(bins[i], vals[i]);
}
}
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
*/