【TeeChart .NET教程】(十三)图表面板上的自定义绘图

上一篇:【TeeChart .NET教程】(十二)Web表单示例

下一篇:【TeeChart .NET教程】(十四)打印图表

【下载TeeChart.Net最新版本】

TeeChart通过Canvas对象提供广泛的自定义绘图工具,使用Canvas,您可以在“ Chart Panel图表面板”的任何位置添加形状,线条和文本,并定义其颜色,笔和画笔样式。

(一)TeeChart Canvas——TeeChart 画布

1.1 绘图顺序

使用TeeChart的Canvas方法时,绘图顺序很重要,在图表上绘制一条线然后添加系列数据点将导致线拉过度 。有四个主要的图表绘制事件,按顺序排列:

  • BeforeDraw event
  • BeforeDrawAxes event
  • BeforeDrawSeries event
  • AfterDraw event

例:

[C#.Net]

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

1.2 确保将自定义绘制的项目保存到Canvas

如果不在其中一个Chart事件中调用Canvas绘制代码,则自定义绘图将不会永久保存到Canvas,从而导致在应用程序最小化时丢失任何添加内容或另一个窗口放在它上面。您的代码不需要直接驻留在Chart事件中; 如果将代码放在BeforeDrawSeries / AfterDraw中并且检查运行时设置的标记,则可以在图表窗口的生命周期中保存用户绘制的项目。当活动标记为true时,绘制方法因此运行绘制代码,如上例所示。

1.3 绘制线

添加一个画布线:示例(从左上角到右下角对角画一条线)

[C#.Net]

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(s); 
        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

在3D图表上,由于3D正交位移,轴位置偏离图表区域。可以相应地移动线:示例(在3D图表的图表区域中从左上角到右下角对角绘制一条线)

[C#.Net]

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

1.4 画布笔和画笔

上面的线是使用为绘制线之前绘制的最后一个对象定义的笔和画笔绘制的。那可能是也可能不是你想要的笔。相应地更改笔:示例(在绘制线之前定义笔)

[C#.Net]

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

1.5 添加2D形状

以与Canvas Lines类似的方式添加Canvas Shapes。以下示例在图表区域的中心添加一个Rectangle:

1.5.1 2D图表

2D图表仅支持2D形状,例:

[C#.Net]

private void tChart1_AfterDraw(object sender, Steema.TeeChart.Drawing.Graphics3D g) { 
        Size s = new Size(100,100); 
        Point l = new Point(g.ChartXCenter - (s.Width / 2), g.ChartYCenter - (s.Height / 2)); 
        Rectangle r = new Rectangle(l,s); 
        g.Pen.Color = Color.Aquamarine; 
        g.Brush.Color = Color.Blue; 
        g.Rectangle(r); 
}

[VB.Net]

Private Sub TChart1_AfterDraw(ByVal sender As Object, ByVal g As Steema.TeeChart.Drawing.Graphics3D) Handles TChart1.AfterDraw 
        Dim S As New Size(100, 100) 
        Dim L As New Point(g.ChartXCenter - (S.Width / 2), g.ChartYCenter - (S.Height / 2)) 
        Dim R As New Rectangle(L, S) 
        g.Pen.Color = Color.Aquamarine 
        g.Brush.Color = Color.Blue 
        g.Rectangle(R) 
End Sub

1.5.2 3D图表

1.5.1 2D图表

在3D图表上,您也可以在Z平面中移动矩形。此示例将矩形放置在左侧壁上,但将其移向图表后部的中间位置(朝向Back Wall),例:

[C#.Net]

private void Form1_Load(object sender, System.EventArgs e) { 
        point3DSeries1.LinePen.Visible = false; 
        point3DSeries1.FillSampleValues(20); 
        point3DSeries1.VertAxis = VerticalAxis.Both; 
        point3DSeries1.HorizAxis = HorizontalAxis.Both; 
        tChart1.Aspect.Chart3DPercent = 50; 
        tChart1.Axes.Depth.Visible = true; 
} 
 
private void tChart1_AfterDraw(object sender, Steema.TeeChart.Drawing.Graphics3D g) { 
        Size s = new Size(100,100); 
        Point l = new Point(tChart1.Axes.Left.Position, g.ChartYCenter - (s.Height / 2)); 
        Rectangle r = new Rectangle(l,s); 
        g.Pen.Color = Color.Aquamarine; 
        g.Brush.Color = Color.Blue; 
        g.Rectangle(r, tChart1.Aspect.Width3D/2); 
}

[VB.Net]

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load 
        Point3DSeries1.LinePen.Visible = False 
        Point3DSeries1.FillSampleValues(20) 
        Point3DSeries1.VertAxis = Steema.TeeChart.VerticalAxis.Both 
        Point3DSeries1.HorizAxis = Steema.TeeChart.HorizontalAxis.Both 
        TChart1.Aspect.Chart3DPercent = 50 
        TChart1.Axes.Depth.Visible = True 
End Sub 
 
Private Sub TChart1_AfterDraw(ByVal sender As Object, ByVal g As Steema.TeeChart.Drawing.Graphics3D) Handles TChart1.AfterDraw 
        Dim S As New Size(100, 100) 
        Dim L As New Point(TChart1.Axes.Left.Position, g.ChartYCenter - (S.Height / 2)) 
        Dim R As New Rectangle(L, S) 
        g.Pen.Color = Color.Aquamarine 
        g.Brush.Color = Color.Blue 
        g.Rectangle(R, TChart1.Aspect.Width3D / 2) 
End Sub

1.6 添加3D形状

您可以将3D形状添加到3D图表中。此示例在Chart矩形的中间绘制一个Cube:

[C#.Net]

private void Form1_Load(object sender, System.EventArgs e) { 
        point3DSeries1.LinePen.Visible = false; 
        point3DSeries1.FillSampleValues(20); 
        tChart1.Aspect.Chart3DPercent = 50; 
        tChart1.Legend.Visible = false; 
        tChart1.Axes.Depth.Visible = true; 
} 
 
private void tChart1_AfterDraw(object sender, Steema.TeeChart.Drawing.Graphics3D g) { 
        Size s = new Size(50,50); 
        Point p = new Point(g.ChartXCenter - (s.Width/2), g.ChartYCenter - (s.Height/2)); 
        Rectangle r = new Rectangle(p,s); 
        g.Cube(r, 0, 20, true); 
}

[VB.Net]

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load 
        Point3DSeries1.LinePen.Visible = False 
        Point3DSeries1.FillSampleValues(20) 
        TChart1.Aspect.Chart3DPercent = 50 
        TChart1.Legend.Visible = False 
        TChart1.Axes.Depth.Visible = True 
End Sub 
 
Private Sub TChart1_AfterDraw(ByVal sender As Object, ByVal g As Steema.TeeChart.Drawing.Graphics3D) Handles TChart1.AfterDraw 
        Dim S As New Size(50, 50) 
        Dim P As New Point(g.ChartXCenter - (S.Width / 2), g.ChartYCenter - (S.Height / 2)) 
        Dim R As New Rectangle(P, S) 
        g.Cube(R, 0, 20, True) 
End Sub

1.7 添加文字

1.7.1 2D文本位置

将文本添加到最后一个矩形,示例:

[C#.Net]

private void tChart1_AfterDraw(object sender, Steema.TeeChart.Drawing.Graphics3D g) { 
        string text = "My Text"; 
        Size s = new Size(150, 50); 
        Point p = new Point(g.ChartXCenter - (s.Width/2), g.ChartYCenter - (s.Height/2)); 
        Rectangle r = new Rectangle(p,s); 
        g.Pen.Color = Color.Blue; 
        g.Rectangle(r); 
 
        g.TextOut(Convert.ToInt32(g.ChartXCenter - (g.TextWidth(text)/2)), Convert.ToInt32(g.ChartYCenter - (g.TextHeight(text)/2)), text); 
}

[VB.Net]

Private Sub TChart1_AfterDraw(ByVal sender As Object, ByVal g As Steema.TeeChart.Drawing.Graphics3D) Handles TChart1.AfterDraw 
        Dim Text As String = "My Text" 
        Dim S As New Size(50, 50) 
        Dim P As New Point(g.ChartXCenter - (S.Width / 2), g.ChartYCenter - (S.Height / 2)) 
        Dim R As New Rectangle(P, S) 
        g.Pen.Color = Color.Blue 
        g.Rectangle(R) 
 
        g.TextOut(Convert.ToInt32(g.ChartXCenter - (g.TextWidth(Text) / 2)), Convert.ToInt32(g.ChartYCenter - (g.TextHeight(Text) / 2)), Text) 
End Sub

1.7.2 3D文字位置

通过使用带有az坐标的TextOut重载,可以将文本放置在不同的3D平面中,例:

[C#.Net]

private void Form1_Load(object sender, System.EventArgs e) { 
        point3DSeries1.FillSampleValues(20); 
        point3DSeries1.LinePen.Visible = false; 
        tChart1.Aspect.Chart3DPercent = 50; 
} 
 
private void tChart1_AfterDraw(object sender, Steema.TeeChart.Drawing.Graphics3D g) { 
        string text = "My Text"; 
        g.TextOut(g.ChartXCenter, g.ChartYCenter, tChart1.Aspect.Width3D / 2, text); 
}

[VB.Net]

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load 
        Point3DSeries1.FillSampleValues(20) 
        Point3DSeries1.LinePen.Visible = False 
        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 Text As String = "My Text" 
        g.TextOut(g.ChartXCenter, g.ChartYCenter, TChart1.Aspect.Width3D / 2, Text) 
End Sub

1.8 应用示例

此示例获取系列的第3和第10个值,在它们之间绘制一条直线,并告诉我们新线的第一个和最后一个点的值以及它们之间的差异,示例:

[C#.Net]

private void Form1_Load(object sender, System.EventArgs e) { 
        tChart1.Aspect.View3D = false; 
        line1.FillSampleValues(20); 
} 
 
private void tChart1_AfterDraw(object sender, Steema.TeeChart.Drawing.Graphics3D g) { 
        if(tChart1.Series.Count > 0){ 
            if(tChart1.Series[0].Count > 10) { 
                Series s = tChart1.Series[0]; 
                int h = Convert.ToInt32(g.TextHeight("H")); 
                Point p1 = new Point(s.CalcXPos(3), s.CalcYPos(3)); 
                Point p2 = new Point(s.CalcXPos(10), s.CalcYPos(10)); 
                g.Pen.Color = Color.Blue; 
                g.Pen.Width = 2; 
                g.Pen.Style = System.Drawing.Drawing2D.DashStyle.Dash; 
                g.MoveTo(p1); 
                g.LineTo(p2, 0); 
                g.TextOut(p1.X, p1.Y - h, "Point value: " + s.YValues[3].ToString()); 
                g.TextOut(p2.X, p2.Y, "Point value: " + s.YValues[10].ToString()); 
                g.TextOut(p2.X, p2.Y + h, "Change is: " + Convert.ToString(s.YValues[3] - s.YValues[10])); 
            } 
        } 
}

[VB.Net]

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load 
        TChart1.Aspect.View3D = False 
        Line1.FillSampleValues(20) 
End Sub 
 
Private Sub TChart1_AfterDraw(ByVal sender As Object, ByVal g As Steema.TeeChart.Drawing.Graphics3D) Handles TChart1.AfterDraw 
        If TChart1.Series.Count > 0 Then 
            If TChart1.Series(0).Count > 10 Then 
                Dim S As Steema.TeeChart.Series = TChart1.Series(0) 
                Dim H As Integer = Convert.ToInt32(g.TextHeight("H")) 
                Dim P1 As New Point(S.CalcXPos(3), S.CalcYPos(3)) 
                Dim P2 As New Point(S.CalcXPos(10), S.CalcYPos(10)) 
                g.Pen.Color = Color.Blue 
                g.Pen.Width = 2 
                g.Pen.Style = System.Drawing.Drawing2D.DashStyle.Dash 
                g.MoveTo(P1) 
                g.LineTo(P2, 0) 
                g.TextOut(P1.X, P1.Y - H, "Point value: " & S.YValues(3)) 
                g.TextOut(P2.X, P2.Y, "Point value: " & S.YValues(10)) 
                g.TextOut(P2.X, P2.Y + H, "Change is: " & (S.YValues(3) - S.YValues(10))) 
            End If 
        End If 
End Sub

猜你喜欢

转载自blog.csdn.net/xiaochuachua/article/details/81565593