Contents page 
  Previous | Next 
 

Tutorial 13 - Custom drawing on the Chart Panel


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
Drawing Lines
Canvas Pen and Brush
Adding 2D Shapes
Adding 3D Shapes
Adding text
Applied example

Advanced custom drawing

Component overview


TeeChart Canvas

Drawing order

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

Drawing Lines

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.

Canvas Pen and Brush

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;

Adding 2D Shapes

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.

Example
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;

Adding 3D Shapes

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;

Adding text

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.

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

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

Applied example

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;

Advanced custom drawing

Component overview

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:

 




© 1996- Steema Software SL. All rights reserved.