Difference between revisions of "BGRABitmap tutorial TAChart"

From Lazarus wiki
Jump to navigationJump to search
 
(13 intermediate revisions by 4 users not shown)
Line 1: Line 1:
You can make beautiful charts using BGRABitmap.
+
{{BGRABitmap tutorial TAChart}}
  
=== BGRA rendering ===
+
You can make beautiful charts using [[BGRABitmap]]. Add TAChartBGRA package with the project inspector.
  
First add the TAChartBGRA package. To render your chart, you can for example use a PaintBox. In the OnPaint event, write :
+
Maybe the package will not appear in the list or will not be installed. In this case, open it manually with the menu Package, Open package file (.lpk). It must be in  ''component\tachart''. Then click on the button to install the package.
<syntaxhighlight>
+
 
 +
== Add a TAChart ==
 +
 
 +
[[TAChart]] in fact has the classname TChart. To add a chart, browse the components, choose Chart tab and click on TChart icon. Click and draw a rectangle on the window to drop it.
 +
 
 +
In order to supply data, click on TRandomChartSource component icon and click once in the window to drop it. In the Object Inspector, define PointsNumber to 10, XMax to 10 and YMax to 10.
 +
 
 +
Now let's create a series that uses this source. To do that, click on your chart and in the Object Inspector, go to Series property. Click on the three dots, and add a ''Bar series''. In its properties, go to Source property and choose RandomChartSource1. The chart should be filled with red bars.
 +
 
 +
[[Image:tachartrandombars.png]]
 +
 
 +
As we are going to do some 3D, we need some depth. So set the Depth property of the series to 10.
 +
 
 +
[[Image:tachartrandombars3D.png]]
 +
 
 +
Finally, click on the chart and set the Align property to alClient in order to fill the window.
 +
 
 +
== Decorate in normal rendering mode ==
 +
 
 +
Go to the <tt>Series</tt> property of your chart. Choose the bar series, and in the Object Inspector, go to the events and define a handler for the event <tt>OnCustomDrawBar</tt>. Add the following code:
 +
 
 +
<syntaxhighlight lang="pascal">
 +
uses
 +
  TADrawUtils, TADrawerCanvas, TABGRAUtils;
 +
 
 +
procedure TForm1.Chart1BarSeries1CustomDrawBar(ASeries: TBarSeries;
 +
  ADrawer: IChartDrawer; const ARect: TRect; APointIndex, AStackIndex: Integer);
 +
var
 +
  ic: IChartTCanvasDrawer;
 +
begin
 +
  if not Supports(ADrawer, IChartTCanvasDrawer, ic) then
 +
    raise Exception.Create('This program requires a canvas drawer.');
 +
 
 +
  DrawPhong3DBar(ASeries, ic.Canvas, ARect, APointIndex);
 +
end;
 +
</syntaxhighlight>
 +
 
 +
{{Note|This code is valid for Lazarus v2.2+. In older versions, the event <tt>TBarSeries.OnBeforeDrawBar</tt> had to be used instead:
 +
<syntaxhighlight lang="pascal">
 +
uses
 +
  TABGRAUtils;
 +
 
 +
procedure TForm1.BeforeDrawBarHandler(ASender: TBarSeries; ACanvas: TCanvas;
 +
  const ARect: TRect; APointIndex, AStackIndex: Integer; var ADoDefaultDrawing: Boolean);
 +
begin
 +
  ADoDefaultDrawing:= false;
 +
  DrawPhong3DBar(ASender, ACanvas, ARect, APointIndex);
 +
end;</syntaxhighlight>}}
 +
 
 +
Then run the program. Your chart should look like this:
 +
 
 +
[[Image:chartwithbgra.png]]
 +
 
 +
You can also use the <tt>DrawChocolateBar</tt> function. Set <tt>PointsNumber</tt> property of the <tt>RandomChartSource1</tt> to 5. Change the code of the <tt>OnCustomDrawBar</tt> (for Laz 2.2+, or <tt>OnBeforeDrawBar</tt> for older versions) to:
 +
 
 +
<syntaxhighlight lang="pascal">
 +
uses
 +
  TADrawUtils, TADrawerCanvas, TABGRAUtils;
 +
 
 +
procedure TForm1.Chart1BarSeries1CustomDrawBar(ASeries: TBarSeries;
 +
  ADrawer: IChartDrawer; const ARect: TRect; APointIndex, AStackIndex: Integer);
 +
var
 +
  ic: IChartTCanvasDrawer;
 +
begin
 +
  if not Supports(ADrawer, IChartTCanvasDrawer, ic) then
 +
    raise Exception.Create('This program requires a canvas drawer.');
 +
 
 +
  DrawChocolateBar(ASeries, icCanvas, ARect, APointIndex, True);
 +
end;
 +
 
 +
{ or for Lazarus before v2.2:
 +
 
 +
procedure TForm1.BeforeDrawBarHandler(ASender: TBarSeries; ACanvas: TCanvas;
 +
  const ARect: TRect; APointIndex, AStackIndex: Integer;
 +
  var ADoDefaultDrawing: Boolean);
 +
begin
 +
  ADoDefaultDrawing:= false;
 +
  DrawChocolateBar(ASender, ACanvas, ARect, APointIndex, True);
 +
end;}
 +
</syntaxhighlight>
 +
 
 +
[[Image:chartwithbgrachocolate.png]]
 +
 
 +
== Using BGRABitmap to render the whole chart ==
 +
 
 +
Bars are not very different with or without antialiasing. Go to the Series property and remove the bars, add a ''Line series'', and set its Source to RandomChartSource1. Then, set its property Depth to 10 and its SeriesColor property to clRed.
 +
 
 +
[[Image:tachartlines3D.png]]
 +
 
 +
In order to change the rendering engine, look for the TChartGUIConnectorBGRA component in the Chart tab. Click to drop it on the chart. Then, click on the chart background and with the object inspector, set the GUIConnector property by choosing ChartGUIConnectorBGRA1. The rendering is now done with antialiasing, no need to start the program to see:
 +
 
 +
[[Image:tachartlines3Dbgra.png]]
 +
 
 +
== Drawing a chart on any Canvas ==
 +
=== Simple drawing ===
 +
 
 +
First add the TAChartBGRA package. To render your chart, you can for example use a PaintBox. In the OnPaint event, write:
 +
 
 +
<syntaxhighlight lang="pascal">
 
uses BGRABitmap, TADrawerBGRA;
 
uses BGRABitmap, TADrawerBGRA;
  
Line 30: Line 128:
  
 
[[Image:chartbgra.png]]
 
[[Image:chartbgra.png]]
 +
 +
To avoid flickering, consider using TBGRAVirtualScreen from [[BGRAControls]].
  
 
=== Text effects ===
 
=== Text effects ===
  
To add text effect, you need the latest version of BGRABitmap, and the latest SVN of Lazarus. There is a FontRenderer property in each TBGRABitmap image, that you can define. You must not free the renderer, as it is automatically freed by the image.
+
To add text effects, you need the latest version of BGRABitmap, and the latest SVN of Lazarus. There is a FontRenderer property in each TBGRABitmap image, that you can define. You must not free the renderer, as it is automatically freed by the image.
  
The text effects are provided by the BGRATextFX unit that contains the TBGRATextEffectFontRenderer class. To add a golden contour to the letters and a shadow, add the following lines :
+
The text effects are provided by the BGRATextFX unit that contains the TBGRATextEffectFontRenderer class. To add a golden contour to the letters and a shadow, add the following lines:
<syntaxhighlight>
+
 
 +
<syntaxhighlight lang="pascal">
 +
uses BGRATextFX, BGRAGradientScanner;
 +
...
 
var
 
var
 
   ...
 
   ...
Line 54: Line 157:
 
end;</syntaxhighlight>
 
end;</syntaxhighlight>
 
[[Image:chartbgrafonteffect.png]]
 
[[Image:chartbgrafonteffect.png]]
 +
 +
[[Category:Tutorials]]
 +
[[Category:Lazarus]]
 +
[[Category:TAChart]]
 +
[[Category:BGRABitmap]]

Latest revision as of 19:27, 9 January 2022

English (en) français (fr)

You can make beautiful charts using BGRABitmap. Add TAChartBGRA package with the project inspector.

Maybe the package will not appear in the list or will not be installed. In this case, open it manually with the menu Package, Open package file (.lpk). It must be in component\tachart. Then click on the button to install the package.

Add a TAChart

TAChart in fact has the classname TChart. To add a chart, browse the components, choose Chart tab and click on TChart icon. Click and draw a rectangle on the window to drop it.

In order to supply data, click on TRandomChartSource component icon and click once in the window to drop it. In the Object Inspector, define PointsNumber to 10, XMax to 10 and YMax to 10.

Now let's create a series that uses this source. To do that, click on your chart and in the Object Inspector, go to Series property. Click on the three dots, and add a Bar series. In its properties, go to Source property and choose RandomChartSource1. The chart should be filled with red bars.

tachartrandombars.png

As we are going to do some 3D, we need some depth. So set the Depth property of the series to 10.

tachartrandombars3D.png

Finally, click on the chart and set the Align property to alClient in order to fill the window.

Decorate in normal rendering mode

Go to the Series property of your chart. Choose the bar series, and in the Object Inspector, go to the events and define a handler for the event OnCustomDrawBar. Add the following code:

uses 
  TADrawUtils, TADrawerCanvas, TABGRAUtils;

procedure TForm1.Chart1BarSeries1CustomDrawBar(ASeries: TBarSeries; 
  ADrawer: IChartDrawer; const ARect: TRect; APointIndex, AStackIndex: Integer);
var
  ic: IChartTCanvasDrawer;
begin
  if not Supports(ADrawer, IChartTCanvasDrawer, ic) then
    raise Exception.Create('This program requires a canvas drawer.');

  DrawPhong3DBar(ASeries, ic.Canvas, ARect, APointIndex);
end;

Light bulb  Note: This code is valid for Lazarus v2.2+. In older versions, the event TBarSeries.OnBeforeDrawBar had to be used instead:

uses
  TABGRAUtils;

procedure TForm1.BeforeDrawBarHandler(ASender: TBarSeries; ACanvas: TCanvas;
  const ARect: TRect; APointIndex, AStackIndex: Integer; var ADoDefaultDrawing: Boolean);
begin
  ADoDefaultDrawing:= false;
  DrawPhong3DBar(ASender, ACanvas, ARect, APointIndex);
end;

Then run the program. Your chart should look like this:

chartwithbgra.png

You can also use the DrawChocolateBar function. Set PointsNumber property of the RandomChartSource1 to 5. Change the code of the OnCustomDrawBar (for Laz 2.2+, or OnBeforeDrawBar for older versions) to:

uses 
  TADrawUtils, TADrawerCanvas, TABGRAUtils;

procedure TForm1.Chart1BarSeries1CustomDrawBar(ASeries: TBarSeries; 
  ADrawer: IChartDrawer; const ARect: TRect; APointIndex, AStackIndex: Integer);
var
  ic: IChartTCanvasDrawer;
begin
  if not Supports(ADrawer, IChartTCanvasDrawer, ic) then
    raise Exception.Create('This program requires a canvas drawer.');

  DrawChocolateBar(ASeries, icCanvas, ARect, APointIndex, True);
end;

{ or for Lazarus before v2.2:

procedure TForm1.BeforeDrawBarHandler(ASender: TBarSeries; ACanvas: TCanvas;
  const ARect: TRect; APointIndex, AStackIndex: Integer;
  var ADoDefaultDrawing: Boolean);
begin
  ADoDefaultDrawing:= false;
  DrawChocolateBar(ASender, ACanvas, ARect, APointIndex, True);
end;}

chartwithbgrachocolate.png

Using BGRABitmap to render the whole chart

Bars are not very different with or without antialiasing. Go to the Series property and remove the bars, add a Line series, and set its Source to RandomChartSource1. Then, set its property Depth to 10 and its SeriesColor property to clRed.

tachartlines3D.png

In order to change the rendering engine, look for the TChartGUIConnectorBGRA component in the Chart tab. Click to drop it on the chart. Then, click on the chart background and with the object inspector, set the GUIConnector property by choosing ChartGUIConnectorBGRA1. The rendering is now done with antialiasing, no need to start the program to see:

tachartlines3Dbgra.png

Drawing a chart on any Canvas

Simple drawing

First add the TAChartBGRA package. To render your chart, you can for example use a PaintBox. In the OnPaint event, write:

uses BGRABitmap, TADrawerBGRA;

procedure TForm1.PaintBox1Paint(Sender: TObject);
var
  bmp: TBGRABitmap;
  id: IChartDrawer;
  rp: TChartRenderingParams;
begin
  bmp := TBGRABitmap.Create(PaintBox1.Width, PaintBox1.Height);
  Chart1.DisableRedrawing;
  try
    id := TBGRABitmapDrawer.Create(bmp);
    id.DoGetFontOrientation := @CanvasGetFontOrientationFunc;
    rp := Chart1.RenderingParams;
    Chart1.Draw(id, Rect(0, 0, PaintBox1.Width, PaintBox1.Height));
    Chart1.RenderingParams := rp;
    bmp.Draw(PaintBox1.Canvas, 0, 0);
  finally
    Chart1.EnableRedrawing;
    bmp.Free;
  end;
end;

chartbgra.png

To avoid flickering, consider using TBGRAVirtualScreen from BGRAControls.

Text effects

To add text effects, you need the latest version of BGRABitmap, and the latest SVN of Lazarus. There is a FontRenderer property in each TBGRABitmap image, that you can define. You must not free the renderer, as it is automatically freed by the image.

The text effects are provided by the BGRATextFX unit that contains the TBGRATextEffectFontRenderer class. To add a golden contour to the letters and a shadow, add the following lines:

uses BGRATextFX, BGRAGradientScanner;
...
var
  ...
  fontRenderer: TBGRATextEffectFontRenderer;
  gold: TBGRAGradientScanner;
begin
  ...
  fontRenderer:= TBGRATextEffectFontRenderer.Create;
  fontRenderer.ShadowVisible := true;     //adds a shadow
  fontRenderer.OutlineVisible := true;    //show the outline
  gold := TBGRAGradientScanner.Create(CSSGold,CSSGoldenrod,gtLinear,PointF(0,0),PointF(20,20),true,true);
  fontRenderer.OutlineTexture := gold;    //define the texture used for the outline
  fontRenderer.OuterOutlineOnly := true;  //just the outer pixels of the text
  bmp.FontRenderer := fontRenderer;       //gives the FontRenderer to the image (which becomes the owner of the renderer)
  ...
  gold.Free;
end;

chartbgrafonteffect.png