You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Delphi FMX中TChart引发TPanel显隐/窗体缩放卡顿问题求助

FMX TChart 频繁重绘导致卡顿问题求助

我在Windows平台基于FMX开发的应用里,使用了包含约10个TFastLineSeries的TChart,每个系列有大量数据点。加载数据后,切换TPanel的Visible属性(显示/隐藏)耗时约4秒;拖动窗体边框缩放时(Chart未设为Client对齐,自身尺寸无变化)也出现相同卡顿。

测试Demo复现步骤:

  • 点击fillchart按钮填充数据(此步骤耗时非重点);
  • 点击showpanel按钮观察TPanel显隐耗时,或拖动窗体边框缩放。

Demo通过Timer和Chart的AfterDraw事件统计重绘次数,发现操作时会触发大量重绘。尝试设置AutoRepaint为False但无效,经Embarcadero技术人员确认这是TChart的问题,寻求解决思路与帮助。


unit1.pas

unit Unit1;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.StdCtrls,
  FMX.Controls.Presentation, FMXTee.Series, FMXTee.Engine, FMXTee.Procs,
  FMXTee.Chart, FMX.Memo.Types, FMX.ScrollBox, FMX.Memo;

type
  TForm1 = class(TForm)
    Chart1: TChart;
    Series1: TFastLineSeries;
    Series2: TFastLineSeries;
    Series3: TFastLineSeries;
    Series4: TFastLineSeries;
    Series5: TFastLineSeries;
    Series6: TFastLineSeries;
    Series9: TFastLineSeries;
    Series11: TFastLineSeries;
    Button1: TButton;
    Panel1: TPanel;
    Button2: TButton;
    Memo1: TMemo;
    Label1: TLabel;
    afterdrawCounterVal: TLabel;
    Timer1: TTimer;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure Chart1BeforeDrawChart(Sender: TObject);
    procedure Chart1AfterDraw(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
  private
    tickCountChartDraw:cardinal;
    afterdrawCounter:Cardinal;
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

uses winapi.Windows;
{$R *.fmx}

procedure TForm1.Button1Click(Sender: TObject);
begin
  panel1.Visible:=not panel1.visible;
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  i,j:Integer;
  tickCount:Cardinal;
begin
  tickCount:=GetTickCount;
  Randomize;
  chart1.BeginUpdate;
  for i := 0 to Chart1.SeriesCount-1 do begin
    Chart1.series[i].BeginUpdate;
    for j := 0 to 100000 do
      Chart1.series[i].AddXY(j,Random(100));
    Chart1.series[i].EndUpdate;
  end;
  chart1.EndUpdate;
  memo1.Lines.Add('filling Chart with data:'+(GetTickCount-tickCount).ToString);
end;

procedure TForm1.Chart1AfterDraw(Sender: TObject);
begin
  //memo1.Lines.Add('Chart After Draw '+(GetTickCount-tickCountChartDraw).ToString);
  Inc(afterdrawCounter);
end;

procedure TForm1.Chart1BeforeDrawChart(Sender: TObject);
begin
  //memo1.Lines.Add('Chart Before Draw');
  //tickCountChartDraw:=getTickcount;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  panel1.Visible:=False;
  afterdrawCounter:=0;
//  chart1.AutoRepaint:=false;
//  Series1.AutoRepaint := False;
//  Series2.AutoRepaint := False;
//  Series3.AutoRepaint := False;
//  Series4.AutoRepaint := False;
//  Series5.AutoRepaint := False;
//  Series6.AutoRepaint := False;
//  Series9.AutoRepaint := False;
//  Series11.AutoRepaint := False;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  afterdrawCounterVal.Text:=afterdrawCounter.ToString;
end;

end.

unit1.fmx

object Form1: TForm1
  Left = 0
  Top = 0
  Caption = 'Form1'
  ClientHeight = 620
  ClientWidth = 640
  FormFactor.Width = 320
  FormFactor.Height = 480
  FormFactor.Devices = [Desktop]
  OnCreate = FormCreate
  DesignerMasterStyle = 0
  object Chart1: TChart
    Position.X = 56.000000000000000000
    Position.Y = 40.000000000000000000
    Foot.Font.StyleExt = {00040000000200000004000000}
    Legend.Title.Font.StyleExt = {00070000000000000004000000}
    SubFoot.Font.StyleExt = {00040000000200000004000000}
    Title.Text.Strings = (
      'TChart')
    View3D = False
    Zoom.Brush.Kind = None
    Zoom.Pen.Fill.Color = claSilver
    OnAfterDraw = Chart1AfterDraw
    OnBeforeDrawChart = Chart1BeforeDrawChart
    TabOrder = 0
    Size.Width = 529.000000000000000000
    Size.Height = 417.000000000000000000
    Size.PlatformDefault = False
    ColorPaletteIndex = 13
    object Series1: TFastLineSeries
      HoverElement = []
      LinePen.Color = xFF4466A3
      LinePen.Fill.Color = xFF4466A3
      XValues.Name = 'X'
      XValues.Order = loAscending
      YValues.Name = 'Y'
      YValues.Order = loNone
    end
    object Series2: TFastLineSeries
      HoverElement = []
      LinePen.Color = xFFF39C35
      LinePen.Fill.Color = xFFF39C35
      XValues.Name = 'X'
      XValues.Order = loAscending
      YValues.Name = 'Y'
      YValues.Order = loNone
    end
    object Series3: TFastLineSeries
      HoverElement = []
      LinePen.Color = xFFF14C14
      LinePen.Fill.Color = xFFF14C14
      XValues.Name = 'X'
      XValues.Order = loAscending
      YValues.Name = 'Y'
      YValues.Order = loNone
    end
    object Series4: TFastLineSeries
      HoverElement = []
      LinePen.Color = xFF4E97A8
      LinePen.Fill.Color = xFF4E97A8
      XValues.Name = 'X'
      XValues.Order = loAscending
      YValues.Name = 'Y'
      YValues.Order = loNone
    end
    object Series5: TFastLineSeries
      HoverElement = []
      LinePen.Color = xFF2B406B
      LinePen.Fill.Color = xFF2B406B
      XValues.Name = 'X'
      XValues.Order = loAscending
      YValues.Name = 'Y'
      YValues.Order = loNone
    end
    object Series6: TFastLineSeries
      HoverElement = []
      LinePen.Color = xFF1D7B63
      LinePen.Fill.Color = xFF1D7B63
      XValues.Name = 'X'
      XValues.Order = loAscending
      YValues.Name = 'Y'
      YValues.Order = loNone
    end
    object Series9: TFastLineSeries
      HoverElement = []
      LinePen.Color = xFF5DB79E
      LinePen.Fill.Color = xFF5DB79E
      XValues.Name = 'X'
      XValues.Order = loAscending
      YValues.Name = 'Y'
      YValues.Order = loNone
    end
    object Series11: TFastLineSeries
      HoverElement = []
      LinePen.Color = xFFF3EA8D
      LinePen.Fill.Color = xFFF3EA8D
      XValues.Name = 'X'
      XValues.Order = loAscending
      YValues.Name = 'Y'
      YValues.Order = loNone
    end
  end
  object Button1: TButton
    Position.X = 136.000000000000000000
    Position.Y = 10.000000000000000000
    TabOrder = 1
    Text = 'showpanel'
    TextSettings.Trimming = None
    OnClick = Button1Click
  end
  object Panel1: TPanel
    Position.X = 328.000000000000000000
    Position.Y = 8.000000000000000000
    TabOrder = 2
  end
  object Button2: TButton
    Position.X = 24.000000000000000000
    Position.Y = 10.000000000000000000
    TabOrder = 3
    Text = 'fillchart'
    TextSettings.Trimming = None
    OnClick = Button2Click
  end
  object Memo1: TMemo
    Touch.InteractiveGestures = [Pan, LongTap, DoubleTap]
    DataDetectorTypes = []
    Align = Bottom
    Position.Y = 512.000000000000000000
    Size.Width = 640.000000000000000000
    Size.Height = 108.000000000000000000
    Size.PlatformDefault = False
    TabOrder = 4
    Viewport.Width = 636.000000000000000000
    Viewport.Height = 104.000000000000000000
  end
  object Label1: TLabel
    Position.X = 8.000000000000000000
    Position.Y = 487.000000000000000000
    Text = 'AfterdrawCounter'
    TabOrder = 6
  end
  object afterdrawCounterVal: TLabel
    Position.X = 136.000000000000000000
    Position.Y = 487.000000000000000000
    TabOrder = 7
  end
  object Timer1: TTimer
    OnTimer = Timer1Timer
    Left = 512
    Top = 480
  end
end

project1.dpr

program Project1;

uses
  System.StartUpCopy,
  FMX.Forms,
  Unit1 in 'Unit1.pas' {Form1};

{$R *.res}

begin
  Application.Initialize;
  Application.CreateForm(TForm1, Form1);
  Application.Run;
end.

内容的提问来源于stack exchange,提问作者andiS

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 01:13:13