using System;
using System.Windows.Forms;
using ChartDirector;
namespace CSharpChartExplorer
{
public partial class FrmZoomScrollTrack : Form
{
// Data arrays
private DateTime[] timeStamps;
private double[] highData;
private double[] lowData;
private double[] openData;
private double[] closeData;
private double[] volData;
// Flag to indicated if initialization has been completed. Prevents events from firing before
// controls are properly initialized.
private bool hasFinishedInitialization;
public FrmZoomScrollTrack()
{
InitializeComponent();
}
private void FrmZoomScrollTrack_Load(object sender, EventArgs e)
{
// Load the data
loadData();
// Initialize the WinChartViewer
initChartViewer(winChartViewer1);
// Can handle events now
hasFinishedInitialization = true;
// Trigger the ViewPortChanged event to draw the chart
winChartViewer1.updateViewPort(true, true);
}
//
// Load the data
//
private void loadData()
{
// Create a finance chart demo containing 100 days of data
int noOfDays = 500;
// To compute moving averages starting from the first day, we need to get extra data
// points before the first day
int extraDays = 30;
// In this exammple, we use a random number generator utility to simulate the data. We
// set up the random table to create 6 cols x (noOfDays + extraDays) rows, using 9 as
// the seed.
RanTable rantable = new RanTable(9, 6, noOfDays + extraDays);
// Set the 1st col to be the timeStamp, starting from Sep 4, 2002, with each row
// representing one day, and counting week days only (jump over Sat and Sun)
rantable.setDateCol(0, new DateTime(2002, 9, 4), 86400, true);
// Set the 2nd, 3rd, 4th and 5th columns to be high, low, open and close data. The open
// value starts from 100, and the daily change is random from -5 to 5.
rantable.setHLOCCols(1, 100, -5, 5);
// Set the 6th column as the vol data from 5 to 25 million
rantable.setCol(5, 50000000, 250000000);
// Now we read the data from the table into arrays
timeStamps = Chart.NTime(rantable.getCol(0));
highData = rantable.getCol(1);
lowData = rantable.getCol(2);
openData = rantable.getCol(3);
closeData = rantable.getCol(4);
volData = rantable.getCol(5);
}
//
// Initialize the WinChartViewer
//
private void initChartViewer(WinChartViewer viewer)
{
// Set the full x range to be the duration of the data
viewer.setFullRange("x", 0, timeStamps.Length - 1);
// Initialize the view port to show the latest 20% of the time range
viewer.ViewPortWidth = 0.5;
viewer.ViewPortLeft = 1 - viewer.ViewPortWidth;
// Set the maximum zoom to 30 points
viewer.ZoomInWidthLimit = 30.0 / timeStamps.Length;
// Enable mouse wheel zooming by setting the zoom ratio to 1.1 per wheel event
viewer.MouseWheelZoomRatio = 1.1;
// Initially set the mouse usage to "Pointer" mode (Drag to Scroll mode)
pointerPB.Checked = true;
}
//
// The ViewPortChanged event handler. This event occurs if the user scrolls or zooms in
// or out the chart by dragging or clicking on the chart. It can also be triggered by
// calling WinChartViewer.updateViewPort.
//
private void winChartViewer1_ViewPortChanged(object sender, WinViewPortEventArgs e)
{
// In addition to updating the chart, we may also need to update other controls that
// changes based on the view port.
updateControls(winChartViewer1);
// Update the chart if necessary
if (e.NeedUpdateChart)
drawChart(winChartViewer1);
}
//
// Update controls when the view port changed
//
private void updateControls(WinChartViewer viewer)
{
// In this demo, we need to update the scroll bar to reflect the view port position and
// width of the view port.
hScrollBar1.Enabled = winChartViewer1.ViewPortWidth < 1;
hScrollBar1.LargeChange = (int)Math.Ceiling(winChartViewer1.ViewPortWidth *
(hScrollBar1.Maximum - hScrollBar1.Minimum));
hScrollBar1.SmallChange = (int)Math.Ceiling(hScrollBar1.LargeChange * 0.1);
hScrollBar1.Value = (int)Math.Round(winChartViewer1.ViewPortLeft *
(hScrollBar1.Maximum - hScrollBar1.Minimum)) + hScrollBar1.Minimum;
}
//
// Draw the chart.
//
private void drawChart(WinChartViewer viewer)
{
// Get the start date and end date that are visible on the chart.
int startIndex = (int)Math.Floor(viewer.getValueAtViewPort("x", viewer.ViewPortLeft));
int endIndex = (int)Math.Ceiling(viewer.getValueAtViewPort("x", viewer.ViewPortLeft +
viewer.ViewPortWidth));
// To compute moving averages starting from the first day, we need to get
// extra data points before the first day.
int extraDays = Math.Min(30, startIndex);
startIndex -= extraDays;
int noOfPoints = endIndex - startIndex + 1;
// Extract the part of the data array that are visible.
DateTime[] viewPortTimeStamps = (DateTime[])Chart.arraySlice(timeStamps, startIndex, noOfPoints);
double[] viewPortHighData = (double[])Chart.arraySlice(highData, startIndex, noOfPoints);
double[] viewPortLowData = (double[])Chart.arraySlice(lowData, startIndex, noOfPoints);
double[] viewPortOpenData = (double[])Chart.arraySlice(openData, startIndex, noOfPoints);
double[] viewPortCloseData = (double[])Chart.arraySlice(closeData, startIndex, noOfPoints);
double[] viewPortVolData = (double[])Chart.arraySlice(volData, startIndex, noOfPoints);
//
// At this stage, we have extracted the visible data. We can use those data to plot the chart.
//
// Create a FinanceChart object of width 640 pixels
FinanceChart c = new FinanceChart(640);
// Add a title to the chart
c.addTitle("Finance Chart Demonstration");
// Set the data into the finance chart object
c.setData(viewPortTimeStamps, viewPortHighData, viewPortLowData, viewPortOpenData, viewPortCloseData,
viewPortVolData, extraDays);
// Add the main chart with 240 pixels in height
c.addMainChart(240);
// Add a 5 period simple moving average to the main chart, using brown color
c.addSimpleMovingAvg(5, 0x663300);
// Add a 20 period simple moving average to the main chart, using purple color
c.addSimpleMovingAvg(20, 0x9900ff);
// Add HLOC symbols to the main chart, using green/red for up/down days
c.addHLOC(0x008000, 0xcc0000);
// Add 20 days bollinger band to the main chart, using light blue (9999ff) as the border
// and semi-transparent blue (c06666ff) as the fill color
c.addBollingerBand(20, 2, 0x9999ff, unchecked((int)0xc06666ff));
// Add a 75 pixels volume bars sub-chart to the bottom of the main chart, using
// green/red/grey for up/down/flat days
c.addVolBars(75, 0x99ff99, 0xff9999, 0x808080);
// Append a 14-days RSI indicator chart (75 pixels high) after the main chart. The main
// RSI line is purple (800080). Set threshold region to +/- 20 (that is, RSI = 50 +/-
// 25). The upper/lower threshold regions will be filled with red (ff0000)/blue
// (0000ff).
c.addRSI(75, 14, 0x800080, 20, 0xff0000, 0x0000ff);
// Append a 12-days momentum indicator chart (75 pixels high) using blue (0000ff) color.
c.addMomentum(75, 12, 0x0000ff);
// Output the chart
viewer.Chart = c;
}
//
// Pointer (Drag to Scroll) button event handler
//
private void pointerPB_CheckedChanged(object sender, EventArgs e)
{
if (((RadioButton)sender).Checked)
winChartViewer1.MouseUsage = WinChartMouseUsage.ScrollOnDrag;
}
//
// Zoom In button event handler
//
private void zoomInPB_CheckedChanged(object sender, EventArgs e)
{
if (((RadioButton)sender).Checked)
winChartViewer1.MouseUsage = WinChartMouseUsage.ZoomIn;
}
//
// Zoom Out button event handler
//
private void zoomOutPB_CheckedChanged(object sender, EventArgs e)
{
if (((RadioButton)sender).Checked)
winChartViewer1.MouseUsage = WinChartMouseUsage.ZoomOut;
}
//
// The scroll bar event handler
//
private void hScrollBar1_ValueChanged(object sender, EventArgs e)
{
// When the view port is changed (user drags on the chart to scroll), the scroll bar will get
// updated. When the scroll bar changes (eg. user drags on the scroll bar), the view port will
// get updated. This creates an infinite loop. To avoid this, the scroll bar can update the
// view port only if the view port is not updating the scroll bar.
if (hasFinishedInitialization && !winChartViewer1.IsInViewPortChangedEvent)
{
// Set the view port based on the scroll bar
winChartViewer1.ViewPortLeft = ((double)(hScrollBar1.Value - hScrollBar1.Minimum))
/ (hScrollBar1.Maximum - hScrollBar1.Minimum);
// Trigger a view port changed event to update the chart
winChartViewer1.updateViewPort(true, false);
}
}
}
}
|