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