实例位置:光盘/mr/5/5.5/01
本实例是对商品的销售情况进行实时动态分析,以秒为单位,将商品的销售金额在图表中进行显示,这样,决策者可以更直观的了解最新的商品销售动态。商品销售情况的效果图,如图5.56所示。
图5.56 商品销售情况动态实时分析图
程序窗体相关组件的说明,如表5.34所示。
表5.34 窗体的相关组件
对象名 |
对象类型 |
属性 |
值 |
Form1 |
TForm |
Caption |
商品销售情况 |
PageControl1 |
PageControl |
ActivePage |
TabSheet1、TabSheet2 |
TabSheet1 |
TTabSheet |
Caption |
商品销售动态图表 |
Chart1 |
TChart |
Align |
alClient |
TabSheet2 |
TTabSheet |
Caption |
商品销售表 |
DBGrid1 |
TDBGrid |
Align |
alClient |
Timer1 |
TTimer |
Enabled |
False |
Interval |
300 |
||
Timer2 |
Enabled |
False |
|
Interval |
1000 |
下面对本实例的制作过程进行说明。
在窗体创建时,为了避免图表中的数据在发生变化时,改变Y轴的最大数据量,可以设置Y轴的最大值。在运行程序时,如果数据库中的最后一条记录是当天录入的,添加数据的编号则从该记录继续往下排,否则从编号1重新排列。代码如下:
procedure TForm1.FormCreate(Sender: TObject);
var
i : Integer;
TabToDay : String;
begin
ToSum := 59;
Chart1.LeftAxis.Automatic := False; //使Y轴的最大值不自动设置
Chart1.LeftAxis.Maximum := 10000; //设置Y轴的最大值
with Chart1.Series[0] do
for i:=0 to ToSum do //为了能够使数据从右向左进行移动,在图表上显示指定个数的数据
ADDXY(i,0,' ',clred);
for i:=0 to Length(ACommoDityName)-1 do
ACommoDityName[i] := char(65+i);
with DataModule1.ADOQuery1 do
begin
Close;
SQL.Clear;
SQL.Add('Select * from tb_DistRealTime');
Open;
Last;
end;
DateTimeToString(TodayIs,'YYYYMMDD',date()); //获取系统的当前时间
//获取数据表中最后一条记录的时间
DateTimeToString(TabToDay,'YYYYMMDD',DataModule1.ADOQuery1.fieldByName
('Dist_Date').AsDateTime);
if TodayIs=TabToDay then //判断数据表中的最后一条记录是不是今天输入的记录
ToID := StrToInt(Copy((DataModule1.ADOQuery1.fieldByName('ID').AsString),9,8))+1
else
ToID := 1;
Timer1.Enabled := True;
Timer2.Enabled := True;
ToDate := now();
DBGrid1.DataSource := DataModule1.DataSource1;
end;
因为条件有限,本实例不可能以手动的方式在每秒中添加多个记录,在这里用Timer1组件以随机的方式向数据库里添加数据。代码如下:
procedure TForm1.Timer1Timer(Sender: TObject); //向数据库中添加数据
begin
with DataModule1.ADOQuery2 do
begin
Close;
SQL.Clear;
SQL.Add('Select * from tb_DistRealTime');
Open;
Last;
OToDate := FieldByName('Dist_Date').AsDateTime; //获取数据表中最后一条记录的时间
end;
with DataModule1.ADOQuery1 do
begin
Insert;
FieldByName('ID').AsString := TodayIs+Format('%.8d',[ToID]);
FieldByName('Dist_Name').AsString := ACommoDityName[Random(25)];
FieldByName('Dist_Money').AsFloat := Random(3000);
FieldByName('Dist_Date').AsDateTime := now();
Prior;
end;
NToDate := Now(); //获取当前系统时间
if NToDate<>OToDate then //用来当前数据的最新时间
ToDate := OToDate
else
ToDate := NToDate;
ToID := ToID+1;
end;
用Timer2组件对数据库中同一时间段中商品的销售金额以秒为单位进行汇总,并将结果添加到图表的最后一个记录中,同时删除图表的第一个记录,使图表可以进行动态移动。代码如下:
procedure TForm1.Timer2Timer(Sender: TObject); //实现图表的动态实时效果
var
year,month,day,hour,minute,second,millisecond:word;
begin
DecodeDateTime(ToDate,year,month,day,hour,minute,second,millisecond);
Chart1.Title.Text.Clear;
Chart1.Title.Text.Add(IntToStr(year)+'-'+IntToStr(month)+'-'+IntToStr(day)+' '
+IntToStr(hour)+'时');
//将同一时间的销售金额进行汇总
with DataModule1.ADOQuery3 do
begin
Close;
SQL.Clear;
SQL.Add('select sum(a.Dist_Money) as DMoney from (Select * from tb_DistRealTime
where Dist_Date='+''''+DateTimeToStr(ToDate)+''''+') a');
Open;
end;
//使图表进行动态显示
with Chart1.Series[0] do
begin
Delete(0); //删除图表中X轴上的第一个数据
ToSum := ToSum+1;
//在图表的最后添加一个数据
ADDXY(ToSum,DataModule1.ADOQuery3.fieldByName('Dmoney').AsInteger
,IntToStr(minute)+':'+IntToStr(second),clred);
end;
end;
用图表对数据进行实时检测时,当数据变化过快时,图表中的数据线将变得十分杂乱,这时,可以将图表的显示速度变慢,在数据表中提取图表在显示时间段内变化的数据值,并按数据的个数对其求平均值,以平均值的形式显示在图表中。