Ich habe mir aus deinem Code folgendes Test-Programm zusammengebaut (mit einigen Vereinfachungen, weil ich einige von dir verwendete Routinen nicht habe):
Code: Alles auswählen
unit Unit1;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, FileUtil, TAGraph, Forms, Controls, Graphics, Dialogs,
StdCtrls, ExtCtrls, TASeries;
type
{ TForm1 }
TMessWert = record
MessWert: Double;
GetTimeString: String;
end;
TForm1 = class(TForm)
Button1: TButton;
Chart1: TChart;
Chart1LineSeries1: TLineSeries;
Panel1: TPanel;
procedure Button1Click(Sender: TObject);
private
{ private declarations }
function GetColor(AColorIndex: Integer): TColor;
procedure GetMessWerte(AIndex: Integer; out AMesswert: TMesswert);
public
{ public declarations }
end;
var
Form1: TForm1;
const
MessWertCount = 150;
implementation
{$R *.lfm}
const
PALETTESIZE = 5;
PALETTE: Array[0..PALETTESIZE-1] of TColor = (
clRed, clBlue, clBlack, clGreen, clFuchsia
);
{ TForm1 }
procedure TForm1.GetMesswerte(AIndex: Integer; out AMessWert: TMessWert);
// Dummy-Prozedur, weil ich deine Routine nicht habe
var
t: TTime;
begin
AMessWert.MessWert := sin(AIndex/2);
t := AIndex / (24*60*60);
// Nehme an, dass jede Sekunde 1 Messung anfällt und die Messung um Mitternacht beginnt
AMessWert.GetTimeString := FormatDateTime('hh:nn:ss', t);
end;
function TForm1.GetColor(AColorIndex: Integer): TColor;
// Dummy-Prozedur:
// Farbe in Palette nachschlagen. Falls die Palette nicht ausreicht, von vorne
// anfangen.
begin
Result := PALETTE[AColorIndex mod PALETTESIZE];
end;
procedure TForm1.Button1Click(Sender: TObject);
var
i: Integer;
pe2: TMesswert;
ActualColor, ActualChange: Integer;
SeriesArray: Array of TLineSeries;
begin
ActualChange:=0;
ActualColor := 0;
SetLength(SeriesArray, ActualChange+1);
SeriesArray[ActualChange] := TLineSeries.Create(Chart1); // besser: Form1 statt Chart1
SeriesArray[ActualChange].AxisIndexX := 1; // MPSeries.AxisIndexX; -- weiß nicht, was MPSeries ist!
SeriesArray[ActualChange].AxisIndexY := 0; // MPSeries.AxisIndexY;
SeriesArray[ActualChange].ShowPoints := false;
SeriesArray[ActualChange].SeriesColor := GetColor(ActualColor);
Chart1.AddSeries(SeriesArray[ActualChange]);
SeriesArray[ActualChange].AddXY(0, 0, '0:00', GetColor(ActualColor));
for i := 1 to MesswertCount do begin
GetMesswerte(i, pe2);
SeriesArray[ActualChange].AddXY(i, pe2.Messwert, pe2.GetTimeString, GetColor(ActualColor));
if i mod 10 = 0 then begin // alle 10 Werte die Farbe wechseln
inc(ActualColor);
inc(ActualChange);
SetLength(SeriesArray, ActualChange+1);
SeriesArray[ActualChange] := TLineSeries.Create(Chart1); // besser: Form1 statt Chart1
SeriesArray[ActualChange].ShowPoints := false;
SeriesArray[ActualChange].AxisIndexX := 1; // MPSeries.AxisIndexX; -- weiß nicht, was MPSeries ist!
SeriesArray[ActualChange].AxisIndexY := 0; // MPSeries.AxisIndexY;
SeriesArray[ActualChange].SeriesColor := GetColor(ActualColor);
Chart1.AddSeries(SeriesArray[ActualChange]);
SeriesArray[ActualChange].AddXY(i, pe2.MessWert, pe2.GetTimeString, GetColor(ActualColor));
// weiß nicht, was "GetDepthInM" ist...
end;
end;
end;
end.
Zum Nachvollziehen: Einfach ein Formular mit einem Chart und einem Button erstellen.
Das Speicherleck sehe ich nicht, es wird wahrscheinlich irgendwo in dem restlichen Code erzeugt werden. Unüblich ist meiner Meinung nach, dass du den Chart als Owner der Series verwendest; ich nehme da immer das Formular, ich erinnere mich, dass es sonst mindestens 1x Probleme gab.
rob hat geschrieben:
Ich frage mich ob das hier sein muss, es funktioniert irgendwie auch ohne ...[/b]
SeriesArray[ActualChange].AxisIndexX:=MPSeries.AxisIndexX;
SeriesArray[ActualChange].AxisIndexY:=MPSeries.AxisIndexY;
Ist normalerweise nicht nötig, wenn du nur die zwei Standardachsen und keine Achsen-Transformationen brauchst. Wenn du aber, wie in den anderen Thread angefragt, mehrere Achsen verwenden willst, ist es ein Muss.
Wenn du diese Klippe umschifft hast, wirst du als nächstes Probleme haben, die Labels, die du den Datenpunkten zugeordnet hast, an der x-Achse angezeigt zu kriegen. Für die Marks der Achse brauchst du eine Datenquelle (ChartSource), aber da die Series nun in viele Teilseries zerstückelt ist, gibt es keine ChartSource, die durchgängig alle Labels für die x-Achse enthält. Deine Original-Daten stehen wahrscheinlich in einem Array. Daher würde ich vorschlagen, für jede Series noch eine "UserDefinedChartSouce" zu erzeugen,die jeweils ihre Daten je nach Indexbereich aus dem Array holt. Wird aber schon ganz schön "advanced"...
[EDIT]
Oder du nimmst dir eine ListChartSource, in die du die Datum/Zeit-Werte für jeden Datenpunkt der Gesamtserie schreibst. Diese wird der Marks.Source der x-Achse zugewiesen. Die Zuweisung eines Labels an die einzelnen Datenpunkte kann dann entfallen (genauso wie jetzt schon die Zuweisung einer Datenpunkt-Farbe, die ja nur für die (nicht angezeigten) Symbole gilt.