/* * ------------------------------------------------------------------------- * $Id: SunSpotAspect.java,v 1.3 2004/05/26 17:57:13 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. *-------------------------------------------------------------------------- */ package com.imsl.demo.Aspect; import com.imsl.chart.*; import java.awt.*; import java.awt.event.*; import java.text.*; import java.util.*; import javax.swing.*; /** * A modified version of the SunSpots ARMA demo that shows a method of * dynamically resizing a JFrameChart's aspect ratio based on the data * contained therein. * *@author JGH *@created Modified October 9, 2002 */ public class SunSpotAspect extends JFrameChart implements ActionListener, MouseMotionListener { private JTextField displayField; private SimpleDateFormat dateFormat, yearFormat; private JButton ar; private NumberFormat intFormat; private Container cp; private Chart chart; private AxisXY axis; private Data data; private boolean arflag; private double[] current, x, y, xAxisLabels; private int num; private final double maxx, minx, maxy, miny, hDataLength, vDataLength; private java.awt.Dimension describeSize, screenSize, windowSize, defaultSize; /** * Constructor for the SunSpotAspect object * *@param exitOnClose if not set, remove JFrameChart WindowListener */ public SunSpotAspect(boolean exitOnClose) { super(); setTitle("Aspect Ratio"); if (!exitOnClose) { // remove the WindowListener, installed by JFrameChart, that // exits the application when the window is closed Object l[] = getListeners(java.awt.event.WindowListener.class); for (int k = 0; k < l.length; k++) { removeWindowListener((java.awt.event.WindowListener) l[k]); } } com.imsl.demo.gallery.Describe des = new com.imsl.demo.gallery.Describe(this, "/com/imsl/demo/Aspect/Aspect.html"); des.show(); describeSize = des.getSize(); screenSize = getToolkit().getScreenSize(); int h = Math.min(screenSize.width/2, screenSize.height-describeSize.height-32); int w = (int)(h/0.8); defaultSize = new java.awt.Dimension(w,h); windowSize = new java.awt.Dimension(defaultSize); setSize(windowSize); setResizable(false); setLocation(screenSize.width-describeSize.width, describeSize.height); dateFormat = new SimpleDateFormat("M/yyyy"); intFormat = NumberFormat.getIntegerInstance(); // set default data y = new double[]{100.8, 81.6, 66.5, 34.8, 30.6, 7, 19.8, 92.5, 154.4, 125.9, 84.8, 68.1, 38.5, 22.8, 10.2, 24.1, 82.9, 132, 130.9, 118.1, 89.9, 66.6, 60, 46.9, 41, 21.3, 16, 6.4, 4.1, 6.8, 14.5, 34, 45, 43.1, 47.5, 42.2, 28.1, 10.1, 8.1, 2.5, 0, 1.4, 5, 12.2, 13.9, 35.4, 45.8, 41.1, 30.4, 23.9, 15.7, 6.6, 4, 1.8, 8.5, 16.6, 36.3, 49.7, 62.5, 67, 71, 47.8, 27.5, 8.5, 13.2, 56.9, 121.5, 138.3, 103.2, 85.8, 63.2, 36.8, 24.2, 10.7, 15, 40.1, 61.5, 98.5, 124.3, 95.9, 66.5, 64.5, 54.2, 39, 20.6, 6.7, 4.3, 22.8, 54.8, 93.8, 95.7, 77.2, 59.1, 44, 47, 30.5, 16.3, 7.3, 37.3, 73.9}; x = new double[y.length]; for (int i = 0; i < y.length; i++) { x[i] = 1770.0 + i; } xAxisLabels = new double[y.length]; for (int i = 0; i < y.length; i++) { xAxisLabels[i] = (new GregorianCalendar(1770 + i, 0, 1)).getTimeInMillis(); } num = 0; minx = 1770; maxx = 1869.0; miny = 0.0; maxy = 154.0; hDataLength = maxx - minx; vDataLength = maxy - miny; arflag = false; current = new double[2]; createChart(); drawGraph(); createComponents(); } /** * Shows a new SunSpotAspect * *@param args -noexit if passed, JFrameChart window listener isn't removed *@since */ public static void main(String args[]) { boolean exitOnClose = true; if (args.length > 0 && args[0].equals("-noexit")) { exitOnClose = false; } new SunSpotAspect(exitOnClose).show(); } public void actionPerformed(ActionEvent e) { if (e.getActionCommand().equals("Reset Aspect Ratio")) { windowSize = defaultSize; //windowSize.width = defaultSize.width; //windowSize.height = defaultSize.height; setLocation(screenSize.width-describeSize.width, describeSize.height); ar.setText("Correct Aspect Ratio"); } else if (e.getActionCommand().equals("Correct Aspect Ratio")) { modifyAR(); setLocation(Math.max(0,screenSize.width-windowSize.width), describeSize.height); ar.setText("Reset Aspect Ratio"); } update(); } public void mouseDragged(MouseEvent e) { } public void mouseMoved(MouseEvent e) { axis.mapDeviceToUser(e.getX(), e.getY(), current); displayField.setText(getDescription()); } private String getDescription() { DecimalFormat nf = new DecimalFormat("0.0000"); StringBuffer sb = new StringBuffer(); sb.append("Cursor At: X = " + dateFormat.format(new Date((long) current[0])) + " Y = " + nf.format(current[1])); return sb.toString(); } private void createChart() { chart = this.getChart(); axis = new AxisXY(chart); axis.getAxisX().getAxisLabel().setTextFormat(dateFormat); axis.getAxisX().getAxisLabel().setTextAngle(90); axis.getAxisX().getAxisTitle().setTitle("Year"); axis.getAxisY().getAxisLabel().setTextFormat(intFormat); axis.getAxisY().getAxisTitle().setTitle("Number of Sun Spots"); chart.setTickLength(1.5); this.getPanel().addMouseMotionListener(this); } private void createComponents() { Container cp = this.getContentPane(); ar = new JButton("Correct Aspect Ratio"); ar.addActionListener(this); JPanel buttonPanel = new JPanel(); buttonPanel.add(ar); JPanel displayPanel = new JPanel(); displayField = new JTextField("Current position: X = ?? Y = ??", 53); displayField.setBorder(null); displayField.setEditable(false); displayPanel.add(displayField); cp.add(buttonPanel, BorderLayout.NORTH); cp.add(displayPanel, BorderLayout.SOUTH); } private void drawGraph() { axis.getAxisX().setAutoscaleInput(AxisXY.AUTOSCALE_OFF); axis.getAxisX().setWindow( (new GregorianCalendar(1770, 0, 1)).getTimeInMillis(), (new GregorianCalendar(1870, 0, 1)).getTimeInMillis()); axis.getAxisY().setAutoscaleInput(AxisXY.AUTOSCALE_OFF); axis.getAxisY().setWindow(0.0, 158.0); axis.setViewport(.1, .9, .05, .8); data = new Data(axis, xAxisLabels, y); data.setTitle("Actual data"); data.setDataType(Data.DATA_TYPE_LINE | Data.DATA_TYPE_MARKER); data.setMarkerType(Data.MARKER_TYPE_FILLED_CIRCLE); data.setMarkerSize(0.4); data.setMarkerColor(Color.red); data.setLineColor(Color.blue); } private void modifyAR() { double[] x2 = new double[y.length]; double[] devX = new double[y.length]; double[] devY = new double[y.length]; int[] devXY = new int[2]; double startYear = 1770.0; for (int i = 0; i < y.length; i++) { x2[i] = startYear + i; } double banking = 100.0; long iterations = 1; while (banking > 45.0 && iterations < 8) { System.out.println("\niteration: " + iterations); for (int i = 0; i < y.length; i++) { axis.mapUserToDevice(x2[i], y[i], devXY); devX[i] = (double) devXY[0]; devY[i] = (double) devXY[1]; if (Math.IEEEremainder((double) i, 25.0) == 0.0) { System.out.println("device coords[" + i + "] = " + devX[i] + ", " + devY[i] + "," + (windowSize.height - devY[i])); System.out.println("x[" + i + "], y[" + i + "] = " + x2[i] + ", " + y[i]); } } double maxdevX; double mindevX; double maxdevY; double mindevY; maxdevX = mindevX = maxdevY = mindevY = 0.0; for (int i = 0; i < y.length; i++) { if (devX[i] < mindevX) { mindevX = devX[i]; } if (devX[i] > maxdevX) { maxdevX = devX[i]; } if (devY[i] < mindevY) { mindevY = devY[i]; } if (devY[i] > maxdevY) { maxdevY = devY[i]; } } System.out.println("mindevX = " + mindevX); System.out.println("maxdevX = " + maxdevX); System.out.println("mindevY = " + mindevY); System.out.println("maxdevY = " + maxdevY); double hPixelLength = maxdevX - mindevX; double vPixelLength = maxdevY - mindevY; System.out.println("hPixelLength = " + hPixelLength); System.out.println("vPixelLength = " + vPixelLength); double aspectRatio = vPixelLength / hPixelLength; double aspectRatio2 = aspectRatio * aspectRatio; double vconv = vPixelLength / vDataLength; double hconv = hPixelLength / hDataLength; double temp = 1.0 / vDataLength; System.out.println("aspectRatio = " + aspectRatio); System.out.println("aspectRatio2 = " + aspectRatio2); System.out.println("vconv = " + vconv); System.out.println("hconv = " + hconv); System.out.println("temp = " + temp); double[] ydiffs = new double[y.length - 1]; for (int i = 1; i < y.length; i++) { ydiffs[i - 1] = Math.abs(y[i] - y[i - 1]); if (Math.IEEEremainder((double) i, 20.0) == 0.0) { System.out.println("ydiffs[" + (i - 1) + "] = " + ydiffs[i - 1]); } } double[] vbar = new double[ydiffs.length]; double[] vbar2 = new double[ydiffs.length]; for (int i = 0; i < ydiffs.length; i++) { vbar[i] = ydiffs[i] * temp; vbar2[i] = vbar[i] * vbar[i]; if (Math.IEEEremainder((double) i, 20.0) == 0.0) { System.out.println("vbar[" + i + "] = " + vbar[i]); System.out.println("vbar2[" + i + "] = " + vbar2[i]); } } temp = 1.0 / hDataLength; double[] xdiffs = new double[y.length - 1]; for (int i = 1; i < y.length; i++) { xdiffs[i - 1] = Math.abs(x2[i] - x2[i - 1]); } double[] hbar = new double[ydiffs.length]; double[] hbar2 = new double[ydiffs.length]; for (int i = 0; i < ydiffs.length; i++) { hbar[i] = xdiffs[i] * temp; hbar2[i] = hbar[i] * hbar[i]; if (Math.IEEEremainder((double) i, 20.0) == 0.0) { System.out.println("hbar[" + i + "] = " + hbar[i]); System.out.println("hbar2[" + i + "] = " + hbar2[i]); } } double[] root = new double[ydiffs.length]; for (int i = 0; i < ydiffs.length; i++) { root[i] = hbar2[i] + (aspectRatio2 * vbar2[i]); root[i] = Math.sqrt(root[i]); if (Math.IEEEremainder((double) i, 20.0) == 0.0) { System.out.println("root[" + i + "] = " + root[i]); } } double denominator = 0.0; for (int i = 0; i < ydiffs.length; i++) { denominator = denominator + root[i]; } double numerator = 0.0; for (int i = 0; i < ydiffs.length; i++) { numerator = numerator + (Math.atan(aspectRatio * vbar[i] / hbar[i]) * root[i]); } System.out.println("denominator = " + denominator); System.out.println("numerator = " + numerator); banking = Math.toDegrees(numerator / denominator); System.out.println("banking = " + banking); if (banking > 45.0) { if (iterations > 3) { windowSize.width += 105; } else { windowSize.height -= 100; } } iterations++; System.out.println("windowSize = " + windowSize); } } private void update() { if (data != null) { data.remove(); } drawGraph(); setSize(windowSize); invalidate(); validate(); repaint(); } }