/* * ------------------------------------------------------------------------- * $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 }