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