| Simple Bar Chart | Lab Report |
| Create a Simple Bar Chart from "Scratch" Delphi 7 VCL Version for Windows |
||
![]() |
||
|
Delphi 7/Windows or Kylix 3/Linux CLX Version |
||
|
|
||
Purpose
The Simple Bar Chart shows how to create a simple bar
chart graphic and display it, or write it to a BMP disk file, using either the Delphi
Visual Component Library (VCL) (Windows only) or Kylix Cross Platform (CLX)
Objects for Windows or Linux.
Materials and Equipment
Software Requirements
Windows 95/98/2000, Delphi 3/4/5/6/7 or
Linux and Kylix (tested with Red Hat 7.2 and Kylix 3)
SimpleBarChart exectuableHardware Requirements
VGA display.
Procedure
Discussion
This project was one of my first attempts to convert a Delphi VCL program
to a Delphi/Kylix CLX program. [VCL programs can only run in
Windows while a Cross Platform (CLX) program can run in Windows or Linux.] The original conversion was from Delphi 5
VCL to Kylix 1 CLX. My
original intent was to use IFDEFs to keep one source program that could be
compiled in Delphi or Kylix. This seemed to work with Delphi 5 VCL and
Kylix 1 CLX, but I have not found a convenient way to use either VCL or CLX
under Windows, and CLX under Kylix. Now I keep separate source files for
VCL and CLX versions. Differences between the VCL and CLX versions will be
described below.
The uses statement in the project file (.dpr) uses the "Q" library for the CLX version:
|
SimpleBarChart.dpr Project File: uses Statement |
|
| CLX |
uses
QForms,
ScreenSimpleBarChart in 'ScreenSimpleBarChart.pas' {FormBarChart};
|
| VCL |
uses
Forms,
ScreenSimpleBarChart in 'ScreenSimpleBarChart.pas' {FormBarChart};
|
The form file was named ScreenSimpleBarChart.dfm in Delphi/VCL and ScreenSimpleBarChart.xfm in Kylix/CLX. Several changes were needed for Kylix to make sure the unit names and the files had the same case since (Kylix is case sensitive but Delphi is not.
The code for the ScreenSimpleBarChart form is in the SimpleBarChart.pas file. In this file, the DrawBarChart procedure is used to draw on any canvas, namely, the Image.Canvas or the Bitmap.Canvas. So a single routine can be used for a screen display or a file (or could also be used for printing). The HeightPercent and WidthPercent functions create device-independent drawings by determining the number of pixels a certain certain percentage of canvas height or width something is.
The first CLX/VCL difference is in the uses statement:
|
SimpleBarChart.pas Project File: uses Statement |
|
| CLX |
uses SysUtils, Types, Classes, Variants, QGraphics, QControls, QForms, QDialogs, QStdCtrls, QExtCtrls; |
| VCL |
uses SysUtils, WinProcs, Messages, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Buttons, ExtCtrls; |
Besides the difference in the name of form files with CLX (*.xfm) and with VCL (*.dfm), an "RGB" function must be provided for the CLX environment:
|
SimpleBarChart.pas Project File: Implementation Difference |
|
| CLX |
{$R *.xfm}
// Delphi Windows unit function missing in Kylix
FUNCTION RGB(CONST r,g,b: BYTE): TColor;
BEGIN
RESULT := (r OR (g SHL 8) OR (b SHL 16))
END {RGB};
|
| VCL |
{$R *.dfm}
|
I normally design forms to be a fixed size such that there is no need to resize the form at run time. This can be easily implemented in Delphi VCL by setting the form's BorderStyle to bsSingle. A different approach is needed with CLX. The following code in a form's create method prevents any resizing:
|
SimpleBarChart.pas Project File: FormCreate Difference |
|
| CLX |
procedure TFormBarChart.FormCreate(Sender: TObject);
...
begin
// Need this in CLX to prevent resizing form
WITH FormBarChart.Constraints DO
BEGIN
MaxHeight := Height;
MaxWidth := Width;
MinHeight := Height;
MinWidth := Width;
END;
|
| VCL |
// Set form's BorderStyle to bsSingle in IDE |
A minor CLX/VCL difference was needed in
|
SimpleBarChart.pas Project File: TBitmap.PixelFormat |
|
| CLX |
Bitmap.PixelFormat := pf32bit; // No pf24bit PixelFormat in Kylix |
| VCL |
Bitmap.PixelFormat := pf24bit; // avoid working with palettes |
I try to always use pf24bit bitmaps in Windows, since they're smaller than pf32bit bitmaps. Unfortunately, CLX only supports pf32bit TBitmaps.
Certain graphics operations needed to be "tweaked" to get the same results in Delphi and Kylix. During the first conversion attempt, Delphi showed a white background and Kylix showed a black background. The FillRect code shown below was added to both versions to always establish the background color.
The DrawBarChart procedure shown above was called to draw the graphics on any canvas in a device-independent way. Here the complete VCL source code for this procedure (the CLX version is quite similar):
|
SimpleBarChart.pas Project File: FormCreate Difference |
|
| VCL |
PROCEDURE DrawBarChart (Canvas: TCanvas; Width, Height: INTEGER);
CONST
BarWidth = 5; // bar width is 5%
Reserved = 5; // reserve 5% margin
TextHeight = 8; // text height is 8%
VAR
iBase : INTEGER;
iWidth : INTEGER;
jBase : INTEGER;
jHeight: INTEGER;
j : INTEGER;
FUNCTION WidthPercent(CONST percent: INTEGER): INTEGER;
BEGIN
RESULT := iBase + MulDiv(iWidth, percent, 100)
END;
FUNCTION HeightPercent(CONST percent: INTEGER): INTEGER;
BEGIN
// '-' sign here to flip "Y" since "Y" goes from top to bottom
RESULT := jBase - MulDiv(jHeight, percent, 100)
END;
PROCEDURE DrawBar(CONST BarColor, OutlineColor: TColor; CONST X, height: INTEGER);
BEGIN
Canvas.Brush.Color := BarColor;
Canvas.Pen.Color := OutlineColor;
// Use 100-height since "Y" values are top to bottom
Canvas.Rectangle( WidthPercent(X), HeightPercent(height),
WidthPercent(X+BarWidth), HeightPercent(0) );
END;
BEGIN
iBase := MulDiv(Width, Reserved, 100); // 5% margin
jBase := Height - MulDiv(Height, Reserved, 100);
iWidth := Width - 2*MulDiv(Width, Reserved, 100); // 90% working area
jHeight := Height - 2*MulDiv(Height, Reserved, 100);
// In Delphi, the background of a new canvas is normally white.
// For Kylix compatibility, the following was added to avoid a black
// background.
Canvas.Brush.Color := clWhite;
Canvas.FillRect(Canvas.ClipRect);
Canvas.Brush.Style := bsClear;
Canvas.Font.Name := 'Arial';
Canvas.Font.Height := MulDiv(jHeight, TextHeight, 100);
Canvas.TextOut(iBase, MulDiv(jHeight, Reserved, 100), 'Simple Bar Chart');
// Draw Horizontal Reference Lines at 20% intervals
Canvas.Pen.Color := clBlack;
FOR j := 0 TO 5 DO
BEGIN
Canvas.MoveTo ( iBase, HeightPercent(20*j) );
Canvas.LineTo ( iBase+iWidth, HeightPercent(20*j) )
END;
// Unclear why this is needed in Kylix but not D3
Canvas.Brush.Style := bsSolid;
DrawBar(clYellow, clRed, 0, 12);
DrawBar(clRed, clRed, 10, 80);
DrawBar(clBlue, clBlue, 20, 40);
// Use RGB function to define a dark shade of Gray
DrawBar(RGB({Red} 100, {Green} 100, {Blue} 100), clBlack, 30, 50);
DrawBar(clRed, clBlue, 40, 90);
DrawBar(clWhite, clRed, 50, 65);
Canvas.Brush.Style := bsDiagCross;
DrawBar(clLime, clRed, 60, 75);
Canvas.Brush.Style := bsSolid;
DrawBar(clLime, clLime, 70, 22);
END {DrawBarChart};
|
Here's a summary of the changes D3 VCL to convert to K1 CLX:
In D3, fix all case sensitivity differences in unit names.
Rename *.dfm to *.xfm
Load project in Kylix. Ignore the error:
"Error reading FormBarChart.BorderStyle: Invalid property value."
For FormBarChart, change Scaled property to False, and AutoScroll to False
Reset form's icon by setting the Icon property to SimpleBarChart.ico
The following chart summarizes the "bloat" by version of Delphi/Kylix: for the SimpleBarChart executable. I really wish Borland would stop this code bloat.
Summary of Executable Size
| Version | Size[KB] |
| D3 VCL | 221 |
| D4 VCL | 312 |
| D5 VCL | 324 |
| D6 VCL | 389 |
| D7 VCL | 393 |
| D7 CLX | 654 |
| Kylix 1 CLX | 415 |
| Kylix 3 CLX | 798 |
Conclusions
This example shows how to create a bar chart graphic
"from scratch".
In Delphi 3 or later for more complicated examples, the TChart component is probably a better alternative. (TChart is not available in Kylix).
Keywords
Canvas, Brush.Color, Pen.Color, Rectangle, FillRect, Delphi/VCL, Kylix/CLX
Download
VCL: Delphi 3..7 Source and EXE (212 KB) for
Windows: SimpleBarChartVCL.zip
CLX: Delphi 7/Kylix 3 Source
and Red Hat Linux executable (352 KB): SimpleBarChart.tar.gz
In Linux to extract files: gunzip <
SimpleBarChart.tar.gz | tar xvf -
See Kylix
Deployment Notes for "Hello World" for deployment of CLX
applications in Linux or to get the needed DLL for Windows.
Updated
26 Feb 2005
since 1 Nov 1998