EMF Optimisation for charts

TeeChart VCL for Borland/CodeGear/Embarcadero RAD Studio, Delphi and C++ Builder.
Post Reply
rtech
Newbie
Newbie
Posts: 8
Joined: Tue Apr 27, 2021 12:00 am

EMF Optimisation for charts

Post by rtech » Wed Nov 03, 2021 12:29 pm

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.

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

Re: EMF Optimisation for charts

Post by Yeray » Thu Nov 04, 2021 10:53 am

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.
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

rtech
Newbie
Newbie
Posts: 8
Joined: Tue Apr 27, 2021 12:00 am

Re: EMF Optimisation for charts

Post by rtech » Mon Nov 08, 2021 9:58 am

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)

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

Re: EMF Optimisation for charts

Post by Yeray » Mon Nov 08, 2021 10:21 am

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.
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

rtech
Newbie
Newbie
Posts: 8
Joined: Tue Apr 27, 2021 12:00 am

Re: EMF Optimisation for charts

Post by rtech » Mon Nov 08, 2021 12:31 pm

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?

rtech
Newbie
Newbie
Posts: 8
Joined: Tue Apr 27, 2021 12:00 am

Re: EMF Optimisation for charts

Post by rtech » Tue Nov 09, 2021 12:28 pm

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?

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

Re: EMF Optimisation for charts

Post by Yeray » Tue Nov 09, 2021 12:42 pm

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
MetafilePerformance.png (29.28 KiB) Viewed 11705 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.
MetafilePerformance.zip
(2.34 KiB) Downloaded 698 times
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

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

Re: EMF Optimisation for charts

Post by Yeray » Tue Nov 09, 2021 12:45 pm

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.
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

rtech
Newbie
Newbie
Posts: 8
Joined: Tue Apr 27, 2021 12:00 am

Re: EMF Optimisation for charts

Post by rtech » Tue Nov 09, 2021 1:15 pm

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
Attachments
TimageTest.7z
(7.45 KiB) Downloaded 706 times

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

Re: EMF Optimisation for charts

Post by Yeray » Thu Nov 11, 2021 12:52 pm

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
Project1_2021-11-11_13-40-53.png (68.32 KiB) Viewed 11641 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
Project1_2021-11-11_13-41-02.png (70.44 KiB) Viewed 11641 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:

Code: Select all

Series2->Color=Series1->Color;
So it looks correct to me.
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