pom.xml0000644000175000017500000000337011326056641012610 0ustar giovannigiovanni global org.freehep 8 4.0.0 org.freehep jas-plotter 2.2.6 JAS(2) Plotter JAS(2) Plotter freehep-maven Maven FreeHEP http://java.freehep.org/maven2 maven-surefire-plugin true org.freehep freehep-export 2.1.1 test javax.help javahelp 2.0.02 provided xerces xercesImpl 2.6.2 junit junit scm:svn:svn://svn.freehep.org/svn/freehep/tags/jas-plotter-2.2.6 scm:svn:svn://svn.freehep.org/svn/freehep/tags/jas-plotter-2.2.6 src/0000755000175000017500000000000011325547132012056 5ustar giovannigiovannisrc/test/0000755000175000017500000000000011325547133013036 5ustar giovannigiovannisrc/test/java/0000755000175000017500000000000011325547132013756 5ustar giovannigiovannisrc/test/java/jas/0000755000175000017500000000000011325547132014533 5ustar giovannigiovannisrc/test/java/jas/hist/0000755000175000017500000000000011325547132015502 5ustar giovannigiovannisrc/test/java/jas/hist/test/0000755000175000017500000000000011325547133016462 5ustar giovannigiovannisrc/test/java/jas/hist/test/MemoryDataSource.java0000644000175000017500000000505511325547133022555 0ustar giovannigiovannipackage jas.hist.test; import jas.hist.DataSource; import jas.hist.HasDataSource; import jas.hist.HasStyle; import jas.hist.HistogramUpdate; import jas.hist.JASHist1DHistogramStyle; import jas.hist.JASHistStyle; import jas.hist.Rebinnable1DHistogramData; import jas.hist.Statistics; import jas.hist.util.ObserverAdapter; import java.util.Observable; public class MemoryDataSource extends ObserverAdapter implements HasDataSource, Rebinnable1DHistogramData, HasStyle { private static final HistogramUpdate hdr = new HistogramUpdate(HistogramUpdate.DATA_UPDATE,true); private static final int SECONDS = 60; public MemoryDataSource() { super(t); } public DataSource getDataSource(String param) { return this; } public double[][] rebin(int nbin, double min, double max, boolean wantErrors, boolean hurry) { double[] result = t.getSnapshot(); double[][] r = { result }; return r; } public double getMin() { return -SECONDS; } public double getMax() { return 0; } public int getBins() { return SECONDS; } public boolean isRebinnable() { return false; } public int getAxisType() { return Rebinnable1DHistogramData.INTEGER; } public String[] getAxisLabels() { return null; } public Statistics getStatistics() { return null; } public String getTitle() { return "Java Memory Usage"; } public JASHistStyle getStyle() { JASHist1DHistogramStyle style = new JASHist1DHistogramStyle(); style.setShowErrorBars(false); style.setShowDataPoints(true); style.setShowLinesBetweenPoints(true); style.setShowHistogramBars(false); return style; } private static MemoryThread t = new MemoryThread(); private static class MemoryThread extends Observable implements Runnable { MemoryThread() { bins = new double[SECONDS]; for (int i=0; i=SECONDS) index = 0; } setChanged(); notifyObservers(hdr); thread.sleep(1000); } } catch (InterruptedException x) { } } synchronized double[] getSnapshot() { double[] result = new double[SECONDS]; int j=0; for (int i=index; i MAXSIZE) m_entries = 0; synchronized (this) { notifyObservers(hu); } } } catch (InterruptedException e) { return; } } private long m_delay = 10; } src/test/java/jas/hist/test/SliceTest.java0000644000175000017500000000626611325547133021236 0ustar giovannigiovannipackage jas.hist.test; import jas.hist.DataSource; import jas.hist.HasSlices; import jas.hist.JASHist; import jas.hist.JASHistData; import jas.hist.Rebinnable1DHistogramData; import jas.hist.ScatterPlotSource; import jas.hist.util.ScatterSliceAdapter; import jas.hist.util.ScatterTwoDAdapter; import jas.hist.util.SliceAdapter; import jas.hist.util.SliceEvent; import jas.hist.util.SliceListener; import jas.hist.util.TwoDSliceAdapter; import java.awt.BorderLayout; import java.awt.FlowLayout; import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.util.Hashtable; import javax.swing.ButtonGroup; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JRadioButton; public class SliceTest extends JPanel implements SliceListener { SliceTest() { super(new BorderLayout()); JPanel p = new JPanel(new GridLayout(1,2)); hist1 = new JASHist(); hist2 = new JASHist(); p.add(hist1); p.add(hist2); add(p,BorderLayout.CENTER); add(new ButtonPanel(),BorderLayout.SOUTH); } void setSliceData(Rebinnable1DHistogramData ds) { hist2.removeAllData(); if (ds != null) hist2.addData(ds).show(true); } void setData(DataSource ds) { hist1.removeAllData(); hist2.removeAllData(); hash.clear(); hist1.addData(ds).show(true); if (ds instanceof SliceAdapter) { ((SliceAdapter) ds).addSliceListener(this); } } public void sliceAdded(SliceEvent e) { HasSlices source = (HasSlices) e.getSource(); DataSource ds = source.getSlice(e.getIndex()); JASHistData data = hist2.addData(ds); data.show(true); hash.put(ds,data); } public void sliceRemoved(SliceEvent e) { HasSlices source = (HasSlices) e.getSource(); DataSource ds = source.getSlice(e.getIndex()); JASHistData data = (JASHistData) hash.get(ds); data.show(false); } public static void main(String[] argv) { JFrame f = new JFrame(); f.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) {System.exit(0);} }); f.setContentPane(new SliceTest()); f.pack(); f.show(); } class ButtonPanel extends JPanel implements ActionListener { ButtonPanel() { super(new FlowLayout()); addButton(b1 = new JRadioButton("Scatter Plot")); addButton(b2 = new JRadioButton("Rebinnable 2D Plot")); addButton(b3 = new JRadioButton("NonRebinnable 2D Plot")); } private void addButton(JRadioButton b) { add(b); g.add(b); b.addActionListener(this); } public void actionPerformed(ActionEvent e) { Object b = e.getSource(); if (b == b1) { setData(new ScatterSliceAdapter(source)); } else if (b == b2) { setData(new TwoDSliceAdapter(new ScatterTwoDAdapter(source))); } else if (b == b3) { setData(new TwoDSliceAdapter(new ScatterTwoDAdapter(source) { public boolean isRebinnable() { return false; } })); } } private ButtonGroup g = new ButtonGroup(); private JRadioButton b1, b2, b3; } private final ScatterPlotSource source = new TestScatterPlotSource(); private JASHist hist2; private JASHist hist1; private Hashtable hash = new Hashtable(); } src/test/java/jas/hist/test/TestJASHistReconnect.java0000644000175000017500000000532311325547133023276 0ustar giovannigiovanni/* * TestJASHistReconnect.java * * Created on May 3, 2005, 2:53 PM */ package jas.hist.test; import jas.hist.JASHist; import jas.hist.JASHistData; import javax.swing.JComponent; import javax.swing.JOptionPane; import javax.swing.RepaintManager; /** * * @author serbo */ public class TestJASHistReconnect extends MemoryDataSource { /** Creates a new instance of TestJASHistReconnect */ public TestJASHistReconnect() { super(); } public String getTitle() { return "Java Memory Usage TIMES TWO"; } public double[][] rebin(int nbin, double min, double max, boolean wantErrors, boolean hurry) { double[][] r = super.rebin(nbin, min, max, wantErrors, hurry); for (int i=0; i MAXSIZE) throw new IllegalArgumentException("Gauss2D: Size too big"); m_tupleX = new double[MAXSIZE]; m_tupleY = new double[MAXSIZE]; m_entries = entries; m_name = name; for (int j=0; j=0 && Xbin=0 && YbinXbins) Xbin = Xbins+1; if (Ybin < 0 ) Ybin = Ybins; if (Ybin >Ybins) Ybin = Ybins+1; hist[Xbin][Ybin] += 1; } } double[][][] result = new double[1][][]; result[0] = hist; return result; } public int getSize() { return m_entries; } public void setSize(int newSize) { if (newSize > MAXSIZE) throw new IllegalArgumentException("Gauss: Size too big"); m_entries = newSize; synchronized (this) { notifyObservers(new HistogramUpdate(HistogramUpdate.DATA_UPDATE,true)); } } public double getXData(int i) { return m_tupleX[i]; } public double getYData(int i) { return m_tupleY[i]; } public Statistics getStatistics() { return null; } double ymax = Math.random(); double m_tupleX[]; double m_tupleY[]; int m_entries; String m_name; protected final static int MAXSIZE = 10000; } src/test/java/jas/hist/test/XYTestData.java0000644000175000017500000000354711325547133021330 0ustar giovannigiovanni/* * XYTestData.java * * Created on November 21, 2001, 3:22 PM */ package jas.hist.test; import jas.hist.HasStyle; import jas.hist.JASHist; import jas.hist.JASHist1DHistogramStyle; import jas.hist.JASHistStyle; import jas.hist.XYDataSource; import javax.swing.JFrame; /** * * @author tonyj */ public class XYTestData implements XYDataSource, HasStyle { private double[] x; private double[] y; /** Creates new XYTestData */ public XYTestData() { int n = 100; x = new double[n]; y = new double[n]; for (int i=0; i 2) { addPoint(value,System.currentTimeMillis()/1000.); previousValue = value; } } } catch (InterruptedException e) { } } synchronized void addPoint(double value, double time) { if (maxPoint < values.length) { values[maxPoint] = value; times[maxPoint] = time; xmin = Math.min(xmin,value); xmax = Math.max(xmax,value); maxPoint++; } else { xmin = xmax = values[1]; for (int i=1; i 0) { try { Thread.sleep(delay); } catch (InterruptedException e) {} } if (limits) { while (n<10000) { if (x[n]>=xmin && x[n]=ymin && y[n] MAXSIZE) m_entries = 0; synchronized (this) { notifyObservers(hu); } } } catch (InterruptedException e) { return; } } private long m_delay = 10; } src/test/java/jas/hist/test/RightPanel.java0000644000175000017500000000355111325547133021366 0ustar giovannigiovannipackage jas.hist.test; import java.awt.BorderLayout; import java.awt.FlowLayout; import java.awt.GridLayout; import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing.JPanel; import javax.swing.JSlider; import javax.swing.event.ChangeListener; class RightPanel extends JPanel { RightPanel() { setLayout(new BorderLayout()); m_top = new TopRightPanel(); m_bottom = new BottomRightPanel(); add("North",m_top); add("Center",m_bottom); } public void addBinsChangeListener(ChangeListener l) { m_bottom.addBinsChangeListener(l); } public void addEventsChangeListener(ChangeListener l) { m_bottom.addEventsChangeListener(l); } public void addActionListener(ActionListener l) { m_top.addActionListener(l); } private TopRightPanel m_top; private BottomRightPanel m_bottom; } class TopRightPanel extends JPanel { TopRightPanel() { m_about = new JButton("About..."); m_prop = new JButton("Properties..."); m_print = new JButton("Print..."); m_xml = new JButton("Save As..."); setLayout(new GridLayout(4,1)); add(m_about); add(m_prop); add(m_print); add(m_xml); } void addActionListener(ActionListener l) { m_about.addActionListener(l); m_prop.addActionListener(l); m_print.addActionListener(l); m_xml.addActionListener(l); } private JButton m_about; private JButton m_prop; private JButton m_print; private JButton m_xml; } class BottomRightPanel extends JPanel { BottomRightPanel() { setLayout(new FlowLayout()); m_bins = new JSlider(JSlider.VERTICAL, 1, 200, 50); add(m_bins); m_events = new JSlider(JSlider.VERTICAL, 0, 10000, 1000); add(m_events); } public void addBinsChangeListener(ChangeListener l) { m_bins.addChangeListener(l); } public void addEventsChangeListener(ChangeListener l) { m_events.addChangeListener(l); } private JSlider m_bins; private JSlider m_events; } src/test/java/jas/hist/test/TestJASHist.java0000644000175000017500000001615611325547133021443 0ustar giovannigiovannipackage jas.hist.test; //****************************************************************************** // TestJASHist.java: Applet // //****************************************************************************** import jas.hist.JASHist; import jas.plot.PrintHelper; import java.awt.BorderLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JApplet; import javax.swing.JOptionPane; import javax.swing.JSlider; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; //============================================================================== // Main Class for applet TestJASHist // //============================================================================== public class TestJASHist extends JApplet implements ChangeListener, ActionListener { // STANDALONE APPLICATION SUPPORT: // m_fStandAlone will be set to true if applet is run standalone //-------------------------------------------------------------------------- boolean m_fStandAlone = false; // STANDALONE APPLICATION SUPPORT // The main() method acts as the applet's entry point when it is run // as a standalone application. It is ignored if the applet is run from // within an HTML page. //-------------------------------------------------------------------------- public static void main(String args[]) { // Create Toplevel Window to contain applet TestJASHist //---------------------------------------------------------------------- frame = new TestJASHistFrame("TestJASHist"); // Attempt to register functions/fitters // Will fail of Fitting.jar is not in the CLASSPATH try { Class c = TestJASHist.class.forName("jasext.hist.Register"); java.lang.reflect.Method m = c.getMethod("init",noArgc); Object reg = c.newInstance(); m.invoke(reg,noArgs); } catch (Throwable t) { System.err.println("Unable to register functions/fitters"); } // Attempt to register exporters // Will fail of freehep-*.jar is not in the CLASSPATH try { Class c = TestJASHist.class.forName("jas.export.Register"); java.lang.reflect.Method m = c.getMethod("init",noArgc); Object reg = c.newInstance(); m.invoke(reg,noArgs); } catch (Throwable t) { System.err.println("Unable to register exporters"); } // Must show Frame before we size it so insets() will return valid values //---------------------------------------------------------------------- //frame.show(); //frame.hide(); //frame.resize(frame.insets().left + frame.insets().right + 600, // frame.insets().top + frame.insets().bottom + 500); // The following code starts the applet running within the frame window. // It also calls GetParameters() to retrieve parameter values from the // command line, and sets m_fStandAlone to true to prevent init() from // trying to get them from the HTML page. //---------------------------------------------------------------------- TestJASHist applet_TestJASHist = new TestJASHist(); frame.setContentPane(applet_TestJASHist); applet_TestJASHist.m_fStandAlone = true; //applet_TestJASHist.init(); applet_TestJASHist.start(); frame.pack(); frame.show(); } // TestJASHist Class Constructor //-------------------------------------------------------------------------- public TestJASHist() { init(); } // APPLET INFO SUPPORT: // The getAppletInfo() method returns a string describing the applet's // author, copyright date, or miscellaneous information. //-------------------------------------------------------------------------- public String getAppletInfo() { return "Name: TestJASHist\n" + "Author: Tony Johnson\n" + "Application for testing features of JASHist"; } // The init() method is called by the AWT when an applet is first loaded or // reloaded. Override this method to perform whatever initialization your // applet needs, such as initializing data structures, loading images or // fonts, creating frame windows, setting the layout manager, or adding UI // components. //-------------------------------------------------------------------------- public void init() { // If you use a ResourceWizard-generated "control creator" class to // arrange controls in your applet, you may want to call its // CreateControls() method from within this method. Remove the following // call to resize() before adding the call to CreateControls(); // CreateControls() does its own resizing. //---------------------------------------------------------------------- resize(400, 300); m_hist = new JASHist(); RightPanel right = new RightPanel(); BottomPanel bottom = new BottomPanel(m_hist); getContentPane().setLayout(new BorderLayout()); getContentPane().add("East",right); getContentPane().add("South",bottom); getContentPane().add("Center",m_hist); right.addBinsChangeListener(this); right.addEventsChangeListener(bottom); right.addActionListener(this); } public void stateChanged(ChangeEvent ev) { m_hist.getXAxis().setBins(((JSlider) ev.getSource()).getValue()); } // Place additional applet clean up code here. destroy() is called when // when you applet is terminating and being unloaded. //------------------------------------------------------------------------- public void destroy() { // TODO: Place applet cleanup code here } // TestJASHist Paint Handler //-------------------------------------------------------------------------- //public void paint(Graphics g) //{ //} // The start() method is called when the page containing the applet // first appears on the screen. The AppletWizard's initial implementation // of this method starts execution of the applet's thread. //-------------------------------------------------------------------------- public void start() { // TODO: Place additional applet start code here } // The stop() method is called when the page containing the applet is // no longer on the screen. The AppletWizard's initial implementation of // this method stops execution of the applet's thread. //-------------------------------------------------------------------------- public void stop() { } // TODO: Place additional applet code here public void actionPerformed(ActionEvent evt) { String arg = evt.getActionCommand(); if (arg.equals("About...")) { JOptionPane.showMessageDialog(this,getAppletInfo() , "About...", JOptionPane.INFORMATION_MESSAGE); } else if (arg.equals("Properties...")) { m_hist.showProperties(); } else if (arg.equals("Print...")) { try { PrintHelper help = PrintHelper.instance(); help.printTarget(m_hist); } catch (Exception x) { System.err.println("Error printing: "+x); } } else if (arg.equals("Save As...")) { try { m_hist.saveAs(); } catch (Exception x) { System.err.println("Error saving: "+x); } } } private JASHist m_hist; private static TestJASHistFrame frame; public final static Class[] noArgc = {}; public final static Object[] noArgs = {}; } src/test/java/jas/hist/test/StringGauss.java0000644000175000017500000000111211325547133021571 0ustar giovannigiovannipackage jas.hist.test; import jas.hist.Rebinnable1DHistogramData; public class StringGauss extends Gauss { public StringGauss(String name, int entries,double max,double offX,double offY) { super(name,entries,labels.length,offX,offY); } public int getAxisType() { return Rebinnable1DHistogramData.STRING; } public boolean isRebinnable() { return false; } public String[] getAxisLabels() { return labels; } public int getBins() { return labels.length; } private static String[] labels = { "Ace","2","3","4","5","6","7","8","9","10","Jack","Queen","King"}; } src/test/java/jas/hist/test/ExportTest.java0000644000175000017500000000557011325547133021455 0ustar giovannigiovannipackage jas.hist.test; import jas.export.SaveAsPluginAdapter; import jas.hist.JASHist; import jas.hist.SaveAsPlugin; import jas.hist.XMLHistBuilder; import java.io.BufferedReader; import java.io.File; import java.io.FileOutputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.util.Properties; import java.util.StringTokenizer; import javax.swing.JFrame; import javax.swing.SwingUtilities; import org.freehep.util.export.ExportFileType; class ExportTest extends JFrame implements Runnable { private JASHist plot; public ExportTest() throws Exception { super("Export Test"); setDefaultCloseOperation(this.DO_NOTHING_ON_CLOSE); XMLHistBuilder xhb = new XMLHistBuilder(new BufferedReader(new InputStreamReader(getClass().getResourceAsStream("ExportTest.plotml"))),"ExportTest.plotml"); plot = xhb.getSoloPlot(); plot.setAllowUserInteraction(false); getContentPane().add(plot); } public static void main(String args[]) throws Exception { ExportTest xhv = new ExportTest(); xhv.pack(); xhv.show(); Thread.currentThread().sleep(500); SwingUtilities.invokeAndWait(xhv); System.exit(0); } public void run() { try { BufferedReader control = new BufferedReader(new InputStreamReader(getClass().getResourceAsStream("ExportTest.ini"))); for (;;) { String line = control.readLine(); if (line == null) break; StringTokenizer st = new StringTokenizer(line,",="); String title = st.nextToken().trim(); String file = st.nextToken().trim(); String klass = st.nextToken().trim(); Properties props = new Properties(); while (st.hasMoreTokens()) { String key = st.nextToken().trim(); if (!st.hasMoreTokens()) break; String value = st.nextToken().trim(); props.setProperty(key,value); } test(title,file,klass,props); } control.close(); } catch (Exception x) { x.printStackTrace(); } } private void test(String title,String file,String exported, Properties options) throws Exception { Class c = Class.forName(exported); Object exporter = c.newInstance(); if (exporter instanceof ExportFileType) exporter = new SaveAsPluginAdapter((ExportFileType) exporter); SaveAsPlugin saveAs = (SaveAsPlugin) exporter; saveAs.restoreOptions(options); File f = new File(file); OutputStream os = new FileOutputStream(f); System.out.println(title+" running..."); long start = System.currentTimeMillis(); saveAs.saveAs(plot,os,f,this); long stop = System.currentTimeMillis(); os.close(); System.out.println(title+" done, time="+(stop-start)+"ms size="+f.length()); } } src/test/java/jas/hist/test/TimeGauss.java0000644000175000017500000000103611325547133021226 0ustar giovannigiovannipackage jas.hist.test; import jas.hist.Rebinnable1DHistogramData; import java.util.Date; public class TimeGauss extends Gauss { public TimeGauss(String name, int entries,double max,double offX,double offY) { super(name,entries,max,offX,offY); } public int getAxisType() { return Rebinnable1DHistogramData.DATE; } public static TimeGauss create(String name,int entries,Date start,Date end) { double offX = start.getTime()/1000; double max = (end.getTime()/1000 - offX); return new TimeGauss(name,entries,max,offX,0); } } src/test/java/jas/hist/test/BottomPanel.java0000644000175000017500000001465711325547132021565 0ustar giovannigiovannipackage jas.hist.test; import jas.hist.JASHist; import jas.hist.JASHist1DHistogramStyle; import jas.hist.JASHistData; import jas.hist.util.TwoDSliceAdapter; import java.awt.GridLayout; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.util.Date; import javax.swing.JCheckBox; import javax.swing.JPanel; import javax.swing.JSlider; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; class BottomPanel extends JPanel implements ItemListener,ChangeListener { BottomPanel(JASHist hist) { m_gauss1.setStats(); m_hist = hist; m_time = TimeGauss.create("Time 1",1000,new Date("1 Jan 1997"),new Date("2 Jan 1997")); JASHist1DHistogramStyle style = new JASHist1DHistogramStyle(); style.setShowHistogramBars(false); style.setShowDataPoints(true); m_gauss2.setStyle(style); setLayout(new GridLayout(2,5)); add(box1 = new JCheckBox("Gaussian 1")); add(box2 = new JCheckBox("Gaussian 2")); add(box3 = new JCheckBox("Gaussian 3")); add(box4 = new JCheckBox("String 1")); add(box5 = new JCheckBox("Time 1")); add(box6 = new JCheckBox("2D Gaussian 1")); add(box7 = new JCheckBox("2D Gaussian 2")); add(box8 = new JCheckBox("ScatterPlot 1")); add(box9 = new JCheckBox("ScatterPlot 2")); add(box10 = new JCheckBox("TimeScatter")); box1.addItemListener(this); box2.addItemListener(this); box3.addItemListener(this); box4.addItemListener(this); box5.addItemListener(this); box6.addItemListener(this); box7.addItemListener(this); box8.addItemListener(this); box9.addItemListener(this); box10.addItemListener(this); //JASHist.registerFunction(StraightLineFunction.class,"Straight Line"); //JASHist.registerFunction(GaussianFunction.class,"Gaussian"); //JASHist.registerFunction(new SplineFactory()); //JASHist.registerFunction(new SumFunctionFactory()); //JASHist.registerFitter(LeastSquaresFit.class,"Least Squares Fitter"); } public void stateChanged(ChangeEvent ev) { int events = ((JSlider) ev.getSource()).getValue(); m_gauss1.setSize(events); m_gauss2.setSize(events); //m_gauss3.setSize(events); m_string.setSize(events); m_time.setSize(events); m_gauss6.setSize(events); m_gauss7.setSize(events); } public void itemStateChanged(ItemEvent evt) { if (recursive) return; recursive = true; Object source = evt.getSource(); if (source == box5) { if (m_mode != 5) { m_hist.removeAllData(); data5 = m_hist.addData(m_time); m_mode = 5; box1.setSelected(false); box2.setSelected(false); box3.setSelected(false); box4.setSelected(false); box6.setSelected(false); box7.setSelected(false); box8.setSelected(false); box9.setSelected(false); box10.setSelected(false); } data5.show(box5.isSelected()); } else if (source == box4) { if (m_mode != 4) { m_hist.removeAllData(); data4 = m_hist.addData(m_string); m_mode = 4; box1.setSelected(false); box2.setSelected(false); box3.setSelected(false); box5.setSelected(false); box6.setSelected(false); box7.setSelected(false); box8.setSelected(false); box9.setSelected(false); box10.setSelected(false); } data4.show(box4.isSelected()); } else if (source == box6 || source == box7) { if (m_mode != 6) { m_hist.removeAllData(); data6 = m_hist.addData(new TwoDSliceAdapter(m_gauss6)); data7 = m_hist.addData(m_gauss7); m_mode = 6; box1.setSelected(false); box2.setSelected(false); box3.setSelected(false); box4.setSelected(false); box5.setSelected(false); box8.setSelected(false); box9.setSelected(false); box10.setSelected(false); } data6.show(box6.isSelected()); data7.show(box7.isSelected()); } else if (source == box8 || source == box9) { if (m_mode != 8) { m_hist.removeAllData(); data8 = m_hist.addData(m_scat8); data9 = m_hist.addData(m_scat9); m_mode = 8; box1.setSelected(false); box2.setSelected(false); box3.setSelected(false); box4.setSelected(false); box5.setSelected(false); box6.setSelected(false); box7.setSelected(false); box10.setSelected(false); } data8.show(box8.isSelected()); data9.show(box9.isSelected()); } else if (source == box10) { if (m_mode != 10) { m_hist.removeAllData(); data10 = m_hist.addData(m_scat10); m_mode = 10; box1.setSelected(false); box2.setSelected(false); box3.setSelected(false); box4.setSelected(false); box5.setSelected(false); box6.setSelected(false); box7.setSelected(false); box8.setSelected(false); box9.setSelected(false); } data10.show(box10.isSelected()); } else { if (m_mode != 1) { m_hist.removeAllData(); data1 = m_hist.addData(m_gauss1); data2 = m_hist.addData(m_gauss2); data3 = m_hist.addData(m_gauss3); m_mode = 1; box4.setSelected(false); box5.setSelected(false); box6.setSelected(false); box7.setSelected(false); box8.setSelected(false); box9.setSelected(false); box10.setSelected(false); } data1.show(box1.isSelected()); data2.show(box2.isSelected()); data3.show(box3.isSelected()); } recursive = false; } private JCheckBox box1; private JCheckBox box2; private JCheckBox box3; private JCheckBox box4; private JCheckBox box5; private JCheckBox box6; private JCheckBox box7; private JCheckBox box8; private JCheckBox box9; private JCheckBox box10; private JASHistData data1; private JASHistData data2; private JASHistData data3; private JASHistData data4; private JASHistData data5; private JASHistData data6; private JASHistData data7; private JASHistData data8; private JASHistData data9; private JASHistData data10; private Gauss m_gauss1 = new Gauss("Gaussian 1",1000,1,0,0); private Gauss m_gauss2 = new Gauss("Gaussian 2",1000,1,0.5,-100); private Gauss m_gauss3 = new LiveGauss("Gaussian 3",0,1,1,0); private Gauss m_string = new StringGauss("String 1",1000,1,0,0); private Gauss m_time; private Gauss2D m_gauss6 = new Gauss2D("Gaussian 6",1000); private Gauss2D m_gauss7 = new Gauss2D("Gaussian 7",1000); private TestScatterPlotSource m_scat8 = new TestScatterPlotSource(); private TestScatterPlotSource m_scat9 = new TestScatterPlotSource(10); //private TestScatterPlotSource m_scat10 = new TimeScatterPlotSource(); private TestCustomOverlay m_scat10 = new TestCustomOverlay(); private JASHist m_hist; private int m_mode = 0; private boolean recursive = false; } src/test/java/jas/hist/test/Gauss.java0000644000175000017500000001011411325547133020404 0ustar giovannigiovannipackage jas.hist.test; import jas.hist.HasStatistics; import jas.hist.HasStyle; import jas.hist.HistogramUpdate; import jas.hist.JASHist1DHistogramStyle; import jas.hist.JASHistStyle; import jas.hist.Rebinnable1DHistogramData; import jas.hist.Statistics; import jas.util.xml.HasXMLRepresentation; import jas.util.xml.XMLWriter; import java.util.Observable; public class Gauss extends Observable implements Rebinnable1DHistogramData, HasStyle, HasStatistics, HasXMLRepresentation { public Gauss() { this("Gaussian",1000,1,0,0); } public void writeAsXML(XMLWriter pw) { pw.println(""); pw.println(""); pw.println(""); pw.println(""); pw.println(""); pw.println(""); pw.println(""); } public Gauss(String name, int entries,double max,double offX,double offY) { if (entries > MAXSIZE) throw new IllegalArgumentException("Gauss: Size too big"); m_tuple = new double[MAXSIZE]; m_entries = entries; m_min = offX; m_max = offX + max; m_offset = offY; m_name = name; for (int j=0; j MAXSIZE) throw new IllegalArgumentException("Gauss: Size too big"); m_entries = newSize; synchronized (this) { notifyObservers(new HistogramUpdate(HistogramUpdate.DATA_UPDATE,true)); } } public double getData(int i) { return m_tuple[i]; } public Statistics getStatistics() { return stats; } double m_tuple[]; int m_entries; double m_max; double m_min; double m_offset; String m_name; protected final static int MAXSIZE = 10000; private JASHist1DHistogramStyle style; private Statistics stats = new GaussStatistics(); private Statistics paulstats = new PaulStatistics(); public void setStats() { stats = paulstats; } private class GaussStatistics implements Statistics { public String[] getStatisticNames() { return statNames; } public double getStatistic(String name) { if (name == statNames[0]) return m_entries; if (name == statNames[1]) return (m_max + m_min)/2; if (name == statNames[2]) return (m_max - m_min); return 0; } } public class PaulStatistics implements Statistics { public String[] getStatisticNames() { return statNames2; } public double getStatistic(String name) { if (name == statNames2[0]) return m_entries; if (name == statNames2[1]) return (m_max + m_min)/2; if (name == statNames2[2]) return (m_max - m_min); if (name == statNames2[3]) return (m_entries*10); return 0; } } private static final String[] statNames = {"Entries","Mean","RMS"}; private static final String[] statNames2 = {"Entries","Mean","RMS", "10Entries"}; } src/test/java/jas/hist/test/XMLHistViewer.java0000644000175000017500000000624511325547133022006 0ustar giovannigiovannipackage jas.hist.test; import jas.hist.JASHist; import jas.hist.XMLHistBuilder; import java.awt.BorderLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.io.BufferedReader; import java.io.FileReader; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.SwingUtilities; class XMLHistViewer extends JFrame { public XMLHistViewer(String str, String fileName) { super(str); getContentPane().add(new JLabel("Reading "+fileName+"...")); addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) {System.exit(0);} }); } void load(String fileName) { try { xhb = new XMLHistBuilder(new BufferedReader(new FileReader(fileName)),fileName); final JASHist hist = xhb.getSoloPlot(); if (hist == null) throw new RuntimeException("No Histogram found"); final JPanel p = new JPanel(new BorderLayout()); p.add("Center",hist); JButton export = new JButton("Save As..."); export.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { hist.saveAs(); } }); p.add("South",export); SwingUtilities.invokeLater(new Runnable() { public void run() { setContentPane(p); pack(); } }); } catch (final Throwable t) { SwingUtilities.invokeLater(new Runnable() { public void run() { dispose(); JOptionPane.showMessageDialog(null, t.getMessage(), "Error", JOptionPane.ERROR_MESSAGE); System.exit(0); } }); } } public static void main(String args[]) { XMLHistViewer xhv = new XMLHistViewer("XMLHistViewer", args[0]); xhv.pack(); xhv.show(); xhv.load(args[0]); // Attempt to register functions/fitters // Will fail of Fitting.jar is not in the CLASSPATH try { Class c = XMLHistViewer.class.forName("jasext.hist.Register"); java.lang.reflect.Method m = c.getMethod("init",noArgc); Object reg = c.newInstance(); m.invoke(reg,noArgs); } catch (Throwable t) { System.err.println("Unable to register functions/fitters"); t.printStackTrace(); } // Attempt to register exporters // Will fail of freehep-*.jar is not in the CLASSPATH try { Class c = TestJASHist.class.forName("jas.export.Register"); java.lang.reflect.Method m = c.getMethod("init",noArgc); Object reg = c.newInstance(); m.invoke(reg,noArgs); } catch (Throwable t) { System.err.println("Unable to register exporters"); } } public final static Class[] noArgc = {}; public final static Object[] noArgs = {}; private XMLHistBuilder xhb; } src/test/java/jas/export/0000755000175000017500000000000011325547132016054 5ustar giovannigiovannisrc/test/java/jas/export/SaveAsPluginAdapter.java0000644000175000017500000000257611325547132022573 0ustar giovannigiovannipackage jas.export; import jas.hist.SaveAsPlugin; import java.awt.Component; import java.io.File; import java.io.IOException; import java.io.OutputStream; import java.util.Properties; import javax.swing.JPanel; import javax.swing.filechooser.FileFilter; import org.freehep.util.export.ExportFileType; /** * * @author tonyj * @version $Id: SaveAsPluginAdapter.java 11553 2007-06-05 22:06:23Z duns $ */ public class SaveAsPluginAdapter implements SaveAsPlugin { private ExportFileType eft; /** Creates a new instance of SaveAsPluginAdapter */ public SaveAsPluginAdapter(ExportFileType eft) { this.eft = eft; } public File adjustFilename(File file) { return eft.adjustFilename(file, null); } public FileFilter getFileFilter() { return eft.getFileFilter(); } public JPanel getOptionsPanel() { return eft.createOptionPanel(null); } public boolean hasOptions() { return eft.hasOptionPanel(); } public void saveAs(Component c, OutputStream out, File file, Component dialogParent) throws IOException { eft.exportToFile(file, c, dialogParent, null, ""); } public boolean supportsClass(Object o) { return true; } public void saveOptions(Properties props) { // eft.saveOptions(props); } public void restoreOptions(Properties props) { // eft.restoreOptions(props); } } src/test/resources/0000755000175000017500000000000011325547133015050 5ustar giovannigiovannisrc/test/resources/jas/0000755000175000017500000000000011325547133015625 5ustar giovannigiovannisrc/test/resources/jas/hist/0000755000175000017500000000000011325547133016574 5ustar giovannigiovannisrc/test/resources/jas/hist/test/0000755000175000017500000000000011325547133017553 5ustar giovannigiovannisrc/test/resources/jas/hist/test/ExportTest.ini0000644000175000017500000000246211325547133022401 0ustar giovannigiovanniEPS Test, ExportTest.eps, org.freehep.graphics2d.exportchooser.EPS2DExportFileType EPS Test type1, ExportTest-t1.eps, org.freehep.graphics2d.exportchooser.EPS2DExportFileType, org.freehep.graphics2d.exportchooser.EPS_PSExportFileType.EmbedFonts=Embed unknown as Type1 EPS Test type3, ExportTest-t3.eps, org.freehep.graphics2d.exportchooser.EPS2DExportFileType, org.freehep.graphics2d.exportchooser.EPS_PSExportFileType.EmbedFonts=Embed unknown as Type3 PDF Test, ExportTest.pdf, org.freehep.graphics2d.exportchooser.PDF2DExportFileType PDF Test type1, ExportTest-t1.pdf, org.freehep.graphics2d.exportchooser.PDF2DExportFileType, org.freehep.graphics2d.exportchooser.PDF2DExportFileType.EmbedFonts=Embed unknown as Type1 PDF Test type3, ExportTest-t3.pdf, org.freehep.graphics2d.exportchooser.PDF2DExportFileType, org.freehep.graphics2d.exportchooser.PDF2DExportFileType.EmbedFonts=Embed unknown as Type3 SVG Test, ExportTest.svg, org.freehep.graphics2d.exportchooser.SVG2DExportFileType EMF Test, ExportTest.emf, org.freehep.graphics2d.exportchooser.EMF2DExportFileType PNG Test, ExportTest.png, org.freehep.graphics2d.exportchooser.PNGExportFileType PPM Test, ExportTest.ppm, org.freehep.graphics2d.exportchooser.PPMExportFileType GIF Test, ExportTest.gif, jas.hist.SaveAsGIF PLOTML Test, ExportTest.plotml, jas.hist.SaveAsPlotMLsrc/main/0000755000175000017500000000000011325547132013002 5ustar giovannigiovannisrc/main/java/0000755000175000017500000000000011325547132013723 5ustar giovannigiovannisrc/main/java/jas/0000755000175000017500000000000011325547132014500 5ustar giovannigiovannisrc/main/java/jas/hist/0000755000175000017500000000000011326056641015450 5ustar giovannigiovannisrc/main/java/jas/hist/AbstractDataManager.java0000644000175000017500000001307011325547132022143 0ustar giovannigiovannipackage jas.hist; import jas.plot.DataArea; import jas.plot.DataAreaLayout; import jas.plot.Legend; import jas.plot.LegendEntry; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.IOException; import java.io.ObjectInputStream; import java.util.Enumeration; import java.util.Vector; import javax.swing.JMenu; import javax.swing.SwingUtilities; import javax.swing.Timer; abstract class AbstractDataManager extends DataManager implements Runnable { AbstractDataManager(JASHist plot, DataArea da, Legend l, StatisticsBlock stats) { super(plot,da); this.legend = l; this.stats = stats; nVisible = 0; nVisibleLegend = 0; xm.setFixed(false); xm.setRangeAutomatic(true); ym[0].setFixed(false); ym[0].setRangeAutomatic(true); timer = new Timer(1000,new ActionListener() { public void actionPerformed(ActionEvent e) { doUpdate(); } }); timer.setRepeats(false); } void init() { computeXAxisRange(); XAxisUpdated(); computeYAxisRange(); // Add a mouse listener to the Axes //new AxisListener(xAxis); //new AxisListener(yAxis); isInit = true; } final void invalidate() { if (isInit) SwingUtilities.invokeLater(this); } final public void run() { doUpdate(); } boolean isRealized() { return isInit; } void setRealized(boolean b) { isInit = b; } void requestShow(JASHistData data) { da.add(data.getOverlay()); nVisible++; if (legend != null) { LegendEntry le = data.getLegendEntry(); if (le != null) { legend.add(le); nVisibleLegend++; showLegend(); } } if (stats != null) { stats.add(data); } if (isInit) { xm.setAttentionNeeded(); computeXAxisRange(); XAxisUpdated(); computeYAxisRange(); da.validate(); da.repaint(); } } void requestHide(JASHistData data) { da.remove(data.getOverlay()); nVisible--; if (legend != null) { LegendEntry le = data.getLegendEntry(); if (le != null) { legend.remove(le); nVisibleLegend--; showLegend(); } } if (stats != null) { stats.remove(data); } if (isInit) { xm.setAttentionNeeded(); computeXAxisRange(); XAxisUpdated(); computeYAxisRange(); da.validate(); da.repaint(); } } protected void showLegend() { int showLegend = plot.getShowLegend(); boolean show = (showLegend == JASHist.LEGEND_ALWAYS) || ( showLegend == JASHist.LEGEND_AUTOMATIC && nVisibleLegend>1 ); legend.setVisible(show); legend.revalidate(); } private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { in.defaultReadObject(); timer = new Timer(1000,new ActionListener() { public void actionPerformed(ActionEvent e) { doUpdate(); } }); timer.setRepeats(false); da.add(xm, DataAreaLayout.X_AXIS); da.add(ym[0], DataAreaLayout.Y_AXIS_LEFT); da.add(ym[1], DataAreaLayout.Y_AXIS_RIGHT); } transient protected Timer timer; transient protected boolean isInit = false; protected Legend legend; protected StatisticsBlock stats; transient protected int nVisible; transient protected int nVisibleLegend; protected transient Vector data = new Vector(); abstract void doUpdate(); void remove(JASHistData d) { d.show(false); d.deleteNormalizationObserver(); data.removeElement(d); } int numberOfDataSources() { return data.size(); } void destroy() // detaches data, but doesn't set up the plot for further use { final Enumeration e = data.elements(); while (e.hasMoreElements()) { JASHistData d = (JASHistData) e.nextElement(); d.show(false); d.deleteNormalizationObserver(); } data.removeAllElements(); destroyYAxis(1); // In case second Y Axis was created stats.clear(); } Enumeration getDataSources() { return data.elements(); } JMenu addPerDataSourceMenu(String name, DataSourceMenuFactory f) { int n = numberOfDataSources(); if (n == 0) { JMenu result = new JMenu(name); result.setEnabled(false); return result; } if (n == 1) { JASHistData ds = (JASHistData) getDataSources().nextElement(); return f.createMenu(name,ds); } else { JMenu result = new JMenu(name); Enumeration e = getDataSources(); for (int i=0; e.hasMoreElements(); i++) { JASHistData ds = (JASHistData) e.nextElement(); JMenu sub = f.createMenu(ds.getTitle(),ds); sub.setMnemonic('0' + (char) i); result.add(sub); } return result; } } } src/main/java/jas/hist/VectorGraphicsTransferable.java0000644000175000017500000000536611325547132023600 0ustar giovannigiovanni/* * VectorGraphicsTransferable.java * * Created on March 29, 2002, 2:53 PM */ package jas.hist; import java.awt.Component; import java.awt.Graphics; import java.awt.Image; import java.awt.datatransfer.Clipboard; import java.awt.datatransfer.ClipboardOwner; import java.awt.datatransfer.DataFlavor; import java.awt.datatransfer.Transferable; import java.awt.datatransfer.UnsupportedFlavorException; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.HashMap; import java.util.Map; import javax.swing.RepaintManager; /** * * @author tonyj */ public class VectorGraphicsTransferable implements ClipboardOwner, Transferable { private Component component; private static DataFlavor imageFlavor = new DataFlavor("image/x-java-image; class=java.awt.Image", "Image"); private static Map types = new HashMap(); /** Creates a new instance of VectorGraphicsTransferable */ public VectorGraphicsTransferable(Component c) { this.component = c; } public Object getTransferData(DataFlavor dataFlavor) throws UnsupportedFlavorException, IOException { if (dataFlavor.match(imageFlavor)) { Image img = component.createImage(component.getWidth(),component.getHeight()); Graphics g = img.getGraphics(); // TODO: It would be better to use the PrintHelper to do this?? // TODO: Make sure we get high quality printing for GIF. RepaintManager pm = RepaintManager.currentManager(component); boolean save = pm.isDoubleBufferingEnabled(); pm.setDoubleBufferingEnabled(false); component.print(g); g.dispose(); pm.setDoubleBufferingEnabled(save); return img; } else { SaveAsPlugin type = (SaveAsPlugin) types.get(dataFlavor); if (type != null) { ByteArrayOutputStream out = new ByteArrayOutputStream(); type.saveAs(component,out,null,component); out.close(); return new ByteArrayInputStream(out.toByteArray()); } } throw new UnsupportedFlavorException(dataFlavor); } public DataFlavor[] getTransferDataFlavors() { DataFlavor[] result = new DataFlavor[types.size() + 1]; types.keySet().toArray(result); result[types.size()] = imageFlavor; return result; } public boolean isDataFlavorSupported(DataFlavor dataFlavor) { if (dataFlavor.match(imageFlavor)) return true; if (types.containsKey(dataFlavor)) return true; return false; } public void lostOwnership(Clipboard clipboard, Transferable transferable) { } public static void register(DataFlavor flavor, SaveAsPlugin type) { types.put(flavor,type); } }src/main/java/jas/hist/JASHist1DHistogramStyle.java0000644000175000017500000002145711325547132022654 0ustar giovannigiovannipackage jas.hist; import jas.plot.PlotGraphics; import java.awt.Color; import java.io.IOException; import java.io.Serializable; /** * Used to control the display style of 1D Histograms. */ public class JASHist1DHistogramStyle extends JASHistStyle implements Serializable { final public static int SYMBOL_DOT = PlotGraphics.SYMBOL_DOT; final public static int SYMBOL_BOX = PlotGraphics.SYMBOL_BOX; final public static int SYMBOL_TRIANGLE = PlotGraphics.SYMBOL_TRIANGLE; final public static int SYMBOL_DIAMOND = PlotGraphics.SYMBOL_DIAMOND; final public static int SYMBOL_STAR = PlotGraphics.SYMBOL_STAR; final public static int SYMBOL_VERT_LINE = PlotGraphics.SYMBOL_VERT_LINE; final public static int SYMBOL_HORIZ_LINE = PlotGraphics.SYMBOL_HORIZ_LINE; final public static int SYMBOL_CROSS = PlotGraphics.SYMBOL_CROSS; final public static int SYMBOL_CIRCLE = PlotGraphics.SYMBOL_CIRCLE; final public static int SYMBOL_SQUARE = PlotGraphics.SYMBOL_SQUARE; static final Color[] lineColors = { Color.blue, Color.red, Color.magenta, Color.green, Color.orange, Color.cyan, }; static final int[] pointStyles = { SYMBOL_DOT, SYMBOL_BOX, SYMBOL_TRIANGLE, SYMBOL_DIAMOND, SYMBOL_STAR, SYMBOL_CROSS, SYMBOL_CIRCLE, SYMBOL_SQUARE }; static int n = 0; static int np = 0; static final long serialVersionUID = 7779996364086801435L; public JASHist1DHistogramStyle() { initTransientData(); m_showDataPoints = false; m_showErrorBars = true; m_histogramFill = true; m_showHistogramBars = true; m_showLinesBetweenPoints = false; m_histogramBarLineWidth = 1.0f; m_linesBetweenPointsWidth = 1.0f; m_errorBarWidth = 1.0f; m_dataPointSize = 6; m_dataPointStyle = pointStyles[np]; m_histogramBarColor = lineColors[n]; m_histogramBarLineColor = Color.BLACK; m_errorBarColor = lineColors[n]; m_errorBarColorIsDefault = true; m_dataPointColor = lineColors[n]; m_lineColor = lineColors[n]; n++; np++; if (n == lineColors.length) n = 0; if (np == pointStyles.length) np = 0; } public boolean getShowHistogramBars() { return m_showHistogramBars; } public void setShowHistogramBars(boolean bNewValue) { m_showHistogramBars = bNewValue; // if (!m_showHistogramBars) m_histogramFill = false; changeNotify(); } public boolean getShowErrorBars() { return m_showErrorBars; } public void setShowErrorBars(boolean bNewValue) { m_showErrorBars = bNewValue; changeNotify(); } public boolean getShowDataPoints() { return m_showDataPoints; } /** * Controls whether markers are drawn at each data point. * @param bNewValue true to show markers * @see #setDataPointStyle(int) * @see #setDataPointSize(int) */ public void setShowDataPoints(boolean bNewValue) { m_showDataPoints = bNewValue; changeNotify(); } public boolean getShowLinesBetweenPoints() { return m_showLinesBetweenPoints; } /** * Controls whether (straight) lines are drawn between data points * @param bNewValue true to show lines */ public void setShowLinesBetweenPoints(boolean bNewValue) { m_showLinesBetweenPoints = bNewValue; changeNotify(); } public int getLinesBetweenPointsStyle() { return m_linesBetweenPointsStyle; } public void setLinesBetweenPointsStyle(int style) { m_linesBetweenPointsStyle = style; changeNotify(); } public float getLinesBetweenPointsWidth() { return m_linesBetweenPointsWidth != 0 ? m_linesBetweenPointsWidth : (float)0.0001; } public void setLinesBetweenPointsWidth(float width) { this.m_linesBetweenPointsWidth = width; changeNotify(); } public int getDataPointStyle() { return m_dataPointStyle; } /** * Set the style (shape) of the data points. * The legal values to pass in are: *
    *
  • SYMBOL_DOT *
  • SYMBOL_BOX *
  • SYMBOL_TRIANGLE *
  • SYMBOL_DIAMOND *
  • SYMBOL_STAR *
  • SYMBOL_VERT_LINE *
  • SYMBOL_HORIZ_LINE *
  • SYMBOL_CROSS *
  • SYMBOL_CIRCLE *
  • SYMBOL_SQUARE *
* @param newValue The data point style to use */ public void setDataPointStyle(int newValue) { m_dataPointStyle = newValue; changeNotify(); } public int getDataPointSize() { return m_dataPointSize; } /** * Set the size of data points * @param newValue The new size for data points (in pixels) */ public void setDataPointSize(int newValue) { m_dataPointSize = newValue; changeNotify(); } public Color getDataPointColor() { return m_dataPointColor; } public void setDataPointColor(Color nNewValue) { m_dataPointColor = nNewValue; changeNotify(); } public Color getHistogramBarColor() { return m_histogramBarColor; } public void setHistogramBarColor(Color nNewValue) { m_histogramBarColor = nNewValue; changeNotify(); } public Color getHistogramBarLineColor() { //This is to keep backward compatibility with the JAS2 code that does //not make use of this method, i.e. the color of the histogram bars outline //is always blak when the bar is filled and the fill color when the bars //are not filled. if ( ( ! histogramBarLineColorChanged ) && ( ! getHistogramFill() ) ) return getHistogramBarColor(); return m_histogramBarLineColor; } public void setHistogramBarLineColor(Color nNewValue) { histogramBarLineColorChanged = true; m_histogramBarLineColor = nNewValue; changeNotify(); } public int getHistogramBarLineStyle() { return m_histogramBarLineStyle; } public void setHistogramBarLineStyle(int style) { m_histogramBarLineStyle = style; changeNotify(); } public float getHistogramBarLineWidth() { return m_histogramBarLineWidth != 0 ? m_histogramBarLineWidth : (float)0.0001; } public void setHistogramBarLineWidth(float width) { m_histogramBarLineWidth = width; changeNotify(); } public Color getLineColor() { return m_lineColor; } public void setLineColor(Color nNewValue) { m_lineColor = nNewValue; changeNotify(); } public Color getErrorBarColor() { if (m_histogramFill && m_errorBarColorIsDefault) return Color.black; return m_errorBarColor; } public void setErrorBarColor(Color nNewValue) { m_errorBarColor = nNewValue; m_errorBarColorIsDefault = false; changeNotify(); } public int getErrorBarStyle() { return m_errorBarStyle; } public void setErrorBarStyle(int style) { m_errorBarStyle = style; changeNotify(); } // Error Bar Decoration: // less than 0 - automatic // 0 - no decoration // greater than 0 - fraction of the bin width public float getErrorBarDecoration() { return m_errorBarDecoration; } public void setErrorBarDecoration(float f) { m_errorBarDecoration = f; changeNotify(); } public float getErrorBarWidth() { return m_errorBarWidth != 0 ? m_errorBarWidth : (float)0.0001; } public void setErrorBarWidth(float width) { m_errorBarWidth = width; changeNotify(); } public boolean getHistogramFill() { return m_histogramFill; } public void setHistogramFill(boolean bNewValue) { m_histogramFill = bNewValue; changeNotify(); } protected void changeNotify() { super.changeNotify(); } private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException { in.defaultReadObject(); initTransientData(); } private void initTransientData() { } private boolean m_histogramFill; private Color m_histogramBarColor; private Color m_histogramBarLineColor; private boolean histogramBarLineColorChanged = false; private Color m_errorBarColor; private Color m_lineColor; private Color m_dataPointColor; private int m_style; private int m_dataPointStyle; private int m_dataPointSize; private boolean m_showHistogramBars; private boolean m_showErrorBars; private boolean m_showDataPoints; private boolean m_showLinesBetweenPoints; private float m_linesBetweenPointsWidth; private int m_linesBetweenPointsStyle; private float m_errorBarWidth; private int m_errorBarStyle; private float m_errorBarDecoration = -1.0f; private float m_histogramBarLineWidth; private int m_histogramBarLineStyle; private boolean m_errorBarColorIsDefault; } src/main/java/jas/hist/HasSlices.java0000644000175000017500000000215211325547132020170 0ustar giovannigiovannipackage jas.hist; public interface HasSlices { /** * Number of slices currently attached to plot */ int getNSlices(); /** * Get the parameters of a slice. The SliceParameters can * subsequently be changed to update the slice. * @param n The index of the slice * @return The Slice parameters of the slice with the specified index */ SliceParameters getSliceParameters(int n); /** * Get the data corresponding to the slice. The data will be observable * and will notify its observers if the slice changes, or the data from * which the slice is derived changes * @param n The index of the slice * @return The data resulting from the slice */ Rebinnable1DHistogramData getSlice(int n); /* * True of the data source allows slices to be added and removed */ boolean canAddRemoveSlices(); /** * Create a new slice with the specified initial parameters * @return the index of the slice that was added */ int addSlice(double x, double y, double width, double height, double phi); /** * Remove a slice from the source * @param n The index of the slice */ void removeSlice(int n); } src/main/java/jas/hist/JASHist1DHistogramData.java0000644000175000017500000005767411325547132022437 0ustar giovannigiovannipackage jas.hist; import jas.plot.Overlay; import jas.util.ColorConverter; import java.io.Serializable; import java.util.Observable; class JASHist1DHistogramData extends JASHistData { JASHist1DHistogramData(DataManager dm,DataSource ds) { super(dm); dataSource = ds; initTransientData(); JASHistStyle s = null; if (ds instanceof HasStyle) s = ((HasStyle) ds).getStyle(); if (s == null) s = new JASHist1DHistogramStyle(); setStyle(s); String property = System.getProperty("hurry", "false"); hurry = property != null && property.equalsIgnoreCase("true"); } private void initTransientData() { yLimitsValid = false; isBinned = false; } public void setStyle(JASHistStyle style) { if (!(style instanceof JASHist1DHistogramStyle)) throw new IllegalArgumentException("Style is not subclass of JASHist1DHistogramStyle"); if (this.style != null) this.style.deleteObserver(this); this.style = (JASHist1DHistogramStyle) style; this.style.addObserver(this); } public String getTitle() { return dataSource.getTitle(); } String[] getAxisLabels() { return dataSource instanceof Rebinnable1DHistogramData ? ((Rebinnable1DHistogramData) dataSource).getAxisLabels() : null; } Overlay createOverlay() { return new OneDOverlay(this); } void writeAsXML(XMLPrintWriter pw, boolean snapshot) { pw.setAttribute("axis","y"+getYAxis()); pw.openTag("data1d"); String theAxisType = pw.convertAxisTypeToString(getAxisType()); if (snapshot) { if (dataSource instanceof Rebinnable1DHistogramData) { pw.setAttribute("title",getTitle()); pw.openTag("bins1d"); for (int i=0; i < data.length; i++) { pw.print(data[i]); pw.print(","); pw.print(plusError[i]); pw.print(","); pw.print(minusError[i]); pw.println(); } pw.closeTag(); pw.printBinnedDataAxisAttributes( "x", "" + xLow, "" + xHigh, "" + xBins, theAxisType); if (theAxisType.equals("string")) { pw.setAttribute("type","x0"); pw.openTag("axisLabels"); String[] labels = getAxisLabels(); for (int i=0; i < labels.length; i++) { pw.setAttribute("value",labels[i]); pw.printTag("axisLabel"); } pw.closeTag(); } } else { pw.setAttribute("title",getTitle()); pw.openTag("points"); for (int i=0; i < data.length; i++) { pw.print(dataX[i]); pw.print(','); pw.print(data[i]); pw.print(','); pw.print(plusError[i]); pw.print(','); pw.print(minusError[i]); pw.println(); } pw.closeTag(); pw.setAttribute("axis","x"); pw.setAttribute("type",theAxisType); pw.printTag("pointDataAxisAttributes"); } if (dataSource instanceof HasStatistics) { Statistics stats = ((HasStatistics) dataSource).getStatistics(); if (stats != null) { pw.openTag("statistics"); String[] names = stats.getStatisticNames(); for (int i=0; i0); } private JButton browse = new JButton("Browse..."); private JButton advanced = new JButton("Options..."); private JTextField file = new JTextField(40); private JComboBox type; private Component component; private class SaveAsRenderer extends DefaultListCellRenderer { public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { super.getListCellRendererComponent(list,value,index,isSelected,cellHasFocus); if (value instanceof SaveAsPlugin) { this.setText(((SaveAsPlugin) value).getFileFilter().getDescription()); } return this; } } } src/main/java/jas/hist/ScatterPlotSource.java0000644000175000017500000000166411325547132021746 0ustar giovannigiovannipackage jas.hist; /** * Interface to be implemented by DataSources which can provide ScatterPlot * data (but not 2D histogram data) * @see Rebinnable2DHistogramData * @see HasScatterPlotData */ public interface ScatterPlotSource extends DataSource { public double getXMin(); public double getXMax(); public double getYMin(); public double getYMax(); /** * Currently we only support DATE and DOUBLE types */ public int getXAxisType(); /** * Currently we only support DOUBLE */ public int getYAxisType(); /** * Starts the enumeration of points from the beginning, and the enumeration * will include only points in the given range. */ public ScatterEnumeration startEnumeration(double xMin, double xMax, double yMin, double yMax); /** * Starts the enumeration of points from the beginning, and the enumeration * will include all points stored in the partition. */ public ScatterEnumeration startEnumeration(); }src/main/java/jas/hist/SpecialComponent.java0000644000175000017500000000041611325547132021556 0ustar giovannigiovannipackage jas.hist; /** * A crude way of interfacing special plot components such * as 3d lego plot. To be replaced by something more generic * one day. */ public interface SpecialComponent { void setData(DataSource ds); java.awt.Component getDisplayComponent(); } src/main/java/jas/hist/HistogramUpdate.java0000644000175000017500000000336711325547132021423 0ustar giovannigiovannipackage jas.hist; /** * This class encapsulates update messages sent from an observable histogram data source to the * histogram display */ final public class HistogramUpdate implements java.io.Serializable { static final long serialVersionUID = 5574611010721023059L; private final static int FINAL_UPDATE = 1; public final static int DATA_UPDATE = 2; public final static int RANGE_UPDATE = 4; public final static int TITLE_UPDATE = 8; public final static int RESET = 16; private final int AXIS_BASE = 32; /** The index to indicate changes to the horizontal axis for histogram updates. */ final public int HORIZONTAL_AXIS = 0; /** The index to indicate changes to the vertical axis for histogram updates. */ final public int VERTICAL_AXIS = 1; public HistogramUpdate(int id, boolean f) { if (f) id |= FINAL_UPDATE; m_id = id; } public void setAxis(final int axisIndex) { m_id |= AXIS_BASE << axisIndex; } public boolean axisIsSet(final int axisIndex) { return (m_id & AXIS_BASE << axisIndex) != 0; } public boolean isFinalUpdate() { return (m_id & FINAL_UPDATE) != 0; } public boolean isDataUpdate() { return (m_id & DATA_UPDATE) != 0; } public boolean isRangeUpdate() { return (m_id & RANGE_UPDATE) != 0; } public boolean isTitleUpdate() { return (m_id & TITLE_UPDATE) != 0; } public boolean isReset() { return (m_id & RESET) != 0; } public String toString() { return "HistogramUpdate! "+ (isDataUpdate() ? "DATA " :"")+ (isRangeUpdate() ? "RANGE ":"")+ (isTitleUpdate() ? "TITLE ":"")+ (isReset() ? "RESET ":"")+ (isFinalUpdate() ? "FINAL ":"")+ (axisIsSet(HORIZONTAL_AXIS) ? "HORIZONTAL_AXIS ":"")+ (axisIsSet(VERTICAL_AXIS) ? "VERTICAL_AXIS ":""); } protected int m_id; } src/main/java/jas/hist/Matrix.java0000644000175000017500000000642611325547132017566 0ustar giovannigiovannipackage jas.hist; import java.text.NumberFormat; public class Matrix { public static double[][] create(int size) { double[][] result = new double[size][]; for (int i=0; i Math.abs(amax)) { amax = array[i][j]; ik[k] = i; jk[k] = j; } } } // Interchange rows and columns to put max in array[k][k] if (amax == 0) throw new IndeterminateMatrix(); { int i = ik[k]; if (k > i) throw new MatrixBug(); if (i > k) { for (int j=0; j j) throw new MatrixBug(); if (j > k) { for (int i=0; ik) { for (int i=0; ik) { for (int j=0; j .8) { grabType = 1; grab = xLow + rgrab * (xHigh - xLow); axis.setCursor(Cursor.getPredefinedCursor(Cursor.W_RESIZE_CURSOR)); } else { grabType = 2; grab = rgrab; xLowOld = xLow; axis.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); } } public void mouseReleased(MouseEvent me) { axis.setCursor(oldCursor); } protected double xLowOld; protected double grab; protected int grabType; protected ManagedAxis axis; protected Cursor oldCursor; } void modifyPopupMenu(JPopupMenu menu, Component source) { super.modifyPopupMenu(menu,source); if (menu.getComponentCount() > 0) menu.addSeparator(); menu.add(new AddFunctionMenu()); menu.add(new RemoveFunctionMenu()); menu.add(new FitMenu()); menu.add(new AdvancedOptionsMenu()); } public void fillFunctionMenu(JMenu menu) { menu.add(new AddFunctionMenu()); menu.add(new RemoveFunctionMenu()); menu.add(new FitMenu()); menu.add(new AdvancedOptionsMenu()); } final private class AddFunctionMenu extends JMenu { public AddFunctionMenu() { super("Add function"); setMnemonic('A'); // we need to build the menu next time it's selected m_build = FitterRegistry.instance().getDefaultFitter() != null && FunctionRegistry.instance().size() > 0; setEnabled(m_build); } private void buildMenu() { removeAll(); int i = 0; final Enumeration e = FunctionRegistry.instance().elements(); while (e.hasMoreElements()) this.add(new AddFunctionMenuItem((FunctionFactory) e.nextElement(), ++i)); m_build = false; // we don't need to build the menu next time it's selected } protected void fireMenuSelected() { if (m_build) buildMenu(); // super.fireMenuSelected(); } private boolean m_build; final private class AddFunctionMenuItem extends JMenuItem /* * This class is for an item on the AddFunctionMenu. * Each is a function from the FuntionRegistry * that can be added to a window. */ { AddFunctionMenuItem(final FunctionFactory func, final int i) { super(new StringBuffer(String.valueOf(i)).append(' ').append(func.getFunctionName()).toString()); m_func = func; setMnemonic('0' + (char) i); } protected void fireActionPerformed(final ActionEvent evt) { try { //This line replaces the one below. This is so that the adding of the //function goes through the JASHist. This allows to control the title and //the name of the function plot.addData(m_func.createFunction(plot)).show(true); // BinnedDataManager.this.addFunction(m_func.createFunction(plot)).show(true); } catch (FunctionFactoryError ffe) { JOptionPane.showMessageDialog(this,"Could not add function."); } } private FunctionFactory m_func; } } final private class RemoveFunctionMenu extends JMenu /* * Has on it all functions that are on the * selected hist. */ { public RemoveFunctionMenu() { super("Remove function"); setMnemonic('R'); // use the same remove all item for all menus m_removeAll = new RemoveAll(); m_build = numberOfFunctions() > 0; // we need to build the menu next time it's selected setEnabled(m_build); } private void buildMenu() { m_build = false; removeAll(); int i = 0; final Enumeration e = getFunctions(); while (e.hasMoreElements()) this.add(new RemoveFunctionMenuItem((JASHist1DFunctionData) e.nextElement(), ++i)); if (i > 1) // at least 2 menu items { addSeparator(); this.add(m_removeAll); } } protected void fireMenuSelected() { if (m_build) buildMenu(); // super.fireMenuSelected(); } private boolean m_build; // indicates whether it should be built when selected private RemoveAll m_removeAll; final private class RemoveFunctionMenuItem extends JMenuItem { RemoveFunctionMenuItem(final JASHist1DFunctionData func, final int i) { super(new StringBuffer(String.valueOf(i)).append(' ').append(func.getTitle()).toString()); m_func = func; setMnemonic('0' + (char) i); } protected void fireActionPerformed(final ActionEvent evt) { BinnedDataManager.this.removeFunction(m_func); } private JASHist1DFunctionData m_func; } final private class RemoveAll extends JMenuItem { RemoveAll() { super("Remove all"); } protected void fireActionPerformed(final ActionEvent evt) { removeAllFunctions(); } } } final private class FitMenu extends JMenu /* * This is a dynamic menu whose contents depend * on what data sets are on the window, and * what fittable functions have already been * added. It is only enabled if there is at * least one fittable function on the window, * and at least one data set displayed. */ { public FitMenu() { super("Fit"); setMnemonic('F'); m_build = false; if (numberOfDataSources() > 0) { final Enumeration e = getFunctions(); while (e.hasMoreElements()) { final Basic1DFunction func = ((JASHist1DFunctionData) e.nextElement()).getFunction(); if (func instanceof Fittable1DFunction && ((Fittable1DFunction) func).getFit() == null) { m_build = true; break; } } } setEnabled(m_build); } private void buildMenu() { removeAll(); m_build = false; if (numberOfDataSources() > 1) // there are multiple data sets to choose from { int i = 0; final Enumeration e = getDataSources(); while ( e.hasMoreElements() ) this.add( new FitMenuDataMenu( (JASHist1DHistogramData) e.nextElement(), ++i ) ); // The FitMenu menu will contain a selection // of FitMenuDataMenu menus (one for each data // source). Each menu will offer a list of // selectable functions. } else // there is only one data set so it's ovbious // which data set to use { m_selectedDataSet = (JASHist1DHistogramData) getDataSources().nextElement(); // the only data set is selected by default final Enumeration e = getFunctions(); int i = 0; while ( e.hasMoreElements() ) { final Basic1DFunction func = ((JASHist1DFunctionData) e.nextElement()).getFunction(); if (func instanceof Fittable1DFunction && ((Fittable1DFunction) func).getFit() == null) this.add( new FitMenuFunctionItem((Fittable1DFunction) func, ++i) ); } // the FitMenu will offer a choice of all of // the available functions to fit } } protected void fireMenuSelected() { if (m_build) buildMenu(); // super.fireMenuSelected(); } private JASHist1DHistogramData m_selectedDataSet; // This is the data that the user has selected // to fit the function to. If only one choice // of data is available, this is selected // automatically. private boolean m_build; final private class FitMenuFunctionItem extends JMenuItem { FitMenuFunctionItem(final Fittable1DFunction func, final int i) { super( String.valueOf(i) +" "+ func.getTitle() ); m_func = func; setMnemonic('0' + (char) i); } protected void fireActionPerformed(final ActionEvent evt) { final Fitter fitter = FitterRegistry.instance().getDefaultFitter(); fitter.setFunction(m_func); fitter.setData((XYDataSource) m_selectedDataSet.getFittableDataSource()); plot.notifyFitListeners(fitter); fitter.start(); } private Fittable1DFunction m_func; } final private class FitMenuDataMenu extends JMenu { FitMenuDataMenu(final JASHist1DHistogramData data, final int i) { super( String.valueOf(i) +" "+ data.getTitle() ); m_data = data; setMnemonic('0' + (char) i); } protected void fireMenuSelected() { m_selectedDataSet = m_data; if (!m_built) { m_built = true; // build menu: this.removeAll(); final Enumeration e = getFunctions(); int i = 0; while ( e.hasMoreElements() ) { JASHist1DFunctionData d = (JASHist1DFunctionData) e.nextElement(); Object f = d.getDataSource(); if (f instanceof Fittable1DFunction) this.add( new FitMenuFunctionItem((Fittable1DFunction) f, ++i) ); } // Users select an FitMenuDataMenu on the // basis of which data set they want. Once a // FitMenuDataMenu is selected, the // selectedDataSet is set. This menu offers a // list of possible functions to fit. Once // a function is selected, the method // FitMenuFunctionItem.fireActionPerformed() // is called, and a fit is added based on the // selected function and data. // super.fireMenuSelected(); } } private boolean m_built = false; private JASHist1DHistogramData m_data; } } final private class AdvancedOptionsMenu extends JMenu { public AdvancedOptionsMenu() { super("Advanced options..."); setMnemonic('o'); final Enumeration e = getFunctions(); m_build = false; if (e != null) while (e.hasMoreElements()) { if (((JASHist1DFunctionData) e.nextElement()).getFunction() instanceof FunctionAdvancedOptions) { m_build = true; break; } } setEnabled(m_build); } protected void fireMenuSelected() { if (m_build) { m_build = false; removeAll(); final Enumeration e = getFunctions(); int i = 0; while ( e.hasMoreElements() ) { final Basic1DFunction func = ((JASHist1DFunctionData) e.nextElement()).getFunction(); if (func instanceof FunctionAdvancedOptions) this.add( new AdvancedOptionsMenuItem( (FunctionAdvancedOptions) func, ++i ) ); } } // super.fireMenuSelected(); } private boolean m_build; final private class AdvancedOptionsMenuItem extends JMenuItem { AdvancedOptionsMenuItem(final FunctionAdvancedOptions function, final int i) { super(String.valueOf(i) +" "+ ((Basic1DFunction) function).getTitle()); m_function = function; setMnemonic('0' + (char) i); } protected void fireActionPerformed(final ActionEvent e) { m_function.openAdvancedDialog((Frame) SwingUtilities.getAncestorOfClass(Frame.class, plot), plot); } private FunctionAdvancedOptions m_function; } } void computeXAxisRange() { if (!xm.needsAttention()) return; xm.payingAttention(); // do first to avoid race conditions if (data.isEmpty()) return; // Note, when we add items which are rebinnable, we coerce them to adopt the binning preferred by // the x-axis. However, when we add items which are non-rebinnable, they are displayed without regard // to the binning preferred by the axis. if (!xm.getRangeAutomatic()) { xLow = xm.getMin(); xHigh = xm.getMax(); return; } int nShowing = 0; xLow = 0; xHigh = 0; boolean hasRebinnables = false; for (Enumeration e = data.elements(); e.hasMoreElements();) { JASHist1DHistogramData dw = (JASHist1DHistogramData) e.nextElement(); if (!dw.isShowing()) continue; if (Double.isNaN(dw.getXMin())) continue; if (nShowing++ == 0) { xLow = dw.getXMin(); xHigh = dw.getXMax(); } else { xLow = Math.min(xLow,dw.getXMin()); xHigh = Math.max(xHigh,dw.getXMax()); } if (dw.isRebinnable()) hasRebinnables = true; } if (nShowing == 0) return; xm.setBinned(hasRebinnables); if (!xm.getAllowSuppressedZero()) { if (xLow > 0) xLow = 0; if (xHigh < 0) xHigh = 0; } if (xHigh <= xLow) xHigh = xLow + 1; calcMinMaxBins(xLow,xHigh); } void computeYAxisRange() { for (int i=0; i 0) ymin = 0; if (ymax < 0) ymax = 0; } if (ymax <= ymin) ymax = ymin + 1; if (ym[i].isLogarithmic()) { //Fix to JAIDA-85, JAP-59, JAP-53 double min = Double.NaN; for (Enumeration e = data.elements(); e.hasMoreElements();) { JASHist1DHistogramData dw = (JASHist1DHistogramData) e.nextElement(); if (dw.isShowing()) { XYDataSource ds = (XYDataSource)dw.getFittableDataSource(); for ( int j = 0; j < ds.getNPoints(); j++ ) { double tmpMin = ds.getY(j) - ds.getMinusError(j); if ( tmpMin > 0 ) { if ( Double.isNaN(min) ) min = tmpMin; else min = Math.min( tmpMin, min ); } } } } if ( Double.isNaN( min ) ) ymin = Math.max(ymin, 0.5); else ymin = 0.8*min; // if Y Axis is logarithmic and ymin > 0.1 and allowSuppressedZero=false, force ymin=0.1 if (!ym[i].getAllowSuppressedZero()) ymin = Math.min(ymin, 0.1); } double oldYMin = yAxis.getPlotMin(); double oldYMax = yAxis.getPlotMax(); if (ymin < oldYMin || ymax > oldYMax || (ymax - ymin) / (oldYMax - oldYMin) < .75) { yAxis.setUseSuggestedRange(true); yAxis.setMin(ymin); yAxis.setMax(ymax); yAxis.getAxis().revalidate(); // Why does this have to be revalidate?? } } } } abstract void calcMinMaxBins(double x1, double x2); } src/main/java/jas/hist/HasHandles.java0000644000175000017500000000021711325547132020324 0ustar giovannigiovannipackage jas.hist; public interface HasHandles { public abstract Handle[] getHandles(double xlow, double xhigh, double ylow, double yhigh); } src/main/java/jas/hist/DefaultFitterFactory.java0000644000175000017500000000214711325547132022410 0ustar giovannigiovannipackage jas.hist; import jas.util.NestedRuntimeException; import jas.util.ObjectFactory; import jas.util.ObjectFactoryException; class DefaultFitterFactory extends ObjectFactory implements FitterFactory { DefaultFitterFactory(Class c, String name) throws FitterFactoryError { super(c); this.name = name; // Class must be a subclass of Fitter if (!inheritsFrom(Fitter.class)) throw new FitterFactoryError("Function "+name+" does not inherit from Basic1DFunction"); // Class must be declared public if (!checkAccess()) throw new FitterFactoryError("Function "+name+" is not declared public"); // The function needs to have a suitable constructor if (!canBeCreatedFrom()) throw new FitterFactoryError("Function "+name+" does not have a suitable constructor"); } public Fitter createFitter() { try { return (Fitter) create(); } catch (ObjectFactoryException x) { throw new NestedRuntimeException("Unexpected failure to create Fitter "+name,x); } } public String getFitterName() { return name; } public String toString() { return name; } private String name; } src/main/java/jas/hist/CustomOverlay.java0000644000175000017500000000020611325547132021124 0ustar giovannigiovannipackage jas.hist; import jas.plot.Overlay; public interface CustomOverlay extends Overlay { void setDataSource(DataSource source); }src/main/java/jas/hist/DateScatterDataManager.java0000644000175000017500000000337611325547132022613 0ustar giovannigiovannipackage jas.hist; import jas.plot.DataArea; import jas.plot.DateAxis; import jas.plot.DoubleAxis; import jas.plot.Legend; import java.util.TimeZone; final class DateScatterDataManager extends ScatterDataManager { DateScatterDataManager(JASHist plot, final DataArea da, final Legend l, StatisticsBlock stats) { super(plot, da, l, stats); // Configure the Axes if (xm.getType() instanceof DateAxis) xAxisType = (DateAxis) xm.getType(); else { xAxisType = new DateAxis(); xm.setType(xAxisType); } DoubleAxis yAxisType; if (ym[0].getType() instanceof DoubleAxis) yAxisType = (DoubleAxis) ym[0].getType(); else { yAxisType = new DoubleAxis(); ym[0].setType(yAxisType); } xm.setDataManager(this, false, xAxisType); ym[0].setDataManager(this, false, yAxisType); } final protected void calcMinMaxXBins(double x1, double x2) { long iLow = (long) (x1*1000); long iHigh = (long) (x2*1000); long oldXMin = xAxisType.getAxisMin(); long oldXMax = xAxisType.getAxisMax(); // Only update the axis if the new range is outside of the old range, // or occupies less than 75% of the old range if (iLow < oldXMin || iHigh > oldXMax || (iHigh - iLow) / (oldXMax - oldXMin) < 0.75) { xAxisType.setMin(iLow); xAxisType.setMax(iHigh); xm.invalidate(); } } JASHistData add(DataSource ds) { JASHistData jhd = super.add(ds); TimeZone tz = jhd.getStyle().getTimeZone(); if (tz != null) xAxisType.setTimeZone(tz); return jhd; } void styleUpdate(JASHistData data) { TimeZone tz = data.getStyle().getTimeZone(); if (tz != null) xAxisType.setTimeZone(tz); super.styleUpdate(data); } private DateAxis xAxisType; } src/main/java/jas/hist/XML2DScatterDataSource.java0000644000175000017500000001200311325547132022435 0ustar giovannigiovannipackage jas.hist; import jas.util.xml.XMLNodeTraverser; import java.io.Serializable; import java.util.Observable; import java.util.StringTokenizer; import org.w3c.dom.Attr; import org.w3c.dom.Node; import org.w3c.dom.Text; public class XML2DScatterDataSource extends Observable implements ScatterPlotSource, Serializable { public XML2DScatterDataSource(int p_xAxisType, int p_yAxisType, String p_title, double[][] p_data) { m_xAxisType = p_xAxisType; m_yAxisType = p_yAxisType; m_title = p_title; m_data = p_data; //now calculate the x and y min and max once and for all //(so we can return them quickly) m_xmin = m_data[0][0]; m_xmax = m_xmin; m_ymin = m_data[1][0]; m_ymax = m_ymin; for (int i=1; i < m_data[0].length; i++) { if (m_data[0][i] < m_xmin) m_xmin = m_data[0][i]; if (m_data[0][i] > m_xmax) m_xmax = m_data[0][i]; if (m_data[1][i] < m_ymin) m_ymin = m_data[1][i]; if (m_data[1][i] > m_ymax) m_ymax = m_data[1][i]; } } public double getXMin() { return m_xmin; } public double getXMax() { return m_xmax; } public double getYMin() { return m_ymin; } public double getYMax() { return m_ymax; } public int getXAxisType() { return m_xAxisType; } public int getYAxisType() { return m_yAxisType; } public ScatterEnumeration startEnumeration(double xMin, double xMax, double yMin, double yMax) { return new FixedEnumeration(m_data, xMin, xMax, yMin, yMax); } public ScatterEnumeration startEnumeration() { return new FixedEnumeration(m_data); } public String getTitle() { return m_title; } private double m_xmin; private double m_xmax; private double m_ymin; private double m_ymax; private int m_xAxisType; private int m_yAxisType; private String m_title; private double[][] m_data; private class FixedEnumeration implements ScatterEnumeration { public FixedEnumeration(double[][] p_data) { m_data = p_data; selectAll = true; } public FixedEnumeration(double[][] p_data, double xMin, double xMax, double yMin, double yMax) { m_data = p_data; selectAll = false; m_xmin = xMin; m_xmax = xMax; m_ymin = yMin; m_ymax = yMax; } public boolean getNextPoint(double[] a) { if (selectAll) { if (pos < (m_data[0].length - 1)) { a[0] = m_data[0][pos]; a[1] = m_data[1][pos++]; return true; } else { return false; } } else { while (!((m_data[0][pos] >= m_xmin) && (m_data[0][pos] <= m_xmax) && (m_data[1][pos] >= m_ymin) && (m_data[1][pos] <= m_ymax))) { //skip points that don't satisfy the conditions pos++; if(pos>m_data[0].length-1){ return false; } } //okay, if we're here the point satisfies the min and max conditions a[0] = m_data[0][pos]; a[1] = m_data[1][pos++]; return posx */ public double[] getDerivatives(double x, double[] a) throws FunctionValueUndefined { int nterms = a.length; double[] result = new double[nterms]; double[] deltaA = getParameterDeltas(); for (int j=0; j 0) && (oldHeight > 0)) { // Size changed, if we do not have an new image // already in preparation create one now Image next = newImage; if (next == null) { next = container.createImage(new ScatterImage(width, height, xt, yt)); newImage = next; container.prepareImage(next, this); //System.out.println("newImage created"+newImage); } else { int newWidth = next.getWidth(null); int newHeight = next.getHeight(null); if ((newWidth > 0) && (newHeight > 0) && ((newWidth != width) || (newHeight != height))) { // the new image is already the wrong size // TODO: Signal the image to start over with the new size //next.setSize(width,height); } } // Until the new image is ready we will draw a // scaled version of the current image //System.out.println("Draw "+imageCache+" scaled to "+width+","+height); g.drawImage(current, x1, y2, width, height, this); // approximation for now } } } } else { super.paint(g,isPrinting); } } public void paintIcon(final PlotGraphics g, final int width, final int height) { JASHistScatterPlotStyle style = (JASHistScatterPlotStyle) parent.style; if (style.getDisplayAsScatterPlot()) { g.setColor(style.getDataPointColor()); g.fillRect(1, 1, width - 2, height - 2); } else { super.paintIcon(g, width, height); } } /** * Called if more points have been added to image */ void continueImage() { //System.out.println("continueImage"); Image image = imageCache; if (image != null) { ((ScatterImage) image.getSource()).continueDrawing(); } image = newImage; if (image != null) { ((ScatterImage) image.getSource()).continueDrawing(); } } void restartImage(boolean newEnumNeeded) { //System.out.println("restartImage"+newEnumNeeded); Image image = imageCache; if (image != null) { ((ScatterImage) image.getSource()).restart(newEnumNeeded); } image = newImage; if (image != null) { ((ScatterImage) image.getSource()).restart(newEnumNeeded); } } private void imageReallyComplete(ImageProducer producer) { // Attention, executed in thread of ImageProducer Image next = newImage; if ((next != null) && (next.getSource() == producer)) { Image oldImage = imageCache; imageCache = next; oldImage.flush(); newImage = null; container.repaint(); //System.out.println("Image Replace"); } } final class ScatterImage implements ImageProducer, Runnable { final private DoubleCoordinateTransformation xt; final private DoubleCoordinateTransformation yt; private ImageConsumer consumer; private ScatterEnumeration enumer; private Thread thread; private boolean abort = false; private boolean pastPointOfNoContinue = false; final private int height; final private int width; ScatterImage(int width, int height, DoubleCoordinateTransformation xt, DoubleCoordinateTransformation yt) { this.width = width; this.height = height; // TODO: Better coordinate transforms // These are live references to the coordinate transformation, so they // can change if the size of the plot changes while the image is // being produced :-( this.xt = xt; this.yt = yt; } public boolean isConsumer(ImageConsumer c) { return consumer.equals(c); } public void addConsumer(ImageConsumer c) { //System.out.println("addConsumer "+c); if (consumer != null) { throw new RuntimeException("Only single consumer supported"); } consumer = c; } public void removeConsumer(ImageConsumer c) { consumer = null; } public void requestTopDownLeftRightResend(ImageConsumer c) { // forget it! } public void run() { ImageConsumer consumer = this.consumer; if (consumer != null) { deliverImage(consumer); } thread = null; //System.out.println("Thread stopped"); } public void startProduction(ImageConsumer c) { //System.out.println("start"); consumer = c; if (async) { thread = new Thread(this); thread.start(); } else { run(); } } void abort() { try { Thread t = thread; if (t != null) { //System.out.println("-----------Interrupt"); abort = true; t.join(); //System.out.println("-----------join"); } } catch (InterruptedException x) { } finally { abort = false; } } /** * A continue message means more data points have been * added to the enumeration. */ void continueDrawing() { Thread t = thread; if (t != null) { // Check if we are past the point of no continue // If not we don't need to do anything, because we // will naturally continue. synchronized (this) { if (!pastPointOfNoContinue) { return; } } // If we are then we must wait for this thread to // complete before starting a new one try { t.join(); } catch (InterruptedException x) { } } if (async) { thread = new Thread(this); thread.start(); } else { run(); } } /** * Restart means we need to start drawing the image again, * from the beginning. */ void restart(final boolean newEnumNeeded) { abort(); // Stop the current thread if (newEnumNeeded) { enumer = null; } else if (enumer != null) { enumer.restart(); } if (async) { thread = new Thread(this); thread.start(); } else { run(); } } private void deliverImage(ImageConsumer consumer) { JASHistScatterPlotStyle style = (JASHistScatterPlotStyle) parent.style; final Color c = style.getDataPointColor(); final byte[] r = { 0, (byte) c.getRed() }; final byte[] g = { 0, (byte) c.getGreen() }; final byte[] b = { 0, (byte) c.getBlue() }; //Fix to JAS-94 and JAS-232 //TO-DO Figure out why setting the alpha value to (byte)255 //the problems in the bugs above reappear. final byte[] a = { 0, (byte) 254 }; final ColorModel model = new IndexColorModel(1, 2, r, g, b, a); byte[] pixels = new byte[width * height]; consumer.setDimensions(width, height); consumer.setColorModel(model); final double[] d = new double[2]; // for one image the following five variables are constant // (if any of them changes we have to start a new thread) final int point = style.getDataPointStyle(); final int size = style.getDataPointSize(); final int size2 = size / 2; // just to keep things fast final double x1 = xt.convert(xt.getPlotMin()); final double y2 = yt.convert(yt.getPlotMax()); if (enumer == null) { final double data_xMin = parent.dataSource.getXMin(); final double data_xMax = parent.dataSource.getXMax(); final double data_yMin = parent.dataSource.getYMin(); final double data_yMax = parent.dataSource.getYMax(); final double plot_xMin = xt.getPlotMin(); final double plot_xMax = xt.getPlotMax(); final double plot_yMin = yt.getPlotMin(); final double plot_yMax = yt.getPlotMax(); if ((data_xMin < plot_xMin) || (data_xMax > plot_xMax) || (data_yMin < plot_yMin) || (data_yMax > plot_yMax)) { final double xMin = Math.max(data_xMin, plot_xMin); final double xMax = Math.min(data_xMax, plot_xMax); final double yMin = Math.max(data_yMin, plot_yMin); final double yMax = Math.min(data_yMax, plot_yMax); // if a point is beyond our regular x bounds by amount "xExtra" // or beyond our regular y bounds by amount "yExtra" // we want to include it anyway because at least part of // its dot will appear within the bounds final double xExtra = ((double) size2 * (plot_xMax - plot_xMin)) / (double) (xt.convert(plot_xMax) - x1); final double yExtra = ((double) size2 * (plot_yMax - plot_yMin)) / (double) (yt.convert(plot_yMin) - y2); if (((data_xMin + xExtra) < plot_xMin) || ((data_xMax - xExtra) > plot_xMax) || ((data_yMin + yExtra) < plot_yMin) || ((data_yMax - yExtra) > plot_yMax)) { enumer = parent.dataSource.startEnumeration(xMin - xExtra, xMax + xExtra, yMin - yExtra, yMax + yExtra); } else { enumer = parent.dataSource.startEnumeration(); } } else { enumer = parent.dataSource.startEnumeration(); } } long nextUpdate = System.currentTimeMillis() + 200L; for (int n = 0; !abort; n++) { boolean ok = enumer.getNextPoint(d); if (!ok) { synchronized (this) { // We need to double check, just in case // more data was added since we checked a millisecond ago // (arent threads fun) ok = enumer.getNextPoint(d); if (!ok) { pastPointOfNoContinue = true; break; } } } final int col = Math.round((float) (xt.convert(d[0]) - x1)); final int row = Math.round((float) (yt.convert(d[1]) - y2)); int i; int col_start; int col_end; int row_start; int row_end; if (size < 2) { if ((col < 0) || (col >= width)) { continue; } try { pixels[(row * width) + col] = 1; } catch (final ArrayIndexOutOfBoundsException e) { } } else { switch (point) { case JASHistScatterPlotStyle.SYMBOL_BOX: col_end = Math.min(width, col + size2); row_start = Math.max(0, row - size2); row_end = Math.min(height, row + size2); for (i = row_start * width; row_start < row_end; i += width, row_start++) for (col_start = Math.max(0, col - size2); col_start < col_end; col_start++) try { pixels[i + col_start] = 1; } catch (final ArrayIndexOutOfBoundsException e) { } break; case JASHistScatterPlotStyle.SYMBOL_TRIANGLE: row_start = row - ((size * 64) / 100); // approximates the top of the triangle i = Math.max(0, row_start) * width; for (int j = Math.max(0, -row_start); j < size; j++, i += width) { final int extra = j / 2; col_end = Math.min(width - 1, col + extra); for (col_start = Math.max(0, col - extra); col_start <= col_end; col_start++) try { pixels[i + col_start] = 1; } catch (final ArrayIndexOutOfBoundsException e) { } } break; case JASHistScatterPlotStyle.SYMBOL_DIAMOND: row_start = Math.max(0, row - size2); row_end = Math.min(height, row + size2); i = row_start * width; for (int j = Math.max(size2 - row, 0); j < size2; j++, i += width) { col_end = Math.min(width - 1, col + j); for (col_start = Math.max(0, col - j); col_start <= col_end; col_start++) try { pixels[i + col_start] = 1; } catch (final ArrayIndexOutOfBoundsException e) { } } for (int j = size2; j >= 0; j--, i += width) { col_end = Math.min(width - 1, col + j); for (col_start = Math.max(0, col - j); col_start <= col_end; col_start++) try { pixels[i + col_start] = 1; } catch (final ArrayIndexOutOfBoundsException e) { } } break; case JASHistScatterPlotStyle.SYMBOL_STAR: i = row * width; col_end = Math.min(width - 1, col + size2); for (col_start = Math.max(0, col - size2); col_start <= col_end; col_start++) try { pixels[i + col_start] = 1; } catch (final ArrayIndexOutOfBoundsException e) { } i -= (size2 * width); for (int j = -size2; j <= size2; j++, i += width) { if ((col >= 0) && (col < width)) { try { pixels[i + col] = 1; } catch (final ArrayIndexOutOfBoundsException e) { } } if (((col + j) >= 0) && ((col + j) < width)) { try { pixels[i + col + j] = 1; } catch (final ArrayIndexOutOfBoundsException e) { } } if (((col - j) >= 0) && ((col - j) < width)) { try { pixels[(i + col) - j] = 1; } catch (final ArrayIndexOutOfBoundsException e) { } } } break; case JASHistScatterPlotStyle.SYMBOL_VERT_LINE: if ((col >= 0) && (col < width)) { row_start = Math.max(0, row - size2); row_end = Math.min(height, row + size2); i = (row_start * width) + col; for (; row_start < row_end; row_start++, i += width) try { pixels[i] = 1; } catch (final ArrayIndexOutOfBoundsException e) { } } break; case JASHistScatterPlotStyle.SYMBOL_HORIZ_LINE: if ((row >= 0) && (row < height)) { i = row * width; col_end = Math.min(width, col + size2); for (col_start = Math.max(0, col - size2); col_start < col_end; col_start++) try { pixels[i + col_start] = 1; } catch (final ArrayIndexOutOfBoundsException e) { } } break; case JASHistScatterPlotStyle.SYMBOL_CROSS: i = row * width; col_end = Math.min(width - 1, col + size2); for (col_start = Math.max(0, col - size2); col_start <= col_end; col_start++) try { pixels[i + col_start] = 1; } catch (final ArrayIndexOutOfBoundsException e) { } row_start = Math.max(0, row - size2); row_end = Math.min(height - 1, row + size2); i -= (((row - row_start) * width) - col); for (; row_start <= row_end; row_start++, i += width) try { pixels[i] = 1; } catch (final ArrayIndexOutOfBoundsException e) { } break; case JASHistScatterPlotStyle.SYMBOL_SQUARE: row_start = Math.max(0, row - size2); row_end = Math.min(height, row + size2); col_end = Math.min(width, col + size2); i = row_start * width; col_start = Math.max(0, col - size2); if (row_start > 0) { for (; col_start < col_end; col_start++) try { pixels[i + col_start] = 1; } catch (final ArrayIndexOutOfBoundsException e) { } } final boolean l_Line = (col - size2) >= 0; final boolean r_Line = (col + size2) < width; i += col; for (; row_start < row_end; row_start++, i += width) { if (l_Line) { try { pixels[i - size2] = 1; } catch (final ArrayIndexOutOfBoundsException e) { } } if (r_Line) { try { pixels[i + size2] = 1; } catch (final ArrayIndexOutOfBoundsException e) { } } } i -= col; for (col_start = Math.max(0, col - size2); col_start <= col_end; col_start++) try { pixels[i + col_start] = 1; } catch (final ArrayIndexOutOfBoundsException e) { } break; } } final long now = System.currentTimeMillis(); if (now > nextUpdate) { consumer.setPixels(0, 0, width, height, model, pixels, 0, width); consumer.imageComplete(consumer.SINGLEFRAMEDONE); nextUpdate = now + 200; //System.out.println("Thread running n="+n); } } if (abort) { consumer.imageComplete(consumer.IMAGEABORTED); } else { // Note, we may still have more frames, for example if the style changes, // or if more points need to be displayed consumer.setPixels(0, 0, width, height, model, pixels, 0, width); consumer.imageComplete(consumer.SINGLEFRAMEDONE); imageReallyComplete(this); } } } } src/main/java/jas/hist/Handle.java0000644000175000017500000000040311325547132017502 0ustar giovannigiovannipackage jas.hist; import java.awt.Cursor; public abstract class Handle { public abstract double getX(); public abstract double getY(); public abstract void moveTo(double x,double y); public Cursor cursor() { return null; } } src/main/java/jas/hist/JASHistScatterPlotStyle.java0000644000175000017500000000344111325547132022767 0ustar giovannigiovannipackage jas.hist; import java.awt.Color; import java.awt.Graphics; public final class JASHistScatterPlotStyle extends JASHist2DHistogramStyle { final public static int SYMBOL_BOX = 0; final public static int SYMBOL_TRIANGLE = 1; final public static int SYMBOL_DIAMOND = 2; final public static int SYMBOL_STAR = 3; final public static int SYMBOL_VERT_LINE = 4; final public static int SYMBOL_HORIZ_LINE = 5; final public static int SYMBOL_CROSS = 6; final public static int SYMBOL_SQUARE = 7; static final Color[] lineColors = { Color.blue, Color.red, Color.darkGray,Color.magenta, Color.yellow, Color.green, Color.orange, Color.cyan, }; static int n = 0; public JASHistScatterPlotStyle() { m_displayAsScatterPlot = false; m_dataPointSize = 3; m_dataPointStyle = n; m_dataPointColor = lineColors[n]; n++; if (n == lineColors.length) n = 0; } public boolean getDisplayAsScatterPlot() { return m_displayAsScatterPlot; } public void setDisplayAsScatterPlot(boolean value) { m_displayAsScatterPlot = value; changeNotify(); } public int getDataPointStyle() { return m_dataPointStyle; } public void setDataPointStyle(int nNewValue) { m_dataPointStyle = nNewValue; changeNotify(); } public int getDataPointSize() { return m_dataPointSize; } public void setDataPointSize(int newValue) { m_dataPointSize = newValue; changeNotify(); } public Color getDataPointColor() { return m_dataPointColor; } public void setDataPointColor(Color nNewValue) { m_dataPointColor = nNewValue; changeNotify(); } void drawLegend(Graphics g, int x, int y, int width, int height) { } private boolean m_displayAsScatterPlot; private int m_dataPointSize; private Color m_dataPointColor; private int m_dataPointStyle; } src/main/java/jas/hist/SupportsFunctions.java0000644000175000017500000000056311325547132022046 0ustar giovannigiovannipackage jas.hist; import java.util.Enumeration; import javax.swing.JMenu; interface SupportsFunctions { int numberOfFunctions(); Enumeration getFunctions(); void removeAllFunctions(); void update(JASHist1DFunctionData func); JASHist1DFunctionData addFunction(Basic1DFunction d); void removeFunction(JASHist1DFunctionData d); void fillFunctionMenu(JMenu menu); } src/main/java/jas/hist/normalization/0000755000175000017500000000000011325547132020335 5ustar giovannigiovannisrc/main/java/jas/hist/normalization/NormalizationPanel.java0000644000175000017500000001147011325547132025011 0ustar giovannigiovanni/* * NormalizationPanel.java * * Created on January 23, 2001, 7:10 PM */ package jas.hist.normalization; /** * * @author tonyj */ public class NormalizationPanel extends javax.swing.JPanel { /** Creates new form NormalizationPanel */ public NormalizationPanel() { initComponents(); } /** This method is called from within the constructor to * initialize the form. * WARNING: Do NOT modify this code. The content of this method is * always regenerated by the Form Editor. */ private void initComponents() {//GEN-BEGIN:initComponents jCheckBox1 = new javax.swing.JCheckBox(); jPanel1 = new javax.swing.JPanel(); jCheckBox2 = new javax.swing.JCheckBox(); jComboBox1 = new javax.swing.JComboBox(); jPanel2 = new javax.swing.JPanel(); jLabel1 = new javax.swing.JLabel(); jComboBox2 = new javax.swing.JComboBox(); jLabel2 = new javax.swing.JLabel(); jTextField1 = new javax.swing.JTextField(); jLabel3 = new javax.swing.JLabel(); jTextField2 = new javax.swing.JTextField(); jLabel4 = new javax.swing.JLabel(); jComboBox3 = new javax.swing.JComboBox(); setLayout(new java.awt.BorderLayout()); jCheckBox1.setText("Normalized"); add(jCheckBox1, java.awt.BorderLayout.NORTH); jPanel1.setLayout(new java.awt.FlowLayout(0, 5, 5)); jCheckBox2.setText("Relative To"); jPanel1.add(jCheckBox2); jComboBox1.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { jComboBox1ActionPerformed(evt); } } ); jPanel1.add(jComboBox1); add(jPanel1, java.awt.BorderLayout.SOUTH); jPanel2.setLayout(new java.awt.GridBagLayout()); java.awt.GridBagConstraints gridBagConstraints1; jLabel1.setText("Method"); gridBagConstraints1 = new java.awt.GridBagConstraints(); jPanel2.add(jLabel1, gridBagConstraints1); gridBagConstraints1 = new java.awt.GridBagConstraints(); gridBagConstraints1.gridwidth = 0; jPanel2.add(jComboBox2, gridBagConstraints1); jLabel2.setText("Multiplier"); gridBagConstraints1 = new java.awt.GridBagConstraints(); jPanel2.add(jLabel2, gridBagConstraints1); jTextField1.setText("jTextField1"); jTextField1.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { jTextField1ActionPerformed(evt); } } ); gridBagConstraints1 = new java.awt.GridBagConstraints(); gridBagConstraints1.gridwidth = 0; jPanel2.add(jTextField1, gridBagConstraints1); jLabel3.setText("Bin"); gridBagConstraints1 = new java.awt.GridBagConstraints(); jPanel2.add(jLabel3, gridBagConstraints1); jTextField2.setText("jTextField2"); gridBagConstraints1 = new java.awt.GridBagConstraints(); gridBagConstraints1.gridwidth = 0; jPanel2.add(jTextField2, gridBagConstraints1); jLabel4.setText("Statistic Name"); gridBagConstraints1 = new java.awt.GridBagConstraints(); jPanel2.add(jLabel4, gridBagConstraints1); gridBagConstraints1 = new java.awt.GridBagConstraints(); jPanel2.add(jComboBox3, gridBagConstraints1); add(jPanel2, java.awt.BorderLayout.CENTER); }//GEN-END:initComponents private void jTextField1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jTextField1ActionPerformed // Add your handling code here: }//GEN-LAST:event_jTextField1ActionPerformed private void jComboBox1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jComboBox1ActionPerformed // Add your handling code here: }//GEN-LAST:event_jComboBox1ActionPerformed // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JCheckBox jCheckBox1; private javax.swing.JPanel jPanel1; private javax.swing.JCheckBox jCheckBox2; private javax.swing.JComboBox jComboBox1; private javax.swing.JPanel jPanel2; private javax.swing.JLabel jLabel1; private javax.swing.JComboBox jComboBox2; private javax.swing.JLabel jLabel2; private javax.swing.JTextField jTextField1; private javax.swing.JLabel jLabel3; private javax.swing.JTextField jTextField2; private javax.swing.JLabel jLabel4; private javax.swing.JComboBox jComboBox3; // End of variables declaration//GEN-END:variables } src/main/java/jas/hist/normalization/SimpleNormalizer.java0000644000175000017500000000155311325547132024500 0ustar giovannigiovanni/* * SimpleNormalizer.java * * Created on January 23, 2001, 12:09 PM */ package jas.hist.normalization; import java.util.Observable; /** * A normalizer that normalizes by a set factor. * @author tonyj * @version $Id: SimpleNormalizer.java 11553 2007-06-05 22:06:23Z duns $ */ public class SimpleNormalizer extends Observable implements Normalizer { /** Creates new SimpleNormalizer */ public SimpleNormalizer(double factor) { this.factor = factor; } public void setFactor(double factor) { if (this.factor != factor) { this.factor = factor; normalizationChanged(); } } protected void normalizationChanged() { setChanged(); notifyObservers(); } public double getNormalizationFactor() { return factor; } private double factor; } src/main/java/jas/hist/normalization/AreaNormalizer.java0000644000175000017500000000233311325547132024114 0ustar giovannigiovanni/* * AreaNormalizer.java * * Created on January 23, 2001, 6:09 PM */ package jas.hist.normalization; import jas.hist.DataSource; import jas.hist.Rebinnable1DHistogramData; /** * Calculates a normalization factor based on the area under a data set. * @author tonyj * @version $Id: AreaNormalizer.java 11553 2007-06-05 22:06:23Z duns $ */ public class AreaNormalizer extends DataSourceNormalizer { /** Create an AreaNormalizer * @param data The data source */ public AreaNormalizer(DataSource data) { super(data); init(); } protected double calculateNormalization() { if (source instanceof Rebinnable1DHistogramData) { Rebinnable1DHistogramData data = (Rebinnable1DHistogramData) source; int nBins = data.getBins(); double xMin = data.getMin(); double xMax = data.getMax(); double[][] bins = data.rebin(nBins,xMin,xMax,false,hurry); double[] y = bins[0]; double area = 0; for (int i=0; i 0 ? area : 1; } else return 1; } } src/main/java/jas/hist/normalization/BinNormalizer.java0000644000175000017500000000217611325547132023761 0ustar giovannigiovanni/* * BinNormalizer.java * * Created on January 24, 2001, 12:12 PM */ package jas.hist.normalization; import jas.hist.DataSource; import jas.hist.Rebinnable1DHistogramData; /** * Calculates a normalization factor base on a specific bin. * @author tonyj * @version $Id: BinNormalizer.java 11553 2007-06-05 22:06:23Z duns $ */ public class BinNormalizer extends DataSourceNormalizer { /** Create a new BinNormalizer * @param data The data source * @param bin The bin number. */ public BinNormalizer(DataSource data, int bin) { super(data); this.bin = bin; init(); } protected double calculateNormalization() { if (source instanceof Rebinnable1DHistogramData) { Rebinnable1DHistogramData data = (Rebinnable1DHistogramData) source; int nBins = data.getBins(); double xMin = data.getMin(); double xMax = data.getMax(); double[][] bins = data.rebin(nBins,xMin,xMax,false,hurry); double[] y = bins[0]; return y[bin] > 0 ? y[bin] : 1; } else return 1; } private int bin; } src/main/java/jas/hist/normalization/MaxBinNormalizer.java0000644000175000017500000000233511325547132024424 0ustar giovannigiovanni/* * MaxBinNormalizer.java * * Created on January 23, 2001, 3:14 PM */ package jas.hist.normalization; import jas.hist.DataSource; import jas.hist.Rebinnable1DHistogramData; /** * Calculates a normalization factor based on the bin with the largest value. * @author tonyj * @version $Id: MaxBinNormalizer.java 11553 2007-06-05 22:06:23Z duns $ */ public class MaxBinNormalizer extends DataSourceNormalizer { /** Creates new MaxBinNormalizer * @param data The data source */ public MaxBinNormalizer(DataSource data) { super(data); init(); } protected double calculateNormalization() { if (source instanceof Rebinnable1DHistogramData) { Rebinnable1DHistogramData data = (Rebinnable1DHistogramData) source; int nBins = data.getBins(); double xMin = data.getMin(); double xMax = data.getMax(); double[][] bins = data.rebin(nBins,xMin,xMax,false,hurry); double[] y = bins[0]; double max = 0; for (int i=0; i 0 ? max : 1; } else return 1; } } src/main/java/jas/hist/normalization/Normalizer.java0000644000175000017500000000074111325547132023324 0ustar giovannigiovanni/* * Normalizer.java * * Created on January 23, 2001, 11:50 AM */ package jas.hist.normalization; /** * A normalizer allows a dataset to be normalized by an arbitrary factor. * @see jas.hist.JASHistData#setNormalization(Normalizer) * @author tonyj * @version $Id: Normalizer.java 11550 2007-06-05 21:44:14Z duns $ */ public interface Normalizer { /** * The displayed data will be divided by this factor */ public double getNormalizationFactor(); } src/main/java/jas/hist/normalization/StatisticsNormalizer.java0000644000175000017500000000266511325547132025406 0ustar giovannigiovanni/* * StatisticsNormalizer.java * * Created on January 23, 2001, 6:13 PM */ package jas.hist.normalization; import jas.hist.DataSource; import jas.hist.ExtendedStatistics; import jas.hist.HasStatistics; import jas.hist.Statistics; /** * A normalizer that calculates a normalization factor based on a specific statistics entry * @author tonyj * @version $Id: StatisticsNormalizer.java 13351 2007-09-21 18:46:46Z serbo $ */ public class StatisticsNormalizer extends DataSourceNormalizer { /** Creates new StatisticsNormalizer * @param source The data source * @param statsName The name of the statistic */ public StatisticsNormalizer(DataSource source, String statsName) { super(source); this.statsName = statsName; init(); } protected double calculateNormalization() { if (source instanceof HasStatistics) { Statistics stats = ((HasStatistics) source).getStatistics(); double stat = stats.getStatistic(statsName); if (stat == 0 && stats instanceof ExtendedStatistics) { Object obj = ((ExtendedStatistics) stats).getExtendedStatistic(statsName); try { stat = Double.parseDouble(obj.toString()); } catch (NumberFormatException e) { stat = 0; } } return stat > 0 ? stat : 1; } else return 1; } private String statsName; } src/main/java/jas/hist/normalization/package.html0000644000175000017500000000023111325547132022612 0ustar giovannigiovanni Handles normalization of data. src/main/java/jas/hist/normalization/DataSourceNormalizer.java0000644000175000017500000000306611325547132025302 0ustar giovannigiovanni/* * DataSourceNormalizer.java * * Created on January 24, 2001, 11:55 AM */ package jas.hist.normalization; import jas.hist.DataSource; import java.util.Observable; import java.util.Observer; /** * A base class for Normalizers which depend upon a DataSource * @author tonyj * @version $Id: DataSourceNormalizer.java 11553 2007-06-05 22:06:23Z duns $ */ public abstract class DataSourceNormalizer extends SimpleNormalizer implements Observer { /** Creates a new DataSourceNormalizer * @param source The Data Source */ public DataSourceNormalizer(DataSource source) { super(1); this.source = source; String property = System.getProperty("hurry", "false"); hurry = property != null && property.equalsIgnoreCase("true"); } /** To be called by superclasses, typically at the end of the constructor. */ protected void init() { if (source instanceof Observable) ((Observable) source).addObserver(this); norm = calculateNormalization(); } public void update(Observable obs,Object arg) { double newNorm = calculateNormalization(); if (newNorm != norm) { norm = newNorm; normalizationChanged(); } } public double getNormalizationFactor() { return super.getNormalizationFactor()*norm; } /** Calculates the normalization factor. * @return The normalization factor. */ protected abstract double calculateNormalization(); protected boolean hurry; protected DataSource source; private double norm; } src/main/java/jas/hist/normalization/NormalizationRegistry.java0000644000175000017500000000311611325547132025560 0ustar giovannigiovanni/* * NormalizationRegistry.java * * Created on January 26, 2001, 5:21 PM */ package jas.hist.normalization; /** * The NormalizationRegistry contains a list of NormalizationFactories * @author tonyj * @version $Id: NormalizationRegistry.java 11550 2007-06-05 21:44:14Z duns $ */ public class NormalizationRegistry { /** Creates a new NormalizationRegistry */ private NormalizationRegistry() { } /** * Add an entry to the registry */ public void add(NormalizationFactory factory) { } /** * Remove an entry from the registry */ public void remove(NormalizationFactory factory) { } /** * Find the factory that created a specific normalizer */ public NormalizationFactory findFactory(Normalizer norm) { // A neat implementation of this would use a weak hashmap // so that entries would be GCed when no longer in use. // For now we could have a kludgy implementation that assumes // that a default factory was used and bases its decission on the // class of the entry. return null; } /** * Access the unique instance of NormalizationRegistry() */ NormalizationRegistry instance() { return theRegistry; } private static NormalizationRegistry theRegistry = new NormalizationRegistry(); } class DefaultNormalizationFactory implements NormalizationFactory { DefaultNormalizationFactory(Class c) { } } interface NormalizationFactory { //String getName(); //Icon getIcon(); //Normalizer createNormalizer(); } src/main/java/jas/hist/normalization/EntriesNormalizer.java0000644000175000017500000000107311325547132024655 0ustar giovannigiovanni/* * EntriesNormalizer.java * * Created on January 24, 2001, 11:53 AM */ package jas.hist.normalization; import jas.hist.DataSource; /** * Calculates a normalization factor based on the number of entries in the data source. * @author tonyj * @version $Id: EntriesNormalizer.java 11550 2007-06-05 21:44:14Z duns $ */ public class EntriesNormalizer extends StatisticsNormalizer { /** Creates new EntriesNormalizer * @param source The data source */ public EntriesNormalizer(DataSource source) { super(source,"Entries"); } } src/main/java/jas/hist/normalization/RelativeNormalizer.java0000644000175000017500000000216311325547132025020 0ustar giovannigiovanni/* * RelativeNormalizer.java * * Created on January 23, 2001, 5:24 PM */ package jas.hist.normalization; import java.util.Observable; import java.util.Observer; /** * A normalizar that normalizes by the ratio of two other normalizers * @author tonyj * @version $Id: RelativeNormalizer.java 11553 2007-06-05 22:06:23Z duns $ */ public class RelativeNormalizer extends Observable implements Normalizer, Observer { /** Creates new RelativeNormalizer */ public RelativeNormalizer(Normalizer numerator, Normalizer denominator) { this.numerator = numerator; this.denominator = denominator; if (numerator instanceof Observable) ((Observable) numerator).addObserver(this); if (denominator instanceof Observable) ((Observable) denominator).addObserver(this); } public double getNormalizationFactor() { return numerator.getNormalizationFactor()/denominator.getNormalizationFactor(); } public void update(Observable obs, Object arg) { setChanged(); notifyObservers(); } private Normalizer numerator; private Normalizer denominator; } src/main/java/jas/hist/JASHist.java0000644000175000017500000007255311325547132017573 0ustar giovannigiovannipackage jas.hist; import jas.plot.Axis; import jas.plot.DataArea; import jas.plot.HasPopupItems; import jas.plot.JASPlotMouseListener; import jas.plot.Legend; import jas.plot.PlotComponent; import jas.plot.PlotPanel; import jas.plot.PrintHelper; import jas.plot.Title; import java.awt.AWTEvent; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; import java.awt.Dimension; import java.awt.Frame; import java.awt.Graphics; import java.awt.event.ActionEvent; import java.awt.event.MouseEvent; import java.io.Writer; import java.util.Enumeration; import java.util.Vector; import javax.swing.JCheckBoxMenuItem; import javax.swing.JComponent; import javax.swing.JMenu; import javax.swing.JMenuItem; import javax.swing.JPopupMenu; import javax.swing.SwingUtilities; import javax.swing.border.Border; /** * JASHist is the main component used for plotting histograms, scatterplots etc. The type of * display produced depends on the DataSource hooked to the component. If the data source is * observable, then the JASHist will update as it receives notifications from the data source. * * JASHist supports overlaying of data and fitting of functions (to 1D histograms). */ public class JASHist extends JComponent implements JASPlotMouseListener { /** * Create a new JASHist component with no initial data source */ public JASHist() { setLayout(new BorderLayout()); add(contentPane, BorderLayout.CENTER); setPreferredSize(new Dimension(200,200)); Axis xAxis = new ManagedAxis(Axis.HORIZONTAL); Axis yAxis = new ManagedAxis(Axis.VERTICAL); legend = new Legend(); contentPane.add(legend); legend.setVisible(false); stats = new StatisticsBlock(); contentPane.add(stats); stats.setVisible(false); dataArea = new JASHistDataArea(xAxis,yAxis); dataManager = new DefaultDataManager(this,dataArea); contentPane.add(dataArea); changed = false; isInit = false; } DataManager getDataManager() { return dataManager; } // Made public to allow DataArea to be set as a DnD target. public DataArea getDataArea() { return dataArea; } /** * @return true if a call to showProperties can currently be honoured * @see #showProperties() */ public boolean supportsProperties() { return !(dataManager instanceof DefaultDataManager); } /** * Pops up the Properties dialog box for this plot * @see #showProperties(byte) */ public void showProperties() { showProperties(JASHistPropertyDialog.DEFAULT); } /** * Pops up the properties dialog box for this plot with the * specified axis tab initially open * @param axis The axis tab to opened (defined??) * @see #showProperties() */ //TODO: Document argument properly public void showProperties(final byte axis) { new JASHistPropertyDialog((Frame) SwingUtilities.getAncestorOfClass(Frame.class, this), this, axis).show(); } /** * Overrides addNotify in JComponent * Starts listening for changes in data */ public void addNotify() { isInit = true; if (dataManager != null) { if (dataManager.numberOfDataSources() != 0) { Enumeration e = dataManager.getDataSources(); while (e.hasMoreElements()) { JASHistData d = (JASHistData) e.nextElement(); d.restoreNormalizationObserver(); d.show(true); } } if (dataManager instanceof BinnedDataManager) { int nFunc = ((BinnedDataManager) dataManager).numberOfFunctions(); if (nFunc > 0) { Enumeration e = ((BinnedDataManager) dataManager).getFunctions(); while (e.hasMoreElements()) { JASHistData d = (JASHistData) e.nextElement(); d.show(true); } } } dataManager.init(); } super.addNotify(); } /** * Overrides removeNotify in JComponent * Stops listening for changes in data */ public void removeNotify() { isInit = false; if (dataManager != null) { dataManager.setRealized(false); if (dataManager.numberOfDataSources() != 0) { Enumeration e = dataManager.getDataSources(); while (e.hasMoreElements()) { JASHistData d = (JASHistData) e.nextElement(); d.deleteNormalizationObserver(); d.show(false); } } if (dataManager instanceof BinnedDataManager) { int nFunc = ((BinnedDataManager) dataManager).numberOfFunctions(); if (nFunc > 0) { Enumeration e = ((BinnedDataManager) dataManager).getFunctions(); while (e.hasMoreElements()) { JASHistData d = (JASHistData) e.nextElement(); d.show(false); } } } } super.removeNotify(); } /** * Writes the histogram, scatterplot etc that we are displaying as XML. * @param pw A PrintWriter to send the output to * @param snapshot A snapshot of the current data is stored if true, otherwise a reference to the datasource * @see XML How To */ public void writeXML(Writer w,boolean snapshot) { XMLPrintWriter pw = new XMLPrintWriter(w); pw.print(this,snapshot); } /** * Test if user direct user interaction with the plot is allowed * @return True if user interaction is currently allowed * @see #setAllowUserInteraction(boolean) */ public boolean getAllowUserInteraction() { return contentPane.getAllowUserInteraction(); } /** * Controls whether end users are allowed to directly interact with * the plot by way of popup menus or "clicking and dragging". By * default user interaction is allowed. If no * * @param allow True if user interactions are to be allowed. */ public void setAllowUserInteraction(boolean allow) { contentPane.setAllowUserInteraction(allow); setChanged(); } public boolean getAllowPopupMenus() { return contentPane.getAllowPopupMenus(); } public void setAllowPopupMenus(boolean allow) { contentPane.setAllowPopupMenus(allow); setChanged(); } public void setShowStatistics(boolean show) { stats.setVisible(show); contentPane.revalidate(); setChanged(); } public boolean getShowStatistics() { return stats.isVisible(); } /** * Set the color used to paint the background (but not the data area) * @param c The new Color to use, or null to set the background to be transparent * @see #setDataAreaColor(Color) * @see #setForegroundColor(Color) */ public void setBackground(Color c) { contentPane.setBackground(c); setChanged(); } /** * Get the background color. */ public Color getBackground() { if (contentPane.isPaintingBackground()) return contentPane.getBackground(); else return super.getBackground(); } /** * Sets the current foreground color, used by default as the color * for the axis, labels, title, legend etc. By default the foreground * color of the plots container is used * @param c The new foreground color */ public void setForegroundColor(Color c) { super.setForeground(c); setChanged(); } /** * Return the current data area background color * @return The current data area background color * @see #setDataAreaColor(Color) */ public Color getDataAreaColor() { return dataArea.getBackground(); } /** * Set the color used to paint the background of the data area * @param c The new color to be used to paint the data area background, or null`to set the bacground back to the default value * @see #setBackground(Color) * @see #setForeground(Color) */ public void setDataAreaColor(Color c) { dataArea.setBackground(c); setChanged(); } public final static int NONE = PlotComponent.NONE; public final static int BEVEL_IN = PlotComponent.BEVEL_IN; public final static int BEVEL_OUT = PlotComponent.BEVEL_OUT; public final static int ETCHED = PlotComponent.ETCHED; public final static int LINE = PlotComponent.LINE; public final static int SHADOW = PlotComponent.SHADOW; /** * Set the border to place around the data area * @param type One of NONE,BEVEL_IN,BEVEL_OUT,ETCHED,LINE,SHADOW */ public void setDataAreaBorderType(int type) { dataArea.setBorderType(type); dataArea.revalidate(); setChanged(); } /** * Get the current data area border type * @return One of NONE,BEVEL_IN,BEVEL_OUT,ETCHED,LINE,SHADOW,OTHER */ public int getDataAreaBorderType() { return dataArea.getBorderType(); } public void setDataAreaBorder(Border b) { dataArea.setBorder(b); } public Border getDataAreaBorder() { return dataArea.getBorder(); } /** * Gets the X axis * @return The current X axis */ public JASHistAxis getXAxis() { return dataManager.getXAxis(); } /** * Gets the default Y Axis * @return The current default Y Axis * @see #getYAxis(int) */ public JASHistAxis getYAxis() { return dataManager.getYAxis(0); } /** * Gets either Y Axis. * @param index The axis to get, 0 = left (default), 1 = right * @return The requested Axis */ public JASHistAxis getYAxis(int index) { return dataManager.getYAxis(index); } /** * Get an array containing all of the Y Axes */ public JASHistAxis[] getYAxes() { return dataManager.getYAxes(); } final public static int LEGEND_NEVER = 0; final public static int LEGEND_AUTOMATIC = 1; final public static int LEGEND_ALWAYS = 2; /** * Set when the legend will be shown. By default the option is * set to LEGEND_AUTOMATIC, which means that the legend will be shown * whenever there is more than one DataSource attached to the plot. * @param legend One of LEGEND_NEVER,LEGEND_AUTOMATIC,LEGEND_ALWAYS */ public void setShowLegend(int legend) { showLegend = legend; dataManager.showLegend(); } /** * Get the current setting of the showLegend property * @return The current settign of showLegend * @see #setShowLegend(int) */ public int getShowLegend() { return showLegend; } /** * Add a DataSource to the plot. * @param ds The DataSource to add * @throws DataManagerException If the subclass of DataSource is unrecognized or if the new DataSource is incompatible with previously added DataSources. */ public JASHistData addData(DataSource ds) throws DataManagerException { if (ds instanceof Rebinnable1DHistogramData) return add1DData((Rebinnable1DHistogramData) ds); if (ds instanceof XYDataSource ) return addXYData((XYDataSource) ds); if (ds instanceof Rebinnable2DHistogramData) return add2DData((Rebinnable2DHistogramData) ds); if (ds instanceof ScatterPlotSource ) return addScatterData((ScatterPlotSource) ds); if (ds instanceof FunctionData ) return addFunctionData((FunctionData) ds); throw new DataManagerException("Unknown DataSource subclass: "+ds); } /** * Add a Rebinnable1DHistogramData source to the plot * @param ds The data source to be added */ private JASHistData add1DData(Rebinnable1DHistogramData ds) throws DataManagerException { if (dataManager instanceof DefaultDataManager) { int type = ds.getAxisType(); if (type == ds.DOUBLE ) dataManager = new DoubleDataManager(this,dataArea,legend,stats,50); else if (type == ds.INTEGER) dataManager = new IntegerDataManager(this,dataArea,legend,stats,50); else if (type == ds.STRING ) dataManager = new StringDataManager(this,dataArea,legend,stats); else if (type == ds.DATE ) dataManager = new DateDataManager(this,dataArea,legend,stats,50); else throw new DataManagerException("Unsupported axis type"); if (isInit) dataManager.init(); // Only necessary if addNotify already called } JASHistData data = dataManager.add(ds); setChanged(); return data; } /** * Add a Rebinnable1DHistogramData source to the plot * @param ds The data source to be added */ private JASHistData addXYData(XYDataSource ds) throws DataManagerException { if (dataManager instanceof DefaultDataManager) { int type = ds.getAxisType(); if (type == ds.DOUBLE ) dataManager = new DoubleDataManager(this,dataArea,legend,stats,50); else if (type == ds.INTEGER) dataManager = new IntegerDataManager(this,dataArea,legend,stats,50); else if (type == ds.DATE ) dataManager = new DateDataManager(this,dataArea,legend,stats,50); else throw new DataManagerException("Unsupported axis type"); if (isInit) dataManager.init(); // Only necessary if addNotify already called } JASHistData data = dataManager.add(ds); setChanged(); return data; } /** * Add a ScatterPlotSource to the plot * @param ds The data source to be added */ private JASHistData addScatterData(ScatterPlotSource ds) throws DataManagerException { if (dataManager instanceof DefaultDataManager) { int typeX = ds.getXAxisType(); int typeY = ds.getYAxisType(); if (typeY != ds.DOUBLE) throw new DataManagerException("Scatterplot Y Axis must be of type DOUBLE"); if (typeX == ds.DOUBLE) dataManager = new DoubleScatterDataManager(this, dataArea, legend, stats); else if (typeX == ds.DATE ) dataManager = new DateScatterDataManager(this,dataArea, legend, stats); if (isInit) dataManager.init(); // Only necessary if addNotify already called } final JASHistData data = dataManager.add(ds); setChanged(); return data; } /** * Add a 2D Histogram data source to the histogram * @param ds The data source to be added */ private JASHistData add2DData(Rebinnable2DHistogramData ds) throws DataManagerException { if (dataManager instanceof DefaultDataManager) { int typeX = ds.getXAxisType(); int typeY = ds.getYAxisType(); if (typeX == ds.DOUBLE) dataManager = new DoubleScatterDataManager(this, dataArea, legend, stats); else if (typeX == ds.DATE ) dataManager = new DateScatterDataManager(this,dataArea, legend, stats); else throw new DataManagerException("Unsupported X Axis type for ScatterPlot"); if (isInit) dataManager.init(); // Only necessary if addNotify already called } final JASHistData data = dataManager.add(ds); setChanged(); return data; } /** * Add a function to be overlayed on a 1D histogram * @param ds The function to be added */ private JASHistData addFunctionData(FunctionData ds) throws DataManagerException { if ( dataManager instanceof SupportsFunctions ) { JASHistData data = ((SupportsFunctions) dataManager).addFunction((Basic1DFunction) ds); setChanged(); return data; } else throw new UnsupportedOperationException("Cannot add function."); } int numberOfDataSets() // used by property dialog { return dataManager.numberOfDataSources(); } int numberOfFunctions() { if (dataManager instanceof SupportsFunctions) return ((SupportsFunctions) dataManager).numberOfFunctions(); return 0; } /** * Get the set of data sources currently attached to the plot. * Note that despite the name of this routine it does not return * an Enumeration of DataSources, but rather an Enumeration of * JASHistData objects, from which the DataSource can be obtained, * for example: *
         * Enumeration  e = hPlot.getDataSources();
         * while (e.hasMoreElements())
         * {
         *    JASHistData data = (JASHistData) e.nextElement();
         *    DataSource source = data.getDataSource();
         * }
         * 
* @return An Enumeration of the JASHistData objects * @see JASHistData * @see JASHistData#getDataSource() */ public Enumeration getDataSources() { return dataManager.getDataSources(); } /** * Get the number of data sources attached to the plot */ public int getNumberOfDataSources() { return dataManager.numberOfDataSources(); } /** * Get the set of Functions currently attached to the plot * @return An Enumeration of the Functions, or null if the current DataSources do not support functions */ public Enumeration get1DFunctions() { if (dataManager instanceof SupportsFunctions) return ((SupportsFunctions) dataManager).getFunctions(); return null; } /** * Removes and detaches all data from the plot, but doesn't set up * the plot for further use. Call this method if you aren't going to * be using the plot object any more. Call removeAllData() * to remove all data and set up the plot for further use. */ public void destroy() { dataManager.destroy(); contentPane.removeAll(); // should detach itself as a listener to all of its children } /** * Removes and detaches all data and sets up the plot for further use. * The method destroy() is less expensive and * should be used if the plot will not be used any more. */ public void removeAllData() { dataManager.destroy(); // this call detached data, now we set up the plot for further use dataManager = new DefaultDataManager(this,dataArea); setChanged(); } private void resetAxis(JASHistAxis a) { a.setRangeAutomatic(true); a.setAllowSuppressedZero(true); a.setLogarithmic(false); setChanged(); } /** * Fills the appropriate Function menu items into a user * provided menu. This routine can be used to make a function * fitting menu available to an external application without having * to rewrite a bunch of code already contained in JASHist * * @param menu The menu to which the items will be added */ public void fillFunctionMenu(JMenu menu) { if (dataManager instanceof SupportsFunctions) { ((SupportsFunctions) dataManager).fillFunctionMenu(menu); menu.setEnabled(true); } else menu.setEnabled(false); } /** * Fills the appriate Slice/Projection menu items into a user * provided menu. This routine can be used to make a function * fitting menu available to an external application without having * to rewrite a bunch of code already contained in JASHist * * @param menu The menu to which the items will be added */ public void fillSliceMenu(JMenu menu) { if (dataManager instanceof TwoDDataManager) { ((TwoDDataManager) dataManager).fillSliceMenu(menu); menu.setEnabled(true); } else menu.setEnabled(false); } /** * Get the text of the title. * @return A String containing the text of the title, or null if there is no title at present * @see #getTitleObject() */ public String getTitle() { if (title == null) return null; return title.getText(); } /** * Actually get the Title object. * @return The current title, or null if there is no title */ public Title getTitleObject() { return title; } /** * Actually set the Title object. * @param newTitle The new title object */ public void setTitleObject(Title newTitle) { if (title != null) { contentPane.remove(title); } title = newTitle; contentPane.add(title); contentPane.invalidate(); setChanged(); } /** * Set the text of the title * @param newValue pass null to remove the title */ public void setTitle(String newValue) { if (newValue != null && newValue.length() != 0) { if (title == null) { title = new Title(newValue); contentPane.add(title); contentPane.invalidate(); validate(); } else title.setText(newValue); setChanged(); } else if (title != null) { contentPane.remove(title); contentPane.invalidate(); validate(); title = null; } } public boolean isChanged() { return changed; } private void setChanged() { changed = true; validate(); repaint(); // does this cause double repaint if the component was invalidated? } /** * Add a FitListener that will receive notifications about the * status of fits being performed by the plot * @param fitListener The FitListener to add */ //TODO: Dont we need a removeFitListener? public static void addFitListener(final FitListener fitListener) { if (fitListeners == null) fitListeners = new Vector(1, 1); fitListeners.addElement(fitListener); } static void notifyFitListeners(final Fitter fitter) { if (fitListeners != null) { final Enumeration e = fitListeners.elements(); while (e.hasMoreElements()) ((FitListener) e.nextElement()).fitStarted(fitter); } } public void mouseEventNotify(final MouseEvent e) { processMouseEvent(e); } public void deselected() { contentPane.deselected(); } public StatisticsBlock getStats() { return stats; } public void setStats(StatisticsBlock newStats) { stats = newStats; } public Legend getLegend() { return legend; } public void setLegend(Legend newLegend) { legend = newLegend; } /** * Pops up a dialog asking the user to choose a file/format to save the plot. */ public void saveAs() { //types.add(new SaveAsPluginAdapter(new org.freehep.graphics2d.exportchooser.EPS2DExportFileType())); //types.add(new SaveAsPluginAdapter(new org.freehep.graphics2d.exportchooser.PDF2DExportFileType())); //types.add(new SaveAsPluginAdapter(new org.freehep.graphics2d.exportchooser.SVG2DExportFileType())); SaveAsDialog dlg = new SaveAsDialog(this); dlg.pack(); dlg.doModal(); } /** * Copies the plot to the clipboard */ public void copy() { VectorGraphicsTransferable t = new VectorGraphicsTransferable(this); getToolkit().getSystemClipboard().setContents(t,t); } static private Vector fitListeners; private Title title; // The plot title private StatisticsBlock stats; private boolean isInit = false; private boolean changed = false; private int showLegend = JASHist.LEGEND_AUTOMATIC; private DataArea dataArea; private DataManager dataManager; private Legend legend; private PlotPanel contentPane = new JASHistPlotPanel(); static final long serialVersionUID = 4433180397297758071L; final private class JASHistPlotPanel extends PlotPanel implements HasPopupItems { void showWarning(Component parent, String text) { javax.swing.JOptionPane.showMessageDialog(parent, text, "Warning: Deprecated", javax.swing.JOptionPane.WARNING_MESSAGE);; } public void print(Graphics g) { jas.plot.PrintHelper ph = jas.plot.PrintHelper.instance(); Thread t = ph.printingThread(); if ( ! ph.isPrinting() ) ph.setPrintingThread(Thread.currentThread()); super.print(g); ph.setPrintingThread(t); } public void modifyPopupMenu(final JPopupMenu menu, final Component source) { if (menu.getComponentCount() > 0) menu.addSeparator(); JCheckBoxMenuItem dl = new JCheckBoxMenuItem("Default Plot Layout") { final protected void fireActionPerformed(final ActionEvent e) { contentPane.restoreDefaultLayout(); } }; boolean def = contentPane.hasDefaultLayout(); dl.setSelected(def); dl.setEnabled(!def); menu.add(dl); menu.add(new JMenuItem("Plot Properties...") { final protected void fireActionPerformed(final ActionEvent e) { String text = "\"Plot Properties...\" is deprecated,\n"; text += "Please try using \"Edit AIDA Style for\" instead"; showWarning(this, text); showProperties(); } }); menu.add(new JMenuItem("Copy Plot to Clipboard...") { final protected void fireActionPerformed(final ActionEvent e) { copy(); } }); menu.add(new JMenuItem("Save Plot As...") { final protected void fireActionPerformed(final ActionEvent e) { saveAs(); } }); menu.add(new JMenuItem("Print Plot...") { final protected void fireActionPerformed(final ActionEvent e) { try { PrintHelper ph = PrintHelper.instance(); ph.printTarget(JASHistPlotPanel.this); } catch (Exception x) { x.printStackTrace(); // TODO: Something better } } }); } } private final class SetTitleMenuItem extends JCheckBoxMenuItem { SetTitleMenuItem() { super("Show Title"); setSelected(title != null && title.isVisible()); } protected void fireActionPerformed(final ActionEvent e) { if (title == null || title.getText().length() == 0) { setTitle("Title"); title.edit(); } else { title.setVisible(!title.isVisible()); } } } private class JASHistDataArea extends DataArea { JASHistDataArea(Axis xAxis, Axis yAxis) { super(xAxis,yAxis); } public void modifyPopupMenu(final JPopupMenu menu, final Component source) { if (source == this || !(source instanceof HasPopupItems)) // Not the axis for example { // Begin the main histogram popup menu, with bunches of Show.... /* menu.add(new SetTitleMenuItem()); JCheckBoxMenuItem ss = new JCheckBoxMenuItem("Show Statistics") { public void fireActionPerformed(ActionEvent e) { setShowStatistics(!getShowStatistics()); } }; ss.setSelected(getShowStatistics()); menu.add(ss); */ dataManager.modifyPopupMenu(menu, source); super.modifyPopupMenu(menu,source); } } } } class JASEvent extends AWTEvent { JASEvent(Component target) { super(target,AWTEvent.RESERVED_ID_MAX+5000); } } src/main/java/jas/hist/FitUpdate.java0000644000175000017500000000104711325547132020201 0ustar giovannigiovannipackage jas.hist; public class FitUpdate { FitUpdate(int state) { this.state = state; this.percent = state == Fitter.FIT ? 100 : 0; } FitUpdate(int state, int percent) { this.state = state; this.percent = percent; } FitUpdate(int state, FitFailed x) { this.state = state; this.percent = 0; this.reason = x; } public int getState() { return state; } public int getPercent() { return percent; } public FitFailed getReason() { return reason; } private int state; private int percent; private FitFailed reason; } src/main/java/jas/hist/DoubleScatterDataManager.java0000644000175000017500000000232611325547132023142 0ustar giovannigiovannipackage jas.hist; import jas.plot.DataArea; import jas.plot.DoubleAxis; import jas.plot.Legend; final class DoubleScatterDataManager extends ScatterDataManager { DoubleScatterDataManager(JASHist plot, final DataArea da, final Legend l, StatisticsBlock stats) { super(plot, da, l, stats); // Configure the Axes if (xm.getType() instanceof DoubleAxis) xAxisType = (DoubleAxis) xm.getType(); else { xAxisType = new DoubleAxis(); xm.setType(xAxisType); } DoubleAxis yAxisType; if (ym[0].getType() instanceof DoubleAxis) yAxisType = (DoubleAxis) ym[0].getType(); else { yAxisType = new DoubleAxis(); ym[0].setType(yAxisType); } xm.setDataManager(this, false, xAxisType); ym[0].setDataManager(this, false, yAxisType); } final protected void calcXMinMax(double x1, double x2) { final double oldXMin = xAxisType.getPlotMin(); final double oldXMax = xAxisType.getPlotMax(); // Only update the axis if the new range is outside of the old range, // or occupies less than 75% of the old range if (x1 < oldXMin || x2 > oldXMax || (x2 - x1) / (oldXMax - oldXMin) < 0.75) { xAxisType.setMin(x1); xAxisType.setMax(x2); xm.invalidate(); } } private DoubleAxis xAxisType; } src/main/java/jas/hist/DataRenderer.java0000644000175000017500000000157011325547132020655 0ustar giovannigiovannipackage jas.hist; import java.awt.Color; import java.awt.Component; import javax.swing.DefaultListCellRenderer; import javax.swing.JList; final class DataRenderer extends DefaultListCellRenderer { public Component getListCellRendererComponent( JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { String s; if (value instanceof Rebinnable1DHistogramData) { s = ((Rebinnable1DHistogramData) value).getTitle(); } else s = value.toString(); return super.getListCellRendererComponent(list,s,index,isSelected,cellHasFocus); } static DataRenderer createRenderer() { if (singleton == null) singleton = new DataRenderer(); return singleton; } private static DataRenderer singleton = null; private Color f = getForeground(); private Color b = getBackground(); } src/main/java/jas/hist/DoubleDataManager.java0000644000175000017500000000311211325547132021606 0ustar giovannigiovannipackage jas.hist; import jas.plot.DataArea; import jas.plot.DoubleAxis; import jas.plot.Legend; import java.io.IOException; import java.io.ObjectInputStream; class DoubleDataManager extends BinnedDataManager { DoubleDataManager(JASHist plot, DataArea da, Legend l, StatisticsBlock stats, int bins) { super(plot,da,l,stats,bins); // Configure the Axes xAxis = new DoubleAxis(); DoubleAxis yAxis = new DoubleAxis(); yAxis.setUseSuggestedRange(true); xm.setDataManager(this,true, xAxis); ym[0].setDataManager(this,false,yAxis); new DoubleAxisListener(xm); xm.setBins(bins); } private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { in.defaultReadObject(); new DoubleAxisListener(xm); } final JASHistData add(DataSource data) { if (data instanceof Rebinnable1DHistogramData) { Rebinnable1DHistogramData d = (Rebinnable1DHistogramData) data; // We only support adding items with continuous axes if (d.getAxisType() != d.DOUBLE) throw new DataManagerException("Incompatible data type for axis"); } else { XYDataSource d = (XYDataSource) data; if (d.getAxisType() != d.DOUBLE) throw new DataManagerException("Incompatible data type for axis"); } return super.add(data); } final protected void calcMinMaxBins(double x1, double x2) { double oldXMin = xAxis.getPlotMin(); double oldXMax = xAxis.getPlotMax(); if (x1 != oldXMin || x2 != oldXMax) { xAxis.setMin(x1); xAxis.setMax(x2); xm.invalidate(); } } private DoubleAxis xAxis; } src/main/java/jas/hist/FitFailed.java0000644000175000017500000000015611325547132020143 0ustar giovannigiovannipackage jas.hist; public class FitFailed extends Exception { public FitFailed(String s) { super(s); } } src/main/java/jas/hist/DateTransformationConverter.java0000644000175000017500000000116611325547132024012 0ustar giovannigiovannipackage jas.hist; import jas.plot.DateCoordinateTransformation; import jas.plot.DoubleCoordinateTransformation; class DateTransformationConverter implements DoubleCoordinateTransformation { private DateCoordinateTransformation source; DateTransformationConverter(DateCoordinateTransformation source) { this.source = source; } public double convert(double d) { return source.convert((long) (d*1000)); } public double unConvert(double i) { return source.map(i)/1000.; } public double getPlotMin() { return source.getAxisMin()/1000.; } public double getPlotMax() { return source.getAxisMax()/1000.; } } src/main/java/jas/hist/Rebinnable1DVariableHistogramData.java0000644000175000017500000000070111325547132024654 0ustar giovannigiovannipackage jas.hist; /** * Extends Rebinnable1DHistogramData interface for the case of Histogram1D * with variable bin width * Example: edges = (0.2, 1.0, 5.0) yields an axis with 2 in-range bins * [0.2, 1.0), [1.0, 5.0) and 2 extra bins [-inf, 0.2), [5.0, +inf]. * @see Rebinnable1DHistogramData */ public interface Rebinnable1DVariableHistogramData extends Rebinnable1DHistogramData { double[] getBinEdges(); } src/main/java/jas/hist/FitterFactoryError.java0000644000175000017500000000017111325547132022110 0ustar giovannigiovannipackage jas.hist; class FitterFactoryError extends Exception { public FitterFactoryError(String s) { super(s); } } src/main/java/jas/hist/JASHist2DHistogramStyle.java0000644000175000017500000001446211325547132022653 0ustar giovannigiovannipackage jas.hist; import java.awt.Color; import java.io.IOException; import java.io.Serializable; public class JASHist2DHistogramStyle extends JASHistStyle implements Serializable { final public static int STYLE_BOX = 0; final public static int STYLE_ELLIPSE = 1; final public static int STYLE_COLORMAP = 2; final public static int STYLE_3DLEGOPLOT = 3; final public static int STYLE_3DSURFACEPLOT = 4; final public static int COLORMAP_WARM = 0; final public static int COLORMAP_COOL = 1; final public static int COLORMAP_THERMAL = 2; final public static int COLORMAP_RAINBOW = 3; final public static int COLORMAP_GRAYSCALE = 4; final public static int COLORMAP_USERDEFINED = 5; static final Color[] lineColors = { Color.blue, Color.red, Color.darkGray, new Color(0,145,0) }; static final Color[] overflowColors = new Color[lineColors.length]; static { for (int i=0; i *
java.lang.Double
jas.util.ScientificFormat
*
jas.util.DoubleWithError
jas.util.ScientificFormat
* * * If the method returns null, then the getStatistic() method from * the subclass will be called instead. This simplifies the use of * simple floating point statistics (no need to create a Double * object for each one). * @param name The name of the statistic to return * @returns The statistic, or null indicating getStatistic(name) should be used. * @see jas.util.ScientificFormat * @see jas.util.DoubleWithError */ Object getExtendedStatistic(String name); } src/main/java/jas/hist/HasStyle.java0000644000175000017500000000120011325547132020037 0ustar giovannigiovannipackage jas.hist; /** * An interface that can be implemented by any DataSource that wants to have control * of the style used to display the data. */ public interface HasStyle { /** * This method is called by the plot to determine what style to be used for a plot. * It is the programmers responsibility to return the correct subclass of JASHistStyle * corresponding to the type of data being implemented by the DataSource. * * @return The style to be used, or null to use the default style. * @see JASHist1DHistogramStyle * @see JASHist2DHistogramStyle * @see JASHistScatterPlotStyle */ JASHistStyle getStyle(); } src/main/java/jas/hist/JASHist2DScatterData.java0000644000175000017500000001613211325547132022070 0ustar giovannigiovannipackage jas.hist; import jas.plot.Overlay; import jas.util.xml.HasXMLRepresentation; import java.util.Observable; class JASHist2DScatterData extends JASHist2DHistogramData { JASHist2DScatterData(final DataManager dm, final HasScatterPlotData ds) { super(dm,ds); dataSource = ds; } JASHistStyle createStyle() { return new JASHistScatterPlotStyle(); } boolean hasScatterPlotData() { return dataSource.hasScatterPlotData(); } public void setStyle(final JASHistStyle style) { if (!(style instanceof JASHistScatterPlotStyle)) throw new IllegalArgumentException("Style "+style.getClass()+" is not subclass of JASHistScatterPlotStyle"); if (this.style != null) this.style.deleteObserver(this); this.style = (JASHistScatterPlotStyle) style; this.style.addObserver(this); } Overlay createOverlay() { return new ScatterOverlay(this); } public void update(Observable o, Object arg) { // Dragons: Likely to be called by different thread if (o == dataSource) { parent.update((HistogramUpdate) arg, this); } else if (o == style) { parent.styleUpdate(this); } } void restartImage(final boolean newEnumNeeded) { if (overlay instanceof ScatterOverlay) { ((ScatterOverlay) overlay).restartImage(newEnumNeeded); } } void continueImage() { if (overlay instanceof ScatterOverlay) { ((ScatterOverlay) overlay).continueImage(); } } public JASHistStyle getStyle() { return style; } HasScatterPlotData dataSource; boolean dataChanged, resetSent, onNewAxis; // the data manager uses these flags // static final long serialVersionUID = 0/* ?? */; protected void calcZLimits() { if (((JASHistScatterPlotStyle) style).getDisplayAsScatterPlot()) return; else super.calcZLimits(); } public void writeAsXML(XMLPrintWriter pw, boolean snapshot) { String theXAxisType = pw.convertAxisTypeToString(dataSource.getXAxisType()); String theYAxisType = pw.convertAxisTypeToString(dataSource.getYAxisType()); pw.setAttribute("type","scatter2d"); pw.openTag("data2d"); int xBins = dataSource.getXBins(); double xLow = dataSource.getXMin(); double xHigh = dataSource.getXMax(); int yBins = dataSource.getYBins(); double yLow = dataSource.getYMin(); double yHigh = dataSource.getYMax(); if (snapshot) { double[][][] result = dataSource.rebin(xBins,xLow,xHigh,yBins,yLow,yHigh,true,hurry, style.getShowOverflow()); if (result == null) result = new double[1][xBins][yBins]; double[][] data = result[0]; pw.setAttribute("title",getTitle()); pw.setAttribute("dimensions","2"); pw.openTag("points"); final double[] d = new double[2]; if (dataSource.hasScatterPlotData()) { ScatterEnumeration se = dataSource.startEnumeration(); while (se.getNextPoint(d)) { pw.println(d[0] + "," + d[1]); } } pw.closeTag(); //output the x,y axis attributes pw.printPointDataAxisAttributes("x",theXAxisType);//5 string args pw.printPointDataAxisAttributes("y",theYAxisType); if (dataSource instanceof HasStatistics) { Statistics stats = ((HasStatistics) dataSource).getStatistics(); if (stats != null) { pw.openTag("statistics"); String[] names = stats.getStatisticNames(); for (int i=0; i"); String[] labels = getAxisLabels(); for (int i=0; i < labels.length; i++) { jas.hist.JASHistXMLUtils.writeTabs(pw, (indentLevel + 2)); pw.println(""); } jas.hist.JASHistXMLUtils.writeTabs(pw, (indentLevel + 1)); pw.println(""); } */ String histStyleName = JASHist2DHistogramStyle.getHistStyleName(style.getHistStyle()); pw.setAttribute("histStyle",histStyleName); if (histStyleName.equals("STYLE_COLORMAP")) { pw.setAttribute("colorMapScheme", JASHist2DHistogramStyle.getColorMapSchemeName(style.getColorMapScheme())); } pw.setAttribute("shapeColor", jas.util.ColorConverter.colorToString(style.getShapeColor())); pw.setAttribute("overflowBinColor", jas.util.ColorConverter.colorToString(style.getOverflowBinColor())); pw.setAttribute("startDataColor", jas.util.ColorConverter.colorToString(style.getStartDataColor())); pw.setAttribute("endDataColor", jas.util.ColorConverter.colorToString(style.getEndDataColor())); pw.setAttribute("showOverflow",style.getShowOverflow()); pw.setAttribute("showPlot",style.getShowPlot()); pw.setAttribute("displayAsScatterPlot", ((JASHistScatterPlotStyle) style).getDisplayAsScatterPlot()); pw.setAttribute("dataPointSize" , ((JASHistScatterPlotStyle) style).getDataPointSize()); pw.setAttribute("dataPointStyle" , ((JASHistScatterPlotStyle) style).getDataPointStyle()); pw.setAttribute("dataPointColor",jas.util.ColorConverter.colorToString(((JASHistScatterPlotStyle) style).getDataPointColor())); pw.printTag("style2d"); pw.closeTag(); } } src/main/java/jas/hist/JASHistPropFunctionStyle.java0000644000175000017500000000202211325547132023143 0ustar giovannigiovannipackage jas.hist; import jas.util.ColorChooser; import jas.util.PropertyBinding; import jas.util.PropertyPage; import java.awt.FlowLayout; import javax.swing.JComboBox; import javax.swing.JLabel; import javax.swing.JSpinner; import javax.swing.SpinnerNumberModel; final class JASHistPropFunctionStyle extends PropertyPage { JASHistPropFunctionStyle() { setLayout(new FlowLayout(FlowLayout.LEFT,5,0)); add(new JLabel("Color")); ColorChooser color = new ColorChooser(); add(color); final JComboBox lineStyle = new JComboBox(); lineStyle.addItem("Solid"); lineStyle.addItem("Dotted"); lineStyle.addItem("Dashed"); lineStyle.addItem("DotDashed"); add(lineStyle); final JSpinner lineWidth = new JSpinner(new SpinnerNumberModel(1,0.0,5.5,0.5)); add(lineWidth); addBinding(new PropertyBinding(color,"LineColor")); addBinding(new PropertyBinding(lineStyle,"LineStyle")); addBinding(new PropertyBinding(lineWidth,"LineWidth")); } } src/main/java/jas/hist/JASHistAxis.java0000644000175000017500000000424311325547132020407 0ustar giovannigiovannipackage jas.hist; import jas.plot.EditableLabel; import java.awt.Color; import java.awt.Font; public interface JASHistAxis { public static final int LEFT = 1; public static final int RIGHT = 2; public static final int DOUBLE = Rebinnable1DHistogramData.DOUBLE; public static final int STRING = Rebinnable1DHistogramData.STRING; public static final int DATE = Rebinnable1DHistogramData.DATE; public boolean isVertical(); public boolean isLogarithmic(); public void setLogarithmic(boolean value); public boolean isShowing(); public void setShowing(boolean value); public String getLabel(); public void setLabel(String s); public EditableLabel getLabelObject(); public void setLabelObject(EditableLabel p_newLabel); public double getMin(); public void setMin(double d); public double getMax(); public void setMax(double d); public void setRange(double min, double max); public Object getMinObject(); public Object getMaxObject(); public void setMinObject(Object value); public void setMaxObject(Object value); public boolean getRangeAutomatic(); public void setRangeAutomatic(boolean b); public boolean getAllowSuppressedZero(); public void setAllowSuppressedZero(boolean b); public boolean isBinned(); public boolean isFixed(); public int getBins(); public void setBins(int value); public double getBinWidth(); public void setBinWidth(double value); public int getLabelPosition(); public void setLabelPosition(int pos); public int getPosition(); public void setPosition(int value); public int getAxisType(); public void setAxisType(int value); public boolean getShowOverflows(); public void setShowOverflows(boolean value); public Font getFont(); /** * The font used for the axis values */ public void setFont(Font value); public Color getAxisColor(); public float getAxisWidth(); public void setAxisWidth(float value); /** * The color used for the axis itself (and markers) * By default the foreground color of the JASHist is used */ public void setAxisColor(Color c); public Color getTextColor(); /** * The color used for the axis values. * By default the foreground color of the JASHist is used */ public void setTextColor(Color c); } src/main/java/jas/hist/JASHist1DFunctionStyle.java0000644000175000017500000000272311325547132022477 0ustar giovannigiovannipackage jas.hist; import java.awt.Color; import java.io.Externalizable; import java.io.IOException; import java.io.ObjectInput; import java.io.ObjectOutput; public class JASHist1DFunctionStyle extends JASHistStyle implements Externalizable { static final Color[] lineColors = { Color.blue, Color.red, Color.darkGray,Color.magenta, Color.yellow, Color.green, Color.orange, Color.cyan, }; static int n = 0; static final long serialVersionUID = -3911970150059917139L; public JASHist1DFunctionStyle() { lineColor = lineColors[n]; n++; if (n == lineColors.length) n = 0; } public void writeExternal(ObjectOutput p) throws IOException { p.writeObject(lineColor); } public void readExternal(ObjectInput p) throws IOException, ClassNotFoundException { lineColor = (Color) p.readObject(); } public Color getLineColor() { return lineColor; } public void setLineColor(Color nNewValue) { lineColor = nNewValue; changeNotify(); } public int getLineStyle() { return lineStyle; } public void setLineStyle(int style) { lineStyle = style; changeNotify(); } public float getLineWidth() { return lineWidth != 0 ? lineWidth : (float)0.0001; } public void setLineWidth(float width) { lineWidth = width; changeNotify(); } private Color lineColor; private float lineWidth; private int lineStyle; }src/main/java/jas/hist/JASHistUtil.java0000644000175000017500000000261511325547132020421 0ustar giovannigiovannipackage jas.hist; public class JASHistUtil { /** * Round number down (closer to Negative Infinity): * "order" defines which significant digit is rounded, order >= 0 * * roundDown(234.5, 0) -> 200.0 * roundDown(234.5, 1) -> 230.0 * roundDown(234.5, 2) -> 234.0 * */ public static double roundDown(double x, int order) { if (Double.isNaN(x) || Double.isInfinite(x) || x == Double.MIN_VALUE) return x; else if (x < 0) { return (-1.)*roundUp(Math.abs(x), order); } else if (x == 0) return x; double mant = Math.floor(Math.log(x)/Math.log(10.)); double factor = Math.pow(10., (order-mant)); double tmp = Math.floor(x*factor)/factor; return tmp; } /** * Round number up (closer to Positive Infinity), * "order" defines which significant digit is rounded, order >= 0 * * roundUp(234.5, 0) -> 300.0 * roundUp(234.5, 1) -> 240.0 * roundUp(234.5, 2) -> 235.0 * */ public static double roundUp(double x, int order) { if (Double.isNaN(x) || Double.isInfinite(x) || x == Double.MAX_VALUE) return x; else if (x < 0) { return (-1.)*roundDown(Math.abs(x), order); } else if (x == 0) return x; double mant = Math.floor(Math.log(x)/Math.log(10.)); double factor = Math.pow(10., (order-mant)); double tmp = Math.ceil(x*factor)/factor; return tmp; } } src/main/java/jas/hist/StatisticsBlock.java0000644000175000017500000003374311325547132021431 0ustar giovannigiovannipackage jas.hist; import jas.plot.TextBlock; import jas.util.DoubleWithError; import jas.util.ScientificFormat; import java.awt.Component; import java.awt.Frame; import java.awt.event.ActionEvent; import java.text.Format; import java.util.Enumeration; import java.util.Hashtable; import java.util.Vector; import javax.swing.JMenuItem; import javax.swing.JPopupMenu; import javax.swing.SwingUtilities; /** * The main class used to display and format statistics. * When a user selects showStatistics from the plots popupmenu, a statistics text block * is displayed showing each displayed plots' statistics (Vector stats) and name. The statistics block * requires a number formatting method to be set (setFormat), the default method is * implemented by jas.util.ScientificFormat. */ public class StatisticsBlock extends TextBlock { public StatisticsBlock() { this(new ScientificFormat()); } public StatisticsBlock(Format g) { super("Statistics"); //set default format types initializeDefaultFormats(g); setFormat(g); } /** * Calculates and returns the total number of lines to be displayed in the statistics block, * including a draw line seperator, plot title (if available) and formatted * statistics for each data set displayed in the plot area. */ public int getNLines() { NothingToShow =false; if (stats.isEmpty()) return 1; int n = 0; for (int i=0; i1 && s.length>0)) { addline = new String[s.length+2]; addline[0] = "\n"; addline[1] = "addplottitle"; for(int i=0;i0) { addline = new String[s.length+1]; addline[0] = "\n"; for(int i=0;i0)) { splitstringalign=a; }else throw new IllegalArgumentException("Integer splitstringalign must be set to 1,2 or 3"); } /**Sets the (int) showtitles to one of three values:SHOWTITLES_ALWAYS, * SHOWTITLES_NEVER, SHOWTITLES_AUTOMATIC. The value controls when a plot title is * displayed in the stat block. If showtitles = SHOWTITLES_AUTOMATIC then titles will * be displayed if there is more than one plot displayed. */ public void setShowTitles(int settitles) { if((settitles<4) && (settitles >0)) { showtitles = settitles; }else throw new IllegalArgumentException("Integer showtitles must be set to 1,2 or 3"); } /**Returns the (int) showtitles which has three values:SHOWTITLES_ALWAYS, * SHOWTITLES_NEVER, SHOWTITLES_AUTOMATIC. The value controls when a plot title is * displayed in the stat block. If showtitles = SHOWTITLES_AUTOMATIC then titles will * be displayed if there is more than one plot displayed. */ public int getShowTitles() { return showtitles; } public void modifyPopupMenu(final JPopupMenu menu, final Component source) { if (menu.getComponentCount() > 0) menu.addSeparator(); statpropertiesitem = new JMenuItem(getPrefix()+" Properties...") { protected void fireActionPerformed( final ActionEvent e) { statwin = new StatsWindow(StatisticsBlock.this); final Frame frame = (Frame) SwingUtilities.getAncestorOfClass(Frame.class, this); statwin.showStatsWindow(); } }; menu.add(statpropertiesitem); super.modifyPopupMenu(menu,source); } private boolean NothingToShow; private Format f; private Hashtable formats = new Hashtable(); private StatsWindow statwin; private Vector stats = new Vector(); private String[] selectedentries; private String[] listnames; private int showtitles = SHOWTITLES_AUTOMATIC; private int splitstringalign=RIGHTALIGNSPLIT; private String line; private JMenuItem statpropertiesitem; private boolean alwaysall=true; final public static int SHOWTITLES_ALWAYS = 1; final public static int SHOWTITLES_NEVER = 2; final public static int SHOWTITLES_AUTOMATIC = 3; final public static int LEFTALIGNSPLIT = 1; final public static int RIGHTALIGNSPLIT = 2; final public static int NOALIGNSPLIT = 3; } src/main/java/jas/hist/FunctionRegistry.java0000644000175000017500000001713011325547132021632 0ustar giovannigiovannipackage jas.hist; import jas.util.JASDialog; import jas.util.JASIcon; import jas.util.JASState; import jas.util.NestedRuntimeException; import jas.util.ObjectFactory; import jas.util.ObjectFactoryException; import java.awt.Component; import java.awt.Frame; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.util.Enumeration; import java.util.Vector; import javax.swing.DefaultListCellRenderer; import javax.swing.Icon; import javax.swing.JList; /** * * A class which maintains a list of functions which can be overlayed * * on a plot. * */ public class FunctionRegistry { private FunctionRegistry() { } /** * Get the (unique) instance of FunctionRegistry */ static public FunctionRegistry instance() { return theFunctionRegistry; } /** * Register a function given its class and name * @param c The class of the function * @param name The name of the function */ public void registerFunction(Class c, String name) { registerFunction(createFunctionFactory(c,name)); } /** * Create a default function factory from a class and a name * @param c The class of the function * @param name The name of the function * @return The function factory */ public FunctionFactory createFunctionFactory(Class c, String name) { try { return new DefaultFunctionFactory(c,name); } catch (FunctionFactoryError e) { // convert the error to a runtime error throw new NestedRuntimeException(e); } } /** * Add a function by specifing a FunctionFactory */ public void registerFunction(FunctionFactory f) { m_functions.addElement(f); } /** * Remove a function factory from the list */ public void removeFunctionFactory(FunctionFactory f) { m_functions.removeElement(f); } /** * Clear the list */ public void removeAllFunctions() { m_functions.removeAllElements(); } /** * Get an enumeration of all the FunctionFactories in the registry */ public Enumeration elements() { return m_functions.elements(); } /** * Get the size of the registry */ public int size() { return m_functions.size(); } public FunctionFactory find(String name) { Enumeration e = m_functions.elements(); while (e.hasMoreElements()) { FunctionFactory ff = (FunctionFactory) e.nextElement(); if (ff.getFunctionName().equals(name)) return ff; } return null; } /** * Replace the contents of the list * @param e An enumeration of function factories */ public void setContents(Vector v) { m_functions = v; } FunctionFactory chooseFunction(Frame f) { // These lines need to be excised in applet version ChooseFunctionDialog dlg = new ChooseFunctionDialog(f); if (dlg.doModal()) { return dlg.getSelectedFunction(); } return null; } private Vector m_functions = new Vector(); private static FunctionRegistry theFunctionRegistry = new FunctionRegistry(); private class ChooseFunctionDialog extends JASDialog implements ItemListener, ActionListener { ChooseFunctionDialog(Frame f) { super(f,"Choose Function..."); m_list = new javax.swing.JList(m_functions); m_list.setCellRenderer(new FunctionListCellRenderer()); getContentPane().add("Center",m_list); pack(); } public void itemStateChanged(ItemEvent evt) { callEnable(); } public void actionPerformed(ActionEvent evt) { onOK(); } public void enableOK(JASState state) { //state.setEnabled(m_list.getSelectedValue()!=null); } public void onOK() { m_selection = (FunctionFactory) m_list.getSelectedValue(); super.onOK(); } public FunctionFactory getSelectedFunction() { return m_selection; } } private FunctionFactory m_selection; private javax.swing.JList m_list; } class DefaultFunctionFactory extends ObjectFactory implements FunctionFactory { DefaultFunctionFactory(Class c, String name) throws FunctionFactoryError { super(c); this.name = name; // Class must be a subclass of Basic1DFunction if (!inheritsFrom(Basic1DFunction.class)) throw new FunctionFactoryError("Function "+name+" does not inherit from Basic1DFunction"); // Class must be declared public if (!checkAccess()) throw new FunctionFactoryError("Function "+name+" is not declared public"); // The function needs to have a suitable constructor if (!canBeCreatedFrom(Double.TYPE,Double.TYPE,Double.TYPE,Double.TYPE)) throw new FunctionFactoryError("Function "+name+" does not have a suitable constructor"); } public Basic1DFunction createFunction(JASHist h) throws FunctionFactoryError { try { JASHistAxis xAxis = h.getXAxis(); JASHistAxis yAxis = h.getYAxis(); // which Y axis? return (Basic1DFunction) create(new Double(xAxis.getMin()), new Double(xAxis.getMax()), new Double(yAxis.getMin()), new Double(yAxis.getMax())); } catch (ObjectFactoryException e) { throw new FunctionFactoryError("Unexpected failure to create function"); } } public String getFunctionName() { return name; } public Icon getFunctionIcon() { return icon; } private String name; private Icon icon = JASIcon.create(this,"function.gif"); } class FunctionListCellRenderer extends DefaultListCellRenderer { public Component getListCellRendererComponent(JList list, Object value, // value to display int index, // cell index boolean isSelected, // is the cell selected boolean cellHasFocus) // the list and the cell have the focus { super.getListCellRendererComponent(list,value,index,isSelected,cellHasFocus); if (value instanceof FunctionFactory) { FunctionFactory ff = (FunctionFactory) value; setText(ff.getFunctionName()); setIcon(ff.getFunctionIcon()); } return this; } } src/main/java/jas/hist/HasScatterPlotData.java0000644000175000017500000000130511325547132022003 0ustar giovannigiovannipackage jas.hist; public interface HasScatterPlotData extends Rebinnable2DHistogramData { /** * Starts the enumeration of points from the beginning, and the enumeration * will include only points in the given range. */ public ScatterEnumeration startEnumeration(double xMin, double xMax, double yMin, double yMax); /** * Starts the enumeration of points from the beginning, and the enumeration * will include all points stored in the partition. */ public ScatterEnumeration startEnumeration(); /** * Even if a DataSource implements this interface it may not have any * ScatterPlot data available at this time, hence the need for this method. */ public boolean hasScatterPlotData(); } src/main/java/jas/hist/Rebinnable2DVariableHistogramData.java0000644000175000017500000000027511325547132024663 0ustar giovannigiovannipackage jas.hist; public interface Rebinnable2DVariableHistogramData extends Rebinnable2DHistogramData { public double[] getXBinEdges(); public double[] getYBinEdges(); } src/main/java/jas/hist/SliceParameters.java0000644000175000017500000000106011325547132021372 0ustar giovannigiovannipackage jas.hist; /** * Defines parameters for a slice. x,y define the center of the slice. * height is the half-distance along the slice, while width is the half-distance perpendicular * to the slice axis. phi defines the slice direction, phi=0 implies the slice is along * the y-axis. */ public interface SliceParameters { double getX(); double getY(); double getWidth(); double getHeight(); double getPhi(); void setX(double x); void setY(double y); void setWidth(double width); void setHeight(double height); void setPhi(double phi); } src/main/java/jas/hist/XMLPrintWriter.java0000644000175000017500000003321411325547132021167 0ustar giovannigiovannipackage jas.hist; import jas.plot.DataArea; import jas.plot.EditableLabel; import jas.plot.Legend; import jas.plot.MovableObject; import jas.plot.Title; import jas.util.ColorConverter; import jas.util.ScientificFormat; import jas.util.xml.XMLWriter; import java.awt.Color; import java.awt.Component; import java.awt.Font; import java.io.Writer; import java.util.Enumeration; import javax.swing.BorderFactory; import javax.swing.border.Border; import javax.swing.border.LineBorder; final class XMLPrintWriter extends XMLWriter { XMLPrintWriter(Writer w) { super(w); } void print(JASHist plot,boolean snapshot) { printPlotHeader(); Title t = plot.getTitleObject(); if (t != null && t.isVisible()) print(t); print(plot.getLegend(),plot.getShowLegend()); StatisticsBlock s = plot.getStats(); if (s != null && s.isVisible()) print(s); DataArea d = plot.getDataArea(); if (d != null && d.isVisible()) print(d,plot.getDataManager(),snapshot); setAttribute("width",plot.getWidth()); setAttribute("height",plot.getHeight()); printTag("bounds"); printColorScheme(plot); printPlotFooter(); } void printColorScheme(Component c) { Component pp = c.getParent(); Color fg = c.getForeground(); Color bg = c.getBackground(); if (pp == null || fg != pp.getForeground() || bg != pp.getBackground()) { if (pp == null || fg != pp.getForeground()) setAttribute("foregroundColor",ColorConverter.colorToString(fg)); if (pp == null || bg != pp.getBackground()) setAttribute("backgroundColor",ColorConverter.colorToString(bg)); printTag("colorScheme"); } } void print(Title t) { openTag("title"); print(t.getInsideBorder()); printBounds(t); print(t.getLabel()); printColorScheme(t); closeTag(); } void print(JASHistAxis a, String p_location) { int type = a.getAxisType(); setAttribute("location",p_location); setAttribute("type",convertAxisTypeToString(type)); setAttribute("showOverflows",a.getShowOverflows()); if (a.isBinned()) setAttribute("numberOfBins",a.getBins()); if (type != a.STRING) { setAttribute("logarithmic",a.isLogarithmic()); setAttribute("allowSuppressedZero",a.getAllowSuppressedZero()); if (!a.getRangeAutomatic()) { setAttribute("min",a.getMin()); setAttribute("max",a.getMax()); } } openTag("axis"); EditableLabel label = a.getLabelObject(); if (label != null) print(label); print(a.getFont()); closeTag(); } void print(EditableLabel label) { setAttribute("text",label.getText()); openTag("label"); print(label.getFont()); closeTag(); } void print(Legend legend,int visibility) { setAttribute("visible",convertLegendToString(visibility)); openTag("legend"); if (legend != null && legend.isVisible()) { print(legend.getInsideBorder()); printBounds(legend); printColorScheme(legend); print(legend.getFont()); int n = legend.getNEntries(); for (int i=0; i * The routine returns a two dimensional array where the first dimension * has the following meaning: *
    *
  • [0] An array of data points (one entry per bin) *
  • [1] An array of plus errors (one entry per bin) *
  • [2] An array of minus errors (one entry per bin) *
* If the minus error is absent the errors are assumed to be symmetric, * if the plus error is also absent the errors are assumed to be the * square root of the data. * @param bin The number of bins requested * @param min The min of the range over which to bin * @param max The max of the range over which to bin * @param wantErrors If false indicates that the errors are not required and need not be calculated (most implementations will ignore this parameter) * @param hurry If true indicates the results should be provided as fast as possible, even if some approximation is needed (most implementations will ignore this parameter) * @return An array representing the binned data and errors (see description above) */ public double[][] rebin(int bins, double min, double max, boolean wantErrors, boolean hurry); /** * Returns the (suggested) minimum value for the X axis */ public double getMin(); /** * Returns the (suggested) maximum value for the X axis */ public double getMax(); /** * Returns the (suggested) number of bins to use */ public int getBins(); /** * Returns true if the data source is capable of recalculating the bin * contents, or false of the interface is not-capable of recalculating the * bin contents. In the former case the values returned by getMin, getMax and * getBins are just taken to be suggestions, in the latter case they are * taken to be fixed in stone. * @return True if the datasource is rebinnable */ public boolean isRebinnable(); /** * Returns one of DOUBLE,INTEGER,STRING,DATE or DELTATIME */ public int getAxisType(); /** * Returns the axis labels. * Only relevant if the axisType is STRING, otherwise can return null * @return An array of bin labels to use on the X axis */ public String[] getAxisLabels(); } src/main/java/jas/hist/FunctionValueUndefined.java0000644000175000017500000000011311325547132022711 0ustar giovannigiovannipackage jas.hist; public class FunctionValueUndefined extends Exception{} src/main/java/jas/hist/StatsWindow.java0000644000175000017500000003105211325547132020601 0ustar giovannigiovannipackage jas.hist; import jas.util.JASDialog; import jas.util.JASState; import jas.util.SciFormatPanel; import jas.util.ScientificFormat; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; import java.awt.Container; import java.awt.Rectangle; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.text.Format; import javax.swing.BorderFactory; import javax.swing.Box; import javax.swing.BoxLayout; import javax.swing.ButtonGroup; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JList; import javax.swing.JPanel; import javax.swing.JRadioButton; import javax.swing.JScrollPane; import javax.swing.ListCellRenderer; import javax.swing.ListModel; /**This class creates a gui popup window for choosing which statistics and titles should be displayed *in the StatisticsBlock, and for setting the number formatting parameters for * base.jas.util.ScientificFormat. The window uses the jpane created by base.jas.util.SciFormatPanel * for setting the ScientificForm parameters. This window created by selecting "Stats Properties.." * from the popup menu. If generated, the number formatting method in Statistics Block is * set to ScientificFormat. * @author Paul Spence * @version 03/20/2000 * "userInterface.propertiesDialog.Statistics" * */ public class StatsWindow extends JASDialog implements ActionListener { public static JFrame frame; private JButton all; private JButton none; private JRadioButton alltitles; private JRadioButton notitles; private JRadioButton sometitles; private JRadioButton leftalign; private JRadioButton rightalign; private JRadioButton noalign; private JRadioButton alwaysall; private JRadioButton subset; private String[] names; private JLabel selectlabel; private SciFormatPanel scipanel; private ScientificFormat f; private StatisticsBlock statblock; private JList list; private int showtitles; private int splitalign; public StatsWindow(StatisticsBlock b) { super(frame, "Statistic Display Options", true, JASDialog.OK_BUTTON | JASDialog.CANCEL_BUTTON | JASDialog.APPLY_BUTTON | JASDialog.HELP_BUTTON); statblock = b; Format sf = b.getFormat(); if (sf instanceof ScientificFormat) f = (ScientificFormat) sf; else f = new ScientificFormat(); } /** * This method will create and show the Statistics Window */ public void showStatsWindow() { super.setHelpTopic("userInterface.Statistics"); Container c = getContentPane(); c.removeAll(); scipanel = new SciFormatPanel(f); //always all or subset buttoons ButtonGroup allways_subset_group = new ButtonGroup(); alwaysall = new JRadioButton("Always show all statistics"); alwaysall.addActionListener(this); alwaysall.setActionCommand("alwaysall"); subset = new JRadioButton("Show selection of current statistics"); subset.addActionListener(this); subset.setActionCommand("subset"); allways_subset_group.add(alwaysall); allways_subset_group.add(subset); Box allways_subset_box = new Box(BoxLayout.X_AXIS); allways_subset_box.add(alwaysall); allways_subset_box.add(subset); //checkbox list names = statblock.getStatNames(); list = new JList( createData(names) ); list.setVisibleRowCount(3); list.setCellRenderer(new CheckListRenderer()); list.addMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent e) { int index = list.locationToIndex(e.getPoint()); if(index != -1 && list.getModel().getSize() >index){ CheckableItem item = (CheckableItem)list.getModel().getElementAt(index); item.setSelected(! item.isSelected()); Rectangle rect = list.getCellBounds(index, index); list.repaint(rect); } } }); JScrollPane checkbuttonspanel = new JScrollPane(list); Box subsetbuttons = new Box(BoxLayout.Y_AXIS); all = new JButton("All"); none = new JButton("None"); all.setActionCommand("all"); all.addActionListener(this); none.setActionCommand("none"); none.addActionListener(this); subsetbuttons.add(all); subsetbuttons.add(none); JPanel statselection = new JPanel(); statselection.setLayout(new BorderLayout()); selectlabel = new JLabel("Choose selection of current statistics for display"); statselection.add(selectlabel,BorderLayout.NORTH); statselection.add(subsetbuttons,BorderLayout.EAST); statselection.add(checkbuttonspanel, BorderLayout.CENTER); Box statoptionsbox = new Box(BoxLayout.Y_AXIS); statoptionsbox.add(allways_subset_box); statoptionsbox.add(statselection); JPanel statoptions = new JPanel(); statoptions.setBorder(BorderFactory.createTitledBorder("Choose a statistics display options")); statoptions.add(statoptionsbox); //display title and alignment showtitles = statblock.getShowTitles(); alltitles = new JRadioButton("Always show title"); notitles = new JRadioButton("Never show title"); sometitles = new JRadioButton("Show if multiple plots"); alltitles.setActionCommand("alltitles"); alltitles.addActionListener(this); notitles.setActionCommand("notitles"); notitles.addActionListener(this); sometitles.setActionCommand("sometitles"); sometitles.addActionListener(this); Box titlebox = new Box(BoxLayout.X_AXIS); titlebox.add(alltitles); titlebox.add(notitles); titlebox.add(sometitles); ButtonGroup titlegroup = new ButtonGroup(); titlegroup.add(alltitles); titlegroup.add(notitles); titlegroup.add(sometitles); if(showtitles == statblock.SHOWTITLES_ALWAYS) alltitles.setSelected(true); else if(showtitles == statblock.SHOWTITLES_NEVER) notitles.setSelected(true); else if(showtitles == statblock.SHOWTITLES_AUTOMATIC) sometitles.setSelected(true); JPanel titleoptions = new JPanel(); titleoptions.setBorder(BorderFactory.createTitledBorder("Select a title display option for plots with statistics")); titleoptions.add(titlebox); splitalign = statblock.getSplitStringAlign(); leftalign = new JRadioButton("Left align numbers"); rightalign = new JRadioButton("Right align numbers"); noalign = new JRadioButton("Do not align numbers"); leftalign.setActionCommand("leftalign"); leftalign.addActionListener(this); rightalign.setActionCommand("rightalign"); rightalign.addActionListener(this); noalign.setActionCommand("noalign"); noalign.addActionListener(this); ButtonGroup aligngroup = new ButtonGroup(); Box alignbox = new Box(BoxLayout.X_AXIS); aligngroup.add(leftalign); aligngroup.add(rightalign); aligngroup.add(noalign); alignbox.add(leftalign); alignbox.add(rightalign); alignbox.add(noalign); JPanel alignoptions = new JPanel(); alignoptions.setBorder(BorderFactory.createTitledBorder("Select an alignment display option for the statistics values")); alignoptions.add(alignbox); if(splitalign == statblock.LEFTALIGNSPLIT) leftalign.setSelected(true); else if(splitalign == statblock.RIGHTALIGNSPLIT) rightalign.setSelected(true); else if(splitalign == statblock.NOALIGNSPLIT) noalign.setSelected(true); JPanel scioptions = scipanel.getPanel(); scioptions.setBorder(BorderFactory.createTitledBorder("Set number formating parameters for numerical statistics")); if(statblock.get_AllwaysAll_Subset()){ alwaysall.setSelected(true); this.enableStatSelections(false); }else subset.setSelected(true); Box box = new Box(BoxLayout.Y_AXIS); box.add(statoptions); box.add(titleoptions); box.add(alignoptions); box.add(scioptions); c.add(box); pack(); show(); } public void onOK(){ String[] s; scipanel.updateSciFormat();//sets max width, sig digits and style for doubles ListModel model = list.getModel(); if(alwaysall.isSelected()){ statblock.setSelectedEntries(s = null); statblock.set_AllwaysAll_Subset(true); }else if(model.getSize()>0){ int n = model.getSize(); int j = 0; for(int i=0;i0 ){ s = new String[j]; int k = 0; for(int i=0;i0){ int n = model.getSize(); int j = 0; for(int i=0;i0 ){ s = new String[j]; int k = 0; for(int i=0;i upperBound ? upperBound : xmax; if ( xmin > xmax ) xmin = xmax; if (overlay instanceof JASHistFunctionOverlay) ((JASHistFunctionOverlay) overlay).setXRange(xmin,xmax); } public String getTitle() { return dataSource.getTitle(); } Overlay createOverlay() { return new JASHistFunctionOverlay(this,style); } public JASHistStyle getStyle() { return style; } public DataSource getDataSource() { return dataSource; } void normalizationChanged(boolean now) { } public void writeAsXML(XMLPrintWriter pw, boolean snapshot) { pw.setAttribute("axis","y"+getYAxis()); //TODO: getTitle is not correct, fix this pw.setAttribute("type",dataSource.getTitle()); pw.openTag("function1d"); String[] pNames = dataSource.getParameterNames(); double[] pValue = dataSource.getParameterValues(); for (int i=0; i (width/2)) flw = (width > 2) ? (float) (width/2 -1) : 1; BasicStroke s = new BasicStroke(flw,BasicStroke.CAP_SQUARE,BasicStroke.JOIN_ROUND,10,lineStyles[style.getLineStyle()],0); g.setStroke(s); g.setStroke(s); g.drawLine(1, height/2, width-2, height/2); g.setStroke(null); } private JASHist1DFunctionStyle style; private JASHist1DFunctionData source; private double xmin, xmax; } src/main/java/jas/hist/XMLHistBuilder.java0000644000175000017500000007474211325547132021127 0ustar giovannigiovannipackage jas.hist; import jas.hist.normalization.AreaNormalizer; import jas.hist.normalization.BinNormalizer; import jas.hist.normalization.EntriesNormalizer; import jas.hist.normalization.MaxBinNormalizer; import jas.hist.normalization.Normalizer; import jas.hist.normalization.RelativeNormalizer; import jas.hist.normalization.SimpleNormalizer; import jas.hist.normalization.StatisticsNormalizer; import jas.plot.Axis; import jas.plot.DataArea; import jas.plot.EditableLabel; import jas.plot.Legend; import jas.plot.Title; import jas.util.ScientificFormat; import jas.util.xml.ClassPathEntityResolver; import jas.util.xml.JASDOMParser; import jas.util.xml.XMLNodeTraverser; import jas.util.xml.XMLNodeTraverser.BadXMLException; import java.awt.Color; import java.awt.Dimension; import java.awt.Font; import java.awt.Rectangle; import java.io.Reader; import java.util.Hashtable; import java.util.Vector; import javax.swing.BorderFactory; import javax.swing.JComponent; import org.w3c.dom.Attr; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; /** * Create a Plot from an XML file. * * Reads an XML file describing a Plot and creates * or modifies a plot to correspond to the data specified in * the XML file. */ public class XMLHistBuilder { // // constructors // /** * Create an XMLHistBuilder by reading an XML file * @param xmlFile The xmlFile to read. * @param fileName The file name (for error messages) */ public XMLHistBuilder(Reader xmlFile, String fileName) throws JASDOMParser.JASXMLException, BadXMLException { ClassPathEntityResolver er = new ClassPathEntityResolver("plotML.dtd",XMLHistBuilder.class); Document node = JASDOMParser.instance().parse(xmlFile,fileName,er); plotML = new PlotMLNodeTraverser(node); } /** * Create an XMLHistBuilder from a pre-parsed Document Object Model */ public XMLHistBuilder(Document dom) throws BadXMLException { plotML = new PlotMLNodeTraverser(dom); } /** * Create a plot using the parsed XML. */ public JASHist getSoloPlot() throws BadXMLException { return modifyPlot(new JASHist()); } /** * Modify an existing plot using the parsed XML. */ public JASHist modifyPlot(JASHist theHist) throws BadXMLException { Node node = plotML.getPlot(); JASHistNodeTraverser traverser = new JASHistNodeTraverser(); theHist.removeAllData(); traverser.traverse(node,theHist); return theHist; } /** * Get a plot page. Not implemented yet. */ public jas.plot.PlotPanel getPlotPage() { return null;//!PA - stub //return (jas.plot.PlotPanel)(getIt("plotPage")); } private PlotMLNodeTraverser plotML; } class PlotMLNodeTraverser extends XMLNodeTraverser { PlotMLNodeTraverser(Document node) throws BadXMLException { traverse(node); } protected void handleElement(Element node, String name) throws BadXMLException { if (name.equals("plotML")) traverse(node); else hash.put(name,node); } protected void handleOtherNode(Node node, String name) throws BadXMLException { if (node.getNodeType() == node.DOCUMENT_TYPE_NODE) return; else super.handleOtherNode(node,name); } Node getPlot() throws BadXMLException { Node node = (Node) hash.get("plot"); if (node == null) throw new BadXMLException(" node not found"); return node; } private Hashtable hash = new Hashtable(); } abstract class ComponentNodeTraverser extends XMLNodeTraverser { void traverse(Node n,JComponent c) throws BadXMLException { this.c = c; super.traverse(n); } protected void handleElement(Element node, String name) throws BadXMLException { if (name.equals("border")) bt.traverse(node,c); else if (name.equals("bounds")) dt.traverse(node,c); else if (name.equals("colorScheme")) ct.traverse(node,c); else if (name.equals("font")) ft.traverse(node,c); else super.handleElement(node,name); } private JComponent c; private static BorderNodeTraverser bt = new BorderNodeTraverser(); private static ColorSchemeNodeTraverser ct = new ColorSchemeNodeTraverser(); private static FontNodeTraverser ft = new FontNodeTraverser(); private static BoundsNodeTraverser dt = new BoundsNodeTraverser(); } class BorderNodeTraverser extends XMLNodeTraverser { void traverse(Node node, JComponent c) throws BadXMLException { super.traverse(node); if (type.equals("Bevel In")) c.setBorder(BorderFactory.createLoweredBevelBorder()); else if (type.equals("Bevel Out")) c.setBorder(BorderFactory.createRaisedBevelBorder()); else if (type.equals("Etched")) c.setBorder(BorderFactory.createEtchedBorder()); else if (type.equals("Shadow")) c.setBorder(jas.util.border.ShadowBorder.createShadowBorder()); else if (type.equals("Line")) c.setBorder(BorderFactory.createLineBorder(color)); } protected void handleAttributeNode(Attr node, String name, String value) throws BadXMLException { if (name.equals("type")) type = value; else if (name.equals("color")) color = toColor(value); else super.handleAttributeNode(node,name,value); } private Color color; private String type; } class FontNodeTraverser extends XMLNodeTraverser { void traverse(Node node, JComponent c) throws BadXMLException { super.traverse(node); c.setFont(new Font(face,style,size)); } protected void handleAttributeNode(Attr node, String name, String value) throws BadXMLException { if (name.equals("face")) face = value; else if (name.equals("style")) style = toFontStyle(value); else if (name.equals("points")) size = toInt(value); else super.handleAttributeNode(node,name,value); } private int toFontStyle(String s) { if (s.equalsIgnoreCase("PLAIN")) return Font.PLAIN; if (s.equalsIgnoreCase("BOLD")) return Font.BOLD; if (s.equalsIgnoreCase("ITALIC")) return Font.ITALIC; if (s.equalsIgnoreCase("BOLD+ITALIC")) return (Font.BOLD + Font.ITALIC); return Font.PLAIN; } private int size; private String face; private int style; } class ColorSchemeNodeTraverser extends XMLNodeTraverser { void traverse(Node node, JComponent c) throws BadXMLException { this.c = c; super.traverse(node); } protected void handleAttributeNode(Attr node, String name, String value) throws BadXMLException { if (name.equals("foregroundColor")) c.setForeground(toColor(value)); else if (name.equals("backgroundColor")) c.setBackground(toColor(value)); else super.handleAttributeNode(node,name,value); } private JComponent c; } class BoundsNodeTraverser extends XMLNodeTraverser { void traverse(Node node, JComponent c) throws BadXMLException { super.traverse(node); Rectangle r = new Rectangle(x,y,width,height); if (c instanceof jas.plot.MovableObject) { ((jas.plot.MovableObject)c).setMovableObjectBounds(r); } else { c.setBounds(r); c.setPreferredSize(new Dimension(width,height)); } } protected void handleAttributeNode(Attr node, String name, String value) throws BadXMLException { if (name.equals("x")) x = toInt(value); else if (name.equals("y")) y = toInt(value); else if (name.equals("width")) width = toInt(value); else if (name.equals("height")) height = toInt(value); else super.handleAttributeNode(node,name,value); } private int x,y,width,height; } class TitleNodeTraverser extends ComponentNodeTraverser { void traverse(Node node, Title t) throws BadXMLException { title = t; super.traverse(node,t); } protected void handleElement(Element node, String name) throws BadXMLException { if (name.equals("label")) lt.traverse(node,title.getLabel()); else super.handleElement(node,name); } private static LabelNodeTraverser lt = new LabelNodeTraverser(); private Title title; } class JASHistNodeTraverser extends ComponentNodeTraverser { void traverse(Node node, JASHist plot) throws BadXMLException { this.plot = plot; super.traverse(node,plot); // We cant apply the legend entries until after the data is added, // so do it here lt.applyLegendEntries(); } protected void handleElement(Element node, String name) throws BadXMLException { if (name.equals("title")) { Title t = plot.getTitleObject(); if (t == null) plot.setTitleObject(t=new Title()); tt.traverse(node,t); } else if (name.equals("stats")) { st.traverse(node,plot.getStats()); plot.setShowStatistics(true); } else if (name.equals("dataArea")) dt.traverse(node,plot.getDataArea(),plot); else if (name.equals("legend")) lt.traverse(node,plot.getLegend(),plot); else super.handleElement(node,name); } protected void handleAttributeNode(Attr node, String name, String value) throws BadXMLException { if (name.equals("allowUserInteraction")) plot.setAllowUserInteraction(toBoolean(value)); else super.handleAttributeNode(node,name,value); } private static TitleNodeTraverser tt = new TitleNodeTraverser(); private static StatsNodeTraverser st = new StatsNodeTraverser(); private static DataAreaNodeTraverser dt = new DataAreaNodeTraverser(); private static LegendNodeTraverser lt = new LegendNodeTraverser(); private JASHist plot; } class LabelNodeTraverser extends ComponentNodeTraverser { void traverse(Node node, EditableLabel label) throws BadXMLException { this.label = label; super.traverse(node,label); } protected void handleAttributeNode(Attr node, String name, String value) throws BadXMLException { if (name.equals("text")) label.setText(value); else super.handleAttributeNode(node,name,value); } private EditableLabel label; } class StatsNodeTraverser extends ComponentNodeTraverser { void traverse(Node node, StatisticsBlock stats) throws BadXMLException { this.stats = stats; super.traverse(node,stats); if (selected != null) { String[] elements = new String[selected.size()]; selected.copyInto(elements); stats.setSelectedEntries(elements); } } protected void handleElement(Element node, String name) throws BadXMLException { if (name.equals("statsEntry")) { if (selected == null) selected = new Vector(); selected.addElement(node.getAttribute("name")); } else if (name.equals("format")) { FormatNodeTraverser ft = new FormatNodeTraverser(node); stats.setFormat(ft.getFormat()); } else super.handleElement(node,name); } protected void handleAttributeNode(Attr node, String name, String value) throws BadXMLException { if (name.equals("showTitles")) stats.setShowTitles(XMLPrintWriter.convertStringToShowTitle(value)); else if (name.equals("alignment")) stats.setSplitStringAlign(XMLPrintWriter.convertStringToAlignment(value)); else super.handleAttributeNode(node,name,value); } private Vector selected; private StatisticsBlock stats; } class FormatNodeTraverser extends XMLNodeTraverser { FormatNodeTraverser(Node node) throws BadXMLException { super.traverse(node); } protected void handleAttributeNode(Attr node, String name, String value) throws BadXMLException { if (name.equals("maximumWidth")) f.setMaxWidth(toInt(value)); else if (name.equals("significantDigits")) f.setSigDigits(toInt(value)); else if (name.equals("style")) f.setScientificNotationStyle(value.equals("pure")); else super.handleAttributeNode(node,name,value); } ScientificFormat getFormat() { return f; } private ScientificFormat f = new ScientificFormat(); } class LegendNodeTraverser extends ComponentNodeTraverser { void traverse(Node node, Legend legend, JASHist plot) throws BadXMLException { this.plot = plot; this.legend = legend; this.node = node; } protected void handleElement(Element node, String name) throws BadXMLException { if (name.equals("legendEntry")) { int index = toInt(node.getAttribute("index")); legend.setCurrentTitle(index,node.getAttribute("title")); } else super.handleElement(node,name); } protected void handleAttributeNode(Attr node, String name, String value) throws BadXMLException { if (name.equals("visible")) plot.setShowLegend(toVisibility(value)); else super.handleAttributeNode(node,name,value); } void applyLegendEntries() throws BadXMLException { if (node != null) super.traverse(node,legend); } private int toVisibility(String value) throws BadXMLException { return XMLPrintWriter.convertStringToLegend(value); } private Node node; private Legend legend; private JASHist plot; } class DataAreaNodeTraverser extends ComponentNodeTraverser { void traverse(Node node, DataArea da, JASHist plot) throws BadXMLException { this.da = da; this.plot = plot; super.traverse(node,da); } protected void handleElement(Element node, String name) throws BadXMLException { if (name.equals("axis")) { NamedNodeMap nnm = node.getAttributes(); String position = nnm.getNamedItem("location").getNodeValue(); JASHistAxis theAxis; if (position.equals("x0")) theAxis = plot.getXAxis(); else if (position.equals("y0")) theAxis = plot.getYAxis(); else if (position.equals("y1")) theAxis = plot.getYAxis(1); else throw new BadXMLException("Illegal axis position"+position); at.traverse(node,theAxis); } else if (name.equals("data1d")) { Data1DTraverser d1d = new Data1DTraverser(node); DataSource ds = d1d.getDataSource(); if (ds == null) return; // Just ignore it ... needed for custom HasDataSource implementations String refName = d1d.getRefName(); if (refName != null) map.put(refName,ds); JASHistData data = plot.addData(ds); data.setYAxis(d1d.getYAxis()); JASHistStyle style = d1d.getStyle(); if (style != null) data.setStyle(style); Normalizer norm = d1d.getNormalizer(ds,map); if (norm != null) data.setNormalization(norm); data.show(true); } else if (name.equals("data2d")) { Data2DTraverser d2d = new Data2DTraverser(node); DataSource ds = d2d.getDataSource(); if (ds == null) return; // Just ignore it ... needed for custom HasDataSource implementations String refName = d2d.getRefName(); if (refName != null) map.put(refName,ds); JASHistData data = plot.addData(ds); JASHistStyle style = d2d.getStyle(); if (style != null) data.setStyle(style); data.show(true); } else if (name.equals("function1d")) { Function1DTraverser f1d = new Function1DTraverser(node,plot); DataSource ds = f1d.getDataSource(); if (ds != null) { String refName = f1d.getRefName(); if (refName != null) map.put(refName,ds); String fitRef = f1d.getFitRef(); if (fitRef != null) { DataSource data = (DataSource) map.get(fitRef); if (data == null) throw new BadXMLException("Cannot resolve reference "+fitRef); if (!(data instanceof Rebinnable1DHistogramData)) throw new BadXMLException("Cannot fit 2D data"); if (!(ds instanceof Fittable1DFunction)) throw new BadXMLException("Function is not fittable"); Fitter fitter = FitterRegistry.instance().getDefaultFitter(); fitter.setData((XYDataSource) data); fitter.setFunction((Fittable1DFunction) ds); try { fitter.fit(); } catch (FitFailed x) { x.printStackTrace(); } } JASHistData data = plot.addData(ds); JASHistStyle style = f1d.getStyle(); if (style != null) data.setStyle(style); data.show(f1d.isVisible()); } } else super.handleElement(node,name); } private Hashtable map = new Hashtable(); private DataArea da; private JASHist plot; private static AxisNodeTraverser at = new AxisNodeTraverser(); } class AxisNodeTraverser extends XMLNodeTraverser { void traverse(Node node, JASHistAxis axis) throws BadXMLException { this.axis = axis; super.traverse(node); } protected void handleElement(Element node, String name) throws BadXMLException { if (name.equals("label")) { EditableLabel l = axis.getLabelObject(); if (l == null) axis.setLabelObject(l = new EditableLabel("","Axis Label")); lt.traverse(node,l); } else if (name.equals("font")) ft.traverse(node,(Axis) axis); else super.handleElement(node,name); } protected void handleAttributeNode(Attr node, String name, String value) throws BadXMLException { if (name.equals("logarithmic" )) axis.setLogarithmic(toBoolean(value)); else if (name.equals("allowSuppressedZero")) axis.setAllowSuppressedZero(toBoolean(value)); else if (name.equals("numberOfBins" )) axis.setBins(toInt(value)); else if (name.equals("type" )) axis.setAxisType(XMLPrintWriter.convertStringToAxisType(value)); else if (name.equals("min" )) axis.setMin(toDouble(value)); else if (name.equals("max" )) axis.setMax(toDouble(value)); else if (name.equals("showOverflows")) axis.setShowOverflows(toBoolean(value)); else if (name.equals("location")) {} // Dealt with elsewhere else super.handleAttributeNode(node,name,value); } private static LabelNodeTraverser lt = new LabelNodeTraverser(); private static FontNodeTraverser ft = new FontNodeTraverser(); private JASHistAxis axis; } class Style1DNodeTraverser extends XMLNodeTraverser { void traverse(Node node,JASHist1DHistogramStyle style) throws BadXMLException { this.style = style; super.traverse(node); } protected void handleAttributeNode(Attr node, String name, String value) throws BadXMLException { if (name.equals("histogramBarsFilled" )) style.setHistogramFill(toBoolean(value)); else if (name.equals("showHistogramBars" )) style.setShowHistogramBars(toBoolean(value)); else if (name.equals("showErrorBars" )) style.setShowErrorBars(toBoolean(value)); else if (name.equals("showDataPoints" )) style.setShowDataPoints(toBoolean(value)); else if (name.equals("showLinesBetweenPoints")) style.setShowLinesBetweenPoints(toBoolean(value)); else if (name.equals("dataPointSize" )) style.setDataPointSize(toInt(value)); else if (name.equals("histogramBarColor" )) style.setHistogramBarColor(toColor(value)); else if (name.equals("errorBarColor" )) style.setErrorBarColor(toColor(value)); else if (name.equals("dataPointColor" )) style.setDataPointColor(toColor(value)); else if (name.equals("lineColor" )) style.setLineColor(toColor(value)); else if (name.equals("dataPointStyle" )) style.setDataPointStyle(XMLPrintWriter.convertStringToStyle(value)); else super.handleAttributeNode(node,name,value); } private JASHist1DHistogramStyle style; } class Style2DNodeTraverser extends XMLNodeTraverser { void traverse(Node node, JASHist2DHistogramStyle style) throws BadXMLException { this.style = style; super.traverse(node); } protected void handleAttributeNode(Attr node, String name, String value) throws BadXMLException { if (name.equals("startDataColor" )) style.setStartDataColor(toColor(value)); else if (name.equals("endDataColor" )) style.setEndDataColor(toColor(value)); else if (name.equals("showOverflow" )) style.setShowOverflow(toBoolean(value)); else if (name.equals("showPlot" )) style.setShowPlot(toBoolean(value)); else if (name.equals("histStyle" )) style.setHistStyle(toStyle(value)); else if (name.equals("colorMapScheme" )) style.setColorMapScheme(toColorMapScheme(value)); else if (name.equals("shapeColor" )) style.setShapeColor(toColor(value)); else if (name.equals("overflowBinColor" )) style.setOverflowBinColor(toColor(value)); else if (name.equals("logZ" )) style.setLogZ(toBoolean(value)); else super.handleAttributeNode(node,name,value); } private int toStyle(String s) { if (s.equalsIgnoreCase("STYLE_BOX")) return JASHist2DHistogramStyle.STYLE_BOX; if (s.equalsIgnoreCase("STYLE_ELLIPSE")) return JASHist2DHistogramStyle.STYLE_ELLIPSE; if (s.equalsIgnoreCase("STYLE_COLORMAP")) return JASHist2DHistogramStyle.STYLE_COLORMAP; return JASHist2DHistogramStyle.STYLE_BOX; } private int toColorMapScheme(String s) { if (s.equalsIgnoreCase("COLORMAP_WARM")) return JASHist2DHistogramStyle.COLORMAP_WARM; if (s.equalsIgnoreCase("COLORMAP_COOL")) return JASHist2DHistogramStyle.COLORMAP_COOL; if (s.equalsIgnoreCase("COLORMAP_THERMAL")) return JASHist2DHistogramStyle.COLORMAP_THERMAL; if (s.equalsIgnoreCase("COLORMAP_RAINBOW")) return JASHist2DHistogramStyle.COLORMAP_RAINBOW; if (s.equalsIgnoreCase("COLORMAP_GRAYSCALE")) return JASHist2DHistogramStyle.COLORMAP_GRAYSCALE; if (s.equalsIgnoreCase("COLORMAP_USERDEFINED")) return JASHist2DHistogramStyle.COLORMAP_USERDEFINED; return JASHist2DHistogramStyle.COLORMAP_WARM; } private JASHist2DHistogramStyle style; } class ScatterStyleNodeTraverser extends Style2DNodeTraverser { void traverse(Node node, JASHistScatterPlotStyle style) throws BadXMLException { this.style = style; super.traverse(node,style); } protected void handleAttributeNode(Attr node, String name, String value) throws BadXMLException { if (name.equals("displayAsScatterPlot")) style.setDisplayAsScatterPlot(toBoolean(value)); else if (name.equals("dataPointSize" )) style.setDataPointSize(toInt(value)); else if (name.equals("dataPointStyle" )) style.setDataPointStyle(toDataPointStyle(value)); else if (name.equals("dataPointColor" ))style.setDataPointColor(toColor(value)); else super.handleAttributeNode(node,name,value); } private int toDataPointStyle(String value) throws BadXMLException { if (toInt(value)==(JASHistScatterPlotStyle.SYMBOL_BOX )) return JASHistScatterPlotStyle.SYMBOL_BOX; if (toInt(value)==(JASHistScatterPlotStyle.SYMBOL_CROSS )) return JASHistScatterPlotStyle.SYMBOL_CROSS; if (toInt(value)==(JASHistScatterPlotStyle.SYMBOL_DIAMOND )) return JASHistScatterPlotStyle.SYMBOL_DIAMOND; if (toInt(value)==(JASHistScatterPlotStyle.SYMBOL_HORIZ_LINE )) return JASHistScatterPlotStyle.SYMBOL_HORIZ_LINE; if (toInt(value)==(JASHistScatterPlotStyle.SYMBOL_SQUARE)) return JASHistScatterPlotStyle.SYMBOL_SQUARE; if (toInt(value)==(JASHistScatterPlotStyle.SYMBOL_STAR )) return JASHistScatterPlotStyle.SYMBOL_STAR; if (toInt(value)==(JASHistScatterPlotStyle.SYMBOL_TRIANGLE)) return JASHistScatterPlotStyle.SYMBOL_TRIANGLE; return JASHistScatterPlotStyle.SYMBOL_VERT_LINE; } private JASHistScatterPlotStyle style; } class Function1DTraverser extends XMLNodeTraverser { Function1DTraverser(Node node, JASHist plot) throws BadXMLException { this.plot = plot; traverse(node); } protected void handleElement(Element node, String name) throws BadXMLException { if (name.equals("functionStyle1d")) st.traverse(node,style=new JASHist1DFunctionStyle()); else if (name.equals("fit")) traverse(node); else if (name.equals("functionParam")) { if (function != null) { try { fp.traverse(node); String paramName = fp.getName(); String[] parameterNames = function.getParameterNames(); for (int i=0; i 5; double errorBarWidth = Math.min(binWidthFixed, (3 * binWidthFixed) / pixelWidth); g.setTransformation(xt, yt); double x = xmin; double oldx = xmin; // y0 is used as the base of histogram bars. It should // be 0 unless there is a suppressed 0 on the Y axis. double y0 = 0; if (yt.getPlotMin() > y0) { y0 = yt.getPlotMin(); } if (yt.getPlotMax() < y0) { y0 = yt.getPlotMax(); } double oldy = y0; double[] lpbx = null; double[] lpby = null; int lpbn = 0; if (style.getShowLinesBetweenPoints() || style.getShowDataPoints()) { // Bottleneck: Created each time paint is called lpbx = new double[bins]; lpby = new double[bins]; } // Note, we want to skip points which have y == NAN. This takes some // care for things such as histogram bars and lines between points. for (int i = 0; i < bins; i++) { double y = data[i]; double binWidth = (binEdges == null) ? binWidthFixed : binEdges[i+1] - binEdges[i]; x = (dataX == null) ? (x + binWidth) : dataX[i]; BasicStroke s = new BasicStroke(style.getHistogramBarLineWidth(),BasicStroke.CAP_SQUARE,BasicStroke.JOIN_ROUND,10,lineStyles[style.getHistogramBarLineStyle()],0); g.setStroke(s); if (style.getShowHistogramBars()) { if (!Double.isNaN(y)) { g.setColor(style.getHistogramBarColor()); if (style.getHistogramFill()) { g.fillRect(oldx, y0, x, y); g.setColor(style.getHistogramBarLineColor()); if (outline) { g.drawRect(oldx, y0, x, y); } else { g.drawLine(oldx, oldy, oldx, y); g.drawLine(oldx, y, x, y); } } else { g.setColor(style.getHistogramBarLineColor()); g.drawLine(oldx, oldy, oldx, y); g.drawLine(oldx, y, x, y); } } else { if (!style.getHistogramFill() || !outline) { g.drawLine(oldx, oldy, oldx, y0); } } } g.setStroke(null); if (style.getShowErrorBars() && !Double.isNaN(y)) { g.setColor(style.getErrorBarColor()); final double xm = (binWidth == 0) ? x : (oldx + (binWidth / 2)); double xe = (style.getErrorBarDecoration() >= 0) ? (double) (style.getErrorBarDecoration() * binWidth/2) : Math.min(binWidth, (3 * binWidth) / pixelWidth); final double yplus = data[i] + plus[i]; final double yminus = data[i] - minus[i]; s = new BasicStroke(style.getErrorBarWidth(),BasicStroke.CAP_SQUARE,BasicStroke.JOIN_ROUND,10,lineStyles[style.getErrorBarStyle()],0); g.setStroke(s); if (!Double.isNaN(yplus) && !Double.isNaN(yminus) && yminus != yplus) { g.drawLine(xm, yplus, xm, yminus); if ((outline && style.getErrorBarDecoration() < 0) || style.getErrorBarDecoration() > 0) { BasicStroke ss = new BasicStroke(style.getErrorBarWidth(),BasicStroke.CAP_SQUARE,BasicStroke.JOIN_ROUND,10); g.setStroke(ss); g.drawLine(xm - xe, yplus, xm + xe, yplus); g.drawLine(xm - xe, yminus, xm + xe, yminus); } } g.setStroke(null); } if (lpbx != null) { if (Double.isNaN(y)) { if (lpbn > 0) { if (style.getShowLinesBetweenPoints()) { g.setColor(style.getLineColor()); s = new BasicStroke(style.getLinesBetweenPointsWidth(),BasicStroke.CAP_SQUARE,BasicStroke.JOIN_ROUND,10,lineStyles[style.getLinesBetweenPointsStyle()],0); g.setStroke(s); g.drawPolyLine(lpbx, lpby, lpbn); g.setStroke(null); } if (style.getShowDataPoints()) { g.setColor(style.getDataPointColor()); g.drawPolySymbol(lpbx, lpby, style.getDataPointSize(), style.getDataPointStyle(), lpbn); } lpbn = 0; } } else { lpbx[lpbn] = (dataX == null) ? (oldx + (binWidth / 2)) : x; lpby[lpbn++] = y; } } oldx = x; oldy = (y == Double.NaN) ? y0 : y; } if (lpbn > 0) { if (style.getShowLinesBetweenPoints()) { g.setColor(style.getLineColor()); BasicStroke s = new BasicStroke(style.getLinesBetweenPointsWidth(),BasicStroke.CAP_SQUARE,BasicStroke.JOIN_ROUND,10,lineStyles[style.getLinesBetweenPointsStyle()],0); g.setStroke(s); g.drawPolyLine(lpbx, lpby, lpbn); g.setStroke(null); } if (style.getShowDataPoints()) { g.setColor(style.getDataPointColor()); g.drawPolySymbol(lpbx, lpby, style.getDataPointSize(), style.getDataPointStyle(), lpbn); } } } else if (xp instanceof StringCoordinateTransformation && yp instanceof DoubleCoordinateTransformation) { final StringCoordinateTransformation xt = (StringCoordinateTransformation) xp; final DoubleCoordinateTransformation yt = (DoubleCoordinateTransformation) yp; final int bins = labels.length; final double binWidth = xt.binWidth(); boolean outline = binWidth > 5; g.setTransformation(null, yt); // y0 is used as the base of histogram bars. It should // be 0 unless there is a suppressed 0 on the Y axis. double y0 = 0; if (yt.getPlotMin() > y0) { y0 = yt.getPlotMin(); } if (yt.getPlotMax() < y0) { y0 = yt.getPlotMax(); } double oldy = yt.getPlotMin(); double[] lpbx = null; double[] lpby = null; int lpbn = 0; if (style.getShowLinesBetweenPoints() || style.getShowDataPoints()) { // Bottleneck: Created each time paint is called lpbx = new double[bins]; lpby = new double[bins]; } for (int i = 0; i < bins; i++) { double x = xt.convert(labels[i]) + (binWidth / 2); double oldx = x - binWidth; double y = data[i]; BasicStroke s = new BasicStroke(style.getHistogramBarLineWidth(),BasicStroke.CAP_SQUARE,BasicStroke.JOIN_ROUND,10,lineStyles[style.getHistogramBarLineStyle()],0); g.setStroke(s); if (style.getShowHistogramBars()) { if (!Double.isNaN(y)) { g.setColor(style.getHistogramBarColor()); if (style.getHistogramFill()) { g.fillRect(oldx, oldy, x, y); g.setColor(style.getHistogramBarLineColor()); if (outline) { g.drawRect(oldx, oldy, x, y); } else { g.drawLine(oldx, oldy, oldx, y); g.drawLine(oldx, y, x, y); } } else { g.setColor(style.getHistogramBarLineColor()); g.drawLine(oldx, oldy, oldx, y); g.drawLine(oldx, y, x, y); } } else { if (!style.getHistogramFill() || !outline) { g.drawLine(oldx, oldy, oldx, y0); } } } g.setStroke(null); if (style.getShowErrorBars() && !Double.isNaN(y)) { s = new BasicStroke(style.getErrorBarWidth(),BasicStroke.CAP_SQUARE,BasicStroke.JOIN_ROUND,10,lineStyles[style.getErrorBarStyle()],0); g.setStroke(s); g.setColor(style.getErrorBarColor()); double xm = x - (binWidth / 2); double xe = (style.getErrorBarDecoration() >= 0) ? (double) (style.getErrorBarDecoration() * binWidth / 2) : Math.min(3, binWidth / 2); double yplus = data[i] + plus[i]; double yminus = data[i] - minus[i]; if (!Double.isNaN(yplus) && !Double.isNaN(yminus) && yminus != yplus) { g.drawLine(xm, yplus, xm, yminus); if ((outline && style.getErrorBarDecoration() < 0) || style.getErrorBarDecoration() > 0) { BasicStroke ss = new BasicStroke(style.getErrorBarWidth(),BasicStroke.CAP_SQUARE,BasicStroke.JOIN_ROUND,10); g.setStroke(ss); g.drawLine(xm - xe, yplus, xm + xe, yplus); g.drawLine(xm - xe, yminus, xm + xe, yminus); } } g.setStroke(null); } if (lpbx != null) { if (Double.isNaN(y)) { if (lpbn > 0) { if (style.getShowLinesBetweenPoints()) { g.setColor(style.getLineColor()); s = new BasicStroke(style.getLinesBetweenPointsWidth(),BasicStroke.CAP_SQUARE,BasicStroke.JOIN_ROUND,10,lineStyles[style.getLinesBetweenPointsStyle()],0); g.setStroke(s); g.drawPolyLine(lpbx, lpby, lpbn); g.setStroke(null); } if (style.getShowDataPoints()) { g.setColor(style.getDataPointColor()); g.drawPolySymbol(lpbx, lpby, style.getDataPointSize(), style.getDataPointStyle(), lpbn); } lpbn = 0; } } else { lpbx[lpbn] = (dataX == null) ? (oldx + (binWidth / 2)) : x; lpby[lpbn++] = y; } } oldx = x; // oldy = (y == Double.NaN) ? y0 : y; } if (lpbn > 0) { if (style.getShowLinesBetweenPoints()) { g.setColor(style.getLineColor()); BasicStroke s = new BasicStroke(style.getLinesBetweenPointsWidth(),BasicStroke.CAP_SQUARE,BasicStroke.JOIN_ROUND,10,lineStyles[style.getLinesBetweenPointsStyle()],0); g.setStroke(s); g.drawPolyLine(lpbx, lpby, lpbn); g.setStroke(null); } if (style.getShowDataPoints()) { g.setColor(style.getDataPointColor()); g.drawPolySymbol(lpbx, lpby, style.getDataPointSize(), style.getDataPointStyle(), lpbn); } } } } public void paintIcon(PlotGraphics g, int width, int height) { JASHist1DHistogramStyle style = source.style; if (style.getShowDataPoints()) { g.setColor(style.getDataPointColor()); g.drawSymbol( width / 2, height / 2, width / 2, style.getDataPointStyle()); } else if (style.getShowHistogramBars()) { if ( style.getHistogramFill() ) { g.setColor(style.getHistogramBarColor()); g.fillRect(1, 1, width - 2, height - 2); } else { g.setColor(style.getHistogramBarLineColor()); float flw = (float) style.getHistogramBarLineWidth()*3.0f; if (flw > (width/2)) flw = (float) (width/2 -1); BasicStroke s = new BasicStroke(flw,BasicStroke.CAP_SQUARE,BasicStroke.JOIN_ROUND,10,lineStyles[style.getHistogramBarLineStyle()],0); g.setStroke(s); g.drawLine(1, height/2, width-2, height/2); g.setStroke(null); } } else if (style.getShowLinesBetweenPoints()) { g.setColor(style.getLineColor()); float flw = (float) style.getHistogramBarLineWidth()*3.0f; if (flw > (width/2)) flw = (width > 2) ? (float) (width/2 -1) : 1; BasicStroke s = new BasicStroke(flw,BasicStroke.CAP_SQUARE,BasicStroke.JOIN_ROUND,10,lineStyles[style.getLinesBetweenPointsStyle()],0); g.setStroke(s); g.drawLine(1, height/2, width-2, height/2); g.setStroke(null); } else if (style.getShowErrorBars()) { g.setColor(style.getErrorBarColor()); BasicStroke s = new BasicStroke(style.getErrorBarWidth(),BasicStroke.CAP_SQUARE,BasicStroke.JOIN_ROUND,10,lineStyles[style.getErrorBarStyle()],0); g.setStroke(s); g.drawLine(1, height/2, width-2, height/2); g.setStroke(null); } else if (style.getHistogramFill()) { g.setColor(style.getHistogramBarColor()); g.fillRect(1, 1, width - 2, height - 2); } } public boolean titleIsChanged() { return source.isLegendChanged(); } void setData(double[] data, double[] plusError, double[] minusError, double xMin, double xMax) { this.data = data; this.plus = plusError; this.minus = minusError; this.xmin = xMin; this.xmax = xMax; } void setData(double[] x, double[] y, double[] plusError, double[] minusError) { this.dataX = x; this.data = y; this.plus = plusError; this.minus = minusError; } void setData(double[] data, double[] plusError, double[] minusError, String[] labels) { this.data = data; this.plus = plusError; this.minus = minusError; this.labels = labels; } } src/main/java/jas/hist/IntegerDataManager.java0000644000175000017500000000333211325547132021775 0ustar giovannigiovannipackage jas.hist; import jas.plot.DataArea; import jas.plot.DoubleAxis; import jas.plot.Legend; final class IntegerDataManager extends BinnedDataManager { IntegerDataManager(JASHist plot, DataArea da, Legend l, StatisticsBlock stats, int bins) { super(plot, da,l,stats,bins); // Configure the Axes xAxis = new DoubleAxis(); DoubleAxis yAxis = new DoubleAxis(); yAxis.setUseSuggestedRange(true); xm.setDataManager(this,true, xAxis); ym[0].setDataManager(this,false,yAxis); new DoubleAxisListener(xm); xm.setBins(bins); targetBins = bins; } JASHistData add(DataSource data) { if (data instanceof Rebinnable1DHistogramData) { Rebinnable1DHistogramData d = (Rebinnable1DHistogramData) data; // We only support adding items with integer axes if (d.getAxisType() != d.INTEGER) throw new DataManagerException("Incompatible data type for axis"); } else { XYDataSource d = (XYDataSource) data; // We only support adding items with integer axes if (d.getAxisType() != d.INTEGER) throw new DataManagerException("Incompatible data type for axis"); } return super.add(data); } protected void calcMinMaxBins(double x1, double x2) { int binWidth = (int) (1 + (x2-x1)/targetBins); int bins = (int) (1+(x2-x1)/binWidth); xLow = x1 - 0.5; double product = (double)binWidth*(double)bins; // See JAS-170 xHigh = xLow + product; double oldXMin = xAxis.getPlotMin(); double oldXMax = xAxis.getPlotMax(); if (xLow != oldXMin || xHigh != oldXMax) { xm.setBins(bins); xAxis.setMin(xLow); xAxis.setMax(xHigh); xAxis.getAxis().invalidate(); } } private DoubleAxis xAxis; private int targetBins; } src/main/java/jas/hist/util/0000755000175000017500000000000011325547132016424 5ustar giovannigiovannisrc/main/java/jas/hist/util/ScatterSliceAdapter.java0000644000175000017500000000671311325547132023164 0ustar giovannigiovannipackage jas.hist.util; import jas.hist.Rebinnable2DHistogramData; import jas.hist.ScatterEnumeration; import jas.hist.ScatterPlotSource; import javax.swing.event.EventListenerList; /** * Takes as its source a Rebinnable2DHistogramData which also * implements HasScatterPlotData and in addition to relaying the source * data to the destination, also implements HasSlices and SliceAdapter */ public class ScatterSliceAdapter extends TwoDSliceAdapter { private EventListenerList listenerList = new EventListenerList(); public ScatterSliceAdapter(Rebinnable2DHistogramData source) { super(source); } public ScatterSliceAdapter(ScatterPlotSource source) { super(new ScatterTwoDAdapter(source)); } public int addSlice(double x, double y, double width, double height, double phi) { if (scatter != null && scatter.hasScatterPlotData()) { int n = slices.size(); String title = (width==Double.POSITIVE_INFINITY?"Projection ":"Slice ")+n; slices.addElement(new Slice(title,x,y,width,height,phi)); fireSliceAdded(n); return n; } else return super.addSlice(x,y,width,height,phi); } private class Slice extends AbstractSlice { private double m_min, m_max; private boolean minMaxValid = false; Slice(String title, double x, double y, double width, double height, double phi) { super(title, (width == Double.POSITIVE_INFINITY)); this.parm = new DefaultSliceParameters(x,y,width,height,phi) { protected void changed() { sendUpdate(); } }; } public void sendUpdate() { minMaxValid = false; super.sendUpdate(); } public double[][] rebin(int bins, double min, double max, boolean wantErrors, boolean hurry) { double[] hist = new double[bins]; ScatterEnumeration e = scatter.startEnumeration(); double sinPhi = Math.sin(parm.phi); double cosPhi = Math.cos(parm.phi); double p0 = -parm.x*sinPhi + parm.y*cosPhi; double q0 = parm.x*cosPhi + parm.y*sinPhi; double[] point = new double[2]; while (e.getNextPoint(point)) { double q = point[0]*cosPhi + point[1]*sinPhi; if (!projection) { if (Math.abs(q-q0) > parm.width) continue; double p = - point[0]*sinPhi + point[1]*cosPhi; if (Math.abs(p-p0) > parm.height) continue; } if (q= bins) continue; hist[bin]++; } double[][] result = { hist }; return result; } private void calcMinMax() { minMaxValid = true; if (projection) { ScatterEnumeration e = scatter.startEnumeration(); double sinPhi = Math.sin(parm.phi); double cosPhi = Math.cos(parm.phi); double[] point = new double[2]; double min = 0; double max = 0; for (boolean first=true; e.getNextPoint(point); first=false) { double q = point[0]*cosPhi + point[1]*sinPhi; if (first) min = max = q; else { min = Math.min(min,q); max = Math.max(max,q); } } m_min = min; m_max = max; } else { double sinPhi = Math.sin(parm.phi); double cosPhi = Math.cos(parm.phi); double q0 = parm.x*cosPhi + parm.y*sinPhi; m_min = q0-parm.width; m_max = q0+parm.width; } } public double getMin() { if (!minMaxValid) calcMinMax(); return m_min; } public double getMax() { if (!minMaxValid) calcMinMax(); return m_max; } public int getBins() { return 40; } public boolean isRebinnable() { return true; } } } src/main/java/jas/hist/util/ObserverAdapter.java0000644000175000017500000000323411325547132022361 0ustar giovannigiovannipackage jas.hist.util; import java.util.Observable; import java.util.Observer; /** * An ObserverAdapter can be used as a base class for class that wants to act * as both and Observer and Observable, and relay things it observers to its * Observers. */ public class ObserverAdapter extends Observable implements Observer { // Ideally we would like to only add ourselves as an Observer if at least one person // is observing us. This makes things more efficient, and helps to avoid useless references // which hinder garbage collection private Observable obs; private boolean observing = false; public ObserverAdapter(Observable obs) { this.obs = obs; } public ObserverAdapter() { } public synchronized void setObservable(Observable newObs) { if (observing && obs != null) obs.deleteObserver(this); obs = newObs; if (observing && obs != null) obs.addObserver(this); } public synchronized void clearObservable() { setObservable(null); } /** * When the object which we are observing is updated, relay the response to our observers */ public void update(Observable o, Object arg) { setChanged(); notifyObservers(arg); } private void observe(boolean set) { if (set != observing) { if (obs != null) { if (set) obs.addObserver(this); else obs.deleteObserver(this); } observing = set; } } public synchronized void addObserver(Observer o) { super.addObserver(o); observe(true); } public synchronized void deleteObserver(Observer o) { super.deleteObserver(o); if (countObservers() == 0) observe(false); } public synchronized void deleteObservers() { super.deleteObservers(); observe(false); } } src/main/java/jas/hist/util/ScatterTwoDAdapter.java0000644000175000017500000000354111325547132022776 0ustar giovannigiovannipackage jas.hist.util; import jas.hist.HasScatterPlotData; import jas.hist.Rebinnable2DHistogramData; import jas.hist.ScatterEnumeration; import jas.hist.ScatterPlotSource; /** * An adaptor that converts a ScatterPlotSource to a DataSource that implements both * Rebinnable2DHistogramData and HasScatterPlotData */ public class ScatterTwoDAdapter extends ScatterSourceAdapter implements Rebinnable2DHistogramData, HasScatterPlotData { public ScatterTwoDAdapter(ScatterPlotSource source) { super(source); } public double[][][] rebin(int Xbins, double Xmin, double Xmax, int Ybins, double Ymin, double Ymax, boolean wantErrors, boolean hurry, boolean overflow) { double[][] hist = new double[Xbins + (overflow?2:0)][Ybins + (overflow?2:0)]; double XbinWidth = (Xmax - Xmin)/Xbins; double YbinWidth = (Ymax - Ymin)/Ybins; ScatterEnumeration e = overflow ? source.startEnumeration() : source.startEnumeration(Xmin,Xmax,Ymin,Ymax); double[] point = new double[2]; while (e.getNextPoint(point)) { // Note Math.floor returns the largest integer value <= the argument int Xbin = (int) Math.floor((point[0] - Xmin)/XbinWidth); int Ybin = (int) Math.floor((point[1] - Ymin)/YbinWidth); if (Xbin>=0 && Xbin=0 && YbinXbins) Xbin = Xbins+1; if (Ybin < 0 ) Ybin = Ybins; if (Ybin >Ybins) Ybin = Ybins+1; hist[Xbin][Ybin] += 1; } } double[][][] result = new double[1][][]; result[0] = hist; return result; } public int getXBins() { return 40; } public int getYBins() { return 40; } public boolean isRebinnable() { return true; } public String[] getXAxisLabels() { return null; } public String[] getYAxisLabels() { return null; } public boolean hasScatterPlotData() { return true; } }src/main/java/jas/hist/util/DefaultSliceParameters.java0000644000175000017500000000273211325547132023663 0ustar giovannigiovannipackage jas.hist.util; import jas.hist.SliceParameters; /** * Basic implementation of SliceParameters * @see jas.hist.SliceParameters */ public class DefaultSliceParameters implements SliceParameters { double x; double y; double width; double height; double phi; public DefaultSliceParameters(double x, double y, double width, double height, double phi) { this.x = x; this.y = y; this.width = width; this.height = height; this.phi = phi; } public String toString() { StringBuffer b = new StringBuffer(); b.append("SliceParameters: x="+x); b.append(",y="+y); b.append(",width="+width); b.append(",height="+height); b.append(",phi="+phi); return b.toString(); } public double getX() { return x; } public double getY() { return y; } public double getWidth() { return width; } public double getHeight() { return height; } public double getPhi() { return phi; } public void setX(double x) { if (x != this.x) { this.x = x; changed(); } } public void setY(double y) { if (this.y != y) { this.y = y; changed(); } } public void setWidth(double width) { if (this.width != width) { this.width = width; changed(); } } public void setHeight(double height) { if (this.height != height) { this.height = height; changed(); } this.height = height; } public void setPhi(double phi) { if (this.phi != phi) { this.phi = phi; changed(); } } protected void changed() { } } src/main/java/jas/hist/util/SliceListener.java0000644000175000017500000000026311325547132022035 0ustar giovannigiovannipackage jas.hist.util; import java.util.EventListener; public interface SliceListener extends EventListener { void sliceAdded(SliceEvent e); void sliceRemoved(SliceEvent e); } src/main/java/jas/hist/util/ScatterAdapter.java0000644000175000017500000000234511325547132022201 0ustar giovannigiovannipackage jas.hist.util; import jas.hist.HasScatterPlotData; import jas.hist.Rebinnable2DHistogramData; import jas.hist.ScatterEnumeration; /** * A ScatterAdapter takes a Rebinnable2DHistogramData source which (optionally) * also implements HasScatterPlotData, and in turn provides the same interface * to its observers. * * It is designed to be used as a base class for classes that do some more interesting * transformation of the data. */ public class ScatterAdapter extends TwoDAdapter implements HasScatterPlotData { protected HasScatterPlotData scatter; public ScatterAdapter(Rebinnable2DHistogramData source) { super(source); if (source instanceof HasScatterPlotData) scatter = (HasScatterPlotData) source; } public ScatterEnumeration startEnumeration(double xMin, double xMax, double yMin, double yMax) { if (scatter == null) throw new RuntimeException("No Scatter Plot Data Awailable"); return scatter.startEnumeration(xMin,xMax,yMin,yMax); } public ScatterEnumeration startEnumeration() { if (scatter == null) throw new RuntimeException("No Scatter Plot Data Awailable"); return scatter.startEnumeration(); } public boolean hasScatterPlotData() { return scatter != null && scatter.hasScatterPlotData(); } } src/main/java/jas/hist/util/SliceAdapter.java0000644000175000017500000000021711325547132021627 0ustar giovannigiovannipackage jas.hist.util; public interface SliceAdapter { void addSliceListener(SliceListener l); void removeSliceListener(SliceListener l); } src/main/java/jas/hist/util/TwoDSliceAdapter.java0000644000175000017500000002265011325547132022432 0ustar giovannigiovannipackage jas.hist.util; import jas.hist.HasSlices; import jas.hist.Rebinnable1DHistogramData; import jas.hist.Rebinnable2DHistogramData; import jas.hist.SliceParameters; import java.util.Vector; import javax.swing.event.EventListenerList; /** * A Two2SliceAdapter can be used to convert any * Rebinnable2DHistogramData object to a Rebinnable2DHistogramData * which also implements HasSlices */ public class TwoDSliceAdapter extends ScatterAdapter implements HasSlices, SliceAdapter { protected Vector slices = new Vector(); private EventListenerList listenerList = new EventListenerList(); public TwoDSliceAdapter(Rebinnable2DHistogramData source) { super(source); } public void addSliceListener(SliceListener l) { listenerList.add(SliceListener.class, l); } public void removeSliceListener(SliceListener l) { listenerList.remove(SliceListener.class, l); } // Notify all listeners that have registered interest for // notification on this event type. The event instance // is lazily created using the parameters passed into // the fire method. protected void fireSliceAdded(int index) { SliceEvent sliceEvent = null; // Guaranteed to return a non-null array Object[] listeners = listenerList.getListenerList(); // Process the listeners last to first, notifying // those that are interested in this event for (int i = listeners.length-2; i>=0; i-=2) { if (listeners[i]==SliceListener.class) { // Lazily create the event: if (sliceEvent == null) sliceEvent = new SliceEvent(this,SliceEvent.EventType.SLICEADDED,index); ((SliceListener)listeners[i+1]).sliceAdded(sliceEvent); } } } protected void fireSliceRemoved(int index) { SliceEvent sliceEvent = null; // Guaranteed to return a non-null array Object[] listeners = listenerList.getListenerList(); // Process the listeners last to first, notifying // those that are interested in this event for (int i = listeners.length-2; i>=0; i-=2) { if (listeners[i]==SliceListener.class) { // Lazily create the event: if (sliceEvent == null) sliceEvent = new SliceEvent(this,SliceEvent.EventType.SLICEREMOVED,index); ((SliceListener)listeners[i+1]).sliceRemoved(sliceEvent); } } } public int getNSlices() { return slices.size(); } public SliceParameters getSliceParameters(int n) { return ((AbstractSlice) slices.elementAt(n)).getParameters(); } public Rebinnable1DHistogramData getSlice(int n) { return (Rebinnable1DHistogramData) slices.elementAt(n); } public boolean canAddRemoveSlices() { return true; } public int addSlice(double x, double y, double width, double height, double phi) { int n = slices.size(); String title = (width==Double.POSITIVE_INFINITY?"Projection ":"Slice ")+n; if (source.isRebinnable()) { slices.addElement(new RebinnableSlice(title,x,y,width,height,phi)); } else { slices.addElement(new NonRebinnableSlice(title,x,y,width,height,phi)); } fireSliceAdded(n); return n; } public void removeSlice(int n) { fireSliceRemoved(n); slices.removeElementAt(n); } private class NonRebinnableSlice extends AbstractSlice { NonRebinnableSlice(String title, double x, double y, double width, double height, double phi) { super(title, (width == Double.POSITIVE_INFINITY)); this.parm = new DefaultSliceParameters(x,y,width,height,phi) { // We need to override all the set methods, since we are restrained by the source binning public void setPhi(double value) { value += 2*Math.PI; value %= Math.PI; value = (value > Math.PI/4 && value < 3*Math.PI/4) ? Math.PI/2 : 0; super.setPhi(value); } public void setX(double value) { double min = source.getXMin(); double max = source.getXMax(); int bins = source.getXBins(); int bin = Math.round((float) (bins*(value-min)/(max-min))); super.setX(min + bin*(max-min)/bins); } public void setY(double value) { double min = source.getYMin(); double max = source.getYMax(); int bins = source.getYBins(); int bin = Math.round((float) (bins*(value-min)/(max-min))); super.setY(min + bin*(max-min)/bins); } public void setWidth(double value) { double min,max; int bins; if (parm.phi == 0) { min = source.getXMin(); max = source.getXMax(); bins = source.getXBins(); } else { min = source.getYMin(); max = source.getYMax(); bins = source.getYBins(); } double binWidth = (max-min)/bins; int w = Math.round((float) (value/binWidth)); super.setWidth(w*binWidth); } public void setHeight(double value) { double min,max; int bins; if (parm.phi == 0) { min = source.getYMin(); max = source.getYMax(); bins = source.getYBins(); } else { min = source.getXMin(); max = source.getXMax(); bins = source.getXBins(); } double binWidth = (max-min)/bins; int w = Math.round((float) (value/binWidth)); super.setHeight(w*binWidth); } protected void changed() { sendUpdate(); } }; } public double[][] rebin(int bins, double min, double max, boolean wantErrors, boolean hurry) { double xmin = source.getXMin(); double xmax = source.getXMax(); double ymin = source.getYMin(); double ymax = source.getYMax(); int xbins = source.getXBins(); int ybins = source.getYBins(); double[][][] sresult = source.rebin(xbins,xmin,xmax,ybins,ymin,ymax,wantErrors,hurry,false); double[][] sdata = sresult[0]; double [] hist = new double[bins]; if (parm.phi == 0) // if slice is || to X axis { int minXBin = Math.round((float) ((min-xmin)*xbins/(xmax-xmin))); int maxXBin = Math.round((float) ((max-xmin)*xbins/(xmax-xmin))); if (maxXBin-minXBin != bins) throw new RuntimeException("Failed sanity check"); int minYBin = Math.round((float) ((parm.y-parm.height-ymin)*ybins/(ymax-ymin))); int maxYBin = Math.round((float) ((parm.y+parm.height-ymin)*ybins/(ymax-ymin))); for (int i = Math.max(minXBin,0); i < Math.min(maxXBin,xbins); i++) { for (int j = Math.max(minYBin,0); j < Math.min(maxYBin,ybins); j++) { hist[i-minXBin] += sdata[i][j]; } } } else { int minXBin = Math.round((float) ((min-ymin)*ybins/(ymax-ymin))); int maxXBin = Math.round((float) ((max-ymin)*ybins/(ymax-ymin))); if (maxXBin-minXBin != bins) throw new RuntimeException("Failed sanity check"); int minYBin = Math.round((float) ((parm.x-parm.height-xmin)*xbins/(xmax-xmin))); int maxYBin = Math.round((float) ((parm.x+parm.height-xmin)*xbins/(xmax-xmin))); for (int i = Math.max(minXBin,0); i < Math.min(maxXBin,ybins); i++) { for (int j = Math.max(minYBin,0); j < Math.min(maxYBin,xbins); j++) { hist[i-minXBin] += sdata[j][i]; } } } double[][] result = { hist }; return result; } public double getMin() { if (projection) { return parm.phi == 0 ? source.getXMin() : source.getYMin(); } else { return parm.phi == 0 ? parm.x-parm.width : parm.y-parm.width; } } public double getMax() { if (projection) { return parm.phi == 0 ? source.getXMax() : source.getYMax(); } else { return parm.phi == 0 ? parm.x+parm.width : parm.y+parm.width; } } public int getBins() { double min = getMin(); double max = getMax(); double binWidth = parm.phi == 0 ? (source.getXMax() - source.getXMin())/source.getXBins() : (source.getYMax() - source.getYMin())/source.getYBins(); return Math.round((float) ((max-min)/binWidth)); } public boolean isRebinnable() { return false; } } private class RebinnableSlice extends AbstractSlice { RebinnableSlice(String title, double x, double y, double width, double height, double phi) { super(title, (width == Double.POSITIVE_INFINITY)); this.parm = new DefaultSliceParameters(x,y,width,height,phi) { // We need to override the setPhi method, since we only allow phi = 0 or PI/2 public void setPhi(double value) { value += 2*Math.PI; value %= Math.PI; value = (value > Math.PI/4 && value < 3*Math.PI/4) ? Math.PI/2 : 0; super.setPhi(value); } protected void changed() { sendUpdate(); } }; } public double[][] rebin(int bins, double min, double max, boolean wantErrors, boolean hurry) { // Since we know our source is rebinnable, we just ask it to do all the hard work! if (parm.phi == 0) { double[][][] data = source.rebin(bins,min,max,1,parm.y-parm.height,parm.y+parm.height,wantErrors,hurry,false); double[] hist = new double[bins]; for (int i=0; i"); pw.println(""); final double[] d = new double[2]; if (dataSource.hasScatterPlotData()) { ScatterEnumeration se = dataSource.startEnumeration(); while (se.getNextPoint(d)) { pw.println(d[0] + "," + d[1]); } } pw.outdent(); pw.println(""); pw.println(""); pw.println(""); pw.outdent(); pw.println(""); }*/ } src/main/java/jas/hist/FunctionFactoryError.java0000644000175000017500000000020411325547132022435 0ustar giovannigiovannipackage jas.hist; public class FunctionFactoryError extends Exception { public FunctionFactoryError(String s) { super(s); } } src/main/java/jas/hist/JASHistPropDataStyle.java0000644000175000017500000000163411325547132022237 0ustar giovannigiovannipackage jas.hist; import jas.util.PropertyBinding; import jas.util.PropertyPage; import java.awt.Dimension; import java.awt.FlowLayout; import javax.swing.JCheckBox; import javax.swing.JComboBox; import javax.swing.JLabel; final class JASHistPropDataStyle extends PropertyPage { JASHistPropDataStyle() { setLayout(new FlowLayout(FlowLayout.LEFT)); JCheckBox show = new JCheckBox("Is Showing"); show.setMnemonic('I'); JComboBox axis = new JComboBox(); axis.addItem("Y0"); axis.addItem("Y1"); add(show); add(new JLabel("Y Axis:")); add(axis); addBinding(new PropertyBinding(show,"Showing")); addBinding(new PropertyBinding(axis,"YAxis")); } public Dimension getMaximumSize() { Dimension d1 = super.getMaximumSize(); Dimension d2 = super.getPreferredSize(); d1.height = d2.height; return d1; } } src/main/java/jas/hist/FunctionData.java0000644000175000017500000000050011325547132020664 0ustar giovannigiovannipackage jas.hist; public interface FunctionData extends DataSource { public double valueAt(double x) throws FunctionValueUndefined; public abstract double[] getParameterValues(); public String[] getParameterNames(); public abstract void setParameter(int index, double value) throws InvalidFunctionParameter; } src/main/java/jas/hist/SliceOverlay.java0000644000175000017500000002117111325547132020715 0ustar giovannigiovannipackage jas.hist; import jas.plot.DoubleCoordinateTransformation; import jas.plot.PlotGraphics; import java.awt.Color; class ProjectionData extends SliceData { ProjectionData(SliceParameters p) { super(p); } void paint(PlotGraphics g, DoubleCoordinateTransformation xt, DoubleCoordinateTransformation yt) { // Note: phi is the direction in which we project, so the line we project // onto is at 90 degrees to that double phi = Math.PI/2 + parm.getPhi()+2*Math.PI; double phi0 = Math.atan2(xt.getPlotMax()-xt.getPlotMin(),yt.getPlotMax()-yt.getPlotMin())+2*Math.PI; double yc = (yt.getPlotMin()+yt.getPlotMax())/2; double xc = (xt.getPlotMin()+xt.getPlotMax())/2; double dx, dy; phi %= Math.PI; phi0 %= Math.PI; if (phi Math.PI - phi0) { dy = (yc - yt.getPlotMin()); dx = - dy*Math.tan(phi); } else { dx = (xc - xt.getPlotMin()); dy = dx * Math.tan(phi - Math.PI/2); } g.setColor(Color.black); g.drawLine(xc-dx, yc-dy, xc+dx,yc+dy); } public Handle[] getHandles(double xlow, double xhigh, double ylow, double yhigh) { double xc = (xlow+xhigh)/2; double yc = (ylow+yhigh)/2; double dx = (xhigh-xlow)/4; double dy = (yhigh-ylow)/4; double phi0 = Math.atan2(dx,dy)+2*Math.PI; double phi = Math.PI/2 + parm.getPhi()+2*Math.PI; phi %= Math.PI; phi0 %= Math.PI; double x,y; if (phi < phi0 || phi > Math.PI - phi0) { y = yc+dy; x = xc-dy*Math.tan(phi); } else { x = xc+dx; y = yc+dx*Math.tan(phi - Math.PI/2); } Handle[] result = { new ProjectionHandle(x,y,xc,yc) }; return result; } private class ProjectionHandle extends Handle { ProjectionHandle(double x, double y, double xc, double yc) { this.x = x; this.y = y; this.xc = xc; this.yc = yc; } public double getX() { return x; } public double getY() { return y; } public void moveTo(double xNew, double yNew) { x = xNew; y = yNew; double phiNew = Math.atan2(yNew-yc,xNew-xc); parm.setPhi(phiNew); } private double x,y; private double xc,yc; } } class SliceData implements HasHandles, DataSource { SliceData(SliceParameters p) { this.parm = p; } /***gpg*** 4/20/00 I would have called these signW and signH respectively. Since they are used to tell whether the width or height of a particular point is to the right/left or up/down relative to the center handle. The numbering of handles is as follow for MiddleHandles: + 2 + 3 + 1 + 0 + for CornerHandles: 2 + 1 + + + 3 + 0 note that the width and the height are actually the halfwidth and halfheight. ***gpg***/ private final static int[] signA = { +1, +1, -1, -1 }; private final static int[] signB = { -1, +1, +1, -1 }; protected SliceParameters parm; void paint(PlotGraphics g, DoubleCoordinateTransformation xt, DoubleCoordinateTransformation yt) { g.setColor(Color.lightGray); g.drawLine(getCornerX(1),getCornerY(1),getCornerX(2),getCornerY(2)); g.drawLine(getCornerX(2),getCornerY(2),getCornerX(3),getCornerY(3)); g.drawLine(getCornerX(3),getCornerY(3),getCornerX(0),getCornerY(0)); g.setColor(Color.black); g.drawLine(getCornerX(0),getCornerY(0),getCornerX(1),getCornerY(1)); } private double getCornerX(int index) { /***gpg*** 4/20/00 Translation + Rotation --- I don't understand the significance of sin(-phi) or cos(-phi) so I have use what I believe is standard notation. see above note for the significance of signA and signB note: x = signB[index]*parm.getWidth() y = signA[index]*parm.getHeight() Rotation: x' = x*cos(phi) + y*sin(phi) y' = -x*sin(phi) + y*cos(phi) Translation: x" = x0 + x' y" = y0 + y' ***gpg***/ // return parm.getX() - signA[index]*parm.getHeight()*Math.sin(-parm.getPhi()) // + signB[index]*parm.getWidth() *Math.cos(-parm.getPhi()); return parm.getX() + signB[index]*parm.getWidth() *Math.cos(parm.getPhi()) + signA[index]*parm.getHeight()*Math.sin(parm.getPhi()); } private double getCornerY(int index) {//***gpg*** getCornerX. // return parm.getY() + signA[index]*parm.getHeight()*Math.cos(-parm.getPhi()) // + signB[index]*parm.getWidth() *Math.sin(-parm.getPhi()); return parm.getY() - signB[index]*parm.getWidth() *Math.sin( parm.getPhi()) + signA[index]*parm.getHeight()*Math.cos( parm.getPhi()); } private double getPhiOffset(int index) { return Math.atan2(signA[index]*parm.getHeight(),signB[index]*parm.getWidth()); } public Handle[] getHandles(double xlow, double xhigh, double ylow, double yhigh) { Handle[] result = new Handle[9]; for (int i=0; i<4; i++) result[i] = new CornerHandle(i); for (int i=0; i<4; i++) result[i+4] = new MiddleHandle(i); result[8] = new MoveHandle(); return result; } /** * Corner handles allow the slice to be resized and rotated while keeping * the center fixed and the aspect ratio fixed */ private class CornerHandle extends Handle { private int index; CornerHandle(int i) { index = i; } public double getX() { return getCornerX(index); } public double getY() { return getCornerY(index); } public void moveTo(double xNew, double yNew) { double x = parm.getX(); double y = parm.getY(); // double width = parm.getWidth(); //***gpg*** removed 4/20/00 reason corner handles only change angle. // double height = parm.getHeight(); //***gpg*** removed 4/20/00 double phiNew = Math.atan2(yNew-y,xNew-x); // double newSize = Math.sqrt((xNew-x)*(xNew-x) + (yNew - y)*(yNew-y)); //***gpg*** removed 4/20/00 // double oldSize = Math.sqrt(width*width + height*height); //***gpg*** removed 4/20/00 parm.setPhi(-phiNew + getPhiOffset(index)); // parm.setWidth(width * newSize/oldSize); //***gpg*** removed 4/20/00 // parm.setHeight(height * newSize/oldSize); //***gpg*** removed 4/20/00 } } /** * Middle handles allow one dimension to be increased or decreased while keeping * the center and opposite dimension fixed. */ private class MiddleHandle extends Handle { private int index; MiddleHandle(int i) { index = i; } public double getX() { return (getCornerX(index) + getCornerX((index+1)%4))/2; //***gpg*** removed 4/20/00 //***gpg this is the same as above. 4/20/00 // if(index % 2 == 0) // { return parm.getX() + (signA[index]*parm.getHeight())*Math.sin(parm.getPhi()); // }else // { return parm.getX() + (signB[index]*parm.getWidth())*Math.cos(parm.getPhi()); // } } public double getY() { return (getCornerY(index) + getCornerY((index+1)%4))/2; //***gpg*** removed 4/20/00 //***gpg this is the same as above. 4/20/00 // if(index % 2 == 0) // { return parm.getY() + (signA[index]*parm.getHeight())*Math.cos(parm.getPhi()); // }else // { return parm.getY() - (signB[index]*parm.getWidth())*Math.sin(parm.getPhi()); // } } public void moveTo(double xNew, double yNew) { double x = parm.getX(); double y = parm.getY(); double phiNew = Math.atan2(yNew-y,xNew-x); double newDist = Math.sqrt((xNew-x)*(xNew-x) + (yNew - y)*(yNew-y)); if (index % 2 == 0) // change height { newDist *= Math.sin(phiNew-parm.getPhi()); //***gpg*** added 4/20/00 reason only allow height changes parm.setHeight(Math.abs(newDist)); }else { newDist *= Math.cos(phiNew-parm.getPhi()); //***gpg*** added 4/20/00 reason only allow width changes parm.setWidth(Math.abs(newDist)); } // parm.setPhi(-phiNew + (getPhiOffset(index)+getPhiOffset((index+1)%4))/2); //***gpg*** removed 4/20/00 reason MiddleHandles are not allowed to change the orientation } } private class MoveHandle extends Handle { public double getX() { return parm.getX(); } public double getY() { return parm.getY(); } public void moveTo(double xNew, double yNew) { parm.setX(xNew); parm.setY(yNew); } } public String getTitle() { return null; } } class SliceOverlay extends OverlayWithHandles { protected SliceData data; SliceOverlay(SliceParameters p) { this(p.getWidth() == Double.POSITIVE_INFINITY ? new ProjectionData(p) : new SliceData(p)); } SliceOverlay(SliceData d) { super(d); data = d; } public void paint(PlotGraphics g, boolean isPrinting) { DoubleCoordinateTransformation xt = (DoubleCoordinateTransformation) container.getXTransformation(); DoubleCoordinateTransformation yt = (DoubleCoordinateTransformation) container.getYTransformation(); g.setTransformation(xt,yt); data.paint(g,xt,yt); super.paint(g); } } src/main/java/jas/hist/ManagedAxis.java0000644000175000017500000002747211325547132020507 0ustar giovannigiovannipackage jas.hist; import jas.plot.Axis; import jas.plot.AxisType; import jas.plot.DateAxis; import jas.plot.DoubleAxis; import jas.plot.EditableLabel; import jas.plot.StringAxis; import java.awt.Component; import java.awt.event.ActionEvent; import java.io.Externalizable; import java.io.IOException; import java.io.ObjectInput; import java.io.ObjectOutput; import java.util.Date; import javax.swing.JCheckBoxMenuItem; import javax.swing.JLabel; import javax.swing.JMenuItem; import javax.swing.JPopupMenu; // This has to be public so that the properties dialog can use reflection on it??? // (otherwise get IllegalAccessException) public final class ManagedAxis extends Axis implements JASHistAxis, Externalizable { ManagedAxis(int orientation) { super(orientation); this.dataManager = null; this.binned = false; } ManagedAxis(DataManager dm, int orientation, boolean binned) { super(orientation); this.dataManager = dm; this.binned = binned; } // for deserialization/deserialization only do not call public ManagedAxis() { } void setDataManager(DataManager dm, boolean binned) { this.dataManager = dm; this.binned = binned; } void setDataManager(DataManager dm, boolean binned, AxisType t) { this.dataManager = dm; this.binned = binned; setType(t); } public void writeExternal(ObjectOutput out) throws IOException { out.writeInt(bins); out.writeBoolean(rangeAutomatic); if (!rangeAutomatic) { out.writeDouble(getMin()); out.writeDouble(getMax()); } out.writeBoolean(allowSuppressedZero); out.writeBoolean(fixed); out.writeBoolean(binned); out.writeInt(position); final AxisType type = getType(); out.writeInt(getAxisOrientation()); out.writeBoolean(getOnLeftSide()); out.writeObject(type); out.writeObject(dataManager); // THINGS THAT SHOULD BE INCLUDED LATER (here and in readObject): // - axis colors (i.e., minorTickMarkColor, axisLineColor, textColor, etc.) // (no point in doing this one now because they are always black) // - whether is visible // (no point in doing this now because can't change whether is visible) } public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { bins = in.readInt(); rangeAutomatic = in.readBoolean(); if (!rangeAutomatic) { setMin(in.readDouble()); setMax(in.readDouble()); } else attentionNeeded(); allowSuppressedZero = in.readBoolean(); fixed = in.readBoolean(); binned = in.readBoolean(); position = in.readInt(); setAxisOrientation(in.readInt()); setOnLeftSide(in.readBoolean()); setType((AxisType) in.readObject()); dataManager = (DataManager) in.readObject(); } public boolean isVertical() { return getAxisOrientation() == Axis.VERTICAL; } public boolean isLogarithmic() { AxisType type = getType(); if (type instanceof DoubleAxis) { return ((DoubleAxis) type).isLogarithmic(); } return false; } public void setLogarithmic(boolean value) { AxisType type = getType(); if (type instanceof DoubleAxis) { ((DoubleAxis) type).setLogarithmic(value); attentionNeeded(); } } public boolean isShowing() { // TODO: Not supported yet by Axis return true; } public void setShowing(boolean value) { // TODO: Not supported yet by Axis } /** * @return the EditableLabel itself, not just the text * @see #getLabel() */ public EditableLabel getLabelObject() { if (dataManager == null) return null; EditableLabel label = dataManager.getLabel(this); if (label == null) return null; return label; } /** * @return the label text * @see #getLabelObject() */ public String getLabel() { EditableLabel label = dataManager.getLabel(this); return label==null ? "" : label.getText(); } /** * sets the label to be the EditableLabel passed in * @param p_newLabel the new label */ public void setLabelObject(EditableLabel p_newLabel) { dataManager.setLabel(this, p_newLabel); } /** * sets the label text, creating the label if needed * @param s the new text of the label */ public void setLabel(String s) { EditableLabel label = dataManager.getLabel(this); if (label == null) { label = new EditableLabel(s,"Axis Label",JLabel.LEFT); dataManager.setLabel(this, label); } else label.setText(s); revalidate(); // Attract the attention of the layout manager! } public double getMin() { // getParent().validate(); AxisType type = getType(); if (type instanceof DoubleAxis) { return ((DoubleAxis) type).getPlotMin(); } else if (type instanceof DateAxis) { return ((DateAxis) type).getAxisMin()/1000.; } throw new RuntimeException("getMin undefined for this axis type"); } public void setMin(double d) { AxisType type = getType(); if (type instanceof DoubleAxis) { rangeAutomatic = false; ((DoubleAxis) type).setMin(d); attentionNeeded(); } else if (type instanceof DateAxis) { rangeAutomatic = false; ((DateAxis) type).setMin((long) (d*1000)); attentionNeeded(); } else throw new RuntimeException("setMin undefined for this axis type"); } public double getMax() { AxisType type = getType(); if (type instanceof DoubleAxis) { return ((DoubleAxis) type).getPlotMax(); } else if (type instanceof DateAxis) { return ((DateAxis) type).getAxisMax()/1000.; } throw new RuntimeException("getMax undefined for this axis type"); } public void setMax(double d) { AxisType type = getType(); if (type instanceof DoubleAxis) { rangeAutomatic = false; ((DoubleAxis) type).setMax(d); attentionNeeded(); } else if (type instanceof DateAxis) { rangeAutomatic = false; ((DateAxis) type).setMax((long) (d*1000)); invalidate(); attentionNeeded(); } else throw new RuntimeException("setMax undefined for this axis type"); } public void setRange(double min, double max) { setMin(min); setMax(max); } public Object getMinObject() { if (getAxisType() == DATE) return new Date((long) (getMin()*1000)); else return new Double(getMin()); } public Object getMaxObject() { if (getAxisType() == DATE) return new Date((long) (getMax()*1000)); else return new Double(getMax()); } public void setMinObject(Object value) { try { double min; if (getAxisType() == DATE) min = ((Date) value).getTime()/1000; else min = ((Double) value).doubleValue(); setMin(min); // attentionNeeded(); // invalidate(); } catch (ClassCastException x) { throw new IllegalArgumentException("Argument to setMinObject is of wrong type"); } } public void setMaxObject(Object value) { try { double max; if (getAxisType() == DATE) max = ((Date) value).getTime()/1000; else max = ((Double) value).doubleValue(); setMax(max); // attentionNeeded(); // invalidate(); } catch (ClassCastException x) { throw new IllegalArgumentException("Argument to setMaxObject is of wrong type"); } } public boolean getRangeAutomatic() { return rangeAutomatic; } public void setRangeAutomatic(boolean b) { rangeAutomatic = b; attentionNeeded(); } public boolean getAllowSuppressedZero() { return allowSuppressedZero; } public void setAllowSuppressedZero(boolean b) { allowSuppressedZero = b; attentionNeeded(); } public boolean isBinned() { return binned; } public void setBinned(boolean value) { binned = value; } public boolean isFixed() { return fixed; } public void setFixed(boolean value) { fixed = value; } public int getBins() { return bins; } public void setBins(int value) { bins = value; attentionNeeded(); } public double getBinWidth() { if (!binned) return 0; double range = getMax() - getMin(); return range/bins; } public void setBinWidth(double value) { double range = getMax() - getMin(); bins = (int) Math.max(1,range/value); attentionNeeded(); } public boolean getShowOverflows() { return showOverflows; } public void setShowOverflows(boolean value) { showOverflows = value; attentionNeeded(); } public int getLabelPosition() { return 0; } public void setLabelPosition(int pos) { //final int positions[] = //{ // JCLegend.EAST, JCLegend.WEST, JCLegend.NORTHEAST, // JCLegend.SOUTHEAST, JCLegend.NORTHWEST, JCLegend.SOUTHEAST //}; //JCAxisTitle t = yAxis.getTitle(); //if (t != null) t.setPlacement(positions[pos]); } public int getPosition() { return position; } public void setPosition(int value) { //if (!isVertical()) throw new IllegalArgumentException("Cannot set position of X axis"); //if (value == LEFT ) axis.setPlacement(JCAxis.MIN); //else if (value == RIGHT) axis.setPlacement(JCAxis.MAX); //else throw new IllegalArgumentException("Illegal argument to setPosition"); position = value; } public int getAxisType() { AxisType type = getType(); if (type instanceof DateAxis) return DATE; if (type instanceof StringAxis) return STRING; return DOUBLE; } public void setAxisType(int value) { if (value != getAxisType()) { if (value == DATE) { setType(new DateAxis()); } else if (value == STRING) { setType(new StringAxis()); } else { setType(new DoubleAxis()); } } } /** * attention needed is called by ManagedAxis when it wants to attract the * attention of the DataManager, e.g. after the user updates some property. */ private void attentionNeeded() { boolean requestedAttention = needsAttention; needsAttention = true; if (!requestedAttention && dataManager != null) dataManager.invalidate(); } /** * set attention needed can be called by the DataManager to remind itself * it needs to work on the axis */ void setAttentionNeeded() { needsAttention = true; } /** * called by the DataManager when it has updated itself to take into account * changes to the axis. Resets the needsAttention flag. */ void payingAttention() { needsAttention = false; } /** * return true if attnetion is needed */ boolean needsAttention() { return needsAttention; } public void modifyPopupMenu(final JPopupMenu menu, final Component source) { if (dataManager != null && !(dataManager instanceof DefaultDataManager)) { super.modifyPopupMenu(menu,source); if (getAxisType() != JASHistAxis.STRING) // BUG: should have a better way of testing whether these items are appropriate { if (getAxisType() != JASHistAxis.DATE) // BUG: should have a better way of testing whether this item is appropriate { menu.add(new JCheckBoxMenuItem("Logarithmic", isLogarithmic()) { final protected void fireActionPerformed(final ActionEvent e) { setLogarithmic(isSelected()); } }); } menu.add(new JCheckBoxMenuItem("Range Automatic", getRangeAutomatic()) { final protected void fireActionPerformed(final ActionEvent e) { setRangeAutomatic(isSelected()); } }); if (getAxisType() != JASHistAxis.DATE) // BUG: should have a better way of testing whether this item is appropriate { final JCheckBoxMenuItem suppZero = new JCheckBoxMenuItem("Suppressed Zeros", getAllowSuppressedZero()) { final protected void fireActionPerformed(final ActionEvent e) { setAllowSuppressedZero(isSelected()); } }; menu.add(suppZero); suppZero.setEnabled(getRangeAutomatic()); } } menu.add(new JMenuItem("Axis Properties...") { final protected void fireActionPerformed(final ActionEvent e) { dataManager.getPlot().showProperties( getAxisOrientation() == Axis.VERTICAL ? (getOnLeftSide() ? JASHistPropertyDialog.Y_AXIS_LEFT : JASHistPropertyDialog.Y_AXIS_RIGHT) : JASHistPropertyDialog.X_AXIS); } }); } } private int bins; private boolean rangeAutomatic = true; private boolean allowSuppressedZero = true; private boolean showOverflows = false; private boolean needsAttention = true; private boolean fixed = false; private boolean binned; private int position; private DataManager dataManager; } src/main/java/jas/hist/IndeterminateMatrix.java0000644000175000017500000000011111325547132022260 0ustar giovannigiovannipackage jas.hist; public class IndeterminateMatrix extends Exception{}; src/main/java/jas/hist/SliceableDataManager.java0000644000175000017500000001107311325547132022264 0ustar giovannigiovannipackage jas.hist; import jas.plot.DataArea; import jas.plot.Legend; import jas.plot.Overlay; import java.awt.Component; import java.awt.event.ActionEvent; import java.util.Enumeration; import java.util.Vector; import javax.swing.JMenu; import javax.swing.JMenuItem; import javax.swing.JPopupMenu; abstract class SliceableDataManager extends AbstractDataManager implements SupportsSlices { private Vector slices = new Vector(); SliceableDataManager(JASHist plot, final DataArea da, final Legend l, StatisticsBlock stats) { super(plot, da, l, stats); } public void addSlice(SliceParameters sp) { // Maybe we should make a JASHistSliceData here Overlay so = new SliceOverlay(sp); slices.addElement(so); da.add(so); } public void removeAllSlices() { Enumeration e = slices.elements(); while (e.hasMoreElements()) { SliceOverlay so = (SliceOverlay) e.nextElement(); da.remove(so); //so.destroy(); } slices.removeAllElements(); } void destroy() { super.destroy(); removeAllSlices(); slices.removeAllElements(); } public void fillSliceMenu(JMenu menu) { menu.add(addPerDataSourceMenu("Add Slice/Projection",new DataSourceMenuFactory() { public JMenu createMenu(String name, final JASHistData ds) { return new SliceMenu(name,ds); } })); menu.add(addPerDataSourceMenu("Remove Slice/Projection",new DataSourceMenuFactory() { public JMenu createMenu(String name, final JASHistData ds) { return new RemoveSliceMenu(name,ds); } })); } void modifyPopupMenu(final JPopupMenu menu, final Component source) { menu.add(addPerDataSourceMenu("Add Slice/Projection",new DataSourceMenuFactory() { public JMenu createMenu(String name, final JASHistData ds) { return new SliceMenu(name,ds); } })); menu.add(addPerDataSourceMenu("Remove Slice/Projection",new DataSourceMenuFactory() { public JMenu createMenu(String name, final JASHistData ds) { return new RemoveSliceMenu(name,ds); } })); } final private class SliceMenu extends JMenu { public SliceMenu(String name, JASHistData data) { super(name); DataSource ds = data.getDataSource(); boolean slice = ds instanceof HasSlices && ((HasSlices) ds).canAddRemoveSlices(); setEnabled(slice); if (slice) { hasSlices = (HasSlices) ds; this.add(new SliceItem("X Projection",0)); this.add(new SliceItem("Y Projection",Math.PI/2)); this.add(new SliceItem("X Slice",xm,ym[0],0)); this.add(new SliceItem("Y Slice",xm,ym[0],Math.PI/2)); } } private HasSlices hasSlices; private class SliceItem extends JMenuItem { SliceItem(String name, double phi) { super(name); this.phi = phi; this.x = 0; this.y = 0; this.width = Double.POSITIVE_INFINITY; this.height = Double.POSITIVE_INFINITY; } SliceItem(String name, ManagedAxis x, ManagedAxis y, double phi) { super(name); this.phi = phi; this.x = (x.getMin()+x.getMax())/2; this.y = (y.getMin()+y.getMax())/2; if (phi == 0) { this.width = (x.getMax()-x.getMin())/4; this.height = (y.getMax()-y.getMin())/4; } else { this.height = (x.getMax()-x.getMin())/4; this.width = (y.getMax()-y.getMin())/4; } } public void fireActionPerformed(ActionEvent e) { int n = hasSlices.addSlice(x,y,width,height,phi); addSlice(hasSlices.getSliceParameters(n)); } private double phi; private double x; private double y; private double width; private double height; } } final private class RemoveSliceMenu extends JMenu { public RemoveSliceMenu(String name, JASHistData data) { super(name); DataSource ds = data.getDataSource(); boolean slice = ds instanceof HasSlices && ((HasSlices) ds).canAddRemoveSlices() && ((HasSlices) ds).getNSlices()>0; setEnabled(slice); if (slice) { hasSlices = (HasSlices) ds; //for (int i=0; i1) //{ add(new JMenuItem("Remove All") { public void fireActionPerformed(ActionEvent e) { removeAllSlices(); for (int i=hasSlices.getNSlices(); i>0;) { hasSlices.removeSlice(--i); } } }); //} } } private HasSlices hasSlices; private class SliceItem extends JMenuItem { SliceItem(String name, int index) { super(name); this.index = index; } public void fireActionPerformed(ActionEvent e) { hasSlices.removeSlice(index); } private int index; } } } src/main/java/jas/hist/XML1DHistDataSource.java0000644000175000017500000003223611325547132021750 0ustar giovannigiovannipackage jas.hist; import jas.hist.normalization.Normalizer; import jas.util.xml.XMLNodeTraverser; import java.lang.reflect.Constructor; import java.util.Hashtable; import java.util.StringTokenizer; import java.util.Vector; import org.w3c.dom.Attr; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.Text; /** * Build a DataSource from a DOM node */ class Data1DTraverser extends XMLNodeTraverser { Data1DTraverser(Node node) throws BadXMLException { traverse(node); } protected void handleElement(Element node, String name) throws BadXMLException { if (name.equals("bins1d")) b1d = new Bins1DNodeTraverser(node); else if (name.equals("points")) xy = new XYPointsNodeTraverser(node); else if (name.equals("binnedDataAxisAttributes")) baa = new BinnedDataAxisAttributesNodeTraverser(node); else if (name.equals("pointDataAxisAttributes")) paa = new PointDataAxisAttributesNodeTraverser(node); else if (name.equals("class")) ct = new ClassNodeTraverser(node); else if (name.equals("datasource")) ct = new DataSourceNodeTraverser(node); else if (name.equals("statistics")) stats = new StatisticsTraverser(node); else if (name.equals("axisLabels")) labels = new AxisLabelsTraverser(node); else if (name.equals("style1d")) st.traverse(node,style=new JASHist1DHistogramStyle()); else if (name.equals("normalization")) norm = new NormalizationTraverser(node); else super.handleElement(node,name); } protected void handleAttributeNode(Attr node, String name, String value) throws BadXMLException { if (name.equals("axis")) yAxis = toInt(value.substring(1)); else if (name.equals("name")) refName = value; else super.handleAttributeNode(node,name,value); } DataSource getDataSource() { if (ct != null) return ct.getDataSource(); else if (b1d != null) return new XML1DHistDataSource(b1d,baa,labels,stats); else return new XMLXYDataSource(xy,paa,stats); } int getYAxis() { return yAxis; } JASHistStyle getStyle() { return style; } String getRefName() { return refName; } Normalizer getNormalizer(DataSource data, Hashtable map) throws BadXMLException { return norm == null ? null : norm.getNormalizer(data,map); } private int yAxis; private StatisticsTraverser stats = null; private AxisLabelsTraverser labels = null; private NormalizationTraverser norm = null; private JASHist1DHistogramStyle style = null; private ConstructorNodeTraverser ct = null; private Style1DNodeTraverser st = new Style1DNodeTraverser(); private Bins1DNodeTraverser b1d; private XYPointsNodeTraverser xy; private PointDataAxisAttributesNodeTraverser paa; private BinnedDataAxisAttributesNodeTraverser baa; private String refName; } class ClassNodeTraverser extends ConstructorNodeTraverser { ClassNodeTraverser(Node node) throws BadXMLException { super(node); if (ds instanceof HasDataSource) return; throw new BadXMLException("Class is not a HasDataSource"); } protected void handleAttributeNode(Attr node, String name, String value) throws BadXMLException { if (name.equals("param")) param = value; else super.handleAttributeNode(node,name,value); } DataSource getDataSource() { return ((HasDataSource) ds).getDataSource(param); } private String param; } class DataSourceNodeTraverser extends ConstructorNodeTraverser { DataSourceNodeTraverser(Node node) throws BadXMLException { super(node); if (ds instanceof DataSource) return; throw new BadXMLException("Class is not a DataSource"); } DataSource getDataSource() { return (DataSource) ds; } } abstract class ConstructorNodeTraverser extends XMLNodeTraverser { ConstructorNodeTraverser(Node node) throws BadXMLException { int maxSize = node.getChildNodes().getLength(); types = new String[maxSize]; values = new String[maxSize]; traverse(node); try { Class c = null; ClassLoader ccl = Thread.currentThread().getContextClassLoader(); if (ccl != null) { c = ccl.loadClass(className); } else { c = Class.forName(className); } if (vc == 0) ds = c.newInstance(); else { Class[] argc = new Class[vc]; Object[] args = new Object[vc]; for (int i=0; i 0) xLow = 0; if (xHigh < 0) xHigh = 0; } if (xHigh <= xLow) xHigh = xLow + 1; calcMinMaxXBins(xLow,xHigh); } protected void calcMinMaxXBins(double x1, double x2) { double oldXMin = xAxis.getPlotMin(); double oldXMax = xAxis.getPlotMax(); if (x1 != oldXMin || x2 != oldXMax) { xAxis.setMin(x1); xAxis.setMax(x2); xm.invalidate(); } } void computeYAxisRange() { int index = 0; // Bug, what about the other axis if (!ym[index].needsAttention()) return; ym[index].payingAttention(); // do first to avoid race conditions if (data.isEmpty()) return; if (!ym[index].getRangeAutomatic() || ym[index].isFixed()) { yLow = ym[index].getMin(); yHigh = ym[index].getMax(); return; } int nShowing = 0; yLow = 0; yHigh = 0; boolean hasRebinnables = false; for (Enumeration e = data.elements(); e.hasMoreElements();) { JASHist2DHistogramData dw = (JASHist2DHistogramData) e.nextElement(); if (!dw.isShowing()) continue; if (nShowing++ == 0) { yLow = dw.getYMin(); yHigh = dw.getYMax(); } else { yLow = Math.min(yLow,dw.getYMin()); yHigh = Math.max(yHigh,dw.getYMax()); } if (dw.isRebinnable()) hasRebinnables = true; } if (nShowing == 0) return; ym[index].setBinned(hasRebinnables); if (!ym[index].getAllowSuppressedZero()) { if (yLow > 0) yLow = 0; if (yHigh < 0) yHigh = 0; } if (yHigh <= yLow) yHigh = yLow + 1; calcMinMaxYBins(yLow,yHigh); } protected void calcMinMaxYBins(double y1, double y2) { double oldYMin = yAxis.getPlotMin(); double oldYMax = yAxis.getPlotMax(); if (y1 != oldYMin || y2 != oldYMax) { yAxis.setMin(y1); yAxis.setMax(y2); ym[0].invalidate(); } } private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { in.defaultReadObject(); data = new Vector(); } final void requestShow(JASHistData data) { da.add(data.getOverlay()); nVisible++; if (legend != null) { LegendEntry le = data.getLegendEntry(); if (le != null) { legend.add(le); nVisibleLegend++; showLegend(); } } if (stats != null) { stats.add(data); } if (isInit) { xm.setAttentionNeeded(); computeXAxisRange(); XAxisUpdated(); ym[0].setAttentionNeeded(); computeYAxisRange(); YAxisUpdated(); computeZAxisRange(); da.revalidate(); da.repaint(); } //restartImages(); } void requestHide(JASHistData data) { da.remove(data.getOverlay()); nVisible--; if (legend != null) { LegendEntry le = data.getLegendEntry(); if (le != null) { legend.remove(le); nVisibleLegend--; showLegend(); } } if (stats != null) { stats.remove(data); } if (isInit) { xm.setAttentionNeeded(); computeXAxisRange(); XAxisUpdated(); ym[0].setAttentionNeeded(); computeYAxisRange(); YAxisUpdated(); computeZAxisRange(); da.revalidate(); da.repaint(); } } void XAxisUpdated() { for (Enumeration e = data.elements(); e.hasMoreElements();) { JASHist2DHistogramData dw = (JASHist2DHistogramData) e.nextElement(); if (dw.isShowing()) dw.setXRange(xm.getBins(),xLow,xHigh); } } void YAxisUpdated() { for (Enumeration e = data.elements(); e.hasMoreElements();) { JASHist2DHistogramData dw = (JASHist2DHistogramData) e.nextElement(); if (dw.isShowing()) dw.setYRange(ym[0].getBins(),yLow,yHigh); } } final private void computeZAxisRange() { for (Enumeration e = data.elements(); e.hasMoreElements();) { JASHist2DHistogramData dw = (JASHist2DHistogramData) e.nextElement(); if (dw.isShowing()) dw.calcZLimits(); } } private void restartImages() { final Enumeration e = data.elements(); while (e.hasMoreElements()) { try { final JASHist2DScatterData data = (JASHist2DScatterData) e.nextElement(); if (data.isVisible) data.restartImage(false); } catch (NullPointerException x) { // don't know where this comes from yet, but this works as is } } } private int oldStyle = -1; private final int m_defaultNumberOfBins; transient protected double xLow, xHigh; // todo: get rid of these transient protected double yLow, yHigh; private DoubleAxis xAxis; private DoubleAxis yAxis; transient private boolean styleChanged; private SizeMenu m_sizeMenu; private StyleMenu m_styleMenu; private static boolean enabled3d; static { try { // check that java 3d and the plot3d routines are both available Class.forName("javax.media.j3d.Canvas3D"); Class.forName("gov.fnal.plot3d.jas.SpecialLego"); Class.forName("gov.fnal.plot3d.jas.SpecialSurface"); enabled3d = true; if (JPopupMenu.getDefaultLightWeightPopupEnabled()) { JPopupMenu.setDefaultLightWeightPopupEnabled(false); } } catch (Throwable t) { enabled3d = false; } } final void modifyPopupMenu(final JPopupMenu menu, final Component source) { if (menu.getComponentCount() > 0) menu.addSeparator(); boolean scat = false; boolean allScat = true; boolean allTwoD = true; Enumeration enumer = getDataSources(); while (enumer.hasMoreElements()) { JASHistData data = (JASHistData) enumer.nextElement(); if (data instanceof JASHist2DScatterData && ((JASHist2DScatterData) data).hasScatterPlotData()) { scat = true; JASHistScatterPlotStyle pstyle = (JASHistScatterPlotStyle) data.getStyle(); if (pstyle.getDisplayAsScatterPlot()) allTwoD = false; else allScat = false; } } if (scat) { JRadioButtonMenuItem b1 = new JRadioButtonMenuItem("Display As Scatter Plot"); JRadioButtonMenuItem b2 = new JRadioButtonMenuItem("Display As Binned Plot"); ButtonGroup bg = new ButtonGroup(); bg.add(b1); bg.add(b2); b1.setSelected(allScat); b2.setSelected(allTwoD); b1.addActionListener(new ScatterActionListener(true)); b2.addActionListener(new ScatterActionListener(false)); menu.add(b1); menu.add(b2); } if (!scat || !allScat) { menu.add(addPerDataSourceMenu("Plot Style",new DataSourceMenuFactory() { public JMenu createMenu(String name, final JASHistData ds) { return new StyleMenu(name,ds); } })); } if (scat && !allTwoD) { if (m_sizeMenu == null) m_sizeMenu = new SizeMenu(); m_sizeMenu.init(); menu.add(m_sizeMenu); menu.add(addPerDataSourceMenu("Point Color",new DataSourceMenuFactory() { public JMenu createMenu(String name, final JASHistData ds) { final JASHistScatterPlotStyle style = (JASHistScatterPlotStyle) ds.getStyle(); ColorSelectionModel cm = new DefaultColorSelectionModel() { public Color getSelectedColor() { return style.getDataPointColor(); } public void setSelectedColor(Color c) { style.setDataPointColor(c); } }; return new ColorMenu(name,cm,true); } })); } super.modifyPopupMenu(menu,source); } final private class ScatterActionListener implements ActionListener { ScatterActionListener(boolean state) { this.state = state; } public void actionPerformed(ActionEvent e) { Enumeration enumer = getDataSources(); while (enumer.hasMoreElements()) { JASHistData data = (JASHistData) enumer.nextElement(); if ((data instanceof JASHist2DScatterData)) { JASHistScatterPlotStyle pstyle = (JASHistScatterPlotStyle) data.getStyle(); pstyle.setDisplayAsScatterPlot(state); } } } private boolean state; } final private class SizeMenu extends JMenu { public SizeMenu() { super("Point Size"); setMnemonic('S'); addButton("Huge",'H',20); addButton("Large",'L',10); addButton("Medium",'M',5); addButton("Small",'S',3); addButton("Tiny",'T',1); } private void addButton(String name, char mnemonic, final int size) { JRadioButtonMenuItem item = new SizeButton(name,size); item.setMnemonic(mnemonic); group.add(item); this.add(item); } public void init() { int iSize = -1; Enumeration enumer = getDataSources(); while (enumer.hasMoreElements()) { JASHistData data = (JASHistData) enumer.nextElement(); if (!(data instanceof JASHist2DScatterData)) continue; JASHistScatterPlotStyle style = (JASHistScatterPlotStyle) data.getStyle(); if (iSize == -1) iSize = style.getDataPointSize(); else if (iSize != style.getDataPointSize()) iSize = -2; } Enumeration e = group.getElements(); while (e.hasMoreElements()) { SizeButton b = (SizeButton) e.nextElement(); b.setSize(iSize); } } ButtonGroup group = new ButtonGroup(); } final class SizeButton extends JRadioButtonMenuItem { SizeButton(String name, int size) { super(name); this.size = size; } public void fireActionPerformed(ActionEvent e) { Enumeration enumer = getDataSources(); while (enumer.hasMoreElements()) { JASHistData data = (JASHistData) enumer.nextElement(); JASHistScatterPlotStyle style = (JASHistScatterPlotStyle) data.getStyle(); style.setDataPointSize(size); } } void setSize(int size) { setSelected(this.size == size); } private int size; } final private class StyleMenu extends JMenu { public StyleMenu(String name, JASHistData ds) { super(name); this.data = ds; JMenu map = new JMenu("Color Map"); map.setMnemonic('M'); StyleMenu.this.add(addButton("Box",'B',JASHist2DHistogramStyle.STYLE_BOX,-1)); StyleMenu.this.add(addButton("Ellipse",'E',JASHist2DHistogramStyle.STYLE_ELLIPSE,-1)); if (enabled3d) { StyleMenu.this.add(addButton("3D Lego Plot",'L',JASHist2DHistogramStyle.STYLE_3DLEGOPLOT,-1)); StyleMenu.this.add(addButton("3D Surface Plot",'S',JASHist2DHistogramStyle.STYLE_3DSURFACEPLOT,-1)); } StyleMenu.this.add(map); map.add(addButton("Warm",'W',JASHist2DHistogramStyle.STYLE_COLORMAP,JASHist2DHistogramStyle.COLORMAP_WARM)); map.add(addButton("Cool",'C',JASHist2DHistogramStyle.STYLE_COLORMAP,JASHist2DHistogramStyle.COLORMAP_COOL)); map.add(addButton("Thermal",'T',JASHist2DHistogramStyle.STYLE_COLORMAP,JASHist2DHistogramStyle.COLORMAP_THERMAL)); map.add(addButton("Rainbow",'B',JASHist2DHistogramStyle.STYLE_COLORMAP,JASHist2DHistogramStyle.COLORMAP_RAINBOW)); map.add(addButton("Gray Scale",'G',JASHist2DHistogramStyle.STYLE_COLORMAP,JASHist2DHistogramStyle.COLORMAP_GRAYSCALE)); final JCheckBoxMenuItem log = new JCheckBoxMenuItem("Logarithmic Z Axis"); log.setMnemonic('Z'); final JASHist2DHistogramStyle style = (JASHist2DHistogramStyle) data.getStyle(); log.setState(style.getLogZ()); log.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { style.setLogZ(log.getState()); } }); StyleMenu.this.add(log); init(); } private JRadioButtonMenuItem addButton(String name, char mnemonic, final int iStyle, final int cStyle) { JRadioButtonMenuItem item = new StyleButton(name,iStyle,cStyle); item.setMnemonic(mnemonic); group.add(item); return item; } private void init() { int iStyle = -1; int cStyle = -1; JASHist2DHistogramStyle style = (JASHist2DHistogramStyle) data.getStyle(); iStyle = style.getHistStyle(); cStyle = style.getColorMapScheme(); Enumeration e = group.getElements(); while (e.hasMoreElements()) { StyleButton b = (StyleButton) e.nextElement(); b.setStyle(iStyle,cStyle); } } ButtonGroup group = new ButtonGroup(); JASHistData data; final class StyleButton extends JRadioButtonMenuItem { StyleButton(String name, int iStyle, int cStyle) { super(name); this.iStyle = iStyle; this.cStyle = cStyle; } public void fireActionPerformed(ActionEvent e) { JASHist2DHistogramStyle style = (JASHist2DHistogramStyle) data.getStyle(); style.setHistStyle(iStyle); if (cStyle >= 0) style.setColorMapScheme(cStyle); } void setStyle(int iStyle, int cStyle) { this.setSelected(this.iStyle == iStyle && (this.cStyle == -1 || this.cStyle == cStyle)); } private int iStyle; private int cStyle; } } } src/main/java/jas/hist/TwoDOverlay.java0000644000175000017500000003152211325547132020534 0ustar giovannigiovannipackage jas.hist; import jas.plot.ColorMap; import jas.plot.ColorMapAxis; import jas.plot.CoordinateTransformation; import jas.plot.DataAreaLayout; import jas.plot.DateCoordinateTransformation; import jas.plot.DoubleCoordinateTransformation; import jas.plot.MutableLegendEntry; import jas.plot.Overlay; import jas.plot.OverlayContainer; import jas.plot.PlotGraphics; import jas.plot.Transformation; import jas.plot.java2.PlotGraphics12; import java.awt.Color; import java.awt.Rectangle; import java.awt.RenderingHints; import java.util.Observable; import java.util.Observer; class TwoDOverlay implements Overlay, MutableLegendEntry, Observer { protected OverlayContainer container; private Color color; private JASHist2DHistogramData parent; private double[][] data; private double binHeightFixed; private double binWidthFixed; private double xHigh; private double xLow; private double yHigh; private double yLow; private double zlogmin; private double zmax; private double zmin; private int xBins; private int yBins; private ColorMapAxis colorMapAxis; private ColorMap colorMap; private boolean isColorMapAxisAdded = false; double cx; double cy; double cw; double ch; int c_mode, s_mode; TwoDOverlay(JASHist2DHistogramData parent) { this.color = Color.black; this.parent = parent; parent.style.addObserver(this); colorMap = new ColorMap(parent.style); colorMapAxis = new ColorMapAxis(colorMap); styleChanged(parent.style); } private void styleChanged(JASHist2DHistogramStyle style) { s_mode = style.getHistStyle(); c_mode = style.getColorMapScheme(); if ( s_mode != 0 && s_mode!= 1 ) { if ( ! isColorMapAxisAdded ) parent.parent.da.add(colorMapAxis,DataAreaLayout.Y_AXIS_RIGHT); isColorMapAxisAdded = true; } else if ( isColorMapAxisAdded ) { parent.parent.da.remove(colorMapAxis); isColorMapAxisAdded = false; } } public void update(Observable o, Object arg) { styleChanged((JASHist2DHistogramStyle) o); } public void setTitle(String newTitle) { parent.setLegendText(newTitle); } public String getTitle() { return parent.getLegendText(); } public void containerNotify(OverlayContainer c) { this.container = c; } // Use local coordinates here boolean isInClip(Transformation xt, Transformation yt, double Lx1, double Ly1, double Lx2, double Ly2) { double Gx1 = xt.convert(Lx1); double Gy1 = yt.convert(Ly1); double Gx2 = xt.convert(Lx2); double Gy2 = yt.convert(Ly2); if (Gx2 < Gx1) { double xTmp = Gx1; Gx1 = Gx2; Gx2 = xTmp; } if (Gy2 < Gy1) { double yTmp = Gy1; Gy1 = Gy2; Gy2 = yTmp; } double Gw = Gx2 - Gx1 + 5.; double Gh = Gy2 - Gy1 + 5.; boolean ok = false; double dGx = cx + (cw - Gx2 - Gx1)*0.5; double dGy = cy + (ch - Gy2 - Gy1)*0.5; double dGw = (cw + Gw)*0.5; double dGh = (ch + Gh)*0.5; if (Math.abs(dGx) <= dGw && Math.abs(dGy) <= dGh) ok = true; //System.out.println("\t\tIntersects="+ok+", dx="+dGx+", dGy="+dGy+", dGw="+Gw+", dGh="+Gh); //System.out.println("\t\t\t\t x1="+ Lx1+", x2="+ Lx2+", y1="+ Ly1+", y2="+ Ly2); //System.out.println("\t\t\t\tGx1="+Gx1+", Gx2="+Gx2+", Gy1="+Gy1+", Gy2="+Gy2); return ok; } public void paint(PlotGraphics g, boolean isPrinting) { //Disable antialiasing for 2D plots. The original rendering hints are set back //at the end of the paint method. RenderingHints oldRh = null; if ( g instanceof PlotGraphics12 ) { oldRh = ((PlotGraphics12)g).graphics().getRenderingHints(); RenderingHints rh = new RenderingHints(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_OFF); ((PlotGraphics12)g).graphics().setRenderingHints(rh); } boolean doClipCheck = true; Rectangle rect = g.getClipBounds(); if (rect == null) { doClipCheck = false; } else { cx = (double) rect.x; cy = (double) rect.y; cw = (double) rect.width; ch = (double) rect.height; } /////////Begin Test Area//////// s_mode = parent.style.getHistStyle(); c_mode = parent.style.getColorMapScheme(); boolean log = parent.style.getLogZ(); boolean uoState = false; //parent.style.getShowOverFlow(); boolean showZeroHeightBins = parent.style.getShowZeroHeightBins(); //boolean showGrid = true; /////////End Test Area///////// if (data == null) { return; } final int x_bins = xBins; final int y_bins = yBins; CoordinateTransformation xp = container.getXTransformation(); final CoordinateTransformation yp = container.getYTransformation(); if (xp instanceof DateCoordinateTransformation) { xp = new DateTransformationConverter((DateCoordinateTransformation) xp); } if (xp instanceof DoubleCoordinateTransformation && yp instanceof DoubleCoordinateTransformation) { double[] binXEdges = null; double[] binYEdges = null; if (parent.getDataSource() instanceof Rebinnable2DVariableHistogramData) { binXEdges = ((Rebinnable2DVariableHistogramData) parent.getDataSource()).getXBinEdges(); binYEdges = ((Rebinnable2DVariableHistogramData) parent.getDataSource()).getYBinEdges(); } final DoubleCoordinateTransformation xt = (DoubleCoordinateTransformation) xp; final DoubleCoordinateTransformation yt = (DoubleCoordinateTransformation) yp; g.setTransformation(xt, yt); //////Set Background///// if ((s_mode == 0) || (s_mode == 1)) //Box/Ellipse Selected { g.setColor(Color.white); } else { /* if (c_mode == 0) { //Warm selected g.setColor(Color.red); } else if ((c_mode == 1) || (c_mode == 3)) { //Cool/Rainbow Selected //g.setColor(Color.black); } else if ((c_mode == 2) || (c_mode == 4)) { //Thermal/GrayScale Selected g.setColor(Color.blue); } else if (c_mode == 5) { //SelectRange Selected g.setColor(parent.style.getStartDataColor()); } else { // Do something here... } g.fillRect(xLow, yHigh, xHigh, yLow); */ } ////////// Show overflow and underflow bins ///////// // FIXME: Does not seem right if (((s_mode == 0) || (s_mode == 1)) && (uoState == true)) { g.setColor(Color.black); g.drawLine(xt.convert(xLow + binWidthFixed), yt.convert(yLow), xt.convert(xLow + binWidthFixed), yt.convert(yHigh)); g.drawLine(xt.convert(xHigh - binWidthFixed), yt.convert(yLow), xt.convert(xHigh - binWidthFixed), yt.convert(yHigh)); g.drawLine(xt.convert(xLow), yt.convert(yLow + binHeightFixed), xt.convert(xHigh), yt.convert(yLow +binHeightFixed)); g.drawLine(xt.convert(xLow), yt.convert(yHigh - binHeightFixed), xt.convert(xHigh), yt.convert(yHigh- binHeightFixed)); } //////////Grid Lines on the Pane///////// /* if ( ((s_mode == 0) || (s_mode == 1)) && showGrid ) { g.setColor(Color.black); double yGrid = yLow; double xGrid = xLow; for (int j = 0; j < y_bins; j++) { double binHeight = (binYEdges == null) ? binWidthFixed : binYEdges[j+1] - binYEdges[j]; yGrid += binHeight; g.drawLine(xt.convert(xLow), yt.convert(yGrid), xt.convert(xHigh), yt.convert(yGrid)); } for (int i = 0; i < x_bins; i++) { double binWidth = (binXEdges == null) ? binWidthFixed : binXEdges[i+1] - binXEdges[i]; xGrid += binWidth; g.drawLine(xt.convert(xGrid), yt.convert(yLow), xt.convert(xGrid), yt.convert(yHigh)); } } */ ///////End Set Background//// // make sure that zero is included in the Z axis range double dispZmin = zmin; double dispZmax = zmax; if (log) { dispZmin = Math.log(zlogmin); dispZmax = Math.log(zmax); } else { if ((dispZmin > 0) && (dispZmax > 0)) { dispZmin = 0; } if ((dispZmin < 0) && (dispZmax < 0)) { dispZmax = 0; } } double zrange = dispZmax - dispZmin; if (zrange > 0) { double binHeight = binHeightFixed; double binWidth = binWidthFixed; g.setColor(parent.style.getShapeColor()); double y = yLow; for (int j = 0; j < y_bins; j++) { if (binYEdges != null) binHeight = binYEdges[j+1] - binYEdges[j]; y += binHeight/2; double x = xLow; for (int i = 0; i < x_bins; i++) { if (binXEdges != null) binWidth = binXEdges[i+1] - binXEdges[i]; x += binWidth/2; double size = 0; if ((s_mode == 0) || (s_mode == 1)) size = log ? Math.sqrt((Math.log(data[i][j]) - dispZmin) / zrange) : Math.sqrt((data[i][j] - dispZmin) / zrange); else size = 1.; double xFact = (binWidth * size) / 2; double yFact = (binHeight * size) / 2; // We dont want anything to appear if size is exactly 0 if (size == 0) { x += binWidth/2; continue; } double x1 = x - binWidth/2; double y1 = y - binHeight/2; double x2 = x + binWidth/2; double y2 = y + binHeight/2; if (doClipCheck && !isInClip(xt, yt, x1, y1, x2, y2)) { x += binWidth/2; continue; } x1 = x - xFact; y1 = y - yFact; x2 = x + xFact; y2 = y + yFact; if (s_mode == 0) { g.drawRect(x1, y1, x2, y2); } else if (s_mode == 1) { g.drawOval(x1, y1, x2, y2); } else // Color Map mode (s_mode == 2) { double colorSize = log ? ((Math.log(data[i][j]) - dispZmin) / zrange) : ((data[i][j] - dispZmin) / zrange); if ( (showZeroHeightBins || colorSize != 0) && colorSize != Double.NEGATIVE_INFINITY ) { g.setColor(colorMap.getColor(colorSize)); g.fillRect(x1, y1, x2, y2); } } x += binWidth/2; } y += binHeight/2; } } else if (zrange == 0) { // empty histogram, so nothing to do } } // else zrange < 0 (should not occur) if ( oldRh != null ) ((PlotGraphics12)g).graphics().setRenderingHints(oldRh); } //paint() public void paintIcon(PlotGraphics g, int width, int height) { g.setColor(parent.style.getShapeColor()); g.fillRect(1, 1, width - 2, height - 2); } public boolean titleIsChanged() { return parent.isLegendChanged(); } void setData(double[][] data, double xLow, double xHigh, double yLow, double yHigh, int xBins, int yBins) { this.data = data; this.xBins = xBins; this.yBins = yBins; this.xLow = xLow; this.xHigh = xHigh; this.yLow = yLow; this.yHigh = yHigh; binWidthFixed = Math.abs(xHigh - xLow) / xBins; binHeightFixed = Math.abs(yHigh - yLow) / yBins; } void setZMinMax(double zMin, double zMax, double zLogMin) { boolean log = parent.style.getLogZ(); this.zmin = zMin; this.zlogmin = zLogMin; this.zmax = zMax; colorMapAxis.setZminZmax(zmin, zmax); colorMapAxis.setLogarithmic(log); } }src/main/java/jas/hist/XYDataSource.java0000644000175000017500000000126511325547132020631 0ustar giovannigiovanni/* * XYDataSource.java * * Created on November 21, 2001, 11:49 AM */ package jas.hist; /** * A Data Source for XY plots. Note this interface is suitable for use with * up to several hundred points. For more points use ScatterPlotSource instead. * @see ScatterPlotSource * @author tonyj * @version $Id: XYDataSource.java 11550 2007-06-05 21:44:14Z duns $ */ public interface XYDataSource extends DataSource { public int getNPoints(); public double getX(int index); public double getY(int index); public double getPlusError(int index); public double getMinusError(int index); /** * Returns one of DOUBLE or DATE */ public int getAxisType(); } src/main/java/jas/hist/FunctionFactory.java0000644000175000017500000000031511325547132021426 0ustar giovannigiovannipackage jas.hist; import javax.swing.Icon; public interface FunctionFactory { Basic1DFunction createFunction(JASHist h) throws FunctionFactoryError; String getFunctionName(); Icon getFunctionIcon(); } src/main/java/jas/hist/FitterRegistry.java0000644000175000017500000000420011325547132021274 0ustar giovannigiovannipackage jas.hist; import jas.util.NestedRuntimeException; import java.util.Enumeration; import java.util.Vector; public class FitterRegistry { private FitterRegistry() { } /** * Get the (unique) FitterRegistry instance */ public static FitterRegistry instance() { return theFitterRegistry; } /** * Add a fitter to the FitterRegistry * @param c The class to instanciate to get a fitter * @param name The name of the fitter */ public void registerFitter(Class c, String name) { registerFitter(createFitterFactory(c,name)); } /** * Create a FitterFactory from a class and a name * @param c The class to instanciate to get a fitter * @param name The name of the fitter */ public FitterFactory createFitterFactory(Class c, String name) { try { return new DefaultFitterFactory(c,name); } catch (FitterFactoryError e) { // convert the error to a runtime error throw new NestedRuntimeException(e); } } /** * Add a fitter factory to the FitterRegistry * @param f The factory to add */ public void registerFitter(FitterFactory f) { m_fitters.addElement(f); if (defaultFitterFactory == null) defaultFitterFactory = f; } /** * Remove a FitterFactory from the registry * @param The FitterFactory to remove */ public void removeFitterFactory(FitterFactory f) { m_fitters.removeElement(f); } /** * Clear the FitterRegistry */ public void removeAllFitters() { m_fitters.removeAllElements(); } public Enumeration elements() { return m_fitters.elements(); } public int size() { return m_fitters.size(); } public FitterFactory getDefaultFitterFactory() { return defaultFitterFactory; } public void setDefaultFitterFactory(FitterFactory f) { defaultFitterFactory = f; } /** * Return an instance of the current default fitter */ public Fitter getDefaultFitter() { return defaultFitterFactory == null ? null : defaultFitterFactory.createFitter(); } public void setContents(Vector v) { m_fitters = v; } private Vector m_fitters = new Vector(); private static FitterRegistry theFitterRegistry = new FitterRegistry(); private FitterFactory defaultFitterFactory; } src/main/java/jas/hist/event/0000755000175000017500000000000011325547132016570 5ustar giovannigiovannisrc/main/java/jas/hist/event/FitEvent.java0000644000175000017500000000065411325547132021164 0ustar giovannigiovannipackage jas.hist.event; import java.util.EventObject; final public class FitEvent extends EventObject { final public static int FIT_STARTED = 0; final public static int FIT_ENDED = 1; final public static int FIT_ERROR = 2; final public static int FIT_PROGRESS_CHANGED = 3; public FitEvent(final Object source, final int id) { super(source); m_id = id; } public int getID() { return m_id; } private int m_id; } src/main/java/jas/hist/SaveAsPlotML.java0000644000175000017500000000354311325547132020571 0ustar giovannigiovanni/* * SaveAsPlotML.java * Created on March 28, 2002, 3:36 PM */ package jas.hist; import jas.util.FileTypeFileFilter; import java.awt.Component; import java.io.File; import java.io.IOException; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.Writer; import java.util.Properties; import javax.swing.ButtonGroup; import javax.swing.JPanel; import javax.swing.JRadioButton; import javax.swing.filechooser.FileFilter; /** * * @author tonyj */ public class SaveAsPlotML implements SaveAsPlugin { public boolean hasOptions() { return true; } public FileFilter getFileFilter() { return new FileTypeFileFilter("plotml","XML Plot File (*.plotml)"); } public JPanel getOptionsPanel() { JPanel custom = new JPanel(); custom.add(button1); custom.add(button2); ButtonGroup bg = new ButtonGroup(); bg.add(button1); bg.add(button2); return custom; } public void saveAs(Component c, OutputStream os, File file, Component dialogParent) throws IOException { Writer writer = new OutputStreamWriter(os); ((JASHist) c).writeXML(writer,button1.isSelected()); writer.close(); } public File adjustFilename(File file) { String name = file.getName(); if (name.endsWith(".plotml")) return file; int pos = name.indexOf('.'); if (pos >= 0) name = name.substring(0,pos); name += ".plotml"; File parent = file.getParentFile(); return new File(parent,name); } public boolean supportsClass(Object o) { return (o instanceof JASHist); } public void restoreOptions(Properties props) { } public void saveOptions(Properties props) { } private JRadioButton button1 = new JRadioButton("Save current snapshot of data",true); private JRadioButton button2 = new JRadioButton("Save reference to live data"); } src/main/java/jas/hist/TwoDDataManager.java0000644000175000017500000000040311325547132021251 0ustar giovannigiovannipackage jas.hist; import jas.plot.DataArea; import jas.plot.Legend; abstract class TwoDDataManager extends SliceableDataManager { TwoDDataManager(JASHist plot, final DataArea da, final Legend l, StatisticsBlock stats) { super(plot, da, l, stats); } } src/main/java/jas/hist/JASHistPropertyDialog.java0000644000175000017500000010603411326056641022451 0ustar giovannigiovannipackage jas.hist; import jas.hist.normalization.Normalizer; import jas.util.CheckBoxBorderPanel; import jas.util.ColorChooser; import jas.util.DateChooser; import jas.util.JASTextField; import jas.util.JTextFieldBinding; import jas.util.PropertyBinding; import jas.util.PropertyDialog; import jas.util.PropertyPage; import jas.util.PropertySite; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; import java.awt.Container; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.Frame; import java.awt.Graphics; import java.awt.Insets; import java.awt.LayoutManager; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.Date; import java.util.Enumeration; import javax.swing.BorderFactory; import javax.swing.Box; import javax.swing.BoxLayout; import javax.swing.ButtonGroup; import javax.swing.DefaultListModel; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JComboBox; import javax.swing.JLabel; import javax.swing.JList; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JSpinner; import javax.swing.SpinnerNumberModel; import javax.swing.UIManager; import javax.swing.border.AbstractBorder; import javax.swing.border.Border; import javax.swing.border.TitledBorder; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import tablelayout.TableLayout; public final class JASHistPropertyDialog extends PropertyDialog { public JASHistPropertyDialog(Frame f,JASHist bean) { this(f, bean, DEFAULT); } public JASHistPropertyDialog(final Frame f, final JASHist bean, final byte axis) { super(f,"Histogram properties...",bean); addPage("General",new JASHistPropGeneral(), false); addPage("Y Axis" ,new JASHistPropYAxis(axis == Y_AXIS_RIGHT), axis == Y_AXIS_LEFT || axis == Y_AXIS_RIGHT); addPage("X Axis" ,new JASHistPropXAxis(), axis == X_AXIS); DataManager dm = bean.getDataManager(); if (bean.numberOfDataSets() > 0) addPage("Data",new JASHistPropData(dm), false); if (dm instanceof SupportsFunctions) addPage("Functions",new JASHistPropFunctions(), false); pack(); } final static byte DEFAULT = 0; final static byte Y_AXIS_LEFT = 1; final static byte Y_AXIS_RIGHT = 2; final static byte X_AXIS = 3; } final class JASHistPropGeneral extends PropertyPage { public JASHistPropGeneral() { setLayout(new BoxLayout(this,BoxLayout.Y_AXIS)); JPanel p1 = new FixedHeightPanel(); p1.add(new JLabel("Title")); JASTextField title = new JASTextField(40); p1.add(title); add(p1); JPanel p4 = new FixedHeightPanel(); /* JCheckBox axis = new JCheckBox("Axis Bounding Box"); axis.setMnemonic('B'); p4.add(axis); */ JComboBox legend = new JComboBox(); legend.addItem("Hide Legend"); legend.addItem("Automatic"); legend.addItem("Show Legend"); p4.add(legend); add(p4); JPanel p3 = new FixedHeightPanel(); p3.setBorder(BorderFactory.createTitledBorder("Border")); JComboBox btype = new JComboBox(); btype.addItem("None"); btype.addItem("Bevel In"); btype.addItem("Bevel Out"); btype.addItem("Etched"); btype.addItem("Line"); btype.addItem("Shadow"); p3.add(btype); /* p3.add(new JLabel("Width")); SpinBox bwidth = new SpinBox(2,0,20); p3.add(bwidth); */ add(p3); JPanel p2 = new FixedHeightPanel(); p2.setBorder(BorderFactory.createTitledBorder("Color")); p2.add(new JLabel("Background")); ColorChooser back = new ColorChooser(); p2.add(back); p2.add(new JLabel("Foreground")); ColorChooser fore = new ColorChooser(); p2.add(fore); p2.add(new JLabel("Data Area")); ColorChooser data = new ColorChooser(); p2.add(data); add(p2); add(Box.createVerticalGlue()); addBinding(new PropertyBinding(title,"Title")); addBinding(new PropertyBinding(back,"Background")); addBinding(new PropertyBinding(fore,"Foreground")); addBinding(new PropertyBinding(data,"DataAreaColor")); addBinding(new PropertyBinding(btype,"DataAreaBorderType")); /* addBinding(new PropertyBinding(bwidth,"DataAreaBorderWidth")); addBinding(new PropertyBinding(axis,"AxisBoundingBox")); */ addBinding(new PropertyBinding(legend,"ShowLegend")); } public String getHelpTopic() { return "userInterface.propertiesDialog.generalTab"; } } final class JASHistPropYAxis extends PropertyPage implements ListSelectionListener, PropertySite { public JASHistPropYAxis(final boolean selectY2) { m_init = false; setLayout(new BorderLayout()); m_listModel = new DefaultListModel(); m_list = new JList(m_listModel); if (selectY2) m_list.setSelectedIndex(1); m_list.addListSelectionListener(this); JScrollPane scroll = new JScrollPane(); scroll.setViewportView(m_list); scroll.setPreferredSize(new Dimension(100,120)); add(scroll,BorderLayout.WEST); m_propAxis = new JASHistPropAxis(); m_propAxis.setPropertySite(this); add(m_propAxis,BorderLayout.CENTER); } public String getHelpTopic() { return "userInterface.propertiesDialog.axesTabs"; } public void activate() { m_init = false; // Recalculate list of axes each time page is activated } public void doDataExchange(boolean set,Object bean) { if (!m_init) { JASHist hist = (JASHist) bean; JASHistAxis[] axes = hist.getYAxes(); m_listModel.removeAllElements(); for (int i=0; i 1); boolean haveMinusError = (result.length > 2); if (havePlusError) { positiveError = result[1]; if (haveMinusError) { negativeError = result[2]; } } for (int i=0; i < data.length; i++) { for (int j=0; j < data[i].length; j++) { pw.print(data[i][j]); if (havePlusError && positiveError.length > i && positiveError[i].length > j) { pw.print("," + positiveError[i][j]); if (haveMinusError && negativeError.length > i && negativeError[i].length > j) { pw.println("," + negativeError[i][j]); } else { pw.println(); } } else { pw.println(); } } } pw.closeTag(); //output the x axis attributes pw.printBinnedDataAxisAttributes( "x", "" + getXMin(), "" + getXMax(), "" + dataSource.getXBins(), theXAxisType); //output the y axis attributes pw.printBinnedDataAxisAttributes( "y", "" + getYMin(), "" + getYMax(), "" + dataSource.getYBins(), theYAxisType); if (dataSource instanceof HasStatistics) { Statistics stats = ((HasStatistics) dataSource).getStatistics(); if (stats != null) { pw.openTag("statistics"); String[] names = stats.getStatisticNames(); for (int i=0; i"); String[] labels = getAxisLabels(); for (int i=0; i < labels.length; i++) { jas.hist.JASHistXMLUtils.writeTabs(pw, (indentLevel + 2)); pw.println(""); } jas.hist.JASHistXMLUtils.writeTabs(pw, (indentLevel + 1)); pw.println(""); } */ String histStyleName = JASHist2DHistogramStyle.getHistStyleName(style.getHistStyle()); pw.setAttribute("histStyle",histStyleName); if (histStyleName.equals("STYLE_COLORMAP")) { pw.setAttribute("colorMapScheme", JASHist2DHistogramStyle.getColorMapSchemeName(style.getColorMapScheme())); } pw.setAttribute("shapeColor", jas.util.ColorConverter.colorToString(style.getShapeColor())); pw.setAttribute("overflowBinColor", jas.util.ColorConverter.colorToString(style.getOverflowBinColor())); pw.setAttribute("startDataColor", jas.util.ColorConverter.colorToString(style.getStartDataColor())); pw.setAttribute("endDataColor", jas.util.ColorConverter.colorToString(style.getEndDataColor())); pw.setAttribute("showOverflow",style.getShowOverflow()); pw.setAttribute("showPlot",style.getShowPlot()); if (style.getLogZ()) pw.setAttribute("logZ",true); pw.printTag("style2d"); pw.closeTag(); } boolean isRebinnable() { return dataSource.isRebinnable(); } double getXMin() { double result = dataSource.getXMin(); if (style.getShowOverflow()) { result -= (dataSource.getXMax()-result)/dataSource.getXBins(); } return result; } double getXMax() { double result = dataSource.getXMax(); if (style.getShowOverflow()) { result += (result-dataSource.getXMin())/dataSource.getXBins(); } return result; } double getYMin() { double result = dataSource.getYMin(); if (style.getShowOverflow()) { result -= (dataSource.getYMax()-result)/dataSource.getYBins(); } return result; } double getYMax() { double result = dataSource.getYMax(); if (style.getShowOverflow()) { result += (result-dataSource.getYMin())/dataSource.getYBins(); } return result; } int getXBins() { return dataSource.getXBins(); } int getYBins() { return dataSource.getYBins(); } void setXRange(int xBins,double xLow, double xHigh) { if (isRebinnable()) { if (xBins != this.xBins || xLow != this.xLow || xHigh != this.xHigh) { this.xBins = xBins; isBinned = false; zLimitsValid = false; } } else { this.xBins = dataSource.getXBins(); } this.xLow = xLow; this.xHigh = xHigh; } void setYRange(int yBins,double yLow, double yHigh) { if (isRebinnable()) { if (yBins != this.yBins || yLow != this.yLow || yHigh != this.yHigh) { this.yBins = yBins; isBinned = false; zLimitsValid = false; } } else { this.yBins = dataSource.getYBins(); } this.yLow = yLow; this.yHigh = yHigh; } private void doBin() { // no support for String axes yet isBinned = true; // Set before call to rebin to avoid race condition double xl, xh, yl, yh; if (isRebinnable()) { xl = xLow; xh = xHigh; yl = yLow; yh = yHigh; } else { xl = ((Rebinnable2DHistogramData) dataSource).getXMin(); xh = ((Rebinnable2DHistogramData) dataSource).getXMax(); yl = ((Rebinnable2DHistogramData) dataSource).getYMin(); yh = ((Rebinnable2DHistogramData) dataSource).getYMax(); } double[][][] result = dataSource.rebin(xBins,xl,xh,yBins,yl,yh,true,hurry,style.getShowOverflow()); if (result == null) result = new double[1][xBins][yBins]; // apply normalization if (normalization != null) { double factor = 1./normalization.getNormalizationFactor(); for (int k=0; k 0 && !text.equals(getTitle())) newText = text; if (newText != legendText) { legendText = newText; parent.getPlot().getLegend().legendTextChanged(); } } public String getLegendText() { return legendText != null ? legendText : getTitle(); } boolean isLegendChanged() { return legendText != null; } Statistics getStatistics() { if (showStatistics) { DataSource dataSource = getDataSource(); if (dataSource instanceof HasStatistics) return ((HasStatistics) dataSource).getStatistics(); } return null; } /** * Writes the data and surrounding XML tags. Subclasses must implement this sensibly. */ abstract void writeAsXML(XMLPrintWriter pw, boolean snapshot); void deleteNormalizationObserver() { if (normalization instanceof Observable) ((Observable) normalization).deleteObserver(this); } void restoreNormalizationObserver() { if (normalization instanceof Observable) ((Observable) normalization).addObserver(this); } /** * Set the normalization for this dataset. * @param factor The normalization to apply, or null for no normalization */ public void setNormalization(jas.hist.normalization.Normalizer factor) { if (factor != normalization) { if (normalization instanceof Observable) { ((Observable) normalization).deleteObserver(this); } normalization = factor; if (factor instanceof Observable) { ((Observable) normalization).addObserver(this); } normalizationChanged(true); } } public jas.hist.normalization.Normalizer getNormalization() { return normalization; } public void setXBounds(double xmin, double xmax) { } abstract void normalizationChanged(boolean now); static final long serialVersionUID = -3529869583896718619L; jas.hist.normalization.Normalizer normalization; int yAxisIndex; boolean isVisible = false; DataManager parent; private String legendText; private boolean showStatistics = true; private boolean showLegend = true; protected Overlay overlay; /** * Y Axis on the left of the data area */ public final static int YAXIS_LEFT = 0; /** * Y Axis on the right of the data area */ public final static int YAXIS_RIGHT = 1; } src/main/java/jas/hist/InvalidFunctionParameter.java0000644000175000017500000000021411325547132023244 0ustar giovannigiovannipackage jas.hist; public class InvalidFunctionParameter extends Exception { public InvalidFunctionParameter(String s) { super(s); } } src/main/java/jas/hist/SaveAsPlugin.java0000644000175000017500000000135511325547132020657 0ustar giovannigiovanni/* * SaveAsPlugin.java * * Created on March 28, 2002, 3:12 PM */ package jas.hist; import java.awt.Component; import java.io.File; import java.io.IOException; import java.io.OutputStream; import java.util.Properties; import javax.swing.JPanel; import javax.swing.filechooser.FileFilter; /** * * @author tonyj */ public interface SaveAsPlugin { public boolean supportsClass(Object o); public boolean hasOptions(); public FileFilter getFileFilter(); public JPanel getOptionsPanel(); public File adjustFilename(File file); public void saveAs(Component c, OutputStream os, File file, Component dialogParent) throws IOException; public void saveOptions(Properties props); public void restoreOptions(Properties props); } src/main/java/jas/hist/Basic1DFunction.java0000644000175000017500000000154211325547132021230 0ustar giovannigiovannipackage jas.hist; import java.io.Serializable; import java.util.Observable; public abstract class Basic1DFunction extends Observable implements FunctionData, Serializable, Statistics, HasStatistics { protected void destroy() { } public void setBatch(boolean b) { this.batch = b; if (!batch) notifyObservers(); } public void setChanged() { super.setChanged(); if (!batch) notifyObservers(); } public void setChanged(Object o) { super.setChanged(); if (!batch) notifyObservers(o); } public String[] getStatisticNames() { return getParameterNames(); } public double getStatistic(String name) { String[] names = getParameterNames(); for (int i=0; i= ym.length) throw new IllegalArgumentException("Y axis index out of range"); if (ym[index] == null) createYAxis(index); return ym[index]; } protected void createYAxis(int index) { ym[index] = new ManagedAxis(this,Axis.VERTICAL,true); DoubleAxis a = (DoubleAxis) ym[index].getType(); a.setUseSuggestedRange(true); ym[index].setOnLeftSide(false); da.add(ym[index],DataAreaLayout.Y_AXIS_RIGHT); da.revalidate(); } protected void destroyYAxis(int index) { if (ym[index] != null) da.remove(ym[index]); da.revalidate(); } protected final static Enumeration nullEnumeration = new NullEnumeration(); final private static class NullEnumeration implements Enumeration { public boolean hasMoreElements() { return false; } public Object nextElement() { throw new NoSuchElementException(); } } protected ManagedAxis xm; protected ManagedAxis[] ym = new ManagedAxis[2]; final protected JASHist plot; final protected DataArea da; } src/main/java/jas/hist/XML2DHistDataSource.java0000644000175000017500000001324711325547132021752 0ustar giovannigiovannipackage jas.hist; import jas.util.xml.XMLNodeTraverser; import jas.util.xml.XMLNodeTraverser.BadXMLException; import java.util.StringTokenizer; import org.w3c.dom.Attr; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.Text; /** * Build a DataSource from a DOM node */ class Data2DTraverser extends XMLNodeTraverser { Data2DTraverser(Node node) throws BadXMLException { traverse(node); } protected void handleElement(Element node, String name) throws BadXMLException { if (name.equals("bins2d")) b2d = new Bins2DNodeTraverser(node); else if (name.equals("points")) p2d = new Points2DNodeTraverser(node); else if(name.equals("pointDataAxisAttributes")) paa[paxis++] = new PointDataAxisAttributesNodeTraverser(node);//bug? axis++ ??? else if (name.equals("binnedDataAxisAttributes")) baa[baxis++] = new BinnedDataAxisAttributesNodeTraverser(node); else if (name.equals("class")) ct = new ClassNodeTraverser(node); else if (name.equals("datasource")) ct = new DataSourceNodeTraverser(node); else if (name.equals("statistics")) stats = new StatisticsTraverser(node); else if (name.equals("style2d")) { if(type.equals("scatter2d")){ JASHistScatterPlotStyle scatstyle=new JASHistScatterPlotStyle(); this.style = scatstyle; scst.traverse(node,scatstyle); } else if(type.equals("histogram2d")) st.traverse(node,style=new JASHist2DHistogramStyle()); else throw new BadXMLException("type attribute for data2d element must be scatter2d of histogram2d."); } else super.handleElement(node,name); } protected void handleAttributeNode(Attr node, String name, String value) throws BadXMLException { if (name.equals("type")) type = value; else if (name.equals("name")) refName = value; else super.handleAttributeNode(node,name,value); } DataSource getDataSource() throws BadXMLException { if (ct != null) return ct.getDataSource(); else if(b2d != null) return new XML2DHistDataSource(b2d,baa[0],baa[1],stats); else return new XML2DScatterDataSource(paa[0].getType(),paa[1].getType(),p2d.getTitle(),p2d.getData()); } JASHistStyle getStyle() { return style; } String getRefName() { return refName; } private String type; private int paxis = 0;//will this counting work? private int baxis = 0;//will this counting work? private JASHist2DHistogramStyle style; private ConstructorNodeTraverser ct = null; private StatisticsTraverser stats = null; private Style2DNodeTraverser st = new Style2DNodeTraverser(); private ScatterStyleNodeTraverser scst = new ScatterStyleNodeTraverser(); private Bins2DNodeTraverser b2d; private BinnedDataAxisAttributesNodeTraverser[] baa = new BinnedDataAxisAttributesNodeTraverser[2]; private PointDataAxisAttributesNodeTraverser[] paa = new PointDataAxisAttributesNodeTraverser[2]; private Points2DNodeTraverser p2d; private String refName; } class Bins2DNodeTraverser extends XMLNodeTraverser { Bins2DNodeTraverser(Node node) throws BadXMLException { traverse(node); } protected void handleAttributeNode(Attr node, String name, String value) throws BadXMLException { if (name.equals("title")) title = value; else if (name.equals("xSize")) xSize = toInt(value); else if (name.equals("ySize")) ySize = toInt(value); else super.handleAttributeNode(node,name,value); } protected void handleTextNode(Text node, String name) throws BadXMLException { StringTokenizer lineTokens = new StringTokenizer(node.getData(),"\n\r"); int lines = lineTokens.countTokens(); if (lines < xSize * ySize || lines > xSize*ySize + 1) throw new BadXMLException("Inconsistent data length for bins2d (lines="+lines+")"); int x = 0; int y = 0; for (int l=0; l= 0) name = name.substring(0,pos); name += ".gif"; File parent = file.getParentFile(); return new File(parent,name); } public boolean supportsClass(Object o) { return true; } public void saveOptions(Properties props) { } public void restoreOptions(Properties props) { } }src/main/java/jas/hist/ScatterEnumeration.java0000644000175000017500000000023311325547132022124 0ustar giovannigiovannipackage jas.hist; public interface ScatterEnumeration { public boolean getNextPoint(double[] a); public void resetEndPoint(); public void restart(); } src/main/java/jas/hist/OverlayWithHandles.java0000644000175000017500000002122111325547132022064 0ustar giovannigiovannipackage jas.hist; import jas.plot.CoordinateTransformation; import jas.plot.DateCoordinateTransformation; import jas.plot.DoubleCoordinateTransformation; import jas.plot.Overlay; import jas.plot.OverlayContainer; import jas.plot.PlotGraphics; import jas.plot.PrintHelper; import java.awt.Color; import java.awt.Cursor; import java.awt.Point; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.event.MouseMotionListener; public abstract class OverlayWithHandles implements Overlay, MouseListener, MouseMotionListener { private Cursor defaultCursor = null; private static MouseEvent mouseEvent = null; private static boolean changeCursor; private boolean handlesPainted = false; protected OverlayWithHandles(DataSource ds) { if (ds instanceof HasHandles) { hasHandles = (HasHandles) ds; } } public void paint(PlotGraphics g) { if (handles != null && !PrintHelper.isPrinting()) { CoordinateTransformation xt = container.getXTransformation(); CoordinateTransformation yt = container.getYTransformation(); g.clearTransformation(); for (int i=0; i= x && p.x <= x+2*handleSize && p.y >= y && p.y > y && p.y <= y+2*handleSize); } void moveTo(Point p) { CoordinateTransformation xt = (CoordinateTransformation) container.getXTransformation(); CoordinateTransformation yt = (CoordinateTransformation) container.getYTransformation(); DoubleCoordinateTransformation xp; DoubleCoordinateTransformation yp; if ( xt instanceof DateCoordinateTransformation ) xp = new DateTransformationConverter( (DateCoordinateTransformation) xt ); else xp = (DoubleCoordinateTransformation) xt; if ( yt instanceof DateCoordinateTransformation ) yp = new DateTransformationConverter( (DateCoordinateTransformation) yt ); else yp = (DoubleCoordinateTransformation) yt; handle.moveTo(xp.unConvert(p.x),yp.unConvert(p.y)); } Cursor cursor() { return handle.cursor(); } private Handle handle; } private static final double handleSize = 2.5; private HandleWrapper[] handles = null; private HandleWrapper currentHandle = null; private HandleWrapper capturedHandle = null; private HasHandles hasHandles; protected OverlayContainer container; } src/main/java/jas/hist/HasDataSource.java0000644000175000017500000000014611325547132021001 0ustar giovannigiovannipackage jas.hist; public interface HasDataSource { public DataSource getDataSource(String param); } src/main/java/jas/hist/OneDDataManager.java0000644000175000017500000001247511325547132021235 0ustar giovannigiovannipackage jas.hist; import jas.plot.DataArea; import jas.plot.Legend; import java.awt.Component; import java.awt.event.ActionEvent; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Enumeration; import javax.swing.JCheckBoxMenuItem; import javax.swing.JMenuItem; import javax.swing.JPopupMenu; import javax.swing.SwingUtilities; abstract class OneDDataManager extends SliceableDataManager { OneDDataManager(JASHist plot, DataArea da, Legend l, StatisticsBlock stats) { super(plot, da,l, stats); } protected transient double xLow; protected transient double xHigh; JASHistData add(DataSource ds) { JASHistData dw = new JASHist1DHistogramData(this,ds); data.addElement(dw); return dw; } void modifyPopupMenu(final JPopupMenu menu, final Component source) { final JMenuItem outline = new HistMenuItem("Show Histogram Bars", "ShowHistogramBars"); final JMenuItem fill = new HistMenuItem("Fill Histogram Bars", "HistogramFill"); final JMenuItem error = new HistMenuItem("Show Error Bars", "ShowErrorBars"); final JMenuItem lines = new HistMenuItem("Draw Lines Between Points", "ShowLinesBetweenPoints"); final JMenuItem symbols = new HistMenuItem("Show Data Points", "ShowDataPoints"); if (menu.getComponentCount() > 0) menu.addSeparator(); menu.add(outline); menu.add(fill); menu.add(error); menu.add(lines); menu.add(symbols); if (fill.isEnabled()) fill.setEnabled(outline.isSelected()); } final protected void doUpdate() { if (isInit) { if (xm.needsAttention()) { computeXAxisRange(); XAxisUpdated(); } computeYAxisRange(); stats.repaint(); da.repaint(); } } public void update(final HistogramUpdate hu, final JASHistData data) { // Danger: likely to be run in a different thread //if (hu.isReset()) //parent.resetNumberOfBins(this); int index = data.getYAxis(); if (hu.isRangeUpdate() || hu.isReset()) xm.setAttentionNeeded(); else ym[index].setAttentionNeeded(); if (hu.isFinalUpdate() || hu.isReset()) { SwingUtilities.invokeLater(this); if (hu.isReset()) // When we get a reset we have to abandon all assumptions // about the data. We may have to create a new data manager // (because a reset is sent when the partition changes) // and inform JASHist somehow, but this has not yet been // implemented. For now, we will make sure that the // isFixed flag is correct in the x axis managed axis // because that is currently the only instance where // a reset is sent. We also check if the number of bins is set. // We also set rangeAutomatic. { // SwingUtilities.invokeLater(new Runnable() // { // final public void run() // { //final boolean isRebinnable = ((Rebinnable1DHistogramData) data.getDataSource()).isRebinnable(); DataSource dataSource = data.getDataSource(); final boolean isRebinnable = (dataSource instanceof Rebinnable1DHistogramData) ? ((Rebinnable1DHistogramData) dataSource).isRebinnable() : false; xm.setFixed(!isRebinnable); xm.setRangeAutomatic(isRebinnable); // } // }); } } else timer.start(); } final void axisChanged(final JASHistData data) { int index = data.getYAxis(); if (ym[index] == null) createYAxis(index); else ym[index].setAttentionNeeded(); // BUG: What about the OLD y-axis, doesnt it need attention? SwingUtilities.invokeLater(this); } void styleUpdate(JASHistData data) { int index = data.getYAxis(); if (ym[index] == null) createYAxis(index); else ym[index].setAttentionNeeded();// BUG: What about the OLD y-axis, doesnt it need attention? SwingUtilities.invokeLater(this); } private final class HistMenuItem extends JCheckBoxMenuItem { HistMenuItem(final String menuLabel, final String methodRoot) { super(menuLabel); if (numberOfDataSources() > 0) { try { m_methodRoot = methodRoot; final Method get = JASHist1DHistogramStyle.class.getMethod("get".concat(methodRoot), new Class[0]); boolean selected = true; final Enumeration e = getDataSources(); final Object[] emptyList = new Object[0]; while (selected && e.hasMoreElements()) selected = ((Boolean) get.invoke(((JASHistData) e.nextElement()).getStyle(), emptyList)).booleanValue(); setSelected(selected); } catch (NoSuchMethodException x) { setEnabled(false); setSelected(false); } catch (IllegalAccessException x) { setEnabled(false); setSelected(false); } catch (InvocationTargetException x) { setEnabled(false); setSelected(false); } } else { setEnabled(false); setSelected(false); } } protected void fireActionPerformed(final ActionEvent event) { final Class[] booleanList = { boolean.class }; try { final Method set = JASHist1DHistogramStyle.class.getMethod("set".concat(m_methodRoot), booleanList); final Object[] arg = { new Boolean(isSelected()) }; final Enumeration enumer = getDataSources(); while (enumer.hasMoreElements()) { try { set.invoke(((JASHistData) enumer.nextElement()).getStyle(), arg); } catch (final Exception exception) { } } } catch (final Exception exception) { } } private String m_methodRoot; } } src/main/java/jas/hist/DataSource.java0000644000175000017500000000062311325547132020345 0ustar giovannigiovannipackage jas.hist; /** * Interface implemented by any JASHist datasource */ public interface DataSource { public final static int DOUBLE = 1; public final static int STRING = 2; public final static int DATE = 3; public final static int INTEGER = 4; public final static int DELTATIME = 5; /** * Return the caption to be used in the legend for this data. */ String getTitle(); } src/main/java/jas/hist/StringDataManager.java0000644000175000017500000000620211325547132021645 0ustar giovannigiovannipackage jas.hist; import jas.plot.DataArea; import jas.plot.DoubleAxis; import jas.plot.Legend; import jas.plot.StringAxis; import java.util.Enumeration; import java.util.Hashtable; final class StringDataManager extends OneDDataManager { StringDataManager(JASHist plot, DataArea da, Legend l, StatisticsBlock stats) { super(plot, da, l, stats); xAxis = new StringAxis(); yAxis = new DoubleAxis(); yAxis.setUseSuggestedRange(true); // Configure the Axes xm.setDataManager(this,true , xAxis); xm.setFixed(true); ym[0].setDataManager(this,false, yAxis); } JASHistData add(DataSource ds) { Rebinnable1DHistogramData d = (Rebinnable1DHistogramData) ds; if (d.getAxisType() != d.STRING) throw new DataManagerException("Data incompatible with String axis"); JASHist1DHistogramData dw = new JASHist1DHistogramData(this,d); data.addElement(dw); return dw; } void destroy() // detaches data, but doesn't set up the plot for further use { Enumeration e; for (e = data.elements(); e.hasMoreElements();) { JASHistData d = (JASHistData) e.nextElement(); d.deleteNormalizationObserver(); d.show(false); } data.removeAllElements(); } void XAxisUpdated() { } void computeXAxisRange() { if (data.isEmpty()) return; Hashtable labels = new Hashtable(); String[] original = null; int n = 0; for (Enumeration e = data.elements(); e.hasMoreElements();) { JASHist1DHistogramData dw = (JASHist1DHistogramData) e.nextElement(); if (!dw.isShowing()) continue; String[] label = dw.getAxisLabels(); if (n++ == 0) original = label; for (int i=0; i 1) { String[] result = new String[labels.size()]; Enumeration e = labels.keys(); for (int i=0; e.hasMoreElements(); i++) { result[i] = (String) e.nextElement(); } xAxis.setLabels(result); } else { xAxis.setLabels(original); } xAxis.getAxis().invalidate(); } void computeYAxisRange() { if (data.isEmpty()) return; if (!ym[0].getRangeAutomatic()) return; double ymin = 0; double ymax = 0; boolean first = true; for (Enumeration e = data.elements(); e.hasMoreElements();) { JASHist1DHistogramData dw = (JASHist1DHistogramData) e.nextElement(); if (!dw.isShowing()) continue; if (first) { ymin = dw.getYMin(); ymax = dw.getYMax(); first = false; } else { ymin = Math.min(ymin,dw.getYMin()); ymax = Math.max(ymax,dw.getYMax()); } } if (ymax <= ymin) ymax = ymin + 1; if (yAxis.isLogarithmic()) ymin = Math.max(ymin,1); // TODO: Correct calculation // Only update the axis if the new range is outside of the old range, or occupies less // than 75% of the old range double oldYMin = yAxis.getPlotMin(); double oldYMax = yAxis.getPlotMax(); if (ymin < oldYMin || ymax > oldYMax || (ymax - ymin) / (oldYMax - oldYMin) < .75) { yAxis.setMin(ymin); yAxis.setMax(ymax); yAxis.getAxis().revalidate(); } } private StringAxis xAxis; private DoubleAxis yAxis; } src/main/java/jas/hist/DateDataManager.java0000644000175000017500000000435611325547132021264 0ustar giovannigiovannipackage jas.hist; import jas.plot.DataArea; import jas.plot.DateAxis; import jas.plot.DoubleAxis; import jas.plot.Legend; import java.io.IOException; import java.io.ObjectInputStream; import java.util.TimeZone; final class DateDataManager extends BinnedDataManager { DateDataManager(JASHist plot, DataArea da, Legend l, StatisticsBlock stats, int bins) { super(plot, da,l,stats,bins); // Configure the Axes xAxis = new DateAxis(); DoubleAxis yAxis = new DoubleAxis(); yAxis.setUseSuggestedRange(true); xm.setDataManager(this,true, xAxis); ym[0].setDataManager(this,false,yAxis); new DateAxisListener(xm); xm.setBins(bins); //createYAxis(1); // todo: something better } JASHistData add(DataSource data) { if (data instanceof Rebinnable1DHistogramData) { Rebinnable1DHistogramData d = (Rebinnable1DHistogramData) data; // We only support adding items with date axis if (d.getAxisType() != d.DATE) throw new DataManagerException("Incompatible data type for axis"); } else { XYDataSource d = (XYDataSource) data; // We only support adding items with date axis if (d.getAxisType() != d.DATE) throw new DataManagerException("Incompatible data type for axis"); } JASHistData jhd = super.add(data); TimeZone tz = jhd.getStyle().getTimeZone(); if (tz != null) xAxis.setTimeZone(tz); return jhd; } void styleUpdate(JASHistData data) { TimeZone tz = data.getStyle().getTimeZone(); if (tz != null) xAxis.setTimeZone(tz); super.styleUpdate(data); } private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { in.defaultReadObject(); new DateAxisListener(xm); } protected void calcMinMaxBins(double x1, double x2) { long iLow = (long) (x1*1000); long iHigh = (long) (x2*1000); long oldXMin = xAxis.getAxisMin(); long oldXMax = xAxis.getAxisMax(); if (iLow != oldXMin || iHigh != oldXMax) { xAxis.setMin(iLow); xAxis.setMax(iHigh); xAxis.getAxis().invalidate(); } } private DateAxis xAxis; } src/main/java/jas/hist/JASHistPropFunctions.java0000644000175000017500000005422311325547132022317 0ustar giovannigiovannipackage jas.hist; import jas.util.JASIcon; import jas.util.JASTextField; import jas.util.PropertyPage; import jas.util.PropertySite; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; import java.awt.Container; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.Frame; import java.awt.GridLayout; import java.awt.TextField; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.util.Enumeration; import java.util.Observable; import java.util.Observer; import javax.swing.BorderFactory; import javax.swing.BoundedRangeModel; import javax.swing.DefaultCellEditor; import javax.swing.DefaultListModel; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JComboBox; import javax.swing.JLabel; import javax.swing.JList; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JProgressBar; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.JTextField; import javax.swing.UIManager; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import javax.swing.event.TableModelEvent; import javax.swing.table.AbstractTableModel; import javax.swing.table.TableCellRenderer; import javax.swing.table.TableColumn; class JASHistPropFunctions extends PropertyPage implements ListSelectionListener, PropertySite { public JASHistPropFunctions() { m_init = false; setLayout(new BorderLayout()); JPanel p1 = new JPanel(new BorderLayout()); m_listModel = new DefaultListModel(); m_list = new JList(m_listModel); m_list.setCellRenderer(DataRenderer.createRenderer()); m_list.addListSelectionListener(this); JScrollPane scroll = new JScrollPane(); scroll.setViewportView(m_list); scroll.setPreferredSize(new Dimension(100,120)); p1.add(scroll,BorderLayout.CENTER); JPanel p2 = new JPanel(); JButton add = new JButton("Add..."); add.addActionListener(new AddButtonListener()); add.setMnemonic('d'); p2.add(add); JButton remove = new JButton("Remove"); remove.addActionListener(new RemoveButtonListener()); remove.setMnemonic('R'); p2.add(remove); p1.add(p2,BorderLayout.SOUTH); add(p1,BorderLayout.WEST); JPanel p = new JPanel(new BorderLayout()); JPanel b = new JPanel(new FlowLayout(FlowLayout.LEFT)); m_propStyle = new JASHistPropFunctionStyle(); m_propStyle.setPropertySite(this); b.add(m_propStyle); m_dataStyle = new JASHistPropDataStyle(); m_dataStyle.setPropertySite(this); b.add(m_dataStyle); advanced = new JButton("Advanced..."); advanced.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { try { FunctionAdvancedOptions fao = (FunctionAdvancedOptions) m_selected.getFunction(); Container w = JASHistPropFunctions.this; while (!(w instanceof Frame)) w = w.getParent(); fao.openAdvancedDialog((Frame) w, m_jHist); // The argument pf simply allows the // dialog box to have access to the // PropFunctions fields } catch (Exception exception) {} // do nothing if an exception is thrown } }); advanced.setMnemonic('v'); b.add(advanced); p.add(b,BorderLayout.NORTH); p.setBorder(BorderFactory.createTitledBorder("Function")); m_paramManager = new ParamManager(); p.add(m_paramManager,BorderLayout.CENTER); m_fitManager = new FitManager(); p.add(m_fitManager,BorderLayout.SOUTH); add(p,BorderLayout.CENTER); updateAdvanced(); } public String getHelpTopic() { return "functionsAndFilters.functions"; } public synchronized void doDataExchange(boolean set,Object bean) { if (!m_init) { JASHist hist = (JASHist) bean; Enumeration e = hist.get1DFunctions(); JASHist1DFunctionData d; while (e.hasMoreElements()) { d = (JASHist1DFunctionData) e.nextElement(); m_listModel.addElement(d); Basic1DFunction f = d.getFunction(); if (f instanceof FunctionAdvancedOptions) { f.addObserver(m_listNameChangeListener); } } if (m_listModel.size()>0) { m_selected = (JASHist1DFunctionData) m_listModel.elementAt(0); m_list.setSelectedValue(m_selected,true); } else m_selected = null; m_jHist = hist; m_fitManager.init(hist); m_init = true; } if (m_selected != null) { m_propStyle.doDataExchange(set,m_selected.getStyle()); m_dataStyle.doDataExchange(set,m_selected); m_paramManager.doDataExchange(set,m_selected.getFunction()); m_fitManager.setFunction(m_selected); } setChanged(false); updateAdvanced(); } private synchronized void addFunction(JASHist1DFunctionData d) { m_selected = d; m_listModel.addElement(d); m_list.setSelectedValue(d,true); doDataExchange(true,m_jHist); } private synchronized void removeFunction() { m_selected.delete(); m_listModel.removeElement(m_selected); doDataExchange(true, m_jHist); } public void valueChanged(ListSelectionEvent evt) { if (!m_init) return; doDataExchange(true,m_jHist); if (m_listModel.getSize() > 0) { m_selected = (JASHist1DFunctionData) m_list.getSelectedValue(); doDataExchange(false,m_jHist); updateAdvanced(); } } private void updateAdvanced() { advanced.setEnabled(m_selected != null && m_selected.getFunction() instanceof FunctionAdvancedOptions); } public void callEnable() { setChanged(true); } protected void deactivate() { m_paramManager.deactivate(); m_fitManager.deactivate(); } private class AddButtonListener implements ActionListener { public void actionPerformed(ActionEvent evt) { FunctionRegistry fr = FunctionRegistry.instance(); Container w = JASHistPropFunctions.this; while (!(w instanceof Frame)) w = w.getParent(); FunctionFactory ff = fr.chooseFunction((Frame) w); if (ff != null) { try { Basic1DFunction f = ff.createFunction(m_jHist); JASHistData d = m_jHist.addData(f); d.show(true); addFunction((JASHist1DFunctionData) d); if (f instanceof FunctionAdvancedOptions) f.addObserver(m_listNameChangeListener); } catch (FunctionFactoryError x) { x.printStackTrace(); // ???? } } } } private class RemoveButtonListener implements ActionListener { public void actionPerformed(ActionEvent evt) { removeFunction(); } } private class ParamTableModel extends AbstractTableModel implements Observer { ParamTableModel() { format.setMaximumFractionDigits(6); } void setFunction(Basic1DFunction f) { // We want to observe the function, so that we can update if the // function changes (e.g. due to a fit), but we need to be careful // to remove the link when we are deactivated. if (f != null) f.deleteObserver(this); this.f = f; f.addObserver(this); fireTableChanged(new TableModelEvent(this, -1)); } void deactivate() { if (f != null) f.deleteObserver(this); } public void update(Observable obs, Object arg) { if (obs == f) { fireTableChanged(new TableModelEvent(this, -1)); } } public int getRowCount() { if (f==null) return 0; String[] names = f.getParameterNames(); return (names == null) ? 0 : names.length; } public int getColumnCount() { return columns.length; } public Object getValueAt(int row, int col) { if (col == 0) return f.getParameterNames()[row]; else if (col == 1) return format.format(f.getParameterValues()[row]); else if (col == 2) { boolean value; if (f instanceof Fittable1DFunction) { value = ((Fittable1DFunction) f).getIncludeParametersInFit()[row]; } else value = false; return new Boolean(value); } else if (col == 3) { if (f instanceof Fittable1DFunction) { Fittable1DFunction func = (Fittable1DFunction) f; Fitter fit = func.getFit(); if (fit != null) { boolean[] inFit = func.getIncludeParametersInFit(); if (! inFit[row]) return "Not in fit"; int i = 0, j = 0; while (i < row) { if (inFit[i]) j++; i++; } return format.format(fit.getParameterSigmas()[j]); } } } return null; } public String getColumnName(int col) { return columns[col]; } public Class getColumnClass(int col) { if (col == 2) return Boolean.class; if (col == 1) return String.class; return super.getColumnClass(col); } public boolean isCellEditable(int row, int col) { return (col == 2 || col == 1); } public void setValueAt(Object value, int row, int col) { if (col == 1) { try { double d = Double.valueOf((String) value).doubleValue(); f.setParameter(row,d); } catch (InvalidFunctionParameter e) {getToolkit().beep();} catch (NumberFormatException e) {getToolkit().beep();} } else if (col == 2) { if (f instanceof Fittable1DFunction) { boolean b = ((Boolean) value).booleanValue(); ((Fittable1DFunction) f).setIncludeParameterInFit(row,b); } else getToolkit().beep(); } } private String[] columns = {"Parameter","Value","Fit","Error"}; private Basic1DFunction f = null; } private class ParamManager extends JPanel { ParamManager() { this.setLayout(new BorderLayout()); m_model = new ParamTableModel(); m_table = new JTable(m_model); m_table.setAutoCreateColumnsFromModel(false); TableColumn col = m_table.getColumn("Value"); col.setCellRenderer(new ParamCellRenderer()); col.setCellEditor(new DefaultCellEditor(new JTextField(""))); //col = m_table.getColumn("Fit"); //col.setHeaderRenderer(new FitHeaderRenderer(m_table, col.getHeaderRenderer())); //col.sizeWidthToFit(); // just wide enough for header cell JScrollPane scrollpane = new JScrollPane(m_table); scrollpane.setPreferredSize(new Dimension(350,100)); this.add("Center",scrollpane); } void doDataExchange(boolean set,Basic1DFunction f) { if (m_f != f) { m_model.setFunction(f); m_f = f; } } void deactivate() { m_model.deactivate(); m_f = null; } private JTable m_table; private Basic1DFunction m_f = null; private ParamTableModel m_model; private class ParamCellRenderer implements TableCellRenderer { public Component getTableCellRendererComponent(JTable table, Object obj, boolean sel, boolean hasFocus, int col, int row) /* * bug: hasFocus not used */ { if (obj != null) text.setText(obj.toString()); if (sel) { text.setBackground(UIManager.getColor("textHighlight")); text.setForeground(UIManager.getColor("textHighlightText")); } else { text.setBackground(b); text.setForeground(f); } text.setScrollOffset(0); return text; } private JASTextField text = new JASTextField(); private Color f = text.getForeground(); private Color b = text.getBackground(); } private class FitHeaderRenderer implements TableCellRenderer { FitHeaderRenderer(JTable table, TableCellRenderer renderer) { m_table = table; m_renderer = renderer; } public Component getTableCellRendererComponent(JTable table, Object obj, boolean sel, boolean hasFocus, int col, int row) { if (table == null) table = m_table; return m_renderer.getTableCellRendererComponent(table, obj, sel, hasFocus, col, row); } private TableCellRenderer m_renderer; private JTable m_table; } } private class FitManager extends JPanel implements Observer,ItemListener { FitManager() { states = new javax.swing.Icon[5]; states[Fitter.FIT] = JASIcon.create(this,"tick.gif"); states[Fitter.FAILED] = JASIcon.create(this,"cross.gif"); states[Fitter.FITTING] = JASIcon.create(this,"running.gif"); states[Fitter.READYTOFIT] = states[Fitter.FIT]; states[Fitter.NOTREADYTOFIT] = states[Fitter.FAILED]; JPanel p4 = new JPanel(); m_state = new JLabel(states[Fitter.FIT]); p4.add(m_state); m_chi2 = new JLabel(" ") { public Dimension getPreferredSize() { Dimension result = super.getPreferredSize(); result.width = 100; // Leave sufficient room return result; } }; m_chi2.setIcon(JASIcon.create(this,"chi2.gif")); p4.add(m_chi2); JPanel p2 = new JPanel(new BorderLayout()); p2.add("North",p4); JProgressBar bar = new JProgressBar(); m_fitWatcher = new FitWatcher(bar.getModel()); p2.add("Center",bar); JPanel p3 = new JPanel(); p3.add(new JLabel("Using")); m_fitterChoice = new JComboBox(); m_fitterChoice.addItemListener(this); p3.add(m_fitterChoice); JPanel p1 = new JPanel(); p1.add(new JLabel("Data")); m_choice = new JComboBox(); p1.add(m_choice); JPanel p5 = new JPanel(new GridLayout(0,1)); p5.add(p3); p5.add(p1); this.setLayout(new BorderLayout()); m_fit = new JCheckBox("Fit"); m_fit.addActionListener(new FitNowHandler()); m_fit.setMnemonic('F'); // It would be nice to make the title contain the // fit checkbox, needs custom swing border //this.setBorder(new CheckBoxBorder(m_fit)); this.setBorder(BorderFactory.createTitledBorder("Fit")); this.add("North",m_fit); this.add("West",p5); this.add("Center",p2); //add("South",new Checkbox("Update fit when data changes")); setEnabled(false); } void init(JASHist hist) { Enumeration e = hist.getDataSources(); if (e.hasMoreElements()) { m_choice.setRenderer(DataRenderer.createRenderer()); m_choice.addItemListener(this); } else m_choice.setEnabled(false); while (e.hasMoreElements()) { JASHist1DHistogramData d = (JASHist1DHistogramData) e.nextElement(); m_choice.addItem(d.getFittableDataSource()); } e = FitterRegistry.instance().elements(); while (e.hasMoreElements()) { FitterFactory ff = (FitterFactory) e.nextElement(); m_fitterChoice.addItem(ff); } m_fitterChoice.setSelectedItem(FitterRegistry.instance().getDefaultFitterFactory()); } void setFunction(JASHist1DFunctionData fd) { if (m_function != null) m_function.deleteObserver(this); m_fitWatcher.clearFit(); if (fd != null && fd.getFunction() instanceof Fittable1DFunction && m_choice.getItemCount() > 0 && m_fitterChoice.getItemCount() > 0) { m_fd = fd; m_function = (Fittable1DFunction) fd.getFunction(); m_function.addObserver(this); Fitter fitter = m_function.getFit(); if (fitter != null) m_fitWatcher.setFit(fitter); update(); setEnabled(true); } else { setEnabled(false); m_function = null; m_fd = null; } } private void update() { Fitter fitter = m_function.getFit(); m_fit.setSelected(fitter != null); if (fitter != null) { m_chi2.setText(format.format(fitter.getChiSquared())); //TO-DO make sure all fitters get data assigned (?). Object data = fitter.getData(); if ( data != null ) m_choice.setSelectedItem(data); } } public void update(Observable obs, Object arg) { //System.out.println("FitManager update"+obs+" "+m_function); if (obs == m_function) update(); } void deactivate() { //System.out.println("Deactivating FitManager"); setFunction(null); } public void setEnabled(boolean state) { m_fit.setEnabled(state); m_choice.setEnabled(state); m_fitterChoice.setEnabled(state); } public void itemStateChanged(ItemEvent e) { // TODO: This causes problems when ComboBox is changed programatically! //if (m_function != null) m_function.clearFit(); //if (m_fit != null && m_fit.isSelected()) m_fit.setSelected(false); } private Fittable1DFunction m_function; private JASHist1DFunctionData m_fd; private JLabel m_state; private JCheckBox m_fit; private JComboBox m_choice; private JComboBox m_fitterChoice; private JLabel m_chi2; private FitWatcher m_fitWatcher; private javax.swing.Icon states[]; private class FitNowHandler implements ActionListener { public void actionPerformed(ActionEvent e) { if (m_fit.isSelected()) { FitterFactory ff = (FitterFactory) m_fitterChoice.getSelectedItem(); Fitter fitter = ff.createFitter(); fitter.setFunction(m_function); XYDataSource data = (XYDataSource) m_choice.getSelectedItem(); fitter.setData(data); m_fitWatcher.setFit(fitter); fitter.start(); } else { m_fitWatcher.clearFit().dispose(); } } } private class FitWatcher implements Observer { FitWatcher(BoundedRangeModel model) { model.setMinimum(0); model.setMaximum(100); this.model = model; clearFit(); } void setFit(Fitter fit) { m_fitter = fit; m_fitter.addObserver(this); m_state.setEnabled(true); m_state.repaint(); // Not needed? Swing 0.6.1 m_chi2.setEnabled(true); m_chi2.repaint(); // Not needed? Swing 0.6.1 } Fitter clearFit() { Fitter fit = m_fitter; if (fit != null) { fit.deleteObserver(this); m_fitter = null; } m_state.setEnabled(false); m_state.repaint(); // Not needed? Swing 0.6.1 m_chi2.setEnabled(false); m_chi2.repaint(); // Not needed? Swing 0.6.1 return fit; } public void update(Observable obs, Object arg) { if (arg instanceof FitUpdate) { FitUpdate fu = (FitUpdate) arg; int state = fu.getState(); if (state == Fitter.OUTAHERE) clearFit(); else { model.setValue(fu.getPercent()); m_state.setIcon(states[state]); if (state == Fitter.FAILED) { Container w = JASHistPropFunctions.this; while (!(w instanceof Frame)) w = w.getParent(); JOptionPane.showMessageDialog(w, fu.getReason(), "Fit error...", JOptionPane.ERROR_MESSAGE); } } } } private BoundedRangeModel model; private Fitter m_fitter; } } public JASHist getHist() { return m_jHist; } private JASHistPropFunctionStyle m_propStyle; private JASHistPropDataStyle m_dataStyle; private ParamManager m_paramManager; private FitManager m_fitManager; private boolean m_init; private JASHist1DFunctionData m_selected; private JList m_list; private DefaultListModel m_listModel; private TextField m_value; private JASHist m_jHist; private java.text.NumberFormat format = java.text.NumberFormat.getInstance(); private JButton advanced; private ListNameChangeListener m_listNameChangeListener = new ListNameChangeListener(); private class ListNameChangeListener implements Observer { public void update(Observable o, Object arg) { m_list.repaint(); } } } src/main/java/jas/hist/DefaultDataManager.java0000644000175000017500000000427011325547132021766 0ustar giovannigiovannipackage jas.hist; import jas.plot.Axis; import jas.plot.DataArea; import jas.plot.EditableLabel; import java.awt.Component; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.util.Enumeration; import javax.swing.JPopupMenu; // This is the data manager that is installed when there is no data, hence it // doesn't actally manage any data at all! final class DefaultDataManager extends DataManager { DefaultDataManager(JASHist plot, DataArea da) { super(plot, da); xm.setDataManager(this, false); ym[0].setDataManager(this, false); } void init() { } JASHistAxis getXAxis() { return (JASHistAxis) da.getXAxis(); } JASHistAxis getYAxis(int index) { return (JASHistAxis) da.getYAxis(index); } JASHistData add(DataSource data) { return null; } void remove(JASHistData data) { } void requestShow(JASHistData data) { } void requestHide(JASHistData data) { } void invalidate() { } boolean isRealized() { return false; } void XAxisUpdated() { } void computeYAxisRange() { } void computeXAxisRange() { } void update(HistogramUpdate update, JASHistData data) { } int numberOfDataSources() { return 0; } Enumeration getDataSources() { return nullEnumeration; } void destroy() { } public EditableLabel getLabel(Axis m) { return da.getLabel(m); } public void setLabel(Axis m, EditableLabel l) { da.setLabel(m,l); } void modifyPopupMenu(JPopupMenu menu, Component source) { } protected void showLegend() { } void styleUpdate(JASHistData source) { } void axisChanged(JASHistData source) { } private void writeObject(final ObjectOutputStream out) throws IOException { out.defaultWriteObject(); // out.writeObject(da.getXAxis()); // out.writeObject(da.getYAxis(0)); // out.writeObject(da.getYAxis(1)); } private void readObject(final ObjectInputStream in) throws ClassNotFoundException, IOException { in.defaultReadObject(); // da.add((Axis) in.readObject(), DataAreaLayout.X_AXIS); // da.add((Axis) in.readObject(), DataAreaLayout.Y_AXIS_LEFT); // da.add((Axis) in.readObject(), DataAreaLayout.Y_AXIS_RIGHT); } void setRealized(boolean b) { } } src/main/java/jas/util/0000755000175000017500000000000011325547132015455 5ustar giovannigiovannisrc/main/java/jas/util/xml/0000755000175000017500000000000011327073533016256 5ustar giovannigiovannisrc/main/java/jas/util/xml/XMLWriter.java0000644000175000017500000003075011325547132020762 0ustar giovannigiovannipackage jas.util.xml; import jas.util.IndentPrintWriter; import java.io.IOException; import java.io.Writer; import java.util.Enumeration; import java.util.Hashtable; import java.util.Stack; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import org.w3c.dom.NodeList; /** * A class that makes it easy to write XML documents. * * @author Tony Johnson * @author Mark Donszelmann * @version $Id: XMLWriter.java 11553 2007-06-05 22:06:23Z duns $ */ public class XMLWriter { public XMLWriter(Writer w, String indentString) { writer = new IndentPrintWriter(w); writer.setIndentString(indentString); } public XMLWriter(Writer w) { this(w, " "); // By popular demand of Babar } /** * closes the writer */ public void close() throws IOException { closeDoc(); writer.close(); } /** * Opens the document with an xml header */ public void openDoc() { openDoc("1.0", "", false); } /** * Opens the document with an xml header */ public void openDoc(String version, String encoding, boolean standalone) { String indentString = writer.getIndentString(); writer.setIndentString(indentString); closed = false; if (!XMLCharacterProperties.validVersionNum(version)) throw new RuntimeException("Invalid version number: "+version); writer.print(""); writer.setIndentString(indentString); } /** * Writes a reference to a DTD */ public void referToDTD(String name, String pid, String ref) { if (dtdName != null) { throw new RuntimeException("ReferToDTD cannot be called twice"); } dtdName = name; writer.println(""); } /** * Writes a reference to a DTD */ public void referToDTD(String name, String system) { if (dtdName != null) { throw new RuntimeException("ReferToDTD cannot be called twice"); } dtdName = name; writer.println(""); } /** * Closes the document, and checks if you closed all the tags */ public void closeDoc() { if (!closed) { if (!openTags.isEmpty()) { StringBuffer sb = new StringBuffer("Not all tags were closed before closing XML document:\n"); while (!openTags.isEmpty()) { sb.append(" \n"); } throw new RuntimeException(sb.toString()); } closed = true; } } /** * Print a comment */ public void printComment(String comment) { if (comment.indexOf("--") >= 0) throw new RuntimeException("'--' sequence not allowed in comment"); writer.print(""); } /** * Prints character data, while escaping < and > */ public void print(String text) { writer.print(normalizeText(text)); } /** * Prints character data, while escaping < and > */ public void println(String text) { print(text); writer.println(); } public void println() { writer.println(); } public void print(double d) { print(String.valueOf(d)); } /** * Prints a new XML tag and increases the identation level */ public void openTag(String namespace, String name) { openTag(namespace+":"+name); } /** * Prints a new XML tag and increases the identation level */ public void openTag(String name) { checkNameValid(name); if (openTags.isEmpty() && dtdName != null && !dtdName.equals(name)) { throw new RuntimeException("First tag: '"+name+"' not equal to DTD id: '"+dtdName+"'"); } writer.print("<"+name); printAttributes(name.length()); writer.println(">"); writer.indent(); openTags.push(name); } /** * Closes the current XML tag and decreases the indentation level */ public void closeTag() { if (openTags.isEmpty()) { writer.close(); throw new RuntimeException("No open tags"); } Object name = openTags.pop(); writer.outdent(); writer.print(""); } /** * Prints an empty XML tag. */ public void printTag(String namespace, String name) { printTag(namespace+":"+name); } /** * Prints an empty XML tag. */ public void printTag(String name) { checkNameValid(name); writer.print("<"+name); printAttributes(name.length()); writer.println("/>"); } /** * Sets an attribute which will be included in the next tag * printed by openTag or printTag */ public void setAttribute(String name, String value) { if ((name != null) && (value != null)) { attributes.put(name,value); } } public void setAttribute(String namespace, String name, String value) { if ((namespace != null) && (name != null)) { attributes.put(namespace+":"+name, value); } } public void setAttribute(String name, double value) { setAttribute(name, String.valueOf(value)); } public void setAttribute(String name, float value) { setAttribute(name, String.valueOf(value)); } public void setAttribute(String name, int value) { setAttribute(name, String.valueOf(value)); } public void setAttribute(String name, long value) { setAttribute(name, String.valueOf(value)); } public void setAttribute(String name, short value) { setAttribute(name, String.valueOf(value)); } public void setAttribute(String name, boolean value) { setAttribute(name, String.valueOf(value)); } public void setAttribute(String name, byte value) { setAttribute(name, String.valueOf(value)); } public void setAttribute(String name, char value) { setAttribute(name, String.valueOf(value)); } public void setAttribute(String ns, String name, double value) { setAttribute(ns+":"+name, String.valueOf(value)); } public void setAttribute(String ns, String name, int value) { setAttribute(ns+":"+name, String.valueOf(value)); } public void setAttribute(String ns, String name, boolean value) { setAttribute(ns+":"+name, String.valueOf(value)); } protected void printAttributes(int tagLength) { int width = tagLength + 1; boolean extraIndent = false; Enumeration e = attributes.keys(); while (e.hasMoreElements()) { String key = e.nextElement().toString(); checkNameValid(key); String value = normalize(attributes.get(key).toString()); int length = key.length() + value.length() + 3; if (width > 0 && width + length + 2*writer.getIndent() > 60) { width = 0; writer.println(); if (!extraIndent) { writer.indent(); extraIndent = true; } } else { width += length; writer.print(' '); } writer.print(key); writer.print("=\""); writer.print(value); writer.print("\""); } attributes.clear(); if (extraIndent) writer.outdent(); } /** * Prints a DOM node, recursively. * No support for a document node */ public void print(Node node) { if ( node == null ) return; int type = node.getNodeType(); switch ( type ) { // print document case Node.DOCUMENT_NODE: throw new RuntimeException("No support for printing nodes of type Document"); // print element with attributes case Node.ELEMENT_NODE: NamedNodeMap attributes = node.getAttributes(); for ( int i = 0; i < attributes.getLength(); i++ ) { Node attr = attributes.item(i); setAttribute(attr.getNodeName(), attr.getNodeValue()); } NodeList children = node.getChildNodes(); if ( children == null ) { printTag(node.getNodeName()); } else { openTag(node.getNodeName()); int len = children.getLength(); for ( int i = 0; i < len; i++ ) { print(children.item(i)); } closeTag(); } break; // handle entity reference nodes case Node.ENTITY_REFERENCE_NODE: writer.print('&'); writer.print(node.getNodeName()); writer.print(';'); break; // print cdata sections case Node.CDATA_SECTION_NODE: writer.print(""); break; // print text case Node.TEXT_NODE: print(node.getNodeValue()); break; // print processing instruction case Node.PROCESSING_INSTRUCTION_NODE: writer.print(" 0 ) { writer.print(' '); writer.print(data); } writer.print("?>"); break; } } // print(Node) /** Normalizes the given string for an Attribute value*/ public static String normalize(String s) { StringBuffer str = new StringBuffer(); int len = (s != null) ? s.length() : 0; for (int i = 0; i < len; i++) { char ch = s.charAt(i); switch (ch) { case '<': { str.append("<"); break; } case '>': { str.append(">"); break; } case '&': { str.append("&"); break; } case '"': { str.append("""); break; } case '\r': case '\n': { str.append("&#"); str.append(Integer.toString(ch)); str.append(';'); break; } default: { if (ch > 0x00FF) { String hex = "0000"+Integer.toHexString(ch); str.append("&#x"); str.append(hex.substring(hex.length()-4)); str.append(';'); } else { str.append(ch); } } } } return str.toString(); } // normalize(String):String /** Normalizes the given string for Text */ public static String normalizeText(String s) { StringBuffer str = new StringBuffer(); int len = (s != null) ? s.length() : 0; for (int i = 0; i < len; i++) { char ch = s.charAt(i); switch (ch) { case '<': { str.append("<"); break; } case '>': { str.append(">"); break; } case '&': { str.append("&"); break; } default: { if (ch > 0x00FF) { String hex = "0000"+Integer.toHexString(ch); str.append("&#x"); str.append(hex.substring(hex.length()-4)); str.append(';'); } else { str.append(ch); } } } } return str.toString(); } protected void checkNameValid(String s) { if (!XMLCharacterProperties.validName(s)) throw new RuntimeException("Invalid name: "+s); } protected boolean closed = true; private String dtdName = null; private Hashtable attributes = new Hashtable(); private Stack openTags = new Stack(); protected IndentPrintWriter writer; } src/main/java/jas/util/xml/JASDOMParser.java0000644000175000017500000000414611325547132021257 0ustar giovannigiovannipackage jas.util.xml; import jas.util.NestedException; import jas.util.NestedRuntimeException; import java.io.Reader; import org.w3c.dom.Document; import org.xml.sax.EntityResolver; /** * Ideally wouldnt need this interface, except that the DOM specification * only specifies how to extract information from a DOM, not how to create * a DOM from an XML file. The JASDOMParser interface is meant to make up * for that deficiency. */ public abstract class JASDOMParser { /** * Create a DOM document by reading an XML file * @param in A reader set up to read an XML file * @param fileName The name of the file being read (used in error messages) * @return Document The resulting DOM * @exception XMLException thrown if there is an error reading the XML */ public abstract Document parse(Reader in, String fileName) throws JASXMLException; /** * Create a DOM document by reading an XML file with an explicit entity resolver. * An entity resolver is typically used to specify where to find the DTD for the XML * document. * @param in A reader set up to read an XML file * @param fileName The name of the file being read (used in error messages) * @param resolver An entity resolver to use when reading the XML file * @return Document The resulting DOM * @exception XMLException thrown if there is an error reading the XML */ public abstract Document parse(Reader in, String fileName, EntityResolver resolver) throws JASXMLException; /** * An exception that gets thrown if there is an error reading an XML file. */ public static class JASXMLException extends NestedException { public JASXMLException(String message) { super(message,null); } public JASXMLException(String message, Throwable detail) { super(message,detail); } } /** * Creates a default instance of a JASDOMParser * @return A JASDOMParser */ public static JASDOMParser instance() { try { return (JASDOMParser) Class.forName("jas.util.xml.parserwrappers.JAXPDOMParser").newInstance(); } catch (Throwable x) { throw new NestedRuntimeException("Unable to create default JASDomParser",x); } } } src/main/java/jas/util/xml/parserwrappers/0000755000175000017500000000000011325547132021335 5ustar giovannigiovannisrc/main/java/jas/util/xml/parserwrappers/XercesDOMParser.java0000644000175000017500000000300211325547132025141 0ustar giovannigiovanni// Copyright 2000, SLAC, Stanford, California, U.S.A. package jas.util.xml.parserwrappers; import jas.util.xml.JASDOMParser; import java.io.IOException; import java.io.Reader; import org.w3c.dom.Document; import org.xml.sax.EntityResolver; import org.xml.sax.InputSource; import org.xml.sax.SAXException; /** * An implementation of DOMParser for the Xerces XML parser * * @version $Id: XercesDOMParser.java 11553 2007-06-05 22:06:23Z duns $ * @see org.freehep.xml.util.DOMParser */ public class XercesDOMParser extends JASDOMParser { public Document parse(Reader in, String fileName) throws JASDOMParser.JASXMLException { return parse(in,fileName,null); } public Document parse(Reader in, final String fileName, EntityResolver resolver) throws JASXMLException { try { org.apache.xerces.parsers.DOMParser parser = new org.apache.xerces.parsers.DOMParser(); parser.setFeature("http://xml.org/sax/features/validation", true); XMLErrorHandler errorHandler = new XMLErrorHandler(fileName); parser.setErrorHandler(errorHandler); if (resolver != null) parser.setEntityResolver(resolver); parser.parse(new InputSource(in)); if (errorHandler.getLevel() > 1) throw new SAXException("Error during XML file parsing"); return parser.getDocument(); } catch (SAXException x) { throw new JASDOMParser.JASXMLException("Syntax error parsing XML file",x); } catch (IOException x) { throw new JASDOMParser.JASXMLException("IO error parsing XML file",x); } } } src/main/java/jas/util/xml/parserwrappers/JAXPDOMParser.java0000644000175000017500000000507511325547132024466 0ustar giovannigiovanni/* * JAXPDomParser.java * * Created on March 30, 2002, 11:51 PM */ package jas.util.xml.parserwrappers; import jas.util.xml.JASDOMParser; import java.io.IOException; import java.io.Reader; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import org.w3c.dom.Document; import org.xml.sax.EntityResolver; import org.xml.sax.InputSource; import org.xml.sax.SAXException; /** * * @author tonyj */ public class JAXPDOMParser extends JASDOMParser { /** * Create a DOM document by reading an XML file * @param in A reader set up to read an XML file * @param fileName The name of the file being read (used in error messages) * @return Document The resulting DOM * @exception XMLException thrown if there is an error reading the XML */ public Document parse(Reader in, String fileName) throws JASXMLException { return parse(in,fileName,null); } /** * Create a DOM document by reading an XML file with an explicit entity resolver. * An entity resolver is typically used to specify where to find the DTD for the XML * document. * @param in A reader set up to read an XML file * @param fileName The name of the file being read (used in error messages) * @param resolver An entity resolver to use when reading the XML file * @return Document The resulting DOM * @exception XMLException thrown if there is an error reading the XML */ public Document parse(Reader in, String fileName, EntityResolver resolver) throws JASXMLException { try { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setValidating(true); DocumentBuilder parser = factory.newDocumentBuilder(); XMLErrorHandler errorHandler = new XMLErrorHandler(fileName); parser.setErrorHandler(errorHandler); if (resolver != null) parser.setEntityResolver(resolver); InputSource is = new InputSource(in); is.setSystemId("file:/"); Document doc = parser.parse(is); if (errorHandler.getLevel() > 1) throw new SAXException("Error during XML file parsing"); return doc; } catch (SAXException x) { throw new JASDOMParser.JASXMLException("Syntax error parsing XML file",x); } catch (IOException x) { throw new JASDOMParser.JASXMLException("IO error parsing XML file",x); } catch (ParserConfigurationException x) { throw new JASDOMParser.JASXMLException("Can not create XML parser",x); } } } src/main/java/jas/util/xml/parserwrappers/XMLErrorHandler.java0000644000175000017500000000211211325547132025144 0ustar giovannigiovanni/* * XMLErrorHandler.java * * Created on March 31, 2002, 12:08 AM */ package jas.util.xml.parserwrappers; import org.xml.sax.ErrorHandler; import org.xml.sax.SAXException; import org.xml.sax.SAXParseException; /** * * @author tonyj */ class XMLErrorHandler implements ErrorHandler { private int level = 0; private String fileName; XMLErrorHandler(String fileName) { this.fileName = fileName; } int getLevel() { return level; } public void warning(SAXParseException exception) { //System.err.println(fileName+": Warning at line "+exception.getLineNumber()+": "+exception); if (level < 1) level = 1; } public void error(SAXParseException exception) { System.err.println(fileName+": Error at line "+exception.getLineNumber()+": "+exception); if (level < 2) level = 2; } public void fatalError(SAXParseException exception) throws SAXException { System.err.println(fileName+": Fatal error at line "+exception.getLineNumber()+": "+exception); if (level < 3) level = 3; throw exception; } } src/main/java/jas/util/xml/XMLNodeTraverser.java0000644000175000017500000000575611325547132022301 0ustar giovannigiovannipackage jas.util.xml; import jas.util.ColorConverter; import java.awt.Color; import org.w3c.dom.Attr; import org.w3c.dom.Element; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import org.w3c.dom.Text; /** * Utility class for traversing XML DOM trees */ public abstract class XMLNodeTraverser { public void traverse(Node node) throws BadXMLException { if (node instanceof Element) { handleElementAttributes((Element) node); } for (Node n = node.getFirstChild(); n != null; n = n.getNextSibling()) { handleSubNode(n,n.getNodeName()); } } protected void handleSubNode(Node node, String name) throws BadXMLException { int type = node.getNodeType(); switch (type) { case Node.ELEMENT_NODE: handleElement((Element) node,name); break; case Node.TEXT_NODE: handleTextNode((Text) node,name); break; default: handleOtherNode(node,name); } } protected void handleElementAttributes(Element node) throws BadXMLException { NamedNodeMap nnm = node.getAttributes(); for (int i=0; idoModal() on the object to show the error. * @see java.lang.Throwable * @see java.lang.Exception * @see java.lang.Error * @author Tony Johnson * @author Jonas Gifford */ public class ErrorBox extends JASDialog { /** * Opens an ErrorBox with no help button and no displayed Throwable. * @param parent the parent JFrame * @param message a String to display as a message */ public ErrorBox(JFrame parent, String message) { this(parent, message, null, null); } /** * Opens an ErrorBox that has a Help button that opens the specified topic. Help books * are accessible throught static constants in the Application class. * @see Application * @param parent the parent JFrame * @param message a String to display as a message * @param helpTopic the help topic (as specified in the .oht topics file for the specified book) */ public ErrorBox(JFrame parent, String message, String helpTopic) { this(parent, message, null, helpTopic); } /** * Opens an ErrorBox that displays a Throwable, but has no help button. Book objects * are accessible through static constants in the Application class. * @see Application * @param parent the parent JFrame * @param message a String to display as a message * @param throwable the Error or Exception that was generated */ public ErrorBox(JFrame parent, String message, Throwable throwable) { this(parent,message,throwable,null); } /** * Opens an ErrorBox that displays a Throwable and has a Help button * that opens the specified topic. Book objects are available through * the Application class. * @see Application * @param parent the parent JFrame * @param message a String to display as a message * @param throwable the Error or Exception that was generated * @param helpTopic the help topic (XML target) */ public ErrorBox(JFrame parent, String message, Throwable throwable, String helpTopic) { super(parent, "Error...", true, OK_BUTTON | (throwable != null ? APPLY_BUTTON | CANCEL_BUTTON : 0) | (helpTopic != null ? HELP_BUTTON : 0)); if (helpTopic != null) setHelpTopic(helpTopic); init(message, throwable,parent); } private void init(String m, Throwable t,JFrame parent) { setApplyLabel("Details"); setApplyMnemonic('D'); setCancelLabel("Traceback"); setCancelMnemonic('T'); JPanel p = new JPanel(); p.add(new JLabel(UIManager.getIcon("OptionPane.errorIcon"))); p.add(new JLabel(m)); getContentPane().add(p,BorderLayout.NORTH); m_frame = parent; m_throw = t; m_details = (t != null); pack(); getToolkit().beep(); } /** Inherited from JASDialog; do not call. */ final protected void enableApply(JASState state) { state.setEnabled(m_details); } /** Inherited from JASDialog; do not call. */ final protected void onCancel() { // We used to use a JASDialog here, but it needs a Frame as its parent. // This cannot be fixed while maintaining JDK 1.1 compatibility, so instead // we swicthed to using a JOptionPane. JTextArea ta = new JTextArea(); PrintWriter pw = new PrintWriter(new DocumentOutputStream(ta.getDocument())); m_throw.printStackTrace(pw); pw.close(); ta.setEditable(false); ta.addMouseListener(new PopupListener(new PopupMenu(ta))); JScrollPane scroll = new JScrollPane(ta); scroll.setPreferredSize(new Dimension(500,300)); JOptionPane.showMessageDialog(this,scroll,"Traceback...",JOptionPane.PLAIN_MESSAGE); } /** Inherited from JASDialog; do not call. */ final protected void onApply() { JTextArea text = new JTextArea(m_throw.toString()); text.setEditable(false); text.addMouseListener(new PopupListener(new PopupMenu(text))); JScrollPane scroll = new JScrollPane(); scroll.setViewportView(text); getContentPane().add(scroll,BorderLayout.CENTER); pack(); m_details = false; callEnable(); } private static class PopupMenu extends OnScreenPopupMenu implements ActionListener { private JTextArea parent; JMenuItem copy = new JMenuItem("Copy",'C'); JMenuItem select = new JMenuItem("Select All",'S'); PopupMenu(JTextArea parent) { this.parent = parent; copy.addActionListener(this); select.addActionListener(this); add(copy); add(select); } public void actionPerformed(ActionEvent e) { Object source = e.getSource(); if (source == select) parent.selectAll(); else if (source == copy) parent.copy(); } } private static class PopupListener extends MouseAdapter { private JPopupMenu menu; PopupListener(JPopupMenu menu) { this.menu = menu; } public void mouseReleased(MouseEvent me) { maybePopup(me); } public void mousePressed(MouseEvent me) { maybePopup(me); } private void maybePopup(MouseEvent me) { if (menu.isPopupTrigger(me)) menu.show(me.getComponent(),me.getX(),me.getY()); } } private Throwable m_throw; private boolean m_details; private JFrame m_frame; }src/main/java/jas/util/JASIcon.java0000644000175000017500000001361511325547132017554 0ustar giovannigiovannipackage jas.util; import java.awt.Image; import java.awt.Toolkit; import java.io.IOException; import java.io.InputStream; import java.util.Hashtable; import javax.swing.ImageIcon; /** * A convenience class for creating small icons where the source file is stored in the * CLASSPATH of the application, typically in the same JAR file as the class creating the * image * * @author Tony Johnson */ public class JASIcon extends ImageIcon { /** * Create a JASIcon, for use within the jas.util package * The file is interpreted to be relative to jas.util */ JASIcon(String file) throws ImageException { this(null,file); } /** * Create a JASIcon from the CLASSPATH. * @param obj The object used as the root of the file path * @param file The path to the image source file, relative to obj * @exception ImageException Thrown if the image source file can not be found * @see #create(Object obj, String file) */ public JASIcon(Object obj,String file) throws ImageException { this(obj == null ? null : obj.getClass(),file); } /** * Create a JASIcon from the CLASSPATH. * @param c The class used as the root of the file path * @param file The path to the image source file, relative to the root class * @exception ImageException Thrown if the image source file can not be found * @see #create(Object c, String file) */ public JASIcon(Class c, String file) throws ImageException { m_c = c == null ? JASIcon.class : c; setImageImpl(file); } /** * Create a JASIcon without specifing the source * @param Class c The class used as the root of the file path when setImage is called * @see #setImage(String file) */ public JASIcon(Class c) { m_c = c == null ? JASIcon.class : c; } /** * This method sets the image of the JASIcon to be that referenced by file. * The image will display as "broken" if the file can not be found, no exception is thrown * @param file The path to the image source file, relative to the root class * */ public void setImage(String file) { try { setImageImpl(file); } catch (ImageException x) { setImage(brokenIcon.getImage()); } } private void setImageImpl(String file) throws ImageException { m_file = file; Image image = (Image) imageCache.get(this); if (image == null) { try { // First try getting a URL for the image, and loading the image using the URL. java.net.URL url = m_c.getResource(file); if (url != null) { image = Toolkit.getDefaultToolkit().getImage(url); } // Some classloaders (notably our own custom class loader for JAR files) cannot // return a resource URL but can return the resource as an InputStream, so.... else { byte[] data = this.getImageBytes(m_c,m_file); if (data == null) throw new ImageException(); image = Toolkit.getDefaultToolkit().createImage(data); } imageCache.put(this,image); } catch (ImageException x) { imageCache.put(this,noImage); throw x; } } else if (image == noImage) throw new ImageException(); setImage(image); } /** * Read a string of byes from a file. * We do this to work around a limitation in our custom class loader which results in them * being able to suport getResourceAsStream but not getResource * @see jas.loader.ClassPathLoader#getResource */ private byte[] getImageBytes(Class c, String file) throws ImageException { try { //System.out.println("JASIcon: Using fallback method of loading image "+file); InputStream stream = c.getResourceAsStream(file); if (stream == null) return null; //TODO: There is no realiable way to tell how many bytes are in the stream // so we have this horrible hack here. byte[] result = new byte[Math.min(10000,stream.available())]; int size = 0; for (;;) { if (size == result.length) throw new ImageException("Image too big for buffer"); int rc = stream.read(result,result.length-size,size); if (rc<=0) break; size += rc; } stream.close(); return result; } catch (IOException x) { return null; } } /** * Override Objects hashCode method */ public int hashCode() { return m_file.hashCode() + m_c.hashCode(); } /** * Override Objects equals method. Two images are considered equal if they have the same * class and file. */ public boolean equals(Object in) { if (!(in instanceof JASIcon)) return false; JASIcon icon = (JASIcon) in; if (icon.m_c != m_c) return false; return icon.m_file.equals(m_file); } /** * Create a JASIcon but do not throw an exception if the source cannot be found * (just displays a "broken" icon instead) * @param obj The object used as the root of the file path * @param file The path to the image source file, relative to obj * @return The resulting JASIcon */ public static JASIcon create(Object obj,String file) { try { return new JASIcon(obj,file); } catch (ImageException x) { return brokenIcon; } } /** * Create a JASIcon but do not throw an exception if the source cannot be found * (just displays a "broken" icon instead) * //TODO: Should create return a cached version of the JASIcon, instead of a cached * // version of the image with a new JASIcon object? * @param obj The class used as the root of the file path * @param file The path to the image source file, relative to obj * @return The resulting JASIcon */ public static JASIcon create(Class c,String file) { try { return new JASIcon(c,file); } catch (ImageException x) { return brokenIcon; } } private Class m_c; private String m_file; private static Hashtable imageCache = new Hashtable(); private static JASIcon brokenIcon; private static Image noImage; // Used to flag non existent image in cache static { try { brokenIcon = new JASIcon("brokenIcon.gif"); noImage = brokenIcon.getImage(); } catch (ImageException x) { System.err.println("Could not load brokenIcon .. this looks bad!"); } } } src/main/java/jas/util/gui/0000755000175000017500000000000011325547132016241 5ustar giovannigiovannisrc/main/java/jas/util/gui/JDirectoryChooser.java0000644000175000017500000003377211325547132022521 0ustar giovannigiovannipackage jas.util.gui; import java.awt.BorderLayout; import java.awt.Component; import java.awt.Cursor; import java.awt.FlowLayout; import java.awt.Frame; import java.awt.Window; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.File; import java.util.Vector; import javax.swing.JButton; import javax.swing.JComponent; import javax.swing.JDialog; import javax.swing.JFileChooser; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextField; import javax.swing.JTree; import javax.swing.SwingUtilities; import javax.swing.event.EventListenerList; import javax.swing.event.TreeModelEvent; import javax.swing.event.TreeModelListener; import javax.swing.event.TreeSelectionEvent; import javax.swing.event.TreeSelectionListener; import javax.swing.filechooser.FileFilter; import javax.swing.filechooser.FileSystemView; import javax.swing.filechooser.FileView; import javax.swing.tree.DefaultTreeCellRenderer; import javax.swing.tree.TreeModel; import javax.swing.tree.TreePath; import javax.swing.tree.TreeSelectionModel; /** * A class which allows a user to select directories or files, similar to JFileChooser, * except that it display files as a tree, and is better suited to selecting directories * than the current file chooser (see java bug id 4239219). * * TODO: Understand issue with moving mouse between double clicks * (seems like MOUSE_PRESSED and MOUSE_RELEASED events are generated, but not MOUSE_CLICKED) * See Bug ID 4218549 * * @author Tony Johnson (tony_johnson@slac.stanford.edu) */ public class JDirectoryChooser extends JComponent { /** * Create a JDirectoryChooser with the default FileSystemView */ public JDirectoryChooser() { this(FileSystemView.getFileSystemView()); } /** * Create a JDirectoryChooser with the default FileSystemView * @param currentDirectory The directory to which the tree is initially set */ public JDirectoryChooser(File currentDirectory) { this(); setCurrentDirectory(currentDirectory); } /** * Create a JDirectoryChooser with the default FileSystemView * @param currentDirectory The directory to which the tree is initially set */ public JDirectoryChooser(String currentDirectory) { this(); if (currentDirectory != null) setCurrentDirectory(new File(currentDirectory)); } /** * Create a JDirectoryChooser * @param currentDirectory The directory to which the tree is initially set * @param view The FileSystemView to use */ public JDirectoryChooser(File currentDirectory, FileSystemView view) { this(view); setCurrentDirectory(currentDirectory); } /** * Create a JDirectoryChooser * @param currentDirectory The directory to which the tree is initially set * @param view The FileSystemView to use */ public JDirectoryChooser(String currentDirectory, FileSystemView view) { this(view); setCurrentDirectory(new File(currentDirectory)); } /** * Create a JDirectoryChooser * @param view The FileSystemView to use */ public JDirectoryChooser(FileSystemView view) { setup(view); ButtonListener al = new ButtonListener(); tree = new JTree(); tree.setRootVisible(false); tree.setShowsRootHandles(true); tree.setCellRenderer(new FileRenderer()); tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION); tree.addTreeSelectionListener(al); approve.addActionListener(al); cancel.addActionListener(al); approve.setEnabled(false); setLayout(new BorderLayout()); add(new JScrollPane(tree)); JPanel p = new JPanel(new FlowLayout()); p.add(approve); p.add(cancel); add(p,BorderLayout.SOUTH); } public void addNotify() { tree.setModel(model); makeCurrentDirectoryVisible(); super.addNotify(); } private void makeCurrentDirectoryVisible() { if (currentDirectory != null) { File dir = currentDirectory; FileSystemView view = foo.getFileSystemView(); Vector v = new Vector(); while (true) { if (dir == null) return; // Something wrong, ignore dir v.addElement(dir); if (view.isRoot(dir)) break; dir = view.getParentDirectory(dir); } Object[] files = new File[v.size()+1]; Object node = model.getRoot(); files[0] = node; for (int i=1; i