/*
 * HistogramDialog.java
 *
 * Created on June 23, 2008, 2:49 PM
 */

package org.statcato.dialogs.graph;

import org.statcato.graph.StatcatoChartFrame;
import org.statcato.*;
import org.statcato.spreadsheet.*;
import org.statcato.utils.HelperFunctions;
import org.statcato.statistics.BasicStatistics;
import org.statcato.graph.GraphFactory;

import java.util.*;
import javax.swing.ButtonGroup;
import org.jfree.data.statistics.HistogramDataset;
import org.jfree.data.statistics.HistogramType;
import org.jfree.chart.axis.NumberTickUnit;
import org.jfree.chart.axis.TickUnits;


/**
 * A dialog for creating histograms.  Allows the user to specify the
 * data variables to be graphed, whether frequency or relative frequency
 * is represented by the heights of bars, the number of, minimum, and maximum
 * of bins, axis labels, title, and whether a legend is displayed.
 * 
 * @author  Margaret Yau
 * @version %I%, %G%
 * @see org.jfree.chart
 * @since 1.0
 */
public class HistogramDialog extends StatcatoDialog {
    
    /** Creates new form HistogramDialog */
    public HistogramDialog(java.awt.Frame parent, boolean modal, Statcato app) {
        super(parent, modal);
        this.app = app;
        ParentSpreadsheet = app.getSpreadsheet();
        initComponents();
        
        ButtonGroup group1 = new ButtonGroup();
        group1.add(FreqRadioButton);
        group1.add(RelFreqRadioButton);
        
        ButtonGroup group2 = new ButtonGroup();
        group2.add(CenterRadioButton);
        group2.add(BetweenRadioButton);
        
        ButtonGroup group3 = new ButtonGroup();
        group3.add(X1RadioButton);
        group3.add(X2RadioButton);
        
        ParentSpreadsheet.populateColumnsList(InputVarList);
        ParentSpreadsheet.populateComboBox(GroupByComboBox);
        
        getRootPane().setDefaultButton(OKButton);
        setHelpFile("graph-histogram");
        name = "Histogram";
        description = "For creating histograms that show the frequencies of " +
                "a number of bins (or classes) with numerical boundaries. ";
        helpStrings.add("Select the column variable(s) containing data values " +
                "for which the plot will be created. A different color is used " +
                "for each column variable.");
        helpStrings.add("Select whether to plot the frequencies or " +
                "the relative frequencies of the bins.");
        helpStrings.add("Select the method of binning values on the x-axis.");
        helpStrings.add("Specify a plot title and labels for the axes.");
        pack();
    }
    
    /**
     * Updates elements on the dialog so that they have the most
     * current values.  Called by {@link #setVisible} to make
     * sure the dialog displays current values when made visible again.
     * 
     * @see #setVisible(boolean)
     */
    @Override
    public void updateElements() {
        updateComboBox(GroupByComboBox);
        updateColumnsList(InputVarList);        
    }
    
    /** 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.
     */
    // //GEN-BEGIN:initComponents
    private void initComponents() {

        OKButton = new javax.swing.JButton();
        CancelButton = new javax.swing.JButton();
        jLabel14 = new javax.swing.JLabel();
        jLabel20 = new javax.swing.JLabel();
        jPanel1 = new javax.swing.JPanel();
        GroupByComboBox = new javax.swing.JComboBox();
        jScrollPane1 = new javax.swing.JScrollPane();
        InputVarList = new javax.swing.JList();
        jLabel1 = new javax.swing.JLabel();
        RelFreqRadioButton = new javax.swing.JRadioButton();
        jLabel2 = new javax.swing.JLabel();
        jLabel4 = new javax.swing.JLabel();
        FreqRadioButton = new javax.swing.JRadioButton();
        jLabel8 = new javax.swing.JLabel();
        jPanel2 = new javax.swing.JPanel();
        jLabel13 = new javax.swing.JLabel();
        jLabel22 = new javax.swing.JLabel();
        jLabel21 = new javax.swing.JLabel();
        jLabel10 = new javax.swing.JLabel();
        X2RadioButton = new javax.swing.JRadioButton();
        X1RadioButton = new javax.swing.JRadioButton();
        jLabel12 = new javax.swing.JLabel();
        jLabel19 = new javax.swing.JLabel();
        Min2TextField = new javax.swing.JTextField();
        jLabel7 = new javax.swing.JLabel();
        NumBinsTextField = new javax.swing.JTextField();
        CenterRadioButton = new javax.swing.JRadioButton();
        MinTextField = new javax.swing.JTextField();
        XTextField = new javax.swing.JTextField();
        jLabel23 = new javax.swing.JLabel();
        MaxTextField = new javax.swing.JTextField();
        jLabel9 = new javax.swing.JLabel();
        BetweenRadioButton = new javax.swing.JRadioButton();
        jLabel11 = new javax.swing.JLabel();
        ClassWidthTextField = new javax.swing.JTextField();
        jLabel6 = new javax.swing.JLabel();
        jPanel3 = new javax.swing.JPanel();
        jLabel16 = new javax.swing.JLabel();
        YTextField = new javax.swing.JTextField();
        jLabel5 = new javax.swing.JLabel();
        jLabel17 = new javax.swing.JLabel();
        YTickMarkTextField = new javax.swing.JTextField();
        jLabel15 = new javax.swing.JLabel();
        jPanel4 = new javax.swing.JPanel();
        TitleTextField = new javax.swing.JTextField();
        LegendCheckBox = new javax.swing.JCheckBox();
        jLabel3 = new javax.swing.JLabel();
        jLabel18 = new javax.swing.JLabel();

        setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
        setTitle("Histogram");

        OKButton.setText("OK");
        OKButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                OKButtonActionPerformed(evt);
            }
        });

        CancelButton.setText("Cancel");
        CancelButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                CancelButtonActionPerformed(evt);
            }
        });

        jLabel14.setText("jLabel14");

        jPanel1.setBorder(javax.swing.BorderFactory.createTitledBorder("Graph Variables"));

        GroupByComboBox.addItemListener(new java.awt.event.ItemListener() {
            public void itemStateChanged(java.awt.event.ItemEvent evt) {
                GroupByComboBoxItemStateChanged(evt);
            }
        });

        jScrollPane1.setViewportView(InputVarList);

        jLabel1.setFont(new java.awt.Font("Tahoma", 1, 11)); // NOI18N
        jLabel1.setText("Graph Variables:");

        RelFreqRadioButton.setText("Relative Frequency");

        jLabel2.setText("Ctrl-click to select multiple variables");

        jLabel4.setText("Grouped By Categories in:
[optional]"); FreqRadioButton.setSelected(true); FreqRadioButton.setText("Frequency"); jLabel8.setFont(new java.awt.Font("Tahoma", 1, 11)); // NOI18N jLabel8.setText("Heights of bars represent:"); javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1); jPanel1.setLayout(jPanel1Layout); jPanel1Layout.setHorizontalGroup( jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel1Layout.createSequentialGroup() .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel1Layout.createSequentialGroup() .addContainerGap() .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(jLabel1) .addComponent(jLabel2) .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 125, javax.swing.GroupLayout.PREFERRED_SIZE))) .addGroup(jPanel1Layout.createSequentialGroup() .addGap(36, 36, 36) .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(FreqRadioButton) .addComponent(RelFreqRadioButton))) .addGroup(jPanel1Layout.createSequentialGroup() .addContainerGap() .addComponent(jLabel8)) .addGroup(jPanel1Layout.createSequentialGroup() .addContainerGap() .addComponent(jLabel4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(GroupByComboBox, 0, 76, Short.MAX_VALUE))) .addContainerGap()) ); jPanel1Layout.setVerticalGroup( jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel1Layout.createSequentialGroup() .addContainerGap() .addComponent(jLabel1) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jLabel2) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 89, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(jLabel4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(GroupByComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addGap(18, 18, 18) .addComponent(jLabel8) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(FreqRadioButton) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(RelFreqRadioButton) .addContainerGap()) ); jPanel2.setBorder(javax.swing.BorderFactory.createTitledBorder("X-Axis")); jLabel13.setText("Position of tick marks:"); jLabel22.setText("Minimum:"); jLabel21.setText("Class width:"); jLabel10.setText("Maximum:"); X2RadioButton.setText("Provide the class width and the minimum"); X2RadioButton.addChangeListener(new javax.swing.event.ChangeListener() { public void stateChanged(javax.swing.event.ChangeEvent evt) { X2RadioButtonStateChanged(evt); } }); X1RadioButton.setSelected(true); X1RadioButton.setText("Provide the number of classes, minimum, and maximum"); X1RadioButton.addChangeListener(new javax.swing.event.ChangeListener() { public void stateChanged(javax.swing.event.ChangeEvent evt) { X1RadioButtonStateChanged(evt); } }); jLabel12.setText("[automatic if left blank]"); jLabel19.setText("Class width = (maximum - minimum) / classes"); Min2TextField.setEnabled(false); jLabel7.setText("Number of bins (classes):"); NumBinsTextField.setText("10"); CenterRadioButton.setText("Center of bar"); jLabel23.setText("[automatic if left blank]"); jLabel9.setText("Minimum:"); BetweenRadioButton.setSelected(true); BetweenRadioButton.setText("Between bars"); jLabel11.setFont(new java.awt.Font("Tahoma", 1, 11)); // NOI18N jLabel11.setText("X-axis (horizontal)"); ClassWidthTextField.setEnabled(false); jLabel6.setText("Label:"); javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2); jPanel2.setLayout(jPanel2Layout); jPanel2Layout.setHorizontalGroup( jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel2Layout.createSequentialGroup() .addContainerGap() .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(jLabel11) .addGroup(jPanel2Layout.createSequentialGroup() .addGap(22, 22, 22) .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel2Layout.createSequentialGroup() .addComponent(jLabel13) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(CenterRadioButton) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(BetweenRadioButton)) .addGroup(jPanel2Layout.createSequentialGroup() .addComponent(jLabel6) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(XTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 140, javax.swing.GroupLayout.PREFERRED_SIZE)) .addComponent(X2RadioButton) .addComponent(X1RadioButton) .addGroup(jPanel2Layout.createSequentialGroup() .addGap(21, 21, 21) .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel2Layout.createSequentialGroup() .addComponent(jLabel7) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(NumBinsTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 72, javax.swing.GroupLayout.PREFERRED_SIZE)) .addComponent(jLabel19) .addGroup(jPanel2Layout.createSequentialGroup() .addComponent(jLabel9) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(MinTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 54, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jLabel10) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(MaxTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 44, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jLabel12)) .addGroup(jPanel2Layout.createSequentialGroup() .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) .addComponent(jLabel21) .addComponent(jLabel22)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) .addComponent(Min2TextField) .addComponent(ClassWidthTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 79, javax.swing.GroupLayout.PREFERRED_SIZE)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jLabel23))))))) .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); jPanel2Layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {MaxTextField, MinTextField, NumBinsTextField}); jPanel2Layout.setVerticalGroup( jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel2Layout.createSequentialGroup() .addContainerGap() .addComponent(jLabel11) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(X1RadioButton) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jLabel19) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(jLabel7) .addComponent(NumBinsTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(jLabel9) .addComponent(MinTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(jLabel10) .addComponent(MaxTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(jLabel12)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(X2RadioButton) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(jLabel21) .addComponent(ClassWidthTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(Min2TextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(jLabel23)) .addComponent(jLabel22)) .addGap(22, 22, 22) .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(jLabel6) .addComponent(XTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(jLabel13) .addComponent(CenterRadioButton) .addComponent(BetweenRadioButton)) .addContainerGap(15, Short.MAX_VALUE)) ); jPanel3.setBorder(javax.swing.BorderFactory.createTitledBorder("Y-Axis")); jLabel16.setText("Tick mark units:"); jLabel5.setText("Label:"); jLabel17.setText("automatic if left blank"); jLabel15.setFont(new java.awt.Font("Tahoma", 1, 11)); // NOI18N jLabel15.setText("Y-axis (vertical)"); javax.swing.GroupLayout jPanel3Layout = new javax.swing.GroupLayout(jPanel3); jPanel3.setLayout(jPanel3Layout); jPanel3Layout.setHorizontalGroup( jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel3Layout.createSequentialGroup() .addContainerGap() .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(jLabel15) .addGroup(jPanel3Layout.createSequentialGroup() .addGap(24, 24, 24) .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel3Layout.createSequentialGroup() .addComponent(jLabel16) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(YTickMarkTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 89, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jLabel17)) .addGroup(jPanel3Layout.createSequentialGroup() .addComponent(jLabel5) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(YTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 305, javax.swing.GroupLayout.PREFERRED_SIZE))))) .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); jPanel3Layout.setVerticalGroup( jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel3Layout.createSequentialGroup() .addContainerGap() .addComponent(jLabel15) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(YTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(jLabel5)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(YTickMarkTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(jLabel17) .addComponent(jLabel16)) .addContainerGap(23, Short.MAX_VALUE)) ); jPanel4.setBorder(javax.swing.BorderFactory.createTitledBorder("Other Options")); TitleTextField.setText("Histogram"); LegendCheckBox.setSelected(true); LegendCheckBox.setText("Show Legend"); jLabel3.setText("Title:"); jLabel18.setFont(new java.awt.Font("Tahoma", 1, 11)); // NOI18N jLabel18.setText("Plot"); javax.swing.GroupLayout jPanel4Layout = new javax.swing.GroupLayout(jPanel4); jPanel4.setLayout(jPanel4Layout); jPanel4Layout.setHorizontalGroup( jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel4Layout.createSequentialGroup() .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(LegendCheckBox) .addComponent(jLabel18) .addGroup(jPanel4Layout.createSequentialGroup() .addComponent(jLabel3) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(TitleTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 194, javax.swing.GroupLayout.PREFERRED_SIZE)))) ); jPanel4Layout.setVerticalGroup( jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel4Layout.createSequentialGroup() .addContainerGap() .addComponent(jLabel18) .addGap(15, 15, 15) .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(jLabel3) .addComponent(TitleTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(LegendCheckBox) .addContainerGap(10, Short.MAX_VALUE)) ); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() .addContainerGap() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) .addComponent(jPanel4, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addComponent(jPanel3, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jLabel20)) .addGroup(layout.createSequentialGroup() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addComponent(OKButton) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(CancelButton)) .addComponent(jPanel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addContainerGap()))) ); layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {CancelButton, OKButton}); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addContainerGap() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addComponent(jPanel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addGap(8, 8, 8)) .addGroup(layout.createSequentialGroup() .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED))) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) .addComponent(jPanel4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(jPanel3, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addGap(11, 11, 11) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) .addComponent(jLabel20) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(OKButton) .addComponent(CancelButton))) .addContainerGap()) ); pack(); }//
//GEN-END:initComponents @SuppressWarnings("unchecked") private void OKButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_OKButtonActionPerformed app.compoundEdit = new DialogEdit("histogram"); // get selected input variables Object[] SelectedColumns = InputVarList.getSelectedValues(); int[] columnNumbers = ParentSpreadsheet.convertColumnLabelsToNumbers(SelectedColumns); // check that at least one input variable is selected if (columnNumbers.length == 0) { app.showErrorDialog("Select at least one input variable."); return; } String text = ""; HistogramDataset dataset = new HistogramDataset(); if (FreqRadioButton.isSelected()) dataset.setType(HistogramType.FREQUENCY); else dataset.setType(HistogramType.RELATIVE_FREQUENCY); // check if using a group by variable String byVarLabel = GroupByComboBox.getSelectedItem().toString(); int byVarColNum = -1; // BY variable column number Vector byVarColVector = null; // BY variable column vector boolean hasByVar = false; TreeSet groupSet = new TreeSet(); if (!byVarLabel.equals("")) { // has BY variable text += "Group by " + byVarLabel + "
"; hasByVar = true; byVarColNum = ParentSpreadsheet.parseColumnNumber(byVarLabel); byVarColVector = ParentSpreadsheet.getColumn(byVarColNum); // create hashset of group names for (Enumeration e = byVarColVector.elements(); e.hasMoreElements();) { Cell next = (Cell) e.nextElement(); if (!next.getContents().equals("")) groupSet.add(next.getContents()); } } // get the number of bins int bins = -1; double classWidth = -1; if (X1RadioButton.isSelected()) { try { bins = Integer.parseInt(NumBinsTextField.getText()); if (bins < 1) throw new NumberFormatException(); } catch (NumberFormatException e) { app.showErrorDialog("Enter a positive integer for the number " + "of bins"); return; } } else { // read class width from text box try { classWidth = Double.parseDouble(ClassWidthTextField.getText()); if (classWidth <= 0) throw new NumberFormatException(); } catch (NumberFormatException e) { app.showErrorDialog("Enter a valid class width."); return; } text += "Class width = " + classWidth + "
"; } double min = Double.POSITIVE_INFINITY, max = Double.NEGATIVE_INFINITY; boolean useUserMax = false; boolean useUserMin = false; // get the maximum and minimum bin boundaries if (X1RadioButton.isSelected()) { if (!MinTextField.getText().equals("") || !MaxTextField.getText().equals("")) { try { min = Double.parseDouble(MinTextField.getText()); } catch (NumberFormatException e) { app.showErrorDialog("Enter a valid minimum bin boundary value."); return; } try { max = Double.parseDouble(MaxTextField.getText()); } catch (NumberFormatException e) { app.showErrorDialog("Enter a valid maximum bin boundary value."); return; } if (min >= max) { app.showErrorDialog("Minimum must be less than maximum."); return; } useUserMax = true; useUserMin = true; } } else { if (!Min2TextField.getText().equals("")) { try { min = Double.parseDouble(Min2TextField.getText()); max = min + classWidth; } catch (NumberFormatException e) { app.showErrorDialog("Enter a valid minimum bin boundary value."); return; } useUserMin = true; } } Vector> vectors = new Vector>(); Vector labels = new Vector(); text += "Graph variable(s) = "; // for each input variable for (int i = 0; i < columnNumbers.length; ++i) { Vector StrColumnVector = ParentSpreadsheet.getColumn(columnNumbers[i]); String columnLabel = (String) SelectedColumns[i]; text += columnLabel + " "; // get input column of doubles Vector ColumnVector = HelperFunctions.ConvertInputVectorToDoubles(StrColumnVector); if (ColumnVector == null) { app.showErrorDialog("Invalid input column " + columnLabel + ": all data must be numbers."); return; } // find min and max, if not provided if (!useUserMax) { double thisMax = BasicStatistics.max( HelperFunctions.removeNullValues(ColumnVector)); if (thisMax > max) max = thisMax; } if (!useUserMin) { double thisMin = BasicStatistics.min( HelperFunctions.removeNullValues(ColumnVector)); if (thisMin < min) min = thisMin; } if (hasByVar) { // has BY variable for (Iterator iter = groupSet.iterator(); iter.hasNext();) { String groupName = (String) iter.next(); // build a vector of doubles just for this group Vector subVector = new Vector(0); for (int j = 0; j < ColumnVector.size(); ++j) { String label = byVarColVector.elementAt(j).getContents(); if (label.equals(groupName)) subVector.addElement(ColumnVector.elementAt(j)); } subVector = HelperFunctions.removeNullValues(subVector); labels.addElement(columnLabel + "-" + groupName); if (max != -1 && min != -1) { vectors.addElement(subVector); } else { vectors.addElement(subVector); } } } else { ColumnVector = HelperFunctions.removeNullValues(ColumnVector); labels.addElement(columnLabel); if (max != -1 && min != -1) vectors.addElement(ColumnVector); else vectors.addElement(ColumnVector); } } // adjusts max when class width is used, then calculates # bins if (X2RadioButton.isSelected()) { bins = 0; while ((bins * classWidth + min) < max) { bins++; } max = min + bins * classWidth; } for (int i = 0; i < vectors.size(); ++i) { Vector vec = (Vector)vectors.elementAt(i); String label = (String) labels.elementAt(i); dataset.addSeries(label, HelperFunctions.ConvertDoubleVectorToArray(vec), bins, min, max); } // add tick units TickUnits units = new TickUnits(); for (int i = 0; i < dataset.getSeriesCount(); ++i) { double width = (dataset.getEndX(i, 0).doubleValue() - dataset.getStartX(i, 0).doubleValue()); units.add(new NumberTickUnit(width)); } // get the minimum of all bins double minBinStart = dataset.getStartX(0,0).doubleValue(); double minBin = dataset.getEndX(0,0).doubleValue() - dataset.getStartX(0,0).doubleValue(); for (int i = 1; i < dataset.getSeriesCount(); ++i) { if (dataset.getStartX(i, 0).doubleValue() < minBin) minBinStart = dataset.getStartX(i, 0).doubleValue(); double width = dataset.getEndX(i, 0).doubleValue() - dataset.getStartX(i, 0).doubleValue(); if (width < minBin) minBin = width; } double ticks = -1; if (!YTickMarkTextField.getText().equals("")) { try { ticks = Double.parseDouble(YTickMarkTextField.getText()); if (ticks <= 0) throw new NumberFormatException(); } catch (NumberFormatException e) { app.showErrorDialog("Enter a valid number for the y-axis " + "tick mark units."); return; } } text += "
Number of bins = " + bins; app.addLogParagraph("histogram", text); app.compoundEdit.end(); app.addCompoundEdit(app.compoundEdit); StatcatoChartFrame frame = new StatcatoChartFrame( TitleTextField.getText(), GraphFactory.createHistogram( TitleTextField.getText(), XTextField.getText(), YTextField.getText(), dataset, LegendCheckBox.isSelected(), units, minBin, minBinStart, CenterRadioButton.isSelected(), ticks), app); frame.pack(); frame.setVisible(true); setVisible(false); }//GEN-LAST:event_OKButtonActionPerformed private void CancelButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_CancelButtonActionPerformed setVisible(false); }//GEN-LAST:event_CancelButtonActionPerformed private void GroupByComboBoxItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_GroupByComboBoxItemStateChanged if (GroupByComboBox.getSelectedItem() != null) { if (GroupByComboBox.getSelectedItem().toString().equals("")) { LegendCheckBox.setSelected(false); } else { LegendCheckBox.setSelected(true); } } }//GEN-LAST:event_GroupByComboBoxItemStateChanged private void X1RadioButtonStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_X1RadioButtonStateChanged if (X1RadioButton.isSelected()) { NumBinsTextField.setEnabled(true); MinTextField.setEnabled(true); MaxTextField.setEnabled(true); } else { NumBinsTextField.setEnabled(false); MinTextField.setEnabled(false); MaxTextField.setEnabled(false); } }//GEN-LAST:event_X1RadioButtonStateChanged private void X2RadioButtonStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_X2RadioButtonStateChanged if (X2RadioButton.isSelected()) { ClassWidthTextField.setEnabled(true); Min2TextField.setEnabled(true); } else { ClassWidthTextField.setEnabled(false); Min2TextField.setEnabled(false); } }//GEN-LAST:event_X2RadioButtonStateChanged // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JRadioButton BetweenRadioButton; private javax.swing.JButton CancelButton; private javax.swing.JRadioButton CenterRadioButton; private javax.swing.JTextField ClassWidthTextField; private javax.swing.JRadioButton FreqRadioButton; private javax.swing.JComboBox GroupByComboBox; private javax.swing.JList InputVarList; private javax.swing.JCheckBox LegendCheckBox; private javax.swing.JTextField MaxTextField; private javax.swing.JTextField Min2TextField; private javax.swing.JTextField MinTextField; private javax.swing.JTextField NumBinsTextField; private javax.swing.JButton OKButton; private javax.swing.JRadioButton RelFreqRadioButton; private javax.swing.JTextField TitleTextField; private javax.swing.JRadioButton X1RadioButton; private javax.swing.JRadioButton X2RadioButton; private javax.swing.JTextField XTextField; private javax.swing.JTextField YTextField; private javax.swing.JTextField YTickMarkTextField; private javax.swing.JLabel jLabel1; private javax.swing.JLabel jLabel10; private javax.swing.JLabel jLabel11; private javax.swing.JLabel jLabel12; private javax.swing.JLabel jLabel13; private javax.swing.JLabel jLabel14; private javax.swing.JLabel jLabel15; private javax.swing.JLabel jLabel16; private javax.swing.JLabel jLabel17; private javax.swing.JLabel jLabel18; private javax.swing.JLabel jLabel19; private javax.swing.JLabel jLabel2; private javax.swing.JLabel jLabel20; private javax.swing.JLabel jLabel21; private javax.swing.JLabel jLabel22; private javax.swing.JLabel jLabel23; private javax.swing.JLabel jLabel3; private javax.swing.JLabel jLabel4; private javax.swing.JLabel jLabel5; private javax.swing.JLabel jLabel6; private javax.swing.JLabel jLabel7; private javax.swing.JLabel jLabel8; private javax.swing.JLabel jLabel9; private javax.swing.JPanel jPanel1; private javax.swing.JPanel jPanel2; private javax.swing.JPanel jPanel3; private javax.swing.JPanel jPanel4; private javax.swing.JScrollPane jScrollPane1; // End of variables declaration//GEN-END:variables }

Ads help maintain this website.