TeeChart Pro ActiveX Tutorial: Custom Drawing on Chart Panel

Posted by Ameslee on Sun, 12 May 2019 07:26:35 +0200

Download the latest version of TeeChart Pro ActiveX

TeeChart provides a wide range of custom drawing tools through Canvas objects. With Canvas, you can add shapes, lines and text anywhere in the "Chart Panel" and define its color, pen and brush style.

TeeChart Canvas

Drawing order

When using TeeChart's Canvas method, remember that drawing order is important. Drawing a line on a graph and adding a series of data points will result in line overdraft. There are four main charting events, arranged in order:

  • BeforeDraw event

  • BeforeDrawAxes event

  • BeforeDrawSeries event

  • AfterDraw event

[C#]

private bool afterDraw; 
private bool beforeDraw; 
private bool beforeDrawAxis; 
private bool beforeDrawSeries; 
 
private void Form1_Load(object sender, System.EventArgs e) {  
     SetFlags(ref beforeDraw); 
     Bar bar1 = new Bar(tChart1.Chart); 
     bar1.FillSampleValues(20); 
     radioButton1.Checked = true; 
} 
private void SetFlags(ref bool Flag) { 
     beforeDraw = false; 
     afterDraw = false; 
     beforeDrawAxis = false; 
     beforeDrawSeries = false; 
     Flag = true; 
} 
private void DrawShape(Steema.TeeChart.Drawing.Graphics3D gg) { 
     gg.Brush.Color = Color.Yellow; 
     gg.Pen.Visible = true; 
     gg.Pen.Style = System.Drawing.Drawing2D.DashStyle.Dash; 
     gg.Brush.Visible = true; 
     gg.Ellipse(1,1,gg.Chart.Width - 1,gg.Chart.Height - 1); 
} 
private void tChart1_AfterDraw(object sender, Steema.TeeChart.Drawing.Graphics3D g) { 
     if(afterDraw) { 
     DrawShape(g); 
    } 
} 
private void tChart1_BeforeDraw(object sender, Steema.TeeChart.Drawing.Graphics3D g) { 
     if(beforeDraw) { 
     DrawShape(g); 
    } 
} 
private void tChart1_BeforeDrawAxes(object sender, Steema.TeeChart.Drawing.Graphics3D g) { 
     if(beforeDrawAxis) { 
     DrawShape(g); 
    } 
} 
private void tChart1_BeforeDrawSeries(object sender, Steema.TeeChart.Drawing.Graphics3D g) { 
     if(beforeDrawSeries) { 
     DrawShape(g); 
    } 
} 
private void radioButton4_Click(object sender, System.EventArgs e) { 
     SetFlags(ref afterDraw); 
     tChart1.Refresh(); 
} 
private void radioButton3_Click(object sender, System.EventArgs e) { 
     SetFlags(ref beforeDrawSeries); 
     tChart1.Refresh(); 
} 
private void radioButton2_Click(object sender, System.EventArgs e) { 
     SetFlags(ref beforeDrawAxis); 
     tChart1.Refresh(); 
} 
private void radioButton1_Click(object sender, System.EventArgs e) { 
     SetFlags(ref beforeDraw); 
     tChart1.Refresh(); 
}

[VB.Net]

Private BeforeDraw As Boolean 
Private BeforeDrawAxis As Boolean 
Private BeforeDrawSeries As Boolean 
Private AfterDraw As Boolean 
 
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load 
    SetFlags(BeforeDraw) 
    Dim Bar1 As New Steema.TeeChart.Styles.Bar(TChart1.Chart) 
    Bar1.FillSampleValues(20) 
    RadioButton1.Checked = True 
End Sub 
Private Sub SetFlags(ByRef Flag As Boolean) 
    BeforeDraw = False 
    BeforeDrawAxis = False 
    BeforeDrawSeries = False 
    AfterDraw = False 
    Flag = True 
End Sub 
Private Sub DrawShape(ByVal gg As Steema.TeeChart.Drawing.Graphics3D) 
    gg.Brush.Color = Color.Yellow 
    gg.Pen.Visible = True 
    gg.Pen.Style = Drawing.Drawing2D.DashStyle.Dash 
    gg.Brush.Visible = True 
    gg.Ellipse(1, 1, gg.Chart.Width - 1, gg.Chart.Height - 1) 
End Sub 
Private Sub TChart1_AfterDraw(ByVal sender As Object, ByVal g As Steema.TeeChart.Drawing.Graphics3D) Handles TChart1.AfterDraw 
    If AfterDraw = True Then 
     DrawShape(g) 
    End If 
End Sub 
Private Sub TChart1_BeforeDraw(ByVal sender As Object, ByVal g As Steema.TeeChart.Drawing.Graphics3D) Handles TChart1.BeforeDraw 
    If BeforeDraw = True Then 
     DrawShape(g) 
    End If 
End Sub 
Private Sub TChart1_BeforeDrawAxes(ByVal sender As Object, ByVal g As Steema.TeeChart.Drawing.Graphics3D) Handles TChart1.BeforeDrawAxes 
    If BeforeDrawAxis = True Then 
     DrawShape(g) 
    End If 
End Sub 
Private Sub TChart1_BeforeDrawSeries(ByVal sender As Object, ByVal g As Steema.TeeChart.Drawing.Graphics3D) Handles TChart1.BeforeDrawSeries 
    If BeforeDrawSeries = True Then 
     DrawShape(g) 
    End If 
End Sub 
Private Sub RadioButton4_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles RadioButton4.Click 
    SetFlags(AfterDraw) 
    TChart1.Refresh() 
End Sub 
Private Sub RadioButton3_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles RadioButton3.Click 
    SetFlags(BeforeDrawSeries) 
    TChart1.Refresh() 
End Sub 
Private Sub RadioButton2_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles RadioButton2.Click 
    SetFlags(BeforeDrawAxis) 
    TChart1.Refresh() 
End Sub 
Private Sub RadioButton1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles RadioButton1.Click 
    SetFlags(BeforeDraw) 
    TChart1.Refresh() 
End Sub

Make sure you save custom drawn items to Canvas

If Canvas drawing code is not called in one of the Chart events, the custom drawing will not be permanently saved to Canvas, resulting in the loss of any additions or another window placed on it when the application is minimized. Your code does not need to reside directly in the Chart event; if you place the code in BeforeDrawSeries / AfterDraw and check the markup set at runtime, you can save the user-drawn items in the lifecycle of the chart window. When the activity is marked true, the drawing method therefore runs the drawing code, as shown in the example above.

Drawing line

Let's add a canvas line: an example (drawing a line diagonally from the upper left to the lower right corner)

[C#]

private void Form1_Load(object sender,System.EventArgs e){ 
        line1.FillSampleValues(20); 
        line1.VertAxis = VerticalAxis.Both; 
        line1.HorizAxis = HorizontalAxis.Both; 
        tChart1.Aspect.View3D = false; 
} 
 
private void tChart1_AfterDraw(object sender,Steema.TeeChart.Drawing.Graphics3D g){ 
        Point s = new Point(tChart1.Axes.Left.Position,tChart1.Axes.Top.Position); 
        //Point e = new point (tChart1.Axes.Right.Position, tChart1.Axes.Bottom.Position);
        g.MoveTo(One or more); 
        g.LineTo(E,0); 
}

[VB.Net]

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load 
        Line1.FillSampleValues(20) 
        Line1.VertAxis = Steema.TeeChart.VerticalAxis.Both 
        Line1.HorizAxis = Steema.TeeChart.HorizontalAxis.Both 
        TChart1.Aspect.View3D = False 
End Sub 
 
Private Sub TChart1_AfterDraw(ByVal sender As Object, ByVal g As Steema.TeeChart.Drawing.Graphics3D) Handles TChart1.AfterDraw 
        Dim S As New Point(TChart1.Axes.Left.Position, TChart1.Axes.Top.Position) 
        Dim E As New Point(TChart1.Axes.Right.Position, TChart1.Axes.Bottom.Position) 
        g.MoveTo(S) 
        g.LineTo(E, 0) 
End Sub

On a 3D chart, the axis position deviates from the graph area due to the 3D orthogonal displacement. We can move the line accordingly: an example (drawing a line diagonally from the top left to the bottom right in the graph area of a 3D chart)

[C#]

private void Form1_Load(object sender, System.EventArgs e) { 
        line1.FillSampleValues(20); 
        line1.VertAxis = VerticalAxis.Both; 
        line1.HorizAxis = HorizontalAxis.Both; 
        tChart1.Aspect.Chart3DPercent = 50; 
} 
 
private void tChart1_AfterDraw(object sender, Steema.TeeChart.Drawing.Graphics3D g) { 
        Steema.TeeChart.Drawing.Point3D s = new Steema.TeeChart.Drawing.Point3D(); 
        s.X = tChart1.Axes.Left.Position; 
        s.Y = tChart1.Axes.Top.Position; 
        s.Z = 0; 
 
        Steema.TeeChart.Drawing.Point3D e = new Steema.TeeChart.Drawing.Point3D(); 
        e.X = tChart1.Axes.Right.Position; 
        e.Y = tChart1.Axes.Bottom.Position; 
        e.Z = tChart1.Aspect.Width3D; 
     
        g.MoveTo(s); 
        g.LineTo(e); 
}

[VB.Net]

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load 
        Line1.FillSampleValues(20) 
        Line1.VertAxis = Steema.TeeChart.VerticalAxis.Both 
        Line1.HorizAxis = Steema.TeeChart.HorizontalAxis.Both 
        TChart1.Aspect.Chart3DPercent = 50 
End Sub 
 
Private Sub TChart1_AfterDraw(ByVal sender As Object, ByVal g As Steema.TeeChart.Drawing.Graphics3D) Handles TChart1.AfterDraw 
        Dim S As New Steema.TeeChart.Drawing.Point3D() 
        S.X = TChart1.Axes.Left.Position 
        S.Y = TChart1.Axes.Top.Position 
        S.Z = 0 
 
        Dim E As New Steema.TeeChart.Drawing.Point3D() 
        E.X = TChart1.Axes.Right.Position 
        E.Y = TChart1.Axes.Bottom.Position 
        E.Z = TChart1.Aspect.Width3D 
 
        g.MoveTo(S) 
        g.LineTo(E) 
End Sub

Canvas brushes and brushes

The line above is drawn with a pen and brush defined for the last object drawn before the line is drawn. It may or may not be the pen you want. Change pens accordingly: Example (Define pens before drawing lines)

[C#]

private void tChart1_AfterDraw(object sender, Steema.TeeChart.Drawing.Graphics3D g) { 
        Point p5 = new Point(line1.CalcXPos(5), line1.CalcYPos(5)); 
        Point p15 = new Point(line1.CalcXPos(15), line1.CalcYPos(15)); 
        g.Pen.DashCap = System.Drawing.Drawing2D.DashCap.Triangle; 
        g.Pen.EndCap = System.Drawing.Drawing2D.LineCap.DiamondAnchor; 
        g.Pen.Style = System.Drawing.Drawing2D.DashStyle.DashDotDot; 
        g.Pen.Transparency = 70; 
        g.Pen.Width = 3; 
        g.Pen.Color = Color.BlueViolet; 
        g.MoveTo(p5); 
        g.LineTo(p15, 0); 
}

[VB.Net]

Private Sub TChart1_AfterDraw(ByVal sender As Object, ByVal g As Steema.TeeChart.Drawing.Graphics3D) Handles TChart1.AfterDraw 
        Dim P5 As New Point(Line1.CalcXPos(5), Line1.CalcYPos(5)) 
        Dim P15 As New Point(Line1.CalcXPos(15), Line1.CalcYPos(15)) 
        g.Pen.DashCap = System.Drawing.Drawing2D.DashCap.Triangle 
        g.Pen.EndCap = System.Drawing.Drawing2D.LineCap.DiamondAnchor 
        g.Pen.Style = System.Drawing.Drawing2D.DashStyle.DashDotDot 
        g.Pen.Transparency = 70 
        g.Pen.Width = 3 
        g.Pen.Color = Color.BlueViolet 
        g.MoveTo(P5) 
        g.LineTo(P15, 0) 
End Sub



Topics: ASP.NET