/* * ChartPanel.java * * Created on September 19, 2001, 4:29 PM */ package com.imsl.demo.StockChart; import com.imsl.chart.*; import java.awt.*; import java.awt.event.*; import java.text.*; import java.util.Date; import javax.swing.*; /** * * @author brophy */ public class ChartPanel extends JPanelChart implements MouseListener, MouseMotionListener { private AxisXY axisPrice; private Data dataMovingAverage; private double time[]; private double high[]; private double low[]; private double close[]; private double vol[]; private double ave[]; private Slice slice = new Slice(); private SliceDialog sliceDialog; /** Creates new form ChartPanel */ public ChartPanel() { initComponents(); sliceDialog = new SliceDialog(); sliceDialog.setVisible(false); sliceDialog.setLocation(500,200); chart = new Chart(this); chart.getChartTitle().setTitle("Random Industries.com"); chart.getChartTitle().setFont(new Font("Serif", Font.ITALIC|Font.BOLD, 20)); chart.getChartTitle().setTextColor(new Color(0,128,64)); chart.setMarkerColor(Color.red); chart.setTextColor(Color.blue); Date date = new Date(933051600000L); // June 27, 1999 setData(date); // price axis axisPrice = new AxisXY(chart); axisPrice.setViewport(0.15, 0.9, 0.1, 0.65); axisPrice.setMarkerSize(0.5); HighLowClose hilo = new HighLowClose(axisPrice, date, high, low, close); axisPrice.getAxisX().getAxisLabel().setPaint(false); initGrid(axisPrice.getAxisX()); initGrid(axisPrice.getAxisY()); // moving average dataMovingAverage = new Data(axisPrice, time, ave); dataMovingAverage.setDataType(Data.DATA_TYPE_LINE); dataMovingAverage.setLineColor(Color.magenta); // volume axis AxisXY axis = new AxisXY(chart); axis.setViewport(0.15, 0.9, 0.7, 0.9); Data data = new Data(axis, time, vol); data.setDataType(Data.DATA_TYPE_FILL); data.setFillColor(Color.orange); data.setFillOutlineType(Data.FILL_TYPE_NONE); initGrid(axis.getAxisX()); initGrid(axis.getAxisY()); axis.getAxisY().getAxisTitle().setTitle("Volume (millions)"); axis.getAxisX().getAxisLabel().setTextAngle(270); DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT); axis.getAxisX().getAxisLabel().setTextFormat(df); addMouseListener(this); } private void initGrid(Axis1D axis1d) { Grid grid = axis1d.getGrid(); grid.setLineColor(Color.lightGray); grid.setPaint(true); } protected void setData(Date date) { int n = 300; high = new double[n]; low = new double[n]; close = new double[n]; vol = new double[n]; time = new double[n]; ave = new double[n]; high[0] = 101.; low[0] = 99.; close[0] = 100; vol[0] = 20.*Math.random(); time[0] = date.getTime(); ave[0] = close[0]; for (int k = 1; k < n; k++) { close[k] = close[k-1] + 2.*Math.random() - 1.; high[k] = close[k] + 0.5*Math.random(); low[k] = close[k] - 0.5*Math.random(); vol[k] = 20*Math.random(); time[k] = time[k-1] + 1000.*24.*60.*60.; ave[k] = 0.90*ave[k-1] + 0.1*close[k]; } } public void setViewMovingAverage(boolean viewMovingAverage) { dataMovingAverage.setPaint(viewMovingAverage); repaint(); } public Dimension getPreferredSize() { return new Dimension(500, 600); } public void paint(Graphics g) { super.paint(g); if (sliceDialog != null) sliceDialog.paint(g); } /** 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 setLayout(new java.awt.BorderLayout()); }//GEN-END:initComponents public void mouseExited(java.awt.event.MouseEvent mouseEvent) { } public void mouseReleased(java.awt.event.MouseEvent mouseEvent) { removeMouseMotionListener(this); slice.erase(); sliceDialog.setVisible(false); } public void mousePressed(java.awt.event.MouseEvent mouseEvent) { addMouseMotionListener(this); double w[] = axisPrice.getAxisY().getWindow(); int y[] = new int[2]; axisPrice.mapUserToDevice(time[0], w[0], y); int y0 = y[1]; axisPrice.mapUserToDevice(time[0], w[1], y); slice.setY(y0, y[1]); sliceDialog.setVisible(true); } public void mouseClicked(java.awt.event.MouseEvent mouseEvent) { } public void mouseEntered(java.awt.event.MouseEvent mouseEvent) { } public void mouseDragged(java.awt.event.MouseEvent mouseEvent) { slice.erase(); double point[] = new double[2]; axisPrice.mapDeviceToUser(mouseEvent.getX(), mouseEvent.getY(), point); int msday = 24*3600*1000; for (int k = 0; k < time.length; k++) { if (Math.abs(time[k]-point[0]) < msday) { slice.draw(mouseEvent.getX()); sliceDialog.setIndex(k); return; } } } public void mouseMoved(java.awt.event.MouseEvent mouseEvent) { } // Variables declaration - do not modify//GEN-BEGIN:variables // End of variables declaration//GEN-END:variables /** * Draw a vertical line to represent the current data slice. */ private class Slice { private int xDevice = -1; // if < 0 then no line is drawn private int yDevice[] = new int[2]; /** * Set vertical range of the line, in device cooordinates. */ void setY(int y0, int y1) { yDevice[0] = y0; yDevice[1] = y1; } /** * Erase the data slice line, if any. */ void erase() { if (xDevice >= 0) { paint(); xDevice = -1; } } /** * Draw the data slice line at a given location. * @param xDevice is the x-coordinate, in device units, * at which the line is to be drawn. */ void draw(int xDevice) { this.xDevice = xDevice; paint(); } /** * Actually paint the data slice line. */ private void paint() { Graphics g = getGraphics(); g.setXORMode(Color.white); g.drawLine(xDevice, yDevice[0], xDevice, yDevice[1]); } } /** * Dialog box to show the value of the current slice. */ private class SliceDialog extends JDialog { /* * The body of the dialog is formatted using HTML. */ final private DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.SHORT); final private NumberFormat vf = NumberFormat.getNumberInstance(); final private DecimalFormat df = new DecimalFormat("0.00"); final private MessageFormat mf = new MessageFormat( "<html><body bgcolor=\"yellow\"><table>" + "<tr><td align=\"right\"><i><font color=\"blue\">Date</td><td>{0}</td></tr>" + "<tr><td align=\"right\"><i><font color=\"blue\">Low</td><td >{1}</td></tr>" + "<tr><td align=\"right\"><i><font color=\"blue\">High</td><td >{2}</td></tr>" + "<tr><td align=\"right\"><i><font color=\"blue\">Close</td><td >{3}</td></tr>" + "<tr><td align=\"right\"><i><font color=\"blue\">Volume</td><td >{4}</td></tr>" + "</table></body></html>" ); private JEditorPane text; SliceDialog() { setBackground(Color.yellow); text = new JEditorPane(); text.setContentType("text/html"); text.setEditable(false); getContentPane().add(text); } public Dimension getPreferredSize() { return new Dimension(150,175); } void setIndex(int index) { String arg[] = new String[5]; arg[0] = dateFormat.format(new Date((long)time[index])); arg[1] = df.format(low[index]); arg[2] = df.format(high[index]); arg[3] = df.format(close[index]); arg[4] = vf.format((int)(1e6*vol[index])); text.setText(mf.format(arg)); pack(); } } }