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