Delphi的TCanvas类可以实现各种复杂的图形输出功能,基于近期项目的需求,利用它实现了一个很炫的动态折线图(模拟了资源管理器中CPU使用率的折线图),可以直观地展现出数值的实时变化情况。
这段代码里边有几个核心的地方:
最终的效果如下:
unit
Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls,Contnrs;
const
{* 网格间隔 *}
GridSpace =
12
;
{* 移动步长(能够被间隔整除) *}
MoveStep =
3
;
{* Y轴最大值(最大刻度) *}
MaxY =
100
;
type
TForm1 =
class
(TForm)
Timer1: TTimer;
Button1: TButton;
Image1: TImage;
procedure
DrawPL(Shower:TImage);
procedure
Timer1Timer(Sender: TObject);
procedure
FormCreate(Sender: TObject);
procedure
Button1Click(Sender: TObject);
procedure
FormShow(Sender: TObject);
procedure
FormDestroy(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end
;
var
Form1: TForm1;
{* 网格竖线X坐标数组 *}
GridXPArr:
array
of
Integer
;
{* 点坐标数组 *}
PointLst:
array
of
TPoint;
{* 数值队列 *}
YPQueue: TQueue;
{* 数值指针 *}
PYValue: PInteger;
{* 网格偏移量 *}
X:
Word
;
implementation
{$R *.dfm}
procedure
TForm1
.
Button1Click(Sender: TObject);
var
YValue:
Integer
;
begin
Randomize;
YValue := Random(
100
);
//新Y坐标点按顺序压入队列
New(PYValue);
PYValue^ := YValue;
YPQueue
.
Push(PYValue);
end
;
procedure
TForm1
.
DrawPL(Shower:TImage);
var
Bit: TBitmap;
i:
Integer
;
PW,PH:
Integer
;
YValue:
Integer
;
begin
//偏移量计算
Inc(X);
if
X = GridSpace
div
MoveStep
then
X :=
0
;
//初始化画布(双缓冲)
Bit := TBitmap
.
Create;
try
PW := Shower
.
Width;
PH := Shower
.
Height;
Bit
.
Width := PW;
Bit
.
Height := PH;
//初始化网格竖线X坐标数组长度为宽/间隔+1
SetLength(GridXPArr,PW
div
GridSpace +
1
);
with
Bit
.
Canvas
do
begin
Brush
.
Color := clBlack;
Brush
.
Style := bsSolid;
Rectangle(
0
,
0
,PW,PH);
Pen
.
Color :=
$00408000
;
//画网格,根据偏移量实现动态效果
for
i :=
0
to
PW
div
GridSpace +
1
do
begin
GridXPArr[i] := GridSpace * i - X * MoveStep;
MoveTo(GridXPArr[i],
0
);
LineTo(GridXPArr[i],PH);
end
;
for
i :=
0
to
PH
div
GridSpace
do
begin
MoveTo(
0
,GridSpace * i);
LineTo(PW,GridSpace * i);
end
;
//画折线
Pen
.
Color := clLime;
YValue :=
0
;
//如果队列中有新的Y坐标点,则输出
if
YPQueue
.
Count >
0
then
begin
PYValue := YPQueue
.
Pop;
YValue := PYValue^;
Dispose(PYValue);
end
;
//画笔移动到起点位置
MoveTo(
0
,PH);
//每执行一次函数,Y坐标向前移动一位,并连线各个点
for
i :=
0
to
Length(PointLst) -
2
do
begin
PointLst[i].Y := PointLst[i +
1
].Y;
LineTo(PointLst[i+
1
].X,PointLst[i+
1
].Y);
end
;
//按比例更新最后一位坐标点
PointLst[Length(PointLst)-
1
].X := PW;
PointLst[Length(PointLst)-
1
].Y := PH - (YValue * PH
div
MaxY);
//打印信息(可根据需要调整显示位置和内容)
Brush
.
Style:=bsClear;
Font
.
Color:=clYellow;
TextOut(
10
,
10
,
'数值:'
+inttostr(YValue));
end
;
Shower
.
Canvas
.
Draw(
0
,
0
,Bit);
finally
Bit
.
Free;
end
;
end
;
procedure
TForm1
.
FormCreate(Sender: TObject);
var
i:
Integer
;
begin
YPQueue := TQueue
.
Create;
//初始化坐标点个数为宽/步长+1
SetLength(PointLst,Image1
.
Width
div
MoveStep +
1
);
//初始化坐标点为X轴基线位置
for
i :=
0
to
Length(PointLst) -
1
do
begin
PointLst[i].X := i*MoveStep;
PointLst[i].Y := Image1
.
Height;
end
;
end
;
procedure
TForm1
.
FormDestroy(Sender: TObject);
begin
YPQueue
.
Free;
end
;
procedure
TForm1
.
FormShow(Sender: TObject);
begin
DrawPL(Image1);
end
;
procedure
TForm1
.
Timer1Timer(Sender: TObject);
begin
DrawPL(Image1);
end
;
end
.
Copyright © 2014 DelphiW.com 开发 源码 文档 技巧 All Rights Reserved
晋ICP备14006235号-8 晋公网安备 14108102000087号
执行时间: 0.037150859832764 seconds