/*
* -------------------------------------------------------------------------
* $Id: RBPanel.java,v 1.5 2006/03/16 18:33:59 estewart Exp $
* -------------------------------------------------------------------------
* Copyright (c) 1999 Visual Numerics Inc. All Rights Reserved.
*
* This software is confidential information which is proprietary to
* and a trade secret of Visual Numerics, Inc. Use, duplication or
* disclosure is subject to the terms of an appropriate license
* agreement.
*
* VISUAL NUMERICS MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE
* SUITABILITY OF THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING
* BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. VISUAL
* NUMERICS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE
* AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR
* ITS DERIVATIVES.
*--------------------------------------------------------------------------
*/
/*
* RBPanel.java
*
* Created on August 19, 2003, 10:45 AM
*/
package com.imsl.demo.fitting;
import com.imsl.chart.*;
import java.util.Vector;
import java.awt.event.*;
import javax.swing.event.*;
public class RBPanel extends javax.swing.JPanel implements ActionListener, ChangeListener, MouseListener {
private double mse;
private Chart chart;
private AxisXY axis;
private Data point;
private Contour contour;
private Vector dataX, dataY, dataZ;
private double[] x, y, z;
private double[] xRange, yRange, zRange;
private boolean showSurface;
private javax.swing.JFrame parentFrame;
private javax.swing.JRadioButtonMenuItem[] jRadioButtons;
public javax.swing.JCheckBox jCheck3d;
private SurfacePlot surfacePlot;
private final java.awt.Color light = new java.awt.Color(255,236,215);
private final java.awt.Color dark = new java.awt.Color(43,0,0);
private final int numData = 4;
private final String dataName[] = {"Blank", "Topography", "Plume Concentration", "Colorado Temperature"};
private final java.awt.Cursor defCursor = new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR);
private final java.awt.Cursor waitCursor = new java.awt.Cursor(java.awt.Cursor.WAIT_CURSOR);
/** Creates new form LRPanel */
public RBPanel(javax.swing.JFrame parent) {
this.parentFrame = parent;
// Set initial values.
mse = 0.0;
dataX = new Vector();
dataY = new Vector();
dataZ = new Vector();
x = new double[2];
y = new double[2];
z = new double[2];
initComponents();
setPreferredSize(new java.awt.Dimension(parent.getSize().width, (int)(0.85*parent.getSize().height)));
jButtonGenerate.addActionListener(this);
jButtonEnter.addActionListener(this);
jButtonReset.addActionListener(this);
addDataButtons();
setChart();
jPanelChartMain.setPreferredSize(new java.awt.Dimension(parent.getSize().width, (int)(0.66*parent.getSize().height)));
getData();
update();
}
private void setChart() {
chart = jPanelChartMain.getChart();
axis = new AxisXY(chart);
axis.setViewport(0.12,0.8,0.1,0.88);
// Set axes ranges
axis.getAxisX().setAutoscaleInput(AxisXY.AUTOSCALE_OFF);
axis.getAxisY().setAutoscaleInput(AxisXY.AUTOSCALE_OFF);
axis.getAxisX().setWindow(0.0, 50.0);
axis.getAxisY().setWindow(0.0, 75.0);
axis.getAxisX().setTextFormat(new java.text.DecimalFormat("###.##"));
axis.getAxisY().setTextFormat(new java.text.DecimalFormat("###.##"));
// Add MouseListeren to the chart.
jPanelChartMain.addMouseListener(this);
Chart sideChart = jPanelChartSide.getChart();
sideChart.setFillType(Data.FILL_TYPE_GRADIENT);
sideChart.setGradient(light, light, dark, dark);
}
// add the available data sets to the dataMenu
private void addDataButtons() {
jRadioButtons = new javax.swing.JRadioButtonMenuItem[numData];
javax.swing.ButtonGroup group = new javax.swing.ButtonGroup();
for (int i=0; i<numData; i++) {
jRadioButtons[i] = new javax.swing.JRadioButtonMenuItem();
jRadioButtons[i].setText(dataName[i]);
jRadioButtons[i].addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
getData();
update();
}
});
group.add(jRadioButtons[i]);
((FittingMain)parentFrame).getDataMenu().add(jRadioButtons[i]);
}
jRadioButtons[1].setSelected(true);
}
// clear and load data sets determined by the menu selection
public void getData() {
dataX.clear();
dataY.clear();
dataZ.clear();
xRange = new double[2];
yRange = new double[2];
zRange = new double[2];
String xTitle = "";
String yTitle = "";
String zTitle = "";
int zTickMajor = 5;
int zTickMinor = 1;
int selected = -1;
for (int i=0; i<numData; i++) {
if (jRadioButtons[i].isSelected()) {
selected = i;
break;
}
}
switch (selected) {
case 0: // blank
xTitle = "X Value";
yTitle = "Y Value";
zTitle = "";
xRange[0] = 0.0;
xRange[1] = 50.0;
yRange[0] = 0.0;
yRange[1] = 50.0;
zRange[0] = 0.0;
zRange[1] = 50.0;
break;
case 2: /* plume concentration
*
*/
double x[] = {-30,-24,-18,-12,-6,0,6,12,18,24,30,-30,-24,-18,-12,-6,0,6,12,18,24,30,-30,-24,-18,-12,-6,0,6,12,18,24,30,-30,-24,-18,-12,-6,0,6,12,18,24,30,-30,-24,-18,-12,-6,0,6,12,18,24,30,-30,-24,-18,-12,-6,0,6,12,18,24,30,-24,-18,-12,-6,0,6,12,18,24,-30,-24,-18,-12,-6,0,6,12,18,24,30,-30,-24,-18,-12,-6,0,6,12,18,24,30,-30,-24,-18,-12,-6,0,6,12,18,24,30};
double y[] = {46,46,46,46,46,46,46,46,46,46,46,52,52,52,52,52,52,52,52,52,52,52,58,58,58,58,58,58,58,58,58,58,58,64,64,64,64,64,64,64,64,64,64,64,70,70,70,70,70,70,70,70,70,70,70,76,76,76,76,76,76,76,76,76,76,76,82,82,82,82,82,82,82,82,82,88,88,88,88,88,88,88,88,88,88,88,94,94,94,94,94,94,94,94,94,94,94,100,100,100,100,100,100,100,100,100,100,100};
double z[] = {0,0,0,0.008103115,0.013900935,0.003619315,0.013900935,0.008103115,0,0,0,0,0,0.013083178,0.027365109,0.03181028,0.006929283,0.03181028,0.027365109,0.013083178,0,0,0,0.008681308,0.023371028,0.031588785,0.039390343,0.011635826,0.039390343,0.031588785,0.023371028,0.008681308,0,0.004919626,0.008167601,0.022924611,0.029348598,0.042998442,0.016685981,0.042998442,0.029348598,0.022924611,0.008167601,0.004919626,0.004981308,0.00882648,0.021449221,0.025684112,0.036566355,0.020574143,0.036566355,0.025684112,0.021449221,0.00882648,0.004981308,0.005433645,0.007045794,0.019802181,0.022018692,0.026570093,0.021243925,0.026570093,0.022018692,0.019802181,0.007045794,0.005433645,0.00610405,0.013904673,0.016543302,0.021547352,0.020204984,0.021547352,0.016543302,0.013904673,0.00610405,0,0.004276012,0.010677614,0.010108411,0.016629283,0.01626729,0.016629283,0.010108411,0.010677614,0.004276012,0,0,0,0.00712648,0.006494393,0.009508411,0.008309346,0.009508411,0.006494393,0.00712648,0,0,0,0,0,0,0.007291589,0.003783801,0.007291589,0,0,0,0};
for (int i=0; i<x.length; i++) {
dataX.add(new Double(x[i]));
dataY.add(new Double(y[i]));
dataZ.add(new Double(z[i]*1000));
}
xTitle = "Width, cm";
yTitle = "Height, cm";
zTitle = "Concentration, gm/cc";
xRange[0] = -30.0;
xRange[1] = 30.0;
yRange[0] = 46.0;
yRange[1] = 100.0;
zRange[0] = 0.0;
zRange[1] = 50;
break;
case 1: /* These data are topography data from an oil field.
*/
double x2[] = {1,2,4,7,8,10,14,14,18,22,23,23,30,35,37,41,42,44};
double y2[] = {43,7,24,48,36,11,1,43,26,8,18,39,27,47,20,42,30,4};
double z2[] = {36.6631,41.7752,42.7543,36.4728,38.0706,43.1325,42.2735,37.5282,38.9239,37.4302,36.1548,34.9149,35.8765,32.6606,34.6344,32.9266,33.6234,32.2425};
for (int i=0; i<x2.length; i++) {
dataX.add(new Double(x2[i]));
dataY.add(new Double(y2[i]));
dataZ.add(new Double(z2[i]));
}
xTitle = "X location";
yTitle = "Y location";
zTitle = "Elevation, m";
xRange[0] = 0.0;
xRange[1] = 45.0;
yRange[0] = 0.0;
yRange[1] = 50.0;
zRange[0] = 35.0;
zRange[1] = 45.0;
zTickMajor = 1;
zTickMinor = 0;
break;
case 3: /* These are average summer temperature in CO
*/
double x3[] = {40.00,38.42,39.22,38.82,39.25,37.67,39.63,37.28,38.48,40.58,40.22,39.17,38.53,37.77,38.05,38.08,38.07,37.17,38.48,38.03,38.08,40.50,37.95,37.17,40.07};
double y3[] = {105.27,105.23,105.28,102.35,107.97,106.35,106.03,107.88,102.78,105.08,103.80,108.75,106.97,107.13,102.12,102.62,103.22,105.95,107.88,103.70,106.13,106.83,107.87,104.48,102.23};
double z3[] = {35.52,38.76,30.86,33.92,28.78,26.84,21.03,31.72,35.41,32.97,34.89,31.93,20.31,20.79,32.77,35.42,37.00,28.48,30.60,36.26,29.60,19.00,22.65,37.66,35.34};
for (int i=0; i<x3.length; i++) {
dataX.add(new Double(x3[i]));
dataY.add(new Double(y3[i]));
dataZ.add(new Double(z3[i]));
}
xTitle = "Latitude";
yTitle = "Longitude";
zTitle = "Average Winter Temperature, °F";
xRange[0] = 37.0;
xRange[1] = 41.0;
yRange[0] = 102.0;
yRange[1] = 110.0;
zRange[0] = 15.0;
zRange[1] = 40.0;
zTickMajor = 5;
break;
}
axis.getAxisX().getAxisTitle().setTitle(xTitle);
axis.getAxisY().getAxisTitle().setTitle(yTitle);
axis.getAxisX().setWindow(xRange);
axis.getAxisY().setWindow(yRange);
chart.getChartTitle().setTitle(zTitle);
zSlider.setMinimum((int)zRange[0]);
zSlider.setMaximum((int)zRange[1]);
zSlider.setValue((int)(zRange[1]+zRange[0])/2);
zSlider.setMajorTickSpacing(zTickMajor);
zSlider.setMinorTickSpacing(zTickMinor);
}
// Draw the graph.
private void drawGraph() {
if ((dataX.size() != 0) && (dataY.size() != 0)) {
x = new double[dataX.size()];
y = new double[dataY.size()];
z = new double[dataZ.size()];
for (int i = 0; i < x.length; i++) {
x[i] = ((Double) dataX.get(i)).doubleValue();
y[i] = ((Double) dataY.get(i)).doubleValue();
z[i] = ((Double) dataZ.get(i)).doubleValue();
}
// Draw the contour graph
if (x.length > 1) {
double[] cLevels = new double[10];
for (int i=0; i<cLevels.length; i++) {
cLevels[i] = (double)i*(zRange[1]-zRange[0])/10.0 + zRange[0];
}
int nCenters = x.length/2;
contour = new Contour(axis, x, y, z, cLevels, nCenters);
contour.getContourLegend().setPaint(true);
contour.getContourLevel(0).setFillColor(new java.awt.Color(43,0,0));
contour.getContourLevel(1).setFillColor(new java.awt.Color(64,23,21));
contour.getContourLevel(2).setFillColor(new java.awt.Color(85,47,43));
contour.getContourLevel(3).setFillColor(new java.awt.Color(106,70,64));
contour.getContourLevel(4).setFillColor(new java.awt.Color(127,94,86));
contour.getContourLevel(5).setFillColor(new java.awt.Color(148,118,107));
contour.getContourLevel(6).setFillColor(new java.awt.Color(170,141,129));
contour.getContourLevel(7).setFillColor(new java.awt.Color(191,165,150));
contour.getContourLevel(8).setFillColor(new java.awt.Color(212,188,172));
contour.getContourLevel(9).setFillColor(new java.awt.Color(233,212,193));
contour.getContourLevel(10).setFillColor(new java.awt.Color(255,236,215));
}
// Draw the points.
point = new Data(axis, x, y);
point.setDataType(Data.DATA_TYPE_MARKER);
point.setMarkerType(Data.MARKER_TYPE_OCTAGON_X);
point.setMarkerSize(0.8);
point.setMarkerColor(java.awt.Color.blue);
}
}
// Redraw the chart.
public void update() {
setCursor(waitCursor);
if (point != null) point.remove();
if (contour != null) {
contour.getContourLegend().remove();
contour.remove();
}
drawGraph();
setCursor(defCursor);
if (showSurface) plotSurface();
repaint();
}
public void setVisible(boolean show) {
super.setVisible(show);
if (show) {
addDataButtons();
if (surfacePlot == null) {
surfacePlot = new SurfacePlot(parentFrame, jCheck3d);
} else {
if (showSurface) {
surfacePlot.setVisible(true);
}
}
} else {
if (surfacePlot != null) {
surfacePlot.setVisible(false);
}
}
}
private void plotSurface() {
if (!surfacePlot.isVisible()) surfacePlot.show();
// note that x,y,z are defined in drawGraph()
surfacePlot.draw(x, y, z);
}
/** 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
jPanel = new javax.swing.JPanel();
jButtonEnter = new javax.swing.JButton();
jButtonGenerate = new javax.swing.JButton();
jLabelPoints = new javax.swing.JLabel();
numField = new javax.swing.JTextField("6", 4);
jButtonReset = new javax.swing.JButton();
jPanelChartMain = new com.imsl.chart.JPanelChart();
jPanelZ = new javax.swing.JPanel();
jLabel1 = new javax.swing.JLabel();
zSlider = new javax.swing.JSlider();
jPanelChartSide = new com.imsl.chart.JPanelChart();
setLayout(new java.awt.BorderLayout());
setPreferredSize(new java.awt.Dimension(500, 600));
jButtonEnter.setText("Enter Points");
jPanel.add(jButtonEnter);
jButtonGenerate.setText("Generate");
jPanel.add(jButtonGenerate);
jLabelPoints.setText("# of Points: ");
jPanel.add(jLabelPoints);
numField.setColumns(4);
numField.setText("6");
jPanel.add(numField);
jButtonReset.setText("Reset");
jPanel.add(jButtonReset);
jCheck3d = new javax.swing.JCheckBox();
jCheck3d.setSelected(false);
jCheck3d.setText("Show 3D Surface");
jCheck3d.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
showSurface = jCheck3d.isSelected();
if ((!showSurface) && (surfacePlot.isVisible())) {
surfacePlot.setVisible(false);
}
if (showSurface) {
plotSurface();
}
}
});
jPanel.add(jCheck3d);
add(jPanel, java.awt.BorderLayout.NORTH);
jPanelChartMain.setPreferredSize(new java.awt.Dimension(500, 500));
add(jPanelChartMain, java.awt.BorderLayout.CENTER);
jPanelZ.setLayout(new java.awt.BorderLayout());
jLabel1.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
jLabel1.setText("Z Value");
jPanelZ.add(jLabel1, java.awt.BorderLayout.NORTH);
zSlider.setMajorTickSpacing(5);
zSlider.setMinorTickSpacing(1);
zSlider.setOrientation(javax.swing.JSlider.VERTICAL);
zSlider.setPaintLabels(true);
zSlider.setPaintTicks(true);
zSlider.setSnapToTicks(true);
jPanelZ.add(zSlider, java.awt.BorderLayout.CENTER);
jPanelZ.add(jPanelChartSide, java.awt.BorderLayout.WEST);
add(jPanelZ, java.awt.BorderLayout.EAST);
}//GEN-END:initComponents
// Implement ActionListener
public void actionPerformed(ActionEvent e) {
if (e.getActionCommand().equals("Enter Points")) {
// Enter points using a text area.
javax.swing.JTextArea textArea = new javax.swing.JTextArea(10, 5);
javax.swing.JScrollPane scroll = new javax.swing.JScrollPane(textArea);
int option = 0;
try {
option = javax.swing.JOptionPane.showConfirmDialog(this, scroll,
"Enter Points", javax.swing.JOptionPane.OK_CANCEL_OPTION);
if (option == javax.swing.JOptionPane.CANCEL_OPTION) return;
} catch (Exception ex) {
}
java.util.StringTokenizer lineToken =
new java.util.StringTokenizer(textArea.getText(), "\n");
while (lineToken.hasMoreElements()) {
java.util.StringTokenizer token = new java.util.StringTokenizer(lineToken.nextToken(), "(){}[] ,\t\n");
// If the line does not contain 3 numbers, then ignore.
if (token.countTokens() == 3) {
try {
double x = Double.parseDouble(token.nextToken());
double y = Double.parseDouble(token.nextToken());
double z = Double.parseDouble(token.nextToken());
// Ignore any points that are not in the range.
if ((x >= xRange[0]) && (x <= xRange[1]) &&
(y >= yRange[0]) && (y <= yRange[1])) {
dataX.add(new Double(x));
dataY.add(new Double(y));
dataZ.add(new Double(z));
}
} catch (Exception ex) {
}
}
}
update();
} else if (e.getActionCommand().equals("Generate")) {
int i = 0;
try {
i = Integer.parseInt(numField.getText());
} catch (Exception exception) {
i = 6;
numField.setText("6");
} finally {
if (i <= 0) {
i = 6;
numField.setText("6");
}
for (int j = 0; j < i; j++) {
dataX.add(new Double(xRange[1] * Math.random() + xRange[0]));
dataY.add(new Double(yRange[1] * Math.random() + yRange[0]));
dataZ.add(new Double(zRange[1] * Math.random() + zRange[0]));
}
update();
}
} else {
// Reset button is clicked. Reset everything to default.
numField.setText("6");
mse = 0.0;
dataX = new Vector();
dataY = new Vector();
dataZ = new Vector();
update();
getData();
update();
}
}
// Implement ChangeListener
public void stateChanged(ChangeEvent e) {
update();
}
// Implement MouseListener
public void mouseClicked(MouseEvent e) {
double user[] = {0,0};
axis.mapDeviceToUser(e.getX(), e.getY(), user);
// Do not add the point if it is not in the range.
if ((user[0] < xRange[0]) || (user[0] > xRange[1]) ||
(user[1] < yRange[0]) || (user[1] > yRange[1])) return;
// Button is to add points. Otherwise, remove points.
if (e.getModifiers() == MouseEvent.BUTTON1_MASK) {
dataX.add(new Double(user[0]));
dataY.add(new Double(user[1]));
dataZ.add(new Double(zSlider.getValue()));
update();
} else {
int idx = -1;
double min = 0.01;
final double ux = (user[0]-xRange[0])/(double)(xRange[1]-xRange[0]);
final double uy = (user[1]-yRange[0])/(double)(yRange[1]-yRange[0]);
for (int i = 0; i < dataX.size(); i++) {
double x = (((Double)dataX.get(i)).doubleValue()-xRange[0])/
(double)(xRange[1]-xRange[0]);
double y = (((Double)dataY.get(i)).doubleValue()-yRange[0])/
(double)(yRange[1]-yRange[0]);
double dist = Math.sqrt((ux - x)*(ux - x) + (uy - y)*(uy - y));
if (dist < min) {
min = dist;
idx = i;
}
}
if (idx != -1) {
dataX.remove(idx);
dataY.remove(idx);
dataZ.remove(idx);
update();
}
}
}
public void mousePressed(MouseEvent e) {
}
public void mouseReleased(MouseEvent e) {
}
public void mouseEntered(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
}
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JLabel jLabel1;
private javax.swing.JLabel jLabelPoints;
private javax.swing.JButton jButtonGenerate;
private javax.swing.JButton jButtonReset;
private javax.swing.JTextField numField;
private javax.swing.JSlider zSlider;
private com.imsl.chart.JPanelChart jPanelChartMain;
private javax.swing.JPanel jPanelZ;
private javax.swing.JButton jButtonEnter;
private com.imsl.chart.JPanelChart jPanelChartSide;
private javax.swing.JPanel jPanel;
// End of variables declaration//GEN-END:variables
}