0

I am a newbie with Firemonkey and XE3 environment.

My program does some calculations and should give feedback to user with a TeeChart component.

OnClick()
begin

    while(boolContinue) do
    begin
    NextStep(boolContinue);

    DoSomeCalculations();

    UpdateTeeChart();
    end;
end;

I used Application.ProcessMessage in Delphi7. In a FireMonkey application it seems to take almost a second to make a single ProcessMessage call.

What is proper way to update TChart (TLineSeries / TeeChart Lite v 2012.06.120613)?

I tryied: - HandleMessage (works, but slow) - process paint messages only (works, but slow) - Invalidate (doesnt work) - Repaint (doesnt work)

I also tryied to use threads with no success.

Edit:

Added a simple test program:

unit Unit1;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Rtti, System.Classes,
  System.Variants, FMX.Types, FMX.Controls, FMX.Forms, FMX.Dialogs,
  FMXTee.Engine, FMXTee.Procs, FMXTee.Chart, FMXTee.Series;

type
  TForm1 = class(TForm)
    Chart1: TChart;
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.fmx}

procedure TForm1.Button1Click(Sender: TObject);
var
  line : TLineSeries;
  ii, x1, x2 : integer;

begin

  line := TLineSeries.Create(chart1);
  line.ParentChart := chart1;

  for ii  := 1 to 100 do
  begin
    line.AddXY(ii, random(20));

    // Do some calculations...
    self.Caption := IntToStr(ii);
    for x1 := 1 to 10000 do
      for x2 := 1 to 1000 do
      begin
      end;
  end;
end;

end.
  • `ProcessMessages` was never the right thing to do. Perhaps you could give an SSCCE so that we can give you good advice. – David Heffernan Apr 08 '14 at 10:15
  • Have you tried `Chart1.Draw();`? – Yeray Apr 08 '14 at 10:27
  • chart1.Draw() doesn't help. – user3509858 Apr 08 '14 at 11:05
  • I know - ProcessMessages is not recommended and it is slow. Added some code into the question.. – user3509858 Apr 08 '14 at 11:08
  • The code you posted is as slow as the same code without any Chart for me here. It takes about 5 seconds to finish – Yeray Apr 08 '14 at 13:16
  • @user3509858 you may also be interested in the "Real-time Charting" article at http://www.teechart.net/reference/articles/index.php. Some of the suggestions there may help you. – Narcís Calvet Apr 08 '14 at 13:35
  • With Application.ProcessMessages() or Application.HandleMessage it takes 14 second. Without those it takes only 2-3 second. – user3509858 Apr 08 '14 at 13:37
  • I calculated the elapsed time with and without `Application.ProcessMessages` using the code [here](http://stackoverflow.com/a/16984761/509369), and got 5.74s vs 6.38s. I think this is an acceptable difference if you consider the chart is being repainted 100 times. – Yeray Apr 08 '14 at 14:08
  • For me the difference is 3s vs 14s - every ProcessMessages takes ~0.1s. I am using XE3 and the application is Firemonkey desktop application. And TeeChart component is TeeChart lite 2012.06.120613 – user3509858 Apr 09 '14 at 06:26

1 Answers1

0

Solution found!

The subject is also discussed here and solution was found there:

https://forums.embarcadero.com/message.jspa?messageID=427282

Now the charts repaints and it takes only ~2 seconds to run.

unit Unit1;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Rtti, System.Classes,
  System.Variants, FMX.Types, FMX.Controls, FMX.Forms, FMX.Dialogs,
  FMXTee.Engine, FMXTee.Procs, FMXTee.Chart, FMXTee.Series, Windows;


type MyThread = class(TThread)
  protected
   procedure Execute; override;
  public
    line : TLineSeries;

    constructor Create; overload;
    destructor Destroy; override;
end;


type
  TForm1 = class(TForm)
    Chart1: TChart;
    Button1: TButton;
    Label2: TLabel;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.fmx}




constructor MyThread.Create;
begin
  inherited Create(true);
  FreeOnTerminate := true;
end;

destructor MyThread.Destroy;
begin
  inherited;
end;


procedure MyThread.Execute;
var
 ii, x1, x2 : integer;
begin
  for ii  := 1 to 100 do
  begin
    line.AddXY(ii, random(20));

    // Do some calculations...
    for x1 := 1 to 10000 do
      for x2 := 1 to 1000 do
      begin
      end;
  end;
end;




procedure TForm1.Button1Click(Sender: TObject);
var
   MT : MyThread;
   line : TLineSeries;
begin
   chart1.BottomAxis.Minimum := 0;
   chart1.BottomAxis.Maximum := 100;
   chart1.BottomAxis.AutomaticMinimum := false;
   chart1.BottomAxis.AutomaticMaximum := false;

   chart1.Legend.Visible := false;

  line := TLineSeries.Create(chart1);
  line.ParentChart := chart1;

  MT := MyThread.Create;
  MT.line := line;
  MT.Start;
end;


end.