Ich habe ein TAChart, in dem bis zu XY-Datenreihen dargestellt werden. Ich würde gern zwischen Liniendarstellung (Gerade zwischen benachbarten Punkten) und kubischem Spline umschalten.
Aktuelle mache ich es so, dass ich je 12 TLineSeries und 12 TCubicSplineSeries erstelle und die Daten entweder in die einen oder die anderen schreibe.
Gibt es auch eine Möglichkeit, nur mit einer Art TxxxSeries zu arbeiten und die Darstellung umzuschalten?
Und gibt es eine Übersicht, welche Setter was am Diagramm verändert (Linienart, Dicke, Farbe, Punkte...). Ich hab zwar einige Seiten zu TACHarts durch aber es ist eine ganz schöne Sucherei.
TAChart - Umschalten zwischen Linie und Spline?
-
- Beiträge: 1224
- Registriert: So 20. Mär 2016, 22:14
- OS, Lazarus, FPC: Win7-64bit Laz1.9.0 FPC3.1.1 für Win, RPi, AVR embedded
- CPU-Target: Raspberry Pi 3
Re: TAChart - Umschalten zwischen Linie und Spline?
Nein, eine so vielgesichtige "LineSpline" Series gibt es nicht. Du musst tatsächlich 12 Series von jeder Sorte in den Chart klicken (oder zur Laufzeit erzeugen). Du kannst die Daten allerdings zentral z.B. in ein einer TListChartSource ablegen, die du dann der jeweils anzuzeigenden Series zuweist (Property Source := ListChartSource1) bzw. von der anderen Sorte wegnimmst (Property Source := nil).
Etwa so (nicht getestet):
Wenn du die Series zur Laufzeit erzeugst, könnte dir auch mir einer Routine wie "ChangeSeriesType" geholfen sein, die ich in einem größeren Projekt einmal verwendet habe (ich hoffe, ich habe alles mit rauskopiert):
Eine Übersicht, wie du sie vielleicht meinst, gibt es nicht. Aber in der TAChart-Documentation wird alles angesprochen, aber halt nur sehr knapp. Wenn du es ausführlicher willst, musst du dir das Lazarus-Handbook besorgen, dort habe ich mich über 50 Seiten ausgetobt.
Etwa so (nicht getestet):
Code: Alles auswählen
procedure TForm1.FomrCreate(Sender: TObject);
var
i: Integer;
x,y: Double;
begin
for i := 0 to 100 do begin
x := i/10;
y := sin(x);
ListChartsource1.Add(x, y);
end;
end;
procedure TForm1.LineOrSpline(line: Boolean);
begin
if line then
begin
Chart1LineSeries1.Source := ListChartSource1
Chart1SplineSeries1.Source := nil;
end else
begin
Chart1LineSeries1.Source := nil;
Chart1SplineSeries1.Source := ListChartSource1;
end;
end;
Code: Alles auswählen
type
TSeriesType = (stAreaSeries, stBarSeries, stLineSeries,
stCubicSplineSeries, stBSplineSeries, stOther);
procedure ApplyColorsToSeries(ASeries: TChartSeries;
ASeriesColor, ABorderColor, ASymbolColor: TColor);
begin
SetSeriesColor(ASeries, ASeriesColor);
SetSeriesBorderColor(ASeries, ABorderColor);
SetSeriesSymbolColor(ASeries, ASymbolColor);
end;
procedure ExtractColorsFromSeries(ASeries: TChartSeries;
var ASeriesColor, ABorderColor, ASymbolColor: TColor);
begin
ASeriesColor := GetSeriesColor(ASeries);
ABorderColor := GetSeriesBorderColor(ASeries);
if ASeries is TLineSeries then
ASymbolColor := GetSeriesSymbolColor(ASeries)
else
ASymbolColor := ASeriesColor;
end;
function GetSeriesBorderColor(ASeries: TChartSeries): TColor;
begin
if ASeries is TLineSeries then
Result := TLineSeries(ASeries).Pointer.Pen.Color
else
if ASeries is TCubicSplineSeries then
Result := TCubicSplineSeries(ASeries).Pointer.Pen.Color
else
if ASeries is TBSplineSeries then
Result := TBSplineSeries(ASeries).Pointer.Pen.Color
else
if ASeries is TBarSeries then
Result := TBarSeries(ASeries).BarPen.Color
else
if ASeries is TAreaSeries then
Result := TAreaSeries(ASeries).AreaContourPen.Color
else
Result := clNone;
end;
procedure SetSeriesBorderColor(ASeries: TChartSeries; AColor: TColor);
begin
if ASeries is TLineSeries then
TLineSeries(ASeries).Pointer.Pen.Color := AColor
else
if ASeries is TCubicSplineSeries then
TCubicSplineSeries(ASeries).Pointer.Pen.Color := AColor
else
if ASeries is TBSplineSeries then
TBSplineSeries(ASeries).Pointer.Pen.Color := AColor
else
if ASeries is TBarSeries then
TBarSeries(ASeries).BarPen.Color := AColor
else
if ASeries is TAreaSeries then
TAreaSeries(ASeries).AreaContourPen.Color := AColor;
end;
function GetSeriesSymbolColor(ASeries: TChartSeries): TColor;
begin
if ASeries is TLineSeries then
Result := TLineSeries(ASeries).Pointer.Brush.Color
else
if ASeries is TCubicSplineSeries then
Result := TCubicSplineSeries(ASeries).Pointer.Brush.Color
else
if ASeries is TBSplineSeries then
Result := TBSplineSeries(ASeries).Pointer.Brush.Color
else
Result := clNone;
end;
procedure SetSeriesSymbolColor(ASeries: TChartSeries; AColor: TColor);
begin
if ASeries is TLineSeries then
TLineSeries(ASeries).Pointer.Brush.Color := AColor
else
if ASeries is TCubicSplineSeries then
TCubicSplineSeries(ASeries).Pointer.Brush.Color := AColor
else
if ASeries is TBSplineSeries then
TBSplineSeries(ASeries).Pointer.Brush.Color := AColor;
end;
function GetSeriesColor(ASeries: TChartSeries): TColor;
begin
if ASeries is TLineSeries then
Result := TLineSeries(ASeries).SeriesColor
else
if ASeries is TCubicSplineSeries then
Result := TCubicSplineSeries(ASeries).Pen.Color
else
if ASeries is TBSplineSeries then
Result := TBSplineSeries(ASeries).Pen.Color
else
if ASeries is TBarSeries then
Result := TBarSeries(ASeries).BarBrush.Color
else
if ASeries is TAreaSeries then
Result := TAreaSeries(ASeries).AreaBrush.Color
else
Result := clNone;
end;
procedure SetSeriesColor(ASeries: TChartSeries; AColor: TColor);
begin
if ASeries is TLineSeries then
TLineSeries(ASeries).SeriesColor := AColor
else
if ASeries is TCubicSplineSeries then
TCubicSplineSeries(ASeries).Pen.Color := AColor
else
if ASeries is TBSplineSeries then
TBSplineSeries(ASeries).Pen.Color := AColor
else
if ASeries is TBarSeries then
TBarSeries(ASeries).BarBrush.Color := AColor
else
if ASeries is TAreaSeries then begin
TAreaSeries(ASeries).AreaBrush.Color := AColor;
TAreaSeries(ASeries).AreaLinesPen.Color := AColor;
end;
end;
function GetSeriesLineSymbolMode(ASeries: TChartSeries): TLineSymbolMode;
begin
Result := lsmLinesOnly;
if ASeries is TLineSeries then
with TLineSeries(ASeries) do
Result := TLineSymbolMode(ord(ShowPoints) + ord(ShowLines)*2 - 1)
else
if ASeries is TCubicSplineSeries then
with TCubicSplineSeries(ASeries) do
Result := TLineSymbolMode(ord(Pointer.Visible) + ord(Pen.Visible)*2 - 1)
else
if ASeries is TBSplineSeries then
with TBSplineSeries(ASeries) do
Result := TLineSymbolMode(ord(Pointer.Visible) + ord(Pen.Visible)*2 - 1);
end;
procedure SetSeriesLineSymbolMode(ASeries: TChartSeries; AMode: TLineSymbolMode);
begin
if ASeries is TLineSeries then
with TLineSeries(ASeries) do begin
ShowPoints := AMode in [lsmSymbolsOnly, lsmBoth];
ShowLines := AMode in [lsmLinesOnly, lsmBoth];
end
else
if ASeries is TCubicSplineSeries then
with TCubicSplineSeries(ASeries) do begin
Pointer.Visible := AMode in [lsmSymbolsOnly, lsmBoth];
Pen.Visible := AMode in [lsmLinesOnly, lsmBoth];
end
else
if ASeries is TBSplineSeries then
with TBSplineSeries(ASeries) do begin
Pointer.Visible := AMode in [lsmSymbolsOnly, lsmBoth];
Pen.Visible := AMode in [lsmLinesOnly, lsmBoth];
end;
end;
function GetSeriesType(ASeries: TChartSeries): TSeriesType;
begin
if ASeries is TLineSeries then
Result := stLineSeries
else
if ASeries is TCubicSplineSeries then
Result := stCubicSplineSeries
else
if ASeries is TBSplineSeries then
Result := stBSplineSeries
else
if ASeries is TBarSeries then
Result := stBarSeries
else
if ASeries is TAreaSeries then
Result := stAreaSeries
else
Result := stOther;
end;
function ChangeSeriesType(ASeries: TChartSeries;
ANewType: TSeriesType): TChartSeries;
var
sertype: TSeriesType;
src: TCustomChartSource;
cs, cb, csym: TColor;
begin
sertype := GetSeriesType(ASeries);
if sertype = ANewType then begin
Result := ASeries;
exit;
end;
case ANewType of
stLineSeries:
begin
Result := TLineSeries.Create(ASeries.Owner);
end;
stCubicSplineSeries:
begin
Result := TCubicSplineSeries.Create(ASeries.Owner);
{$IFDEF LCL_FullVersion < 2000000}
with TCubicSplineSeries(Result) do begin
Options := Options + [csoDrawFewPoints];
end;
{$IFEND}
end;
stBSplineSeries:
begin
Result := TBSplineSeries.Create(ASeries.Owner);
end;
stBarSeries:
begin
Result := TBarSeries.Create(ASeries.Owner);
end;
stAreaSeries:
begin
Result := TAreaSeries.Create(ASeries.Owner);
TAreaSeries(Result).UseZeroLevel := true;
end;
stOther:
raise Exception.Create('Unknown series type in ChangeSeriesType.');
end;
// Copy colors from old to new series
ExtractColorsFromSeries(ASeries, cs, cb, csym);
ApplyColorsToSeries(Result, cs, cb, csym);
if Result is TCubicSplineSeries then
with TCubicSplineSeries(Result) do
BadDataPen.Color := Pen.Color;
// Copy properties to new series
Result.Active := ASeries.Active;
Result.AxisIndexX := ASeries.AxisIndexX;
Result.AxisIndexY := ASeries.AxisIndexY;
Result.Legend.Assign(ASeries.Legend);
//Result.MarkPositions := ASeries.MarkPosition;:
Result.Marks.Assign(ASeries.Marks);
Result.Tag := ASeries.Tag;
Result.Title := ASeries.Title;
Result.Transparency := ASeries.Transparency;
Result.ZPosition := ASeries.ZPosition;
// Now copy the chart sources. If no external source is used by ASeries then
// copy the built-in source to the result series. If an external source is
// used just assign it to the result source as well.
if IsBuiltInChartSource(ASeries.Source) then
Result.ListSource.CopyFrom(ASeries.ListSource)
else
Result.Source := ASeries.Source;
// Add new series to chart and move to the index of the old series
ASeries.ParentChart.AddSeries(Result);
Result.Index := ASeries.Index;
// Remove and destroy old series
ASeries.ParentChart.RemoveSeries(ASeries);
ASeries.Free;
end;
-
- Beiträge: 1224
- Registriert: So 20. Mär 2016, 22:14
- OS, Lazarus, FPC: Win7-64bit Laz1.9.0 FPC3.1.1 für Win, RPi, AVR embedded
- CPU-Target: Raspberry Pi 3
Re: TAChart - Umschalten zwischen Linie und Spline?
Danke, hab ich so umgesetzt.