Performance Issue with Grid Lines and PenStyle psDot
Posted: Thu Dec 19, 2024 9:43 am
Hello Steema Support,
I am experiencing significant performance degradation when enabling minor grid lines in TChart. Here are the details:
- TChart Version: 2023.38.230607
- Delphi Version: Delphi 11
- Operating System: Windows 11 Enterprise
Description:
When I enable minor grid lines in a TChart, the chart's rendering performance drops significantly. This is an issue when we do realtime redraws on mousemove events (see example) and in general when redrawing multiple/big charts.
Steps to Reproduce:
1. Create a new VCL Forms Application in Delphi.
2. Add the code provided below
3. run the app in 64-bit, maximized (in full screen) (performance is the same in 32-bit, but that is not our usecase)
4. Move the mouse into the chart, and the last point in the fastlineseries will follow the movement of the mouse.
5. Use mouse button click to add points to the chart. The display of minor grid lines will be switched on/off every time you click to add a point.
6. Observe the performance degradation when the chart is rendered with minor grid lines visible and you move the mouse.
Sample Code:
I would appreciate any advice or solutions you can provide to improve the performance when minor grid lines are enabled.
Thank you,
Ags
Update:
After further investigation the cause of the performance issue is narrowed down to the PenStyle:
Chart1.LeftAxis.MinorGrid.Style := psDot; // is slow
Chart1.LeftAxis.MinorGrid.Style := psSolid; // is fast
However that means that the performance issue is also observed if psDot is used for the major grid lines:
Chart1.LeftAxis.Grid.Style := psDot; // is slow
I am experiencing significant performance degradation when enabling minor grid lines in TChart. Here are the details:
- TChart Version: 2023.38.230607
- Delphi Version: Delphi 11
- Operating System: Windows 11 Enterprise
Description:
When I enable minor grid lines in a TChart, the chart's rendering performance drops significantly. This is an issue when we do realtime redraws on mousemove events (see example) and in general when redrawing multiple/big charts.
Steps to Reproduce:
1. Create a new VCL Forms Application in Delphi.
2. Add the code provided below
3. run the app in 64-bit, maximized (in full screen) (performance is the same in 32-bit, but that is not our usecase)
4. Move the mouse into the chart, and the last point in the fastlineseries will follow the movement of the mouse.
5. Use mouse button click to add points to the chart. The display of minor grid lines will be switched on/off every time you click to add a point.
6. Observe the performance degradation when the chart is rendered with minor grid lines visible and you move the mouse.
Sample Code:
Code: Select all
uses
VCLTee.Chart, VCLTee.TeEngine, VCLTee.Series;
var
Chart1: TChart;
FastLineSeries: TFastLineSeries;
procedure TForm1.AddFastLineSeriesToPlot;
begin
FastLineSeries := TFastLineSeries.Create(nil);
FastLineSeries.XValues.Order := loNone;
FastLineSeries.YValues.Order := loNone;
FastLineSeries.LinePen.OwnerCriticalSection := nil; // single threaded
FastLineSeries.LinePen.Style := psSolid;
FastLineSeries.LinePen.Width := 5;
FastLineSeries.Color := clRed;
FastLineSeries.AutoRepaint := False;
Chart1.AddSeries(FastLineSeries);
end;
procedure TForm1.ShowHideMinorGrid;
var
MinorGridVisible: Boolean;
begin
if FastLineSeries.XValues.Count > 0 then begin
MinorGridVisible := Odd(FastLineSeries.XValues.Count);
Chart1.BottomAxis.MinorGrid.Visible := MinorGridVisible;
Chart1.LeftAxis.MinorGrid.Visible := MinorGridVisible;
end;
end;
procedure TForm1.AddPoint(MouseX, MouseY: Integer);
var
X: Double;
Y: Double;
begin
X := Chart1.BottomAxis.CalcPosPoint(MouseX);
Y := Chart1.LeftAxis.CalcPosPoint(MouseY);
FastLineSeries.AddXY(X, Y);
FastLineSeries.Repaint;
end;
procedure TForm1.MoveLastPoint(MouseX, MouseY : Integer);
var
Index: Integer;
begin
if FastLineSeries.XValues.Count > 0 then begin
Index := FastLineSeries.XValues.Count - 1;
FastLineSeries.XValues[Index] := Chart1.BottomAxis.CalcPosPoint(MouseX);
FastLineSeries.YValues[Index] := Chart1.LeftAxis.CalcPosPoint(MouseY);
FastLineSeries.Repaint;
end;
end;
procedure TForm1.Chart1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
AddPoint(X, Y);
ShowHideMinorGrid;
end;
procedure TForm1.Chart1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
begin
MoveLastPoint(X, Y);
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
Chart1 := TChart.Create(Self);
Chart1.Parent := Self;
Chart1.Align := alClient;
Chart1.View3D := False;
Chart1.Legend.Visible := False;
Chart1.ClipPoints := False;
Chart1.Canvas.ReferenceCanvas.Pen.OwnerCriticalSection := nil; // single threaded
Chart1.Axes.FastCalc := True;
Chart1.BottomAxis.SetMinMax(0, 100);
Chart1.LeftAxis.SetMinMax(0, 10);
Chart1.OnMouseDown := Chart1MouseDown;
Chart1.OnMouseMove := Chart1MouseMove;
// major grid
Chart1.BottomAxis.Grid.Visible := True;
Chart1.BottomAxis.Grid.Style := psSolid;
Chart1.BottomAxis.Grid.Width := 2;
Chart1.BottomAxis.Grid.Color := clLtGray;
Chart1.LeftAxis.Grid.Visible := True;
Chart1.LeftAxis.Grid.Style := psSolid;
Chart1.LeftAxis.Grid.Width := 2;
Chart1.LeftAxis.Grid.Color := clLtGray;
// minor grid
Chart1.BottomAxis.MinorGrid.Visible := False;
Chart1.BottomAxis.MinorGrid.Style := psDot;
Chart1.BottomAxis.MinorGrid.Width := 1;
Chart1.BottomAxis.MinorGrid.Color := clLtGray;
Chart1.LeftAxis.MinorGrid.Visible := False;
Chart1.LeftAxis.MinorGrid.Style := psDot;
Chart1.LeftAxis.MinorGrid.Width := 1;
Chart1.LeftAxis.MinorGrid.Color := clLtGray;
AddFastLineSeriesToPlot;
AddPoint(10, 10);
end;
I would appreciate any advice or solutions you can provide to improve the performance when minor grid lines are enabled.
Thank you,
Ags
Update:
After further investigation the cause of the performance issue is narrowed down to the PenStyle:
Chart1.LeftAxis.MinorGrid.Style := psDot; // is slow
Chart1.LeftAxis.MinorGrid.Style := psSolid; // is fast
However that means that the performance issue is also observed if psDot is used for the major grid lines:
Chart1.LeftAxis.Grid.Style := psDot; // is slow