Slow histograms

TeeChart VCL for Borland/CodeGear/Embarcadero RAD Studio, Delphi and C++ Builder.
Post Reply
Toreba
Newbie
Newbie
Posts: 12
Joined: Fri Aug 05, 2016 12:00 am

Slow histograms

Post by Toreba » Fri Jun 23, 2017 10:33 am

Hi,

Users expect series of a certain type to be displayed as histograms. Clearly plotting these is going to be slower than simple point or line series, presumably due to the pixel calculations that need to be done, and the screen rendering that ensues. In the extreme case, users are plotting perhaps 50 series, each of over 100,000 points, on the same axis. It takes many minutes to generate the graph, which is perhaps not surprising. Of course, they always zoom in a long way to actually view the data, but all zoom operations are very slow too. It appears to users that the software has hung, and they don't notice that the CPU is working manically.

THistogramSeries seems rather faster than TBarSeries, and switching off the 'hover' setting seems to help, but what else can be done to optimize performance? At full zoom extents, with maybe 100x more points to plot than available pixels, I guess a lot of unnecessary calculations are being done.

Thanks for any advice.

Toreba

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

Re: Slow histograms

Post by Yeray » Fri Jun 23, 2017 2:02 pm

Hello Toreba,

You could change your THistogramSeries for TFastLineSeries, which are much faster, each one with a TSeriesRegionTool. Then when the zoom is close enough, you could change tour series to THistogramSeries and hide the TSeriesRegionTools. Ie:

Code: Select all

uses Series, StatChar, TeeSeriesRegion;

const threshold=100;

procedure TForm1.FormCreate(Sender: TObject);
var i: Integer;
    tmpSeries: TChartSeries;
begin
  Chart1.View3D:=False;
  Chart1.Legend.Visible:=False;
  Chart1.Hover.Visible:=False;

  for i:=0 to 49 do
    Chart1.AddSeries(THistogramSeries).FillSampleValues(1000);

  Chart1.AutoRepaint:=False;
  //Change all the THistogramSeries for TFastLineSeries with TSeriesRegionTools
  for i:=0 to Chart1.SeriesCount-1 do
  begin
    with Chart1.Tools.Add(TSeriesRegionTool) as TSeriesRegionTool do
    begin
      Color:=Chart1[i].Color;
      Series:=Chart1[i];
      Pen.Hide;
    end;

    tmpSeries:=Chart1[i];
    tmpSeries:=ChangeSeriesType(tmpSeries, TFastLineSeries);
    TFastLineSeries(tmpSeries).DrawAllPoints:=False;
    TFastLineSeries(tmpSeries).Stairs:=True;
    tmpSeries.Pen.Color:=clBlack;
  end;

  Chart1.Title.Text.Text:='Now we have TFastLineSeries';

  Chart1.AutoRepaint:=True;
  Chart1.Draw;
end;

procedure TForm1.Chart1Zoom(Sender: TObject);
var i: Integer;
    tmpSeries: TChartSeries;
begin
  if (Chart1[0] is TFastLineSeries) and (Chart1.Axes.Bottom.Maximum-Chart1.Axes.Bottom.Minimum < threshold) then
  begin
    Chart1.AutoRepaint:=False;

    for i:=0 to Chart1.SeriesCount-1 do
    begin
      tmpSeries:=Chart1[i];
      tmpSeries:=ChangeSeriesType(tmpSeries, THistogramSeries);
      Chart1.Tools[i].Active:=False;
    end;

    Chart1.Title.Text.Text:='Now we have THistogramSeries';

    Chart1.AutoRepaint:=True;
    Chart1.Draw;
  end;
end;

procedure TForm1.Chart1UndoZoom(Sender: TObject);
var i: Integer;
    tmpSeries: TChartSeries;
begin
  if (Chart1[0] is THistogramSeries) then
  begin
    Chart1.AutoRepaint:=False;

    for i:=0 to Chart1.SeriesCount-1 do
    begin
      tmpSeries:=Chart1[i];
      tmpSeries:=ChangeSeriesType(tmpSeries, TFastLineSeries);
      TFastLineSeries(tmpSeries).DrawAllPoints:=False;
      TFastLineSeries(tmpSeries).Stairs:=True;
      tmpSeries.Pen.Color:=clBlack;
      Chart1.Tools[i].Active:=True;
    end;

    Chart1.Title.Text.Text:='Now we have TFastLineSeries';
    Chart1.AutoRepaint:=True;
    Chart1.Draw;
  end;
end;
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

Toreba
Newbie
Newbie
Posts: 12
Joined: Fri Aug 05, 2016 12:00 am

Re: Slow histograms

Post by Toreba » Mon Jun 26, 2017 9:08 pm

Yeray,

Fantastic, thanks very much for this explanation.

I notice that the ChangeSeriesType method triggers the chart's OnRemoveSeries event. So is it true to say that this call simply creates and populates a new series of the specified class, removes the old series from the chart series list and adds the new?

Regards

Toreba

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

Re: Slow histograms

Post by Yeray » Tue Jun 27, 2017 8:17 am

Hello Toreba,

Yes, pretty much:

Code: Select all

Function ChangeSeriesType(var ASeries:TChartSeries; NewType:TChartSeriesClass):TChartSeries;
var NewSeries : TChartSeries;
begin
  if ASeries.ClassType<>NewType then
  begin
    NewSeries:=CreateNewSeries(ASeries.Owner,ASeries.ParentChart,NewType);

    if Assigned(NewSeries) then
    begin
      AssignSeries(ASeries,NewSeries);
      ASeries.Free;
      ASeries:=NewSeries;
    end;
  end;

  result:=ASeries;
end;
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