Delphi运行时为DBChart添加ChartSeries后Y轴无数据显示问题
问题分析与解决
你的问题核心在于运行时创建的是TChartSeries而非数据库绑定的系列类型:TChartSeries是基础图表系列,不会自动从DataSource读取Y轴数据;而DBChart设计阶段默认添加的是TDBLineSeries这类数据库关联的系列,所以能正常加载数据。
下面是具体的修复方案和优化建议:
1. 核心修改:替换为数据库绑定系列
将TChartSeries换成TDBLineSeries(或你需要的其他DB系列,比如TDBBarSeries),同时确保引入对应的单元。
2. 优化数据源管理(可选但更合理)
你的GetData()每次调用都会新建TFDMemTable,导致两个系列使用独立数据源,既浪费资源也没必要。可以只创建一次数据集,复用给所有系列。
修改后的完整代码
unit ChartTest; interface uses Data.DB, FireDAC.Comp.Client, Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, System.DateUtils, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, VclTee.TeeGDIPlus, VclTee.TeEngine, Vcl.ExtCtrls, VclTee.TeeProcs, VclTee.Chart, VclTee.DBChart, VclTee.DBSeries; // 新增DB系列单元 type TfrmChartTest = class(TForm) chtTestChart: TDBChart; procedure FormShow(Sender: TObject); private FChartData: TFDMemTable; // 保存数据集,避免重复创建 procedure CreateField(MemoryDataSet: TFDMemTable; AFieldName: string; AFieldType: TFieldType; ASize: integer); procedure AddValues(FieldNameXAxe, FieldNameYAxe: string; LineColor: TColor); function GetData(): TFDMemTable; procedure FormDestroy(Sender: TObject); override; public end; var frmChartTest: TfrmChartTest; implementation {$R *.dfm} const dateField: string = 'date1'; intField1: string = 'int1'; intField2: string = 'int2'; { TfrmChartTest } procedure TfrmChartTest.AddValues(FieldNameXAxe, FieldNameYAxe: string; LineColor: TColor); var chartSeries: TDBLineSeries; // 替换为数据库绑定系列 begin chartSeries := TDBLineSeries.Create(chtTestChart); with chartSeries do begin ParentChart := chtTestChart; Marks.Style := smsXValue; DataSource := FChartData; // 复用同一个数据集 SeriesColor := LineColor; XLabelsSource := FieldNameXAxe; Pen.Color := LineColor; Pen.Width := 3; XValues.DateTime := True; YValues.ValueSource := FieldNameYAxe; DrawBetweenPoints := True; end; chtTestChart.AddSeries(chartSeries); chartSeries.Active := True; end; procedure TfrmChartTest.CreateField(MemoryDataSet: TFDMemTable; AFieldName: string; AFieldType: TFieldType; ASize: integer); begin with MemoryDataSet.FieldDefs.AddFieldDef do begin name := AFieldName; DataType := AFieldType; if ASize > 0 then Size := ASize; end; end; procedure TfrmChartTest.FormShow(Sender: TObject); begin FChartData := GetData(); AddValues(dateField, intField1, clRed); AddValues(dateField, intField2, clBlue); chtTestChart.LeftAxis.Minimum := 45; chtTestChart.LeftAxis.Maximum := 175; end; procedure TfrmChartTest.FormDestroy(Sender: TObject); begin FChartData.Free; // 窗体销毁时释放数据集 inherited; end; function TfrmChartTest.GetData: TFDMemTable; var Data: TFDMemTable; begin Data := TFDMemTable.Create(nil); try CreateField(Data, dateField, ftDate, 0); CreateField(Data, intField1, ftInteger, 0); CreateField(Data, intField2, ftInteger, 0); Data.CreateDataSet(); Data.Append(); Data.FieldByName(dateField).AsDateTime := Yesterday; Data.FieldByName(intField1).AsInteger := 50; Data.FieldByName(intField2).AsInteger := 130; Data.Append(); Data.FieldByName(dateField).AsDateTime := Today; Data.FieldByName(intField1).AsInteger := 70; Data.FieldByName(intField2).AsInteger := 150; Data.Append(); Data.FieldByName(dateField).AsDateTime := Tomorrow; Data.FieldByName(intField1).AsInteger := 90; Data.FieldByName(intField2).AsInteger := 170; Data.First; // 移动到数据集起始位置 Result := Data; except Data.Free; raise; end; end; end.
修改点说明
- 系列类型替换:
TDBLineSeries是专门为数据库绑定设计的系列,会自动从DataSource读取X/Y轴数据,而TChartSeries需要手动添加数据点,这就是之前Y轴无数据的根本原因。 - 数据集生命周期管理:把
TFDMemTable作为窗体私有成员,在窗体销毁时释放,避免系列失去数据源导致显示异常。 - 引入
VclTee.DBSeries单元:该单元包含所有数据库绑定的Chart系列类型,必须引入才能使用TDBLineSeries等DB系列。
如果设计阶段添加的是其他DB系列(比如TDBBarSeries),只需把代码中的TDBLineSeries换成对应类型即可。
内容的提问来源于stack exchange,提问作者Nico Haegens
相关产品推荐
相关产品推荐

