![]() |
Contents page Previous | Next |
TeeChart offers extensive custom drawing facilities via the TCanvas3D component. With Canvas you may add shapes, lines and text anywhere on the Chart Panel and define their colours, pen and brush styles.
Contents |
TeeChart Canvas
Drawing order Advanced custom drawing |
When using TeeChart's Canvas methods remember that drawing order is important. Drawing a Line on the Chart then adding Series data points will cause the Line to be overdrawn. You could put the Line in the Series BeforeDrawValues event for the Line to appear above the Chart grid and below the Series. You could place the Line code in the OnAfterDraw event for the Line to appear above the Series.
Event order, 4 principle Chart draw events
2D Chart
Let's add a Canvas Line:
Example
//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;
3D Orthogonal Chart
On an Orthogonal 3D Chart the Axis positions are offset from the Chart area due to 3D orthogonal displacement. We can move the Line accordingly:
Example
//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 or OpenGL Chart
To draw the same line on a Native 3D Chart or OpenGL Chart (This will also work on a 2D and 3D Orthogonal Chart):
//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 and LineTo3D methods recognise the displacement made to the ChartRect as a result of Elevation and Rotation applied with 'Full' 3D.
The Line above is drawn using the Pen and Brush defined for the last object drawn before the Line is drawn. That may or may not be the Pen you want. You can change the Pen accordingly:
Example
//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;
Add 2D Canvas Shapes in a similar manner to Canvas Lines. The following example adds a Rectangle in the centre of the Chart Area:
2D Chart
3D orthogonal Charts support only 2D shapes.
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 Charts
On a 3D Chart you can move the Rectangle in a Z plane too. See the RectangleWithZ method. This example for an orthogonal or Nativemode/OpenGL Chart places the Rectangle on the Left Wall but displaces it halfway towards the rear of the Chart (towards the Back Wall).
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;
You may add 3D shapes to 3D Charts. This example draws a Cube in the top, left quadrant of the Chart rectangle. The depth covers the area from the front of the Walls to the Back Wall. See the Cube method.
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 Text location
Add Text to a Rectangle:
Example
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 Text location
You can place Text in a differing 3D plane by using the TextOut3D method.
With Chart1, Canvas, ChartRect do begin Brush.Style := bsClear; TextOut3D(Left, Top, Width3D div 2, 'Hello'); end;
This example takes the 3rd and 10th values of a Series, plots a Line between them and tells us the value of the first and Last point of the new Line and the difference between them:
Example
'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;
Almost all TeeChart units use now the TeCanvas unit.
This unit is a low-level unit that provides all drawing functions encapsulated
in the new TCanvas3D component.
If you do special customized drawing using the TeeChart Canvas property, you should add this unit to your Forms "Uses" clause. It is safe to use it as it has no dependencies other than the normal Delphi units.
TCanvas3D class
This Canvas-derived class incorporates support for 3D rotation, zoom, scroll and 3D primitives. It has all methods virtual and abstract, so it means you can not use it directly. You should use a derived class which implements all methods and properties.
Using this Canvas, the Chart components can now support "plug-in" Canvases. That is, you can change at design-time or run-time the "Chart1.Canvas" property, and all drawing will be redirected to the new Canvas:
Chart1.Canvas := TGLCanvas.Create ; //<-- switches display to OpenGL
TeeChart includes these new virtual Canvases:
Implementing a new virtual Canvas, though not trivial, should be quite easy to do. You can even create, for example, a TVRMLCanvas, which will generate an ascii file containing VRML (Virtual Reality) graphic instructions. ( Or another to save to DXF, 3DS, etc ).
These Canvases apply to the base class TCustomChart, so they work for TChart, TDBChart, TQRChart or any other derived Chart class.
Note: OpenGL DLL's are only for 32bit Windows, hence too, the GLCanvas.
TTeeCanvas3D class:
This is the implementation of the virtual TCanvas3D class used internally. It is a wrapper around a standard
Delphi TCanvas class. It has many direct calls to Windows GDI to speed up drawing.
It adds the TCanvas3D features like rotation, zoom, etc. It works with all Delphi and C++Builder versions.
TGLCanvas class:
This class resides in a separate unit / package to make applications independant
of OpenGL's DLLs. It works only for 32bit Delphi
(and C++Builder ). When using the TGLCanvas for a Chart include 'Uses TeeGLEditor'
and the Chart Editor will add another page at runtime to change GL
characteristics such as Light location and colour. For OpenGL to be available at
designtime, add the TTeeOpenGL component to the Form, associate it with the
Chart and set Active:=True.
There is a new non-visual component ( TTeeOpenGL ), that allows you to "connect" an existing Chart to it at design or run-time, and immediately see the Chart rendered using OpenGL 3D libraries. This component allows you to also define OpenGL specific properties, like Lighting attributes.
Comparison between TTeeCanvas3D and TGLCanvas:
![]() |
![]() |