/*
* -------------------------------------------------------------------------
* $Id: FPanel.java,v 1.5 2006/05/05 19:58:46 brophy 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.
*--------------------------------------------------------------------------
*/
/*
* FPanel.java
*
* Created on September 13, 2004, 3:52 PM
*/
package com.imsl.demo.heatmaps;
import com.imsl.chart.*;
import com.imsl.stat.Sort;
import java.util.*;
import java.io.*;
import java.awt.event.*;
import java.awt.Color;
public class FPanel extends javax.swing.JPanel implements MouseMotionListener {
private Chart chart;
private AxisXY axis;
private HashMap map;
private String[][] labels;
private String oldKey="nada";
private javax.swing.JFrame parentFrame;
private final int xMin = 0;
private final int xMax = 10;
/** Creates new form FPanel */
public FPanel(javax.swing.JFrame parent) {
this.parentFrame = parent;
initComponents();
setPreferredSize(new java.awt.Dimension(parent.getSize().width, (int)(0.85*parent.getSize().height)));
setChart();
jPanelChart.setPreferredSize(new java.awt.Dimension(parent.getSize().width, (int)(0.66*parent.getSize().height)));
try {
getData();
} catch (Exception e) {
e.printStackTrace();
}
update(0);
}
private void setChart() {
chart = jPanelChart.getChart();
axis = new AxisXY(chart);
axis.setViewport(0.05,0.80,0.05,0.95);
// Set axis ranges
axis.getAxisX().setAutoscaleInput(AxisXY.AUTOSCALE_OFF);
axis.getAxisY().setAutoscaleInput(AxisXY.AUTOSCALE_OFF);
axis.getAxisX().setWindow(0.0, 10.0);
axis.getAxisY().setWindow(0.0, 10.0);
// Add a MouseMotionListener to the chart.
jPanelChart.addMouseMotionListener(this);
}
// load data set
public void getData() throws IOException, java.text.ParseException {
InputStream is = getClass().getResourceAsStream("NASDAQ100.txt");
Reader fr = new InputStreamReader(is);
LineNumberReader lnr = new LineNumberReader(fr);
map = new HashMap(135);
while (true) {
String line = lnr.readLine();
if (line == null) break;
StringTokenizer st = new StringTokenizer(line,"\t");
String sym = st.nextToken();
String nam = st.nextToken();
double las = Double.valueOf(st.nextToken()).doubleValue();
double cha = Double.valueOf(st.nextToken()).doubleValue();
double hig = Double.valueOf(st.nextToken()).doubleValue();
double low = Double.valueOf(st.nextToken()).doubleValue();
long vol = Long.valueOf(st.nextToken()).longValue();
double clo = Double.valueOf(st.nextToken()).doubleValue();
Stock s = new Stock(sym,nam,las,cha,hig,low,vol,clo);
map.put(sym,s);
}
}
// Draw the graph
private void drawGraph(int num, double[][] data, String[][] labels) {
//Heatmap heatmap = new Heatmap(axis, 0, num, 0, num, -2.5, 2.5, data, Colormap.SPECTRAL);
double ext = findExtreme(data);
Heatmap heatmap = new Heatmap(axis, 0, num, 0, num, -ext, ext, data, new RedGreenColormap());
heatmap.setHeatmapLabels(labels);
heatmap.setTextColor("black");
heatmap.getHeatmapLegend().setPaint(true);
heatmap.getHeatmapLegend().setTextFormat("##.##");
heatmap.getHeatmapLegend().setTitle("Percent Change");
axis.getAxisX().setPaint(false);
axis.getAxisY().setPaint(false);
}
// Find min & max of scaled values
private double findExtreme(double[][] data) {
double ext = 0;
for (int i=0; i<data[0].length; i++) {
for (int j=0; j<data.length; j++) {
if (Math.abs(data[i][j]) > ext) ext = Math.abs(data[i][j]);
}
}
return ext;
}
// print the details for the current mouse location
private void getDetails(String key) {
Stock s = (Stock)map.get(key);
StringBuffer sb = new StringBuffer(s.getSymbol());
sb.append(": "+s.getName()+"\n");
sb.append("Last: "+s.getLast()+"\t% Change: "+s.getChange()+"\n");
sb.append("High: "+s.getHigh()+"\tLow: "+s.getLow()+"\n");
sb.append("Close: "+s.getClose()+"\tVolume: "+s.getVolume()+"\n");
displayText.setText(sb.toString());
}
// resort the data based on combo box selection
// this could be done once since the data in this demo
// are static; however, if one were receiving realtime
// updates, the sort would have to occur live.
private void sortData(int sel) {
final int num = 10;
final int num2 = num*num;
double data[][] = new double[num][num];
labels = new String[num][num];
Set keys;
Iterator iter;
double[] tmpData = new double[num2];
double[] tmpSort = new double[num2];
String[] tmpLab = new String[num2];
int[] perms = new int[num2];
switch (sel) {
case 0:
// sort by key -- easiest is to use a TreeMap
TreeMap tree = new TreeMap(map);
keys = tree.keySet();
iter = keys.iterator();
for (int i = 0; i < num; i++) {
for (int j = 0; j < num; j++) {
String key = (String)iter.next();
Stock s = (Stock)map.get(key);
String sym = s.getSymbol();
data[j][num-1-i] = s.getChange();
labels[j][num-1-i] = sym;
}
}
break;
case 1:
// sort by % change, ascending
keys = map.keySet();
iter = keys.iterator();
for (int i=0; i<num2; i++) {
String key = (String)iter.next();
Stock s = (Stock)map.get(key);
String sym = s.getSymbol();
tmpData[i] = s.getChange();
tmpLab[i] = sym;
perms[i] = i;
}
Sort.ascending(tmpData, perms);
for (int i=0; i<num; i++) {
for (int j=0; j<num; j++) {
data[j][num-1-i] = tmpData[i*num + j];
labels[j][num-1-i] = tmpLab[perms[i*num + j]];
}
}
break;
case 2:
// sort by % change, descending
keys = map.keySet();
iter = keys.iterator();
for (int i=0; i<num2; i++) {
String key = (String)iter.next();
Stock s = (Stock)map.get(key);
String sym = s.getSymbol();
tmpData[i] = s.getChange();
tmpLab[i] = sym;
perms[i] = i;
}
Sort.descending(tmpData, perms);
for (int i=0; i<num; i++) {
for (int j=0; j<num; j++) {
data[j][num-1-i] = tmpData[i*num + j];
labels[j][num-1-i] = tmpLab[perms[i*num + j]];
}
}
break;
case 3:
// sort by volume
keys = map.keySet();
iter = keys.iterator();
for (int i=0; i<num2; i++) {
String key = (String)iter.next();
Stock s = (Stock)map.get(key);
String sym = s.getSymbol();
tmpSort[i] = s.getVolume();
tmpData[i] = s.getChange();
tmpLab[i] = sym;
perms[i] = i;
}
Sort.ascending(tmpSort, perms);
for (int i=0; i<num; i++) {
for (int j=0; j<num; j++) {
data[j][num-1-i] = tmpData[perms[i*num + j]];
labels[j][num-1-i] = tmpLab[perms[i*num + j]];
}
}
break;
}
drawGraph(num, data, labels);
}
// Redraw the chart.
public void update(int sel) {
sortData(sel);
repaint();
}
private void initComponents() {
jPanel = new javax.swing.JPanel();
jLabel = new javax.swing.JLabel();
String[] sortChoices = {"Symbol", "% Change Ascending", "% Change Descending", "Volume"};
jComboBox = new javax.swing.JComboBox(sortChoices);
displayText = new javax.swing.JTextArea(2, 30);
jPanelChart = new com.imsl.chart.JPanelChart();
setLayout(new javax.swing.BoxLayout(this, javax.swing.BoxLayout.Y_AXIS));
setPreferredSize(new java.awt.Dimension(500, 600));
jLabel.setText("Sort by: ");
jPanel.add(jLabel);
jComboBox.setSelectedIndex(0);
jComboBox.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
update(jComboBox.getSelectedIndex());
}
});
jPanel.add(jComboBox);
add(jPanel);
displayText.setEditable(false);
displayText.setText("Move the mouse over the heat map for details.");
displayText.setPreferredSize(new java.awt.Dimension(500, 16));
displayText.setBackground(getBackground());
add(displayText);
jPanelChart.setPreferredSize(new java.awt.Dimension(500, 500));
add(jPanelChart);
}
// Implement MouseMotionListener
public void mouseMoved(MouseEvent e) {
double user[] = {0,0};
axis.mapDeviceToUser(e.getX(), e.getY(), user);
if ((user[0] < xMin) || (user[0] > xMax) ||
(user[1] < xMin) || (user[1] > xMax)) {
displayText.setText("Move the mouse over the heat map for details.");
return;
}
String key = labels[(int)user[0]][(int)user[1]];
if (!key.equals(oldKey)) {
oldKey = key;
getDetails(key);
}
}
public void mouseDragged(MouseEvent e) {
}
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JLabel jLabel;
private javax.swing.JComboBox jComboBox;
private com.imsl.chart.JPanelChart jPanelChart;
private javax.swing.JTextArea displayText;
private javax.swing.JPanel jPanel;
// End of variables declaration//GEN-END:variables
private class RedGreenColormap implements com.imsl.chart.Colormap {
int[] c = new int[] {16711680,16515072,16384000,16187392,16056320,15859712,15728640,15597568,15400960,15269888,15073280,14942208,14745600,14614528,14483456,14286848,14155776,13959168,13828096,13631488,13500416,13369344,13172736,
13041664,12845056,12713984,12582912,12386304,12255232,12058624,11927552,11730944,11599872,11468800,11272192,11141120,10944512,10813440,10616832,10485760,10354688,10158080,10027008,9830400,9699328,9568256,
9371648,9240576,9043968,8912896,8716288,8585216,8454144,8257536,8126464,7929856,7798784,7602176,7471104,7340032,7143424,7012352,6815744,6684672,6553600,6685443,6817543,7015179,7147279,7344915,7477015,
7609115,7806751,7938851,8136487,8268587,8466223,8598323,8730423,8928059,9060159,9257795,9389895,9587531,9719631,9851731,10049367,10181467,10379103,10511203,10643303,10840939,10973039,11170675,11302775,
11500411,11632511,11764611,11962247,12094347,12291983,12424083,12621719,12753819,12885919,13083555,13215655,13413291,13545391,13677491,13875127,14007227,14204863,14336963,14534599,14666699,14798799,14996435,
15128535,15326171,15458271,15655907,15788007,15920107,16117743,16249843,16447479,16579579,16777215,16514299,16251639,15988723,15726063,15463147,15200487,14937827,14674911,14412251,14149335,13886675,13623759,
13361099,13098439,12835523,12572863,12309947,12047287,11784371,11521711,11259051,10996135,10733475,10470559,10207899,9945239,9682323,9419663,9156747,8894087,8631171,8368511,8105851,7842935,7580275,7317359,
7054699,6791783,6529123,6266463,6003547,5740887,5477971,5215311,4952651,4689735,4427075,4164159,3901499,3638583,3375923,3113263,2850347,2587687,2324771,2062111,1799195,1536535,1273875,1010959,748299,485383,
222723,25600,26112,26624,27392,27904,28672,29184,29952,30464,31232,31744,32512,33024,33536,34304,34816,35584,36096,36864,37376,38144,38656,39424,39936,40704,41216,41728,42496,43008,43776,44288,45056,45568,
46336,46848,47616,48128,48896,49408,49920,50688,51200,51968,52480,53248,53760,54528,55040,55808,56320,57088,57600,58112,58880,59392,60160,60672,61440,61952,62720,63232,64000,64512,65280};
public java.awt.Color color(double t) {
int i = (int)(t*255);
return new java.awt.Color(c[i]);
}
}
}