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

Message ListMessage List     Post MessagePost Message

  Adding crosshir to Interactive finance chart
Posted by Tunde on Jun-17-2013 23:21
Hi Peter,
i am trying to add crosshir to my finance chart but get this error each time:

Unable to cast object of type 'ChartDirector.FinanceChart' to type
'ChartDirector.XYChart'.
My code sample is bellow:

Private Sub FrmTrackFinance_Load(ByVal sender As Object, ByVal e As
System.EventArgs) Handles MyBase.Load

        ' Create a finance chart demo containing 100 days of data
        Dim noOfDays As Integer = 100

        ' To compute moving averages starting from the first day, we need to get extra
data points before the
        ' first day
        Dim extraDays As Integer = 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.
        Dim rantable As RanTable = New RanTable(9, 6, noOfDays + extraDays)

        ' Set the 1st col to be the timeStamp, starting from Sep 4, 2011, with each row
representing one day,
        ' and counting week days only (jump over Sat and Sun)
        rantable.setDateCol(0, DateSerial(2011, 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
        Dim timeStamps() As Double = rantable.getCol(0)
        Dim highData() As Double = rantable.getCol(1)
        Dim lowData() As Double = rantable.getCol(2)
        Dim openData() As Double = rantable.getCol(3)
        Dim closeData() As Double = rantable.getCol(4)
        Dim volData() As Double = rantable.getCol(5)

        ' Create a FinanceChart object of width 720 pixels
        Dim c As FinanceChart = New FinanceChart(720)

        Dim SignalData() As Double = closeData ' Array(NoValue, NoValue, NoValue, 10.56,
NoValue, NoValue)


        'Dim md As XYChart = c.addMainChart(Width)

        'md.addScatterLayer(Nothing, SignalData, "Buy", Chart.TriangleSymbol, 10,
&H33FF33)



        ' Add a title to the chart
        c.addTitle("Finance Chart Demonstration")

        ' Disable default legend box, as we are using dynamic legend
        c.setLegendStyle("normal", 8, Chart.Transparent, Chart.Transparent)

        ' Set the data into the finance chart object
        c.setData(timeStamps, highData, lowData, openData, closeData, volData,
extraDays)

        ' Add the main chart with 240 pixels in height
        c.addMainChart(240)

        ' Add a 10 period simple moving average to the main chart, using brown color
        c.addSimpleMovingAvg(10, &H663300)

        ' Add a 20 period simple moving average to the main chart, using purple color
        c.addSimpleMovingAvg(20, &H9900ff)

        ' Add candlestick symbols to the main chart, using green/red for up/down days
        c.addCandleStick(&H00ff00, &Hff0000)

        ' 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, &H9999ff, &Hc06666ff)

        ' 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, &H99ff99, &Hff9999, &H808080)

        ' 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, &H800080, 20, &Hff0000, &H0000ff)

        ' Append a MACD(26, 12) indicator chart (75 pixels high) after the main chart, using
9 days for
        ' computing divergence.
        c.addMACD(75, 26, 12, 9, &H0000ff, &Hff00ff, &H008000)

        ' Include track line with legend for the latest data values
        trackFinance(c, CType(c.getChart(0), XYChart).getPlotArea().getRightX())
        crossHair(CType(c.getChart(0), XYChart), CType(c.getChart(0),
XYChart).getPlotArea().getRightX(), CType(c.getChart(0),
XYChart).getPlotArea().getBottomY)

        ' Assign the chart to the WinChartViewer
        winChartViewer1.Chart = c



    End Sub

    '
    ' Draw track cursor when mouse is moving over plotarea
    '
    Private Sub winChartViewer1_MouseMovePlotArea(ByVal sender As Object, _
        ByVal e As System.Windows.Forms.MouseEventArgs) Handles
winChartViewer1.MouseMovePlotArea

        Dim viewer As WinChartViewer = sender
        trackFinance(viewer.Chart, viewer.PlotAreaMouseX)
        '
        crossHair(viewer.Chart, viewer.PlotAreaMouseX, viewer.PlotAreaMouseY)
        viewer.updateDisplay()

    End Sub
    '
    ' Draw cross hair cursor with axis labels
    '
    Private Sub crossHair(ByVal c As XYChart, ByVal mouseX As Integer, ByVal mouseY As
Integer)

        ' Clear the current dynamic layer and get the DrawArea object to draw on it.
        Dim d As DrawArea = c.initDynamicLayer()

        ' The plot area object
        Dim plotArea As PlotArea = c.getPlotArea()

        ' Draw a vertical line and a horizontal line as the cross hair
        d.vline(plotArea.getTopY(), plotArea.getBottomY(), mouseX, d.dashLineColor(&H0,
&H101))
        d.hline(plotArea.getLeftX(), plotArea.getRightX(), mouseY, d.dashLineColor(&H0,
&H101))

        ' Draw y-axis label
        Dim label As String = "<*block,bgColor=FFFFDD,margin=3,edgeColor=000000*>" &
c.formatValue( _
            c.getYValue(mouseY, c.yAxis()), "{value|P4}") & "<*/*>"
        Dim t As TTFText = d.text(label, "Arial Bold", 8)
        t.draw(plotArea.getLeftX() - 5, mouseY, &H0, Chart.Right)

        ' Draw x-axis label
        label = "<*block,bgColor=FFFFDD,margin=3,edgeColor=000000*>" &
c.formatValue(c.getXValue(mouseX), _
            "{value|P4}") & "<*/*>"
        t = d.text(label, "Arial Bold", 8)
        t.draw(mouseX, plotArea.getBottomY() + 5, &H0, Chart.Right)

    End Sub

  Re: Adding crosshir to Interactive finance chart
Posted by Tunde on Jun-17-2013 23:25
Hi Peter,
i am trying to add crosshir to my finance chart but get this error each time:

Unable to cast object of type 'ChartDirector.FinanceChart' to type
'ChartDirector.XYChart'.
My code sample is bellow:

Private Sub FrmTrackFinance_Load(ByVal sender As Object, ByVal e As
System.EventArgs) Handles MyBase.Load

        ' Create a finance chart demo containing 100 days of data
        Dim noOfDays As Integer = 100

        ' To compute moving averages starting from the first day, we need to get extra
data points before the
        ' first day
        Dim extraDays As Integer = 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.
        Dim rantable As RanTable = New RanTable(9, 6, noOfDays + extraDays)

        ' Set the 1st col to be the timeStamp, starting from Sep 4, 2011, with each row
representing one day,
        ' and counting week days only (jump over Sat and Sun)
        rantable.setDateCol(0, DateSerial(2011, 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
        Dim timeStamps() As Double = rantable.getCol(0)
        Dim highData() As Double = rantable.getCol(1)
        Dim lowData() As Double = rantable.getCol(2)
        Dim openData() As Double = rantable.getCol(3)
        Dim closeData() As Double = rantable.getCol(4)
        Dim volData() As Double = rantable.getCol(5)

        ' Create a FinanceChart object of width 720 pixels
        Dim c As FinanceChart = New FinanceChart(720)

        Dim SignalData() As Double = closeData ' Array(NoValue, NoValue, NoValue, 10.56,
NoValue, NoValue)


        'Dim md As XYChart = c.addMainChart(Width)

        'md.addScatterLayer(Nothing, SignalData, "Buy", Chart.TriangleSymbol, 10,
&H33FF33)



        ' Add a title to the chart
        c.addTitle("Finance Chart Demonstration")

        ' Disable default legend box, as we are using dynamic legend
        c.setLegendStyle("normal", 8, Chart.Transparent, Chart.Transparent)

        ' Set the data into the finance chart object
        c.setData(timeStamps, highData, lowData, openData, closeData, volData,
extraDays)

        ' Add the main chart with 240 pixels in height
        c.addMainChart(240)

        ' Add a 10 period simple moving average to the main chart, using brown color
        c.addSimpleMovingAvg(10, &H663300)

        ' Add a 20 period simple moving average to the main chart, using purple color
        c.addSimpleMovingAvg(20, &H9900ff)

        ' Add candlestick symbols to the main chart, using green/red for up/down days
        c.addCandleStick(&H00ff00, &Hff0000)

        ' 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, &H9999ff, &Hc06666ff)

        ' 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, &H99ff99, &Hff9999, &H808080)

        ' 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, &H800080, 20, &Hff0000, &H0000ff)

        ' Append a MACD(26, 12) indicator chart (75 pixels high) after the main chart, using
9 days for
        ' computing divergence.
        c.addMACD(75, 26, 12, 9, &H0000ff, &Hff00ff, &H008000)

        ' Include track line with legend for the latest data values
        trackFinance(c, CType(c.getChart(0), XYChart).getPlotArea().getRightX())
        crossHair(CType(c.getChart(0), XYChart), CType(c.getChart(0),
XYChart).getPlotArea().getRightX(), CType(c.getChart(0),
XYChart).getPlotArea().getBottomY)

        ' Assign the chart to the WinChartViewer
        winChartViewer1.Chart = c



    End Sub

    '
    ' Draw track cursor when mouse is moving over plotarea
    '
    Private Sub winChartViewer1_MouseMovePlotArea(ByVal sender As Object, _
        ByVal e As System.Windows.Forms.MouseEventArgs) Handles
winChartViewer1.MouseMovePlotArea

        Dim viewer As WinChartViewer = sender
        trackFinance(viewer.Chart, viewer.PlotAreaMouseX)
        '
        crossHair(viewer.Chart, viewer.PlotAreaMouseX, viewer.PlotAreaMouseY)
        viewer.updateDisplay()

    End Sub
    '
    ' Draw cross hair cursor with axis labels
    '
    Private Sub crossHair(ByVal c As XYChart, ByVal mouseX As Integer, ByVal mouseY As
Integer)

        ' Clear the current dynamic layer and get the DrawArea object to draw on it.
        Dim d As DrawArea = c.initDynamicLayer()

        ' The plot area object
        Dim plotArea As PlotArea = c.getPlotArea()

        ' Draw a vertical line and a horizontal line as the cross hair
        d.vline(plotArea.getTopY(), plotArea.getBottomY(), mouseX, d.dashLineColor(&H0,
&H101))
        d.hline(plotArea.getLeftX(), plotArea.getRightX(), mouseY, d.dashLineColor(&H0,
&H101))

        ' Draw y-axis label
        Dim label As String = "<*block,bgColor=FFFFDD,margin=3,edgeColor=000000*>" &
c.formatValue( _
            c.getYValue(mouseY, c.yAxis()), "{value|P4}") & "<*/*>"
        Dim t As TTFText = d.text(label, "Arial Bold", 8)
        t.draw(plotArea.getLeftX() - 5, mouseY, &H0, Chart.Right)

        ' Draw x-axis label
        label = "<*block,bgColor=FFFFDD,margin=3,edgeColor=000000*>" &
c.formatValue(c.getXValue(mouseX), _
            "{value|P4}") & "<*/*>"
        t = d.text(label, "Arial Bold", 8)
        t.draw(mouseX, plotArea.getBottomY() + 5, &H0, Chart.Right)

    End Sub



get the error when i try to run the code.
Also, i want to get the price to be display in a label either on the right or left of the y-
axis as the user may chose.

Please help me with these two issues.

Thanks
Tunde

  Re: Adding crosshir to Interactive finance chart
Posted by Peter Kwan on Jun-19-2013 01:05
Hi Tunde,

The error means that you are using a FinanceChart, but your code expects an XYChart.

Also, I am not too clear what you mean by a "crosshair" in a FinanceChart. In the original ChartDirector sample code, a "crosshair" plots the x and y values under the mouse cursor. It works for continuous x and y values. For financial charts, the x values are discrete and unpredictable. For example, if there are two consecutive trading days on "Jun 20" and "Jun 24" (the days in between can be national holidays or other non-trading days), and the mouse move in between "Jun 20" and "Jun 24", what should be the x-coordinate? Most people would expect the vertical line to "snap" to the nearest trading day, but then it is just the original "trackFinance" code.

Since yiour code also calls the original "trackFinance" code, I assume you just want the "horizontal" part of the "crosshair".

For the crosshair code, please modify the code to expect a FinanceChart, not an XYChart. A short example is as follows. Please modify it to fit your own needs. The code below display the text on the left plot area border. To change it to the right plot area border, please modify the coordinates of the "t.text(...)" line to use plotArea.getLeftX() + 5 as the x-coordinate and Chart.Left as the alignment.

Hope this can help.

Regards
Peter Kwan

  Re: Adding crosshir to Interactive finance chart
Posted by Tunde on Jun-19-2013 21:22
Hi Peter,
Thanks very much for your reply. Please can you show me some code sample as to changing this code from XYChart to FinanceChart as there is no code seen in your reply as stated.

See below code which i tried but am getting errors:

'
    ' Draw cross hair cursor with axis labels
    '
    Private Sub crossHair(ByVal c As FinanceChart, ByVal mouseX As Integer, ByVal mouseY As Integer)

        ' Clear the current dynamic layer and get the DrawArea object to draw on it.
        Dim d As DrawArea = c.initDynamicLayer()

        ' The plot area object
        Dim plotArea As DrawArea = c.getDrawArea ' c.getPlotArea()

        ' Draw a vertical line and a horizontal line as the cross hair
        d.vline(plotArea.getARGBColor(), plotArea.getBottomY(), mouseX, d.dashLineColor(&H0, &H101))
        d.hline(plotArea.getLeftX(), plotArea.getRightX(), mouseY, d.dashLineColor(&H0, &H101))



        ' Draw y-axis label
        Dim label As String = "<*block,bgColor=FFFFDD,margin=3,edgeColor=000000*>" & c.formatValue( _
            c.getYValue(mouseY, c.yAxis()), "{value|P4}") & "<*/*>"
        Dim t As TTFText = d.text(label, "Arial Bold", 8)
        t.draw(plotArea.getLeftX() + 5, mouseY, &H0, Chart.Right)

        ' Draw x-axis label
        label = "<*block,bgColor=FFFFDD,margin=3,edgeColor=000000*>" & c.formatValue(c.getXValue(mouseX), _
            "{value|P4}") & "<*/*>"
        t = d.text(label, "Arial Bold", 8)
        t.draw(mouseX, plotArea.getBottomY() + 5, &H0, Chart.Right)

    End Sub

Thanks
Tunde

  Re: Adding crosshir to Interactive finance chart
Posted by Peter Kwan on Jun-20-2013 13:03
Hi Tunde,

Sorry. I forgot to include the code:

    Private Sub crossHair(ByVal c As FinanceChart, ByVal mouseX As Integer, ByVal mouseY As Integer)

        ' Clear the current dynamic layer and get the DrawArea object to draw on it.
        Dim d As DrawArea = c.initDynamicLayer()

        ' The plot area object
        Dim mainChart As XYChart = c.getChart(0)
        Dim plotArea As PlotArea = mainChart.getPlotArea()

        Dim topLimit As Double = plotArea.getTopY() + mainChart.getAbsOffsetY()
        Dim bottomLimit As Double = plotArea.getBottomY() + mainChart.getAbsOffsetY()
        If mouseY >= topLimit And mouseY <= bottomLimit Then

            d.hline(plotArea.getLeftX(), plotArea.getRightX(), mouseY, d.dashLineColor(&H0, &H101))

            ' Draw y-axis label
            Dim label As String = "<*block,bgColor=FFFFDD,margin=3,edgeColor=000000*>" & c.formatValue( _
                mainChart.getYValue(mouseY, mainChart.yAxis()), "{value|P4}") & "<*/*>"
            Dim t As TTFText = d.text(label, "Arial Bold", 8)
            t.draw(plotArea.getLeftX() - 5, mouseY, &H0, Chart.Right)

        End If

    End Sub


In brief, as your chart is a FinanceChart, you need to use declare the crossHair function to accept a FinanceChart object. If you need to obtain the position of the plot area, you need to specify which XYChart you are referring to. (A FinanceChart can contain multiple XYCharts for the main price chart and the various indicators.)

Hope this can help.

Regards
Peter Kwan