logo 【TeeChart VCL/FMX】教程2019 我也要发布文档

(十三):图表面板上的自定义绘图


    TeeChart Pro VCL/FMX是一款主流的图表制作工具。提供了数百种用于可视化的2D、3D图形样式、56种数学、统计和金融函数,以及不限数量的坐标轴和30种调色板组件。TeeChart Pro VCL/FMX教程将会以连载的形式持续为大家带来TeeChart Pro VCL/FMX的使用方法。 

点击下载TeeChart Pro VCL/FMX最新试用版


    本篇教程为大家带来的是TeeChart Pro VCL/FMX中图表面板上的自定义绘图的这一节,TeeChart通过TCanvas3D组件提供广泛的定制绘图设施。 使用Canvas,您可以在Chart Panel/图表面板的任何位置添加形状,线条和文本,并定义其颜色,笔和画笔样式。内容主要分为以下几个部分:

  1. TeeChart Canvas

    绘图顺序和绘图线

    Canvas笔和画笔

    添加2D形状和3D形状

    添加文本

    应用实例

  2. 高级自定义绘图

    组件概述


TeeChart Canvas

绘画顺序

    使用TeeChart的Canvas方法时,请记住绘图顺序很重要。如果在图表上绘制一条线,然后添加系列数据点将会导致线透支,您可以将线放入Series BeforeDrawValues事件中,让线显示在Chart网格上方和Series下方;您可以将线代码放在OnAfterDraw事件中,让线显示在Series上方。

    在顺序上有4个主要图表绘制事件:

  • OnBeforeDrawChart事件

  • OnBeforeDrawAxes事件

  • OnBeforeDrawSeries事件

  • OnAfterDraw事件

绘画线

    在2D图表添加绘画线:

//Draw a Line diagonally from top left to bottom right 
//in the Chart Area of a 2D Chart

With Chart1, ChartRect do
begin
  //Move the pointer to the top left Chart point
  Canvas.MoveTo(Left,Top);
  
  //Draw the Line
  Canvas.LineTo(Right,Bottom);
end;

    在正交三维图表上,由于三维正交的位移问题,轴位置将会偏离图表区域,我们可以相应地移动线路:

//Draw a Line diagonally from top left to bottom right 
//in the Chart Area of a 3D Chart

With Chart1, ChartRect do
begin
  //Move the pointer to the top left Chart point
  Canvas.MoveTo(Left + Width3D,Top - Height3D);

  //Draw the Line + adjustment for 3D displacement
  Canvas.LineTo(Right + Width3D,Bottom - Height3D);
end;

    在3D Nativemode或OpenGL图表上绘制相同的线条(这也适用于2D和3D正交图表):

//Draw a Line diagonally from top left to bottom right 
//in the Chart Area of a 3D Nativemode or OpenGL Chart
With Chart1,Canvas do
begin
  Pen.Color := clBlue;
  Pen.Width := 1;
  Pen.Style := psDot; //Pen must be 1 to use Pen.Style
  Brush.Style := bsClear; //transparency
  //Then draw the Line
  MoveTo3D(ChartRect.Left,ChartRect.Top,0);
  LineTo3D(ChartRect.Right,ChartRect.Bottom,Width3D);
end;

    MoveTo3D和LineTo3D方法识别将会由于使用完整3D应用的Elevation和Rotation而对ChartRect进行的位移。

Canvas笔和画笔

    上面呈现的线是使用在绘画线之前绘制的最后一个对象时的笔和笔刷,那可能不是您想要的的效果,您可以自己定义:

//Define Pen and Brush before drawing the Line
With Chart1,Canvas,ChartRect do
begin
  Pen.Color := clBlue;
  Pen.Width := 1;
  Pen.Style := psDot; //Pen must be 1 to use Pen.Style
  Brush.Style := bsClear; //transparency

  //Then draw the Line
  MoveTo(Left + Width3D,Top - Height3D);
  LineTo(Right + Width3D,Bottom - Height3D);
end;

添加2D形状和3D形状

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

2D图表(3D正交图表仅支持2D形状)

With Chart1, Canvas do
begin
   //prepare Pen and Brush
   Pen.Color := clBlue;
   Pen.Width := 1;
   Pen.Style := psDot;
   Brush.Color := clWhite;
   Brush.Style := bsSolid;

   //You can draw a Rectangle on any Chart (2D or 3D)
   Rectangle(100,100,200,200);
end;

在3D图表上,您也可以在Z平面中移动矩形。

With Chart1,Canvas,ChartRect do
begin
   //prepare Pen and Brush
   Pen.Color := clBlue;
   Pen.Width := 1;
   Pen.Style := psDot;
   Brush.Color := clWhite;
   Brush.Style := bsSolid;
   //Draw Rectangle with Z displacement
   RectangleWithZ(Rect(Left,
	               Top,
		       Left+((Right-Left) div 2),
		       Top+((Bottom-top) div 2)),
		  Width3D div 2);
end;

    可以将3D形状添加到3D图表中,此示例在图表矩形的顶部左侧象限中绘制多维数据集,深度覆盖从墙壁前部到后墙的区域。

With Chart1,Canvas,ChartRect do
begin
   //prepare Pen and Brush
   Pen.Color := clBlue;
   Pen.Width := 1;
   Pen.Style := psDot;
   Brush.Color := clWhite;
   Brush.Style := bsSolid;

   Cube(Left,
        Left+((Right-Left) div 2),
        Top,
        Top+((Bottom-Top) div 2),
        0,
        Width3D,
        True);
end;

添加文本

在2D文本中,您可以将文本添加到矩形:

procedure TForm1.Button1Click(Sender: TObject);
var rectLeft,rectTop,rectRight,rectBottom:Integer;
begin
 With Chart1, Canvas, ChartRect do
 begin
    rectLeft:= Left;
    rectTop:= Top;
    rectRight:= Left + (Right - Left) div 2;
    rectBottom:= Top + (Bottom - Top) div 2;

    //prepare Pen and Brush
    Pen.Color := clBlue;
    Pen.Width := 1;
    Pen.Style := psDot;
    Brush.Color := clWhite;
    Brush.Style := bsSolid;

    //Draw the Rectangle
    Rectangle(rectLeft,rectTop,rectRight,rectBottom);

    //Modify Font
    Font.Color := clRed;

    //add the Text start at the midpoint of the Rectangle
    TextOut(rectLeft + (rectRight - rectLeft) div 2, 
            rectTop + (rectBottom-rectTop) div 2,
            'Hello');
 end;
end;

在3D文本中,您可以使用TextOut3D方法将文本放置在不同的3D平面中。

 With Chart1, Canvas, ChartRect do
 begin
   Brush.Style := bsClear;

   TextOut3D(Left, Top, Width3D div 2, 'Hello');
 end;

应用实例

下方示例获取Series的第3和第10个值,在它们之间绘制一条直线,并告诉我们new Lin的第一个和最后一个点的值以及它们之间的差异:

'First add some data to the empty Chart
procedure TForm1.BitBtn1Click(Sender: TObject);
begin
  Series1.FillSampleValues(20);
end;
//You could put this code in the OnAfterDraw event
procedure TForm1.Chart1AfterDraw(Sender: TObject);
begin
 With Chart1 do
 Begin
   If SeriesCount > 0 Then
   begin
     If Series1.Count > 10 Then
     begin
       //Add some Shapes
       Canvas.Pen.Color := clBlue;
       Canvas.Pen.Width := 1;
       Canvas.Pen.Style := psDot;
       Canvas.Brush.Style := bsClear;
       Canvas.MoveTo (Axes.Bottom.CalcXPosValue(Series1.XValues[3]),
                      Axes.Left.CalcYPosValue(Series1.YValues[3]));
       Canvas.LineTo (Axes.Bottom.CalcXPosValue(Series1.XValues[10]),
                      Axes.Left.CalcYPosValue(Series1.YValues[10]));
       Canvas.Brush.Style := bsSolid;
       Canvas.TextOut(Axes.Bottom.CalcXPosValue(Series1.XValues[3]),
                      Axes.Left.CalcYPosValue(Series1.YValues[3]),
                      'Point value: ' + FloatToStr(Series1.YValues[3]));
       Canvas.TextOut(Axes.Bottom.CalcXPosValue(Series1.XValues[10]),
                      Axes.Left.CalcYPosValue(Series1.YValues[10]),
                      'Point value: ' + FloatToStr(Series1.YValues[10]));
       Canvas.TextOut(Axes.Bottom.CalcXPosValue(Series1.XValues[10]),
                      Axes.Left.CalcYPosValue(Series1.YValues[10]) +
                      Canvas.TextHeight('Any letter'), 'Change is: ' +
                      FloatToStr(Series1.YValues[10] - Series1.YValues[3]));
     end;
   end;
 end;
end;

高级自定义绘图

组件概述

    几乎所有的TeeChart装置现在都使用TeCanvas装置,该单元是一个低级单元,提供封装在新TCanvas3D组件中的所有绘图功能。

    如果使用TeeChart Canvas属性进行特殊的自定义绘图,则应将此单元添加到格式Uses中,使用它是安全的,因为除了普通的Delphi单元之外它没有依赖性。

TCanvas3D类

    此Canvas派生类包含对3D旋转,缩放,滚动和3D基元的支持。它具有虚拟和抽象的所有方法,因此意味着您无法直接使用它,您应该使用实现所有方法和属性的派生类。

    使用此Canvas,Chart组件现在可以支持插件画布,也就是说,您可以在设计时或运行时更改Chart1.Canvas属性,并且所有绘图都将重新定向到新的Canvas:

Chart1.Canvas := TGLCanvas.Create ;   //<-- switches display to OpenGL

TeeChart包括这些新的虚拟画布:

  • TTeeCanvas3D

  • TGLCanvas(用于OpenGL渲染)

    一个新的虚拟Canvas很容易实现,您甚至可以创建一个TVRMLCanvas,它将生成一个包含VRML(虚拟现实)图形指令的ascii文件(或另一个保存到DXF,3DS等)。

    这些画布适用于基类TCustomChart,因此它们适用于TChart,TDBChart,TQRChart或任何其他派生的Chart类。

注意:OpenGL DLL仅适用于32位Windows,因此也适用于GLCanvas。

TTeeCanvas3D类:

    这是内部使用的虚拟TCanvas3D类的实现,它是标准Delphi TCanvas类的包装器。它有许多直接调用Windows GDI来加速绘图的工具,它增加了TCanvas3D的功能,如旋转,缩放等。它适用于所有Delphi和C ++ Builder版本。

TGLCanvas类:

    此类驻留在单独的单元/包中,以使应用程序独立于OpenGL的DLL,它仅适用于32位Delphi(和C ++ Builder)。当使用TGLCanvas作为图表时,包括使用TeeGLEditor,图表编辑器将在运行时添加另一个页面以更改GL特征,例如灯光位置和颜色,要使OpenGL在设计时可用,请将TTeeOpenGL组件添加到Form,将其与Chart关联并设置为 Active:= True。

    新的非可视组件(TTeeOpenGL),允许您在设计或运行时将现有图表连接到它,并立即看到使用OpenGL 3D库所呈现的图表,此组件还允许您定义OpenGL特定属性,如Lighting属性。

TTeeCanvas3D和TGLCanvas之间的比较:

  •     OpenGL画布支持照明(灯光,灯光颜色,位置等),而TeeCanvas使用较暗的颜色绘制3D来模拟光照。

  •     OpenGL画布不支持 metafile 创建,因此对于打印,应该创建一个大而胖的TBitmap并将其发送到打印机Canvas,这意味着它只适用于具有良好内存和优良驱动程序的打印机,它无法创建,复制到剪贴板,保存或打印metafile。

  •     OpenGL画布需要OpenGL DLL(在Windows NT及更高版本中可用,以及www.sgi.com的替代库)。如果您的CPU和视频硬件良好,Silicon Graphics的OpenGL Dlls可能比Microsoft的更快。

  •     OpenGL画布支持不同的字体大小和颜色,但它不支持多种字体样式,字体的所有字符都将转换为绘图指令,这占用了相当多的内存和CPU速度。 


   TeeChart for .NETTeeChart for JavaScript/HTML5TeeChart for Xamarin.Android均已加入在线订购,现在抢购可立享特别优惠!!!

    关注慧聚IT微信公众号???,了解产品的最新动态及最新资讯。

dd2629f30d553d56ccaf7164fdcb784e-sz_28327.webp.jpg