TChart.PaintOnCanvas TBitmap

Rund um die LCL und andere Komponenten
Antworten
Dr. Spencer
Beiträge: 7
Registriert: Mi 26. Jan 2011, 19:42
OS, Lazarus, FPC: Winux (L 0.9.31 FPC 2.4.0)
CPU-Target: x86 32/64

TChart.PaintOnCanvas TBitmap

Beitrag von Dr. Spencer »

Hallo,
ich verzweifel gerade an der Komponente TAChart, da die Routine PaintOnCanvas bei mir Schrott erzeugt.
Der Witz ist, wenn ich den Abschnitt isolier, dann funktionierts:

Code: Alles auswählen

procedure TForm1.pngClick(Sender: TObject);
var
  i, x, y: integer;
  charts: array of TChart;
  series: array of array of TLineSeries;
  img: TPortableNetworkGraphic;
  R: TRect;
  eCh: TChartNames;
  fname: string;
begin
  // initialisieren
  SetLength(charts, Ord(cnDrei)+1);
  SetLength(series, Ord(cnDrei)+1, 2);
  for eCh:=cnEins to cnDrei do
    begin x:=Ord(eCh);
    charts[x] := TChart.Create(self);
    charts[x].BackColor:=clWhite;
    charts[x].Width:=675;
    charts[x].Height:=450;
 
    for i:=0 to Length(series[x])-1 do
      series[x][i]:=TLineSeries.Create(charts[x]);
    for i:=0 to 10 do
      begin
      series[x][0].AddXY(i, i*(i+x));
      series[x][1].AddXY(i, i*((i+x)/2));
      end;
    charts[x].AddSeries(series[x][0]);
    charts[x].AddSeries(series[x][1]);
    end;
 
  // zeichnen
  img:=TPortableNetworkGraphic.Create;
  for eCh:=cnEins to cnDrei do
    begin
    i:=Ord(eCh);
    fname:='test_'+IntToStr(i)+'.png';
    case eCh of
      cnDrei:
        begin
        x:=charts[i].Width;
        y:=charts[i].Height;
 
        img.Width:=x+1;
        img.Height:=y*3;
 
 
        R:=Rect(0,0,x,y);
        charts[Ord(cnEins)].PaintOnCanvas(img.Canvas, R);
        R:=Rect(0,y,x,y*2);
        charts[Ord(cnZwei)].PaintOnCanvas(img.Canvas, R);
        R:=Rect(0,y*2,x,y*3);
        charts[i].PaintOnCanvas(img.Canvas, R);
 
        img.SaveToFile(fname);
        img.Clear;
        end;
      cnZwei:
        x:=x
      else
        charts[i].SaveToFile(TPortableNetworkGraphic, fname);
      end;
    end;
 
  img.Free;
  for eCh:=cnEins to cnDrei do
    begin x:=Ord(eCh);
    for i:=0 to Length(series[x])-1 do
      series[x][i].Free;
    charts[x].Free;
    end;
  SetLength(series, 0,0);
  SetLength(charts, 0);
end;


Ich hatte mir ein workaround für das "zusammenmalen" der Charts ausgedacht, mit temporären Bitmaps, welche dann mit TBitmap.Canvas.Draw zusammengeführt werden. Das lief aber instabil und langsam (bei 150 Bildern).

Ich weiß langsam nicht mehr weiter, daher meine Frage:
Ist mein Schnipsel da oben im Sinne des Erfinders? Woran könnte es liegen, das nur die Serien und die Legende gemalt werden?

Gruß, Hannes

Ach ja, mit TChart.PaintTo gabs wohl auch mal stress: http://bugs.freepascal.org/view.php?id=18242
Dateianhänge
isoliert und heil
isoliert und heil
echt aber kaputt
echt aber kaputt

Dr. Spencer
Beiträge: 7
Registriert: Mi 26. Jan 2011, 19:42
OS, Lazarus, FPC: Winux (L 0.9.31 FPC 2.4.0)
CPU-Target: x86 32/64

Re: TChart.PaintOnCanvas TBitmap

Beitrag von Dr. Spencer »

hat sich erledigt. TAChart ist mit meiner alten rev nicht stabil.

Meine Anforderung sind 12 Charts * 33 Standorte = 396 Charts -> 5 Bilder * 33 Standorte = 165 .png Dateien

Es scheint wohl innerhalb der Komponente ein irgendein Fehler zu geben, der den Intervall für die Achsenbeschriftung und eben das malen des TChart beeinflusst, wenn bestimmte Datenkonstellationen auftreten. Die Anzahl der Datenpunkte spielt dabei wohl indirekt eine Rolle.

Ich hab mir nun einen aktuellen Snapshot besorgt (Lazarus-0.9.31-32006-fpc-2.4.4-20110819-win32.exe) mit dem mein Code bisher problemlos läuft.

Antworten