ASE Home Page Products Download Purchase Support About ASE
ChartDirector Support
Forum HomeForum Home   SearchSearch

Message ListMessage List     Post MessagePost Message

  scrollbar with MultiChart issue
Posted by C.H.wang on Dec-25-2016 18:34
Attachments:
Hi Peter :
  I merge two FinanceChart objects with multichart and I can't find scroll bar on the chart.
How can I let the scroll bar works?
The attached file is my code(C#).

Regard
C.H.Wang
FScroll.zip
FScroll.zip

6.31 Kb

  Re: scrollbar with MultiChart issue
Posted by Peter Kwan on Dec-27-2016 00:37
Hi C.H.Wang,

You may refer to the example below on how to scroll the FinanceChart:

http://www.chartdir.com/forum/download_thread.php?bn=chartdir_support&thread=1467686966#N1467721784

Note that the above code is in C++. In C#, I think it is something like:

private void initChartViewer(WinChartViewer viewer)
{
     // Set the full x range to be the duration of the data
     viewer.setFullRange("x", 0, timeStamps.Length - 1);

     ......................
}


//
// 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 = 0;
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);

       ..... use the above viewPortXXXXData to plot the FinanceChart .....
       ..... perform same steps for your second FinanceChart .....
}


Hope this can help.

Regards
Peter Kwan

  Re: scrollbar with MultiChart issue
Posted by C.H.Wang on Dec-28-2016 16:33
Hi Peter:
Thanks for your reply.
I modify code at your suggestion but scrollbar is still not useless and I have another question about full range.I want to show the latest 50% of the time range,but the chart show full range,so I think it cause the scrollbar useless. How should I do just to show  the latest 50% of range? My code is as follows.



        private void initChartViewer(WinChartViewer viewer)
        {
            // Set the full x range to be the duration of the data
            viewer.setFullRange("x", 0, timeStamps.Length - 1);

            //viewer.setFullRange("x", timeStamps[0], timeStamps[timeStamps.Length - 1]);
            // Initialize the view port to show the latest 50% of the time range
            viewer.ViewPortWidth = 0.5;
            viewer.ViewPortLeft = 1 - viewer.ViewPortWidth;
            // Set the maximum zoom to 10 points
            viewer.ZoomInWidthLimit = 10.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;
        }

  Re: scrollbar with MultiChart issue
Posted by C.H.Wang on Dec-28-2016 17:20
Sorry, I change my code as follows and it is still not as expected.

        private void initChartViewer(WinChartViewer viewer)
        {
            // Set the full x range to be the duration of the data
            //viewer.setFullRange("x", 0, timeStamps.Length - 1);

            viewer.setFullRange("x", timeStamps[0], timeStamps[timeStamps.Length - 1]);
            // Initialize the view port to show the latest 50% of the time range
            viewer.ViewPortWidth = 0.5;
            viewer.ViewPortLeft = 1 - viewer.ViewPortWidth;
            // Set the maximum zoom to 10 points
            viewer.ZoomInWidthLimit = 10.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;
        }

  Re: scrollbar with MultiChart issue
Posted by Peter Kwan on Dec-29-2016 03:10
Attachments:
Hi C.H.Wang,

In addition to the initChartViewer, have you also modified the drawChart routine to obtain the viewPortTimeStamps and other viewPort data, and use them to plot the chart? I have attached an example for your reference.

Regards
Peter Kwan
frmzoomscrolltrack.cs
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);
            }
        }
    }
}

  Re: scrollbar with MultiChart issue
Posted by C.H.Wang on Dec-30-2016 11:46
Hi Peter:
    Thanks for your help. The scrolling and zooming work perfectly fine.