Dynamic dbchart creation slow

TeeChart VCL for Borland/CodeGear/Embarcadero RAD Studio, Delphi and C++ Builder.
Post Reply
den
Newbie
Newbie
Posts: 15
Joined: Wed Jan 30, 2008 12:00 am

Dynamic dbchart creation slow

Post by den » Thu Aug 02, 2012 1:00 am

I have an application that creates the required dbcharts on startup. However, this dynamic chart creation is very slow, and slows down expotentially with the number of charts. After doing some profiling, I discovered that the 'findnameloop' routine is called excessively, in order, I believe to create unique 'names' for each of the created charts.

Is there a way around this? (having TeeChart calling this routine when dynamically creating dbcharts).

Thanks,

Dennis

Yeray
Site Admin
Site Admin
Posts: 9612
Joined: Tue Dec 05, 2006 12:00 am
Location: Girona, Catalonia
Contact:

Re: Dynamic dbchart creation slow

Post by Yeray » Thu Aug 02, 2012 3:16 pm

Hi Dennis,

I don't think it's creating the charts, but maybe using CreateNewSeries, CreateNewTeeFunction, CloneChartTool,...
Could you please arrange a simple example project we can run as-is to reproduce the exact situation here so we can try to suggest you another way to do the same?
Best Regards,
ImageYeray Alonso
Development & Support
Steema Software
Av. Montilivi 33, 17003 Girona, Catalonia (SP)
Image Image Image Image Image Image Please read our Bug Fixing Policy

den
Newbie
Newbie
Posts: 15
Joined: Wed Jan 30, 2008 12:00 am

Re: Dynamic dbchart creation slow

Post by den » Thu Aug 02, 2012 9:01 pm

Thanks so much Yeray, for your prompt reply. As it is a major project, and for expediency sake, is it OK that I include the procedure from my Delphi 2007 project that generates the charts - see below. (if this is too onnerous for you, please let me know. I will especially create a stand-alone application for you. I am hoping you have come across this before, and will have a 'quick' solution).

Also, FYI the FindNameLoop procedure appears to be in the GetUniqueName procedure in the TeeProcs Unit. It is being 'hit' 2018 times and is taking approx 45 secs out of the 55 secs to load the entire application.

Again, Thanks so much.

Here is the procedure:

procedure TForm24.createcharts(noofcharts: integer);
var
i:integer;
mytool, mytool1, mytool2:tdatatabletool;

begin
freecharts(chartarray);
freecharts(chartarray1);
freecharts(chartarray2);

ts.free;
ts:=nil;

ts1.Free;
ts1:=nil;

ts2.Free;
ts2:=nil;


setlength(chartarray,noofcharts);
setlength(chartarray1,noofcharts);
setlength(chartarray2, noofcharts);
setlength(tabsheetarray,noofcharts);
setlength(tabsheetarray1,noofcharts);
setlength(tabsheetarray2, noofcharts);
setlength(myseries,noofcharts);
setlength(myseries1,noofcharts);
setlength(myseries2, noofcharts);
setlength(mylineseries, noofcharts);
setlength (mylineseries1, noofcharts);
setlength (mylineseries2, noofcharts);
setlength(mybuttons,3*noofcharts);

adoquery2.Recordset.MoveFirst;

ts:=ttabsheet.Create(self);
ts.PageControl:=pagecontrol1;
ts.Caption:='Machine Downtime Hrs';
pc:=tpagecontrol.Create(self);
pc.Parent:=ts;
pc.Align:=alclient;

ts2:=ttabsheet.Create(self);
ts2.PageControl:=pagecontrol1;
ts2.Caption:='Machine Downtime %';
pc2:=tpagecontrol.Create(self);
pc2.Parent:=ts2;
pc2.Align:=alclient;


ts1:=ttabsheet.Create(self);
ts1.PageControl:=pagecontrol1;
ts1.Caption:='Machine Incidents';
pc1:=tpagecontrol.Create(self);
pc1.Parent:=ts1;
pc1.Align:=alclient;

for I := 1 to noofcharts do
begin
if screen.Forms[0].Name = 'splashscreen' then
begin
splashscreen.ProgressBar1.StepIt;
splashscreen.Label2.Caption:='creating chart group ' + inttostr(i);
splashscreen.Update;
end;
tabsheetarray:=ttabsheet.Create(self);
tabsheetarray.PageControl :=pc;
tabsheetarray.Caption:=adoquery2.Recordset.Fields[0].Value;
tabsheetarray.OnShow:=tabshow;
mybuttons:=tbutton.Create(self);
mybuttons.Parent:=tabsheetarray;
mybuttons.Anchors:=[aktop,akright];
mybuttons.Top:=10;
mybuttons.Left:=tabsheetarray[i].Width-150;
mybuttons[i].Caption:='Print This Chart';
mybuttons[i].Width:=100;
mybuttons[i].OnClick:=buttonclicked;

tabsheetarray2[i]:=ttabsheet.Create(self);
tabsheetarray2[i].PageControl :=pc2;
tabsheetarray2[i].Caption:=adoquery2.Recordset.Fields[0].Value;
tabsheetarray2[i].OnShow:=tabshow;
mybuttons[i+noofcharts]:=tbutton.Create(self);
mybuttons[i+noofcharts].Parent:=tabsheetarray2[i];
mybuttons[i+noofcharts].Anchors:=[aktop,akright];
mybuttons[i+noofcharts].Top:=10;
mybuttons[i+noofcharts].Left:=tabsheetarray2[i].Width-150;
mybuttons[i+noofcharts].Caption:='Print This Chart';
mybuttons[i+noofcharts].Width:=100;
mybuttons[i+noofcharts].OnClick:=buttonclicked;

tabsheetarray1[i]:=ttabsheet.Create(self);
tabsheetarray1[i].PageControl :=pc1;
tabsheetarray1[i].Caption:=adoquery2.Recordset.Fields[0].Value;
tabsheetarray1[i].OnShow:=tabshow;
mybuttons[(i+(noofcharts*2))]:=tbutton.Create(self);
mybuttons[(i+(noofcharts*2))].parent:=tabsheetarray1[i];
mybuttons[(i+(noofcharts*2))].Anchors:=[aktop,akright];
mybuttons[(i+(noofcharts*2))].Top:=10;
mybuttons[(i+(noofcharts*2))].Left:=tabsheetarray1[i].Width-150;
mybuttons[(i+(noofcharts*2))].Caption:='Print This Chart';
mybuttons[(i+(noofcharts*2))].Width:=100;
mybuttons[(i+(noofcharts*2))].OnClick:=buttonclicked;

chartarray[i]:=tdbchart.Create(self);
with chartarray[i] do
begin
Title.Text.Text:=adoquery2.Recordset.Fields[0].Value + ' - ' + adoquery2.Recordset.Fields[1].Value;;
Title.Font.Size:=11;
Title.Font.Color:=clblack;
color:=clwhite;
backwall.Color:=clbtnface;
backwall.Transparent:=false;
view3d:=false;
legend.Visible:=false;
//legend.CheckBoxes:=true;
leftaxis.LabelsSize:=30;
leftaxis.Title.Caption:='Downtime Hrs';
bottomaxis.Increment:=datetimestep[dtonemonth];
bottomaxis.DateTimeFormat:='mmm-yy';
bottomaxis.Grid.Style:=psclear;
bottomaxis.MinorTickCount:=1;
bottomaxis.MinorTickLength:=10;
bottomaxis.Title.caption:='Month-Year';
bottomaxis.LabelsSize:=50;
marginbottom:=10;
onclickseries:=chartclickseries;
borderstyle:=bsnone;
bevelinner:=bvnone;
bevelouter:=bvnone;
Parent:=tabsheetarray[i];
align:=alclient;
tools.Add(tdatatabletool);
zoom.allow:=false;
end;

mytool:=chartarray[i].Tools.Items[0] as tdatatabletool;
mytool.Legend.OtherSide:=true;
mylineseries[i]:=tlineseries.Create(self);
mylineseries[i].ParentChart:=chartarray[i];
mylineseries[i].DataSource:=adoquery1;
mylineseries[i].YValues.ValueSource:='#sum#sumdowntimehours';
mylineseries[i].XLabelsSource:='yearmonth';
mylineseries[i].Title:='TOTAL';
mylineseries[i].Pointer.Visible:=true;
mylineseries[i].LinePen.Width:=2;
mylineseries[i].Active:=true;
mycrosstabsource:=tdbcrosstabsource.Create(self);
myseries[i]:=tbarseries.Create(self);
myseries[i].Marks.Visible:=false;
myseries[i].ParentChart:=chartarray[i];
//myseries[i].XValues.DateTime:=true;
myseries[i].Active:=true;
myseries[i].MultiBar:=mbstacked;
mycrosstabsource.Series:=myseries[i];
mycrosstabsource.LabelField:='yearmonth';
mycrosstabsource.GroupField:='machinefaultdesc';
mycrosstabsource.ValueField:='sumdowntimehours';
mycrosstabsource.Formula:=gfsum;
mycrosstabsource.DataSet:=adoquery1;
mycrosstabsource.Active:=true;

chartarray2[i]:=tdbchart.Create(self);
with chartarray2[i] do
begin
Title.Text.Text:=adoquery2.Recordset.Fields[0].Value + ' - ' + adoquery2.Recordset.Fields[1].Value;;
Title.Font.Size:=11;
Title.Font.Color:=clblack;
color:=clwhite;
backwall.Color:=clbtnface;
backwall.Transparent:=false;
view3d:=false;
legend.Visible:=false;
//legend.CheckBoxes:=true;
leftaxis.LabelsSize:=30;
leftaxis.Title.Caption:='Downtime %';
bottomaxis.Increment:=datetimestep[dtonemonth];
bottomaxis.DateTimeFormat:='mmm-yy';
bottomaxis.Grid.Style:=psclear;
bottomaxis.MinorTickCount:=1;
bottomaxis.MinorTickLength:=10;
bottomaxis.Title.caption:='Month-Year';
bottomaxis.LabelsSize:=50;
marginbottom:=10;
onclickseries:=chartclickseries;
borderstyle:=bsnone;
bevelinner:=bvnone;
bevelouter:=bvnone;
Parent:=tabsheetarray2[i];
align:=alclient;
tools.Add(tdatatabletool);
zoom.Allow:=false;
end;

mytool2:=chartarray2[i].Tools.Items[0] as tdatatabletool;
mytool2.Legend.OtherSide:=true;
mylineseries2[i]:=tlineseries.Create(self);
mylineseries2[i].ParentChart:=chartarray2[i];
mylineseries2[i].DataSource:=adoquery8;
mylineseries2[i].YValues.ValueSource:='#sum#pcdwntimehrs';
mylineseries2[i].XLabelsSource:='ym';
mylineseries2[i].Title:='TOTAL';
mylineseries2[i].Pointer.Visible:=true;
mylineseries2[i].LinePen.Width:=2;
mylineseries2[i].Active:=true;
mycrosstabsource2:=tdbcrosstabsource.Create(self);
myseries2[i]:=tbarseries.Create(self);
myseries2[i].Marks.Visible:=false;
myseries2[i].ParentChart:=chartarray2[i];
//myseries2[i].XValues.DateTime:=true;
myseries2[i].Active:=true;
myseries2[i].MultiBar:=mbstacked;
mycrosstabsource2.Series:=myseries2[i];
mycrosstabsource2.LabelField:='ym';
mycrosstabsource2.GroupField:='machinefaultdesc';
mycrosstabsource2.ValueField:='pcdwntimehrs';
mycrosstabsource2.Formula:=gfsum;
mycrosstabsource2.DataSet:=adoquery8;
mycrosstabsource2.Active:=true;


chartarray1[i]:=tdbchart.Create(self);

with chartarray1[i] do
begin
Title.Text.Text:=adoquery2.Recordset.Fields[0].Value + ' - ' + adoquery2.Recordset.Fields[1].Value;;
Title.Font.Size:=11;
Title.Font.Color:=clblack;
color:=clwhite;
backwall.Color:=clbtnface;
backwall.Transparent:=false;
view3d:=false;
legend.Visible:=false;
//legend.CheckBoxes:=true;
leftaxis.LabelsSize:=30;
leftaxis.Title.Caption:='Number of Incidents';
bottomaxis.Increment:=datetimestep[dtonemonth];
bottomaxis.DateTimeFormat:='mmm-yy';
bottomaxis.Grid.Style:=psclear;
bottomaxis.MinorTickCount:=1;
bottomaxis.MinorTickLength:=10;
bottomaxis.Title.caption:='Month-Year';
bottomaxis.LabelsSize:=50;
marginbottom:=10;
onclickseries:=chartclickseries;
borderstyle:=bsnone;
bevelinner:=bvnone;
bevelouter:=bvnone;
Parent:=tabsheetarray1[i];
align:=alclient;
sendtoback;
tools.Add(tdatatabletool);
zoom.allow:=false;
end;

mytool1:=chartarray1[i].Tools.Items[0] as tdatatabletool;
mytool1.Legend.OtherSide:=true;
mylineseries1[i]:=tlineseries.Create(self);
mylineseries1[i].ParentChart:=chartarray1[i];
mylineseries1[i].DataSource:=adoquery1;
mylineseries1[i].YValues.ValueSource:='#sum#countdowntimehours';
mylineseries1[i].XLabelsSource:='yearmonth';
mylineseries1[i].Title:='TOTAL';
mylineseries1[i].Pointer.Visible:=true;
mylineseries1[i].LinePen.Width:=2;
mylineseries1[i].Active:=true;
mycrosstabsource1:=tdbcrosstabsource.Create(self);
myseries1[i]:=tbarseries.Create(self);
myseries1[i].Marks.Visible:=false;
myseries1[i].ParentChart:=chartarray1[i];
myseries1[i].MultiBar:=mbstacked;
//myseries1[i].XValues.DateTime:=true;
myseries1[i].Active:=true;
mycrosstabsource1.Series:=myseries1[i];
mycrosstabsource1.LabelField:='yearmonth';
mycrosstabsource1.GroupField:='machinefaultdesc';
mycrosstabsource1.ValueField:='countdowntimehours';
mycrosstabsource1.Formula:=gfsum;
mycrosstabsource1.DataSet:=adoquery1;
mycrosstabsource1.Active:=true;
mybuttons[i].BringToFront;
mybuttons[i+noofcharts].BringToFront;
adoquery2.Recordset.MoveNext;
end;
if screen.Forms[0].Name = 'splashscreen' then
begin
splashscreen.Label2.Caption:='almost done!';
screen.Cursor:=crdefault;
splashscreen.visible:=false;
end;

end;

Yeray
Site Admin
Site Admin
Posts: 9612
Joined: Tue Dec 05, 2006 12:00 am
Location: Girona, Catalonia
Contact:

Re: Dynamic dbchart creation slow

Post by Yeray » Fri Aug 03, 2012 7:38 pm

Hi Dennis,

Thanks for the code but I'm afraid it's not enough. There are too many undeclared arrays, data queries, etc
So I have to ask you if you can arrange a simple example project.
Best Regards,
ImageYeray Alonso
Development & Support
Steema Software
Av. Montilivi 33, 17003 Girona, Catalonia (SP)
Image Image Image Image Image Image Please read our Bug Fixing Policy

den
Newbie
Newbie
Posts: 15
Joined: Wed Jan 30, 2008 12:00 am

Re: Dynamic dbchart creation slow

Post by den » Wed Aug 08, 2012 11:25 pm

Yeray:

After some 'light reading', I decided to dynamically create my dbcharts with no owners (ie dbchart.create(nil)) in Delphi. I then wrote code to destroy these components upon form.close. This speeded up the loading of the form from 50+ seconds to approx. 8 seconds. This is good enough!

It is curious, however, that the FindNameLoop procedure is still being 'hit' 2016 times (according to my profiler). I still am not able to determine what 'call' is doing this.

I thought I would post my 'solution' to put this topic to rest and perhaps help others who want to speed up form loading for forms with dynamically created dbcharts (and other components).

Thanks,

Cheers,

Dennis

Yeray
Site Admin
Site Admin
Posts: 9612
Joined: Tue Dec 05, 2006 12:00 am
Location: Girona, Catalonia
Contact:

Re: Dynamic dbchart creation slow

Post by Yeray » Thu Aug 09, 2012 2:52 pm

Hi Dennis,

Thanks for sharing.
If you find a way to reproduce the problem in a simple example project we can run as-is here, we'll be glad to take a look at it.
Best Regards,
ImageYeray Alonso
Development & Support
Steema Software
Av. Montilivi 33, 17003 Girona, Catalonia (SP)
Image Image Image Image Image Image Please read our Bug Fixing Policy

Post Reply