Page 1 of 1
EMF Optimisation for charts
Posted: Wed Nov 03, 2021 12:29 pm
by 16591079
Hello.
We use Rad Studio 10.4.1 and teechart 2020.30 for c++.
We need to export charts (fastline and line series) in EMF format in reports (Fast report 6). In report we use TfrxPictureView component for chart output.
example of exporting code:
Code: Select all
const int width = static_cast<int>( pictureView->Width );
const int height = static_cast<int>( pictureView->Height );
TRect r( 0, 0, width, height * 0.95 );
auto Metafile = chart->TeeCreateMetafile( /*Enhanced*/true, r );
if ( Metafile )
{
pictureView->Picture->Assign(Metafile);
}
it works fine, but if we have a lot of points (1000000+) report stutters, works slowly and can freeze for a few sec.
Is there any way to optimize chart before export? For example, hide unvisible points. We need emf format, not picture.
Re: EMF Optimisation for charts
Posted: Thu Nov 04, 2021 10:53 am
by yeray
Hello,
The time TeeChart spends to draw points (lines in the case of
TFastLineSeries
/
TLineSeries
) depends on factors like the number of shapes/lines to draw, the complexity of the brushes to be used (gradients, dash lines,...) and the specifications of the target machine.
We use to recommend trying to avoid drawing more points than the actual screen/app resolution, since most of them won't be shown anyway and will be wasting resources.
Please read
these tips to improve the performance when drawing many points. The majority are related to the
TFastLineSeries
, but some of them are more general.
Re: EMF Optimisation for charts
Posted: Mon Nov 08, 2021 9:58 am
by 16591079
Thanks for the answer, We've already use almost all of tips like DrawAllPoints = false and others from reply.
Can you please give as correct link for this:
Implement as tips as possible from the ones explained in the Real-time Charting article here.
and more detailed example of TDownSampleFunction(looks like i did not install Demos)
Re: EMF Optimisation for charts
Posted: Mon Nov 08, 2021 10:21 am
by yeray
Hello,
rtech wrote: ↑Mon Nov 08, 2021 9:58 am
Can you please give as correct link for this:
Implement as tips as possible from the ones explained in the Real-time Charting article here.
I've just corrected the link in that post to this:
https://www.steema.com/docs/TeeChartVCLRealtime.htm
rtech wrote: ↑Mon Nov 08, 2021 9:58 am
and more detailed example of TDownSampleFunction(looks like i did not install Demos)
You can find the TeeNew project
here, and the DownSamping example
here.
Re: EMF Optimisation for charts
Posted: Mon Nov 08, 2021 12:31 pm
by 16591079
Thanks for the link.
I've tried to use TDownSampleFunction before metafile creation and i can't see any difference. Code example is here:
Code: Select all
TDownSamplingFunction *samplingFun = new TDownSamplingFunction(chart);
for(size_t i = 0; i < chart->SeriesCount(); i++)
{
auto ser = dynamic_cast<TFastLineSeries *>(chart->Series[i]);
if(ser)
{
ser->DrawStyle = flAll;
ser->DrawAllPoints = false;
ser->DrawAllPointsStyle = daMinMax;
ser->AutoRepaint = false;
ser->SetFunction(samplingFun);
samplingFun->Tolerance = 2;
samplingFun->DownSampleMethod = dsMinMax;
samplingFun->Calculate(ser, 0, ser->Count() - 1);
}
}
auto Metafile = chart->TeeCreateMetafile( /*Enhanced*/true, r );
if ( Metafile )
{
//Подготовка графике к импорту в отчет
pictureView->Picture->Assign(Metafile);
}
Maybe i did something wrong?
Re: EMF Optimisation for charts
Posted: Tue Nov 09, 2021 12:28 pm
by 16591079
It doesn't seem that TDownSampling function works if series have more than 15000 of points.
Adn how can i use function without second series?
Re: EMF Optimisation for charts
Posted: Tue Nov 09, 2021 12:42 pm
by yeray
Hello,
I've done a simple application to test how the export performs with the "default"
TFastLineSeries
, setting
DrawAllPointsStyle.daMinMax
, using a
TDownSampleFunction
and using a
TDownSampleFunction
with
DrawAllPointsStyle.daMinMax
.
- MetafilePerformance.png (29.28 KiB) Viewed 12008 times
As you can see, the
TDownSampleFunction
is a big performance improvement over the Default
TFastLineSeries
, but
TDownSampleFunction
with
DrawAllPointsStyle.daMinMax
isn't necessarily an improvement against the
DrawAllPointsStyle.daMinMax
on the Default
TFastLineSeries
.
Re: EMF Optimisation for charts
Posted: Tue Nov 09, 2021 12:45 pm
by yeray
Hello,
rtech wrote: ↑Tue Nov 09, 2021 12:28 pm
It doesn't seem that TDownSampling function works if series have more than 15000 of points.
As shown in the example above, it's an improvement against using the
TFastLineSeries
per default. But you won't probably notice an improvement if you are using
daMinMax
.
rtech wrote: ↑Tue Nov 09, 2021 12:28 pm
Adn how can i use function without second series?
You can't, that's a requirement.
Re: EMF Optimisation for charts
Posted: Tue Nov 09, 2021 1:15 pm
by 16591079
Thanks for the example
I still can't reproduce your example. Simple code:
Code: Select all
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
dynamic_cast<TGDIPlusCanvas *>(Chart1->Canvas)->AntiAlias = false;
Chart1->Axes->FastCalc = true;
Chart1->Hover->Visible = false;
samplingFun = new TDownSamplingFunction(this);
Series1->DrawAllPoints = false;
Series1->DrawAllPointsStyle = daMinMax;
Series1->FillSampleValues(1500000);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::cxButton1Click(TObject *Sender)
{
const int width = static_cast<int>( pictureView->Width );
const int height = static_cast<int>( pictureView->Height );
TRect r( 0, 0, width, height * 0.95 );
auto Metafile = Chart1->TeeCreateMetafile( /*Enhanced*/true, r );
if(Metafile)
{
pictureView->Picture->Assign(Metafile);
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::cxButton2Click(TObject *Sender)
{
TFastLineSeries *Series2 = new TFastLineSeries(Chart1);
samplingFun->DownSampleMethod = dsAverage;
samplingFun->Tolerance = 2;
Series2->SetFunction(samplingFun);
Series2->DataSource = Series1;
Series2->CheckDataSource();
Chart1->AddSeries(Series2);
Series1->Visible = false;
}
Is it correct?
As i understand, i need to create another series with datasource of first series and then use TDownSampling? But it seems like TDownSampling do nothing. Maybe i've done something wrong?
I've added sample project to this post
Re: EMF Optimisation for charts
Posted: Thu Nov 11, 2021 12:52 pm
by yeray
Hello,
I've been able to run your project after cleaning the project from packages I don't have here.
After clicking the first button, which generates the metafile below, this is what I see:
- Project1_2021-11-11_13-40-53.png (68.32 KiB) Viewed 11944 times
Next, I click on the second button to generate the DownSampling function, and I also click at the first button again to generate the metafile again. This is what I get:
- Project1_2021-11-11_13-41-02.png (70.44 KiB) Viewed 11944 times
If you debug the code, you'll see how Series1 has 1200 points (
Series1->Count()
), while Series2 has only 3000 (
Series2->Count()
) while still looking pretty similar
Of course the color is different but it's easy to correct that with:
So it looks correct to me.