html HotPDF Przykład wykresu | losLab Software Development Blog

Artykuł techniczny

HotPDF Przykład wykresu

Ten przykładowy komponent HotPDF eksportuje wykres Delphi TeeChart do dokumentu PDF. Przykład demonstruje praktyczny pomost pomiędzy interaktywnymi wykresami VCL i dystrybuowalnymi raportami PDF: użytkownicy mogą skonfigurować styl wykresu w formularzu, a następnie aplikacja drukuje wybrany stan wykresu na stronie PDF.

Kod jest przydatny w przypadku dashboardów, raportów inżynieryjnych, podsumowań finansowych i dowolnej aplikacji Delphi, która już korzysta z TeeChart do wizualizacji na ekranie. Zamiast ręcznie odbudowywać wykres za pomocą wywołań rysowania PDF, przykład pozwala TeeChart renderować się na kanwie strony HotPDF.

Zakreślacz składni Urvanov v2.9.1

Kiedy ten wzorzec pomaga

Eksport wykresu jest często potrzebny po interaktywnej konfiguracji. Użytkownik mógł wybrać tryb stosu, zmienić widoczne serie, przefiltrować dane albo przełączyć widok między wartościami bezwzględnymi i procentami. Przechwycenie bieżącego stanu TeeChart sprawia, że PDF odpowiada temu, co sprawdzono na ekranie.

To podejście utrzymuje też mały kod raportu. TeeChart nadal odpowiada za osie, etykiety, legendy, style słupków i serie, a HotPDF obsługuje cykl życia dokumentu PDF i canvas strony. Taki podział jest łatwiejszy w utrzymaniu niż duplikowanie każdej reguły wykresu w osobnej rutynie PDF.

Przed eksportem

  • Ustaw wykres w stanie wizualnym, który ma trafić do PDF.
  • Wybierz prostokąt wykresu zgodny z orientacją strony i marginesami.
  • Zarezerwuj miejsce na tytuł raportu, filtry, zakres dat i notatki o źródle danych, jeśli PDF będzie archiwizowany.
  • Przetestuj długie etykiety i zlokalizowane nazwy miesięcy przed udostępnieniem eksportu.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
unit ChartUnit;
 
interface
 
uses
  {$IF CompilerVersion >= 16} Winapi.Windows, Winapi.Messages, System.SysUtils, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ExtCtrls, VclTee.TeeGDIPlus, VclTee.TeEngine, VclTee.Series, VclTee.TeeProcs, VclTee.Chart,
  {$ELSE}Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls, TeEngine, Series, TeeProcs, Chart,
  {$ENDIF} HPDFDoc;
 
type
  TForm1 = class(TForm)
    RadioGroup1: TRadioGroup;
    DemoChart: TChart;
    BarSeries1: TBarSeries;
    BarSeries2: TBarSeries;
    BarSeries3: TBarSeries;
    Panel1: TPanel;
    Label1: TLabel;
    RadioGroup2: TRadioGroup;
    ComboBox1: TComboBox;
    Button1: TButton;
    procedure RadioGroup1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure RadioGroup2Click(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
 
var
  Form1: TForm1;
 
implementation
 
{$R *.DFM}
 
procedure TForm1.RadioGroup1Click(Sender: TObject);
begin
  Case RadioGroup1.ItemIndex of
    0: BarSeries1.MultiBar:=mbNone;
    1: BarSeries1.MultiBar:=mbSide;
    2: BarSeries1.MultiBar:=mbStacked;
    3: BarSeries1.MultiBar:=mbStacked100;
  end;
end;
 
procedure TForm1.FormCreate(Sender: TObject);
var
  H: Integer;
begin
  DemoChart.View3D:=False;
  Randomize;
  {$IFDEF VER220}
  with BarSeries1 do
   for H:=1 to 12 do Add( Random(100),FormatSettings.ShortMonthNames[H],clTeeColor);
  with BarSeries2 do
   for H:=1 to 12 do Add( Random(100),FormatSettings.ShortMonthNames[H],clTeeColor);
  with BarSeries3 do
  for H:=1 to 12 do Add( Random(100),FormatSettings.ShortMonthNames[H],clTeeColor);
  {$ELSE}
  with BarSeries1 do
   for H:=1 to 12 do Add( Random(100),ShortMonthNames[H],clTeeColor);
  with BarSeries2 do
   for H:=1 to 12 do Add( Random(100),ShortMonthNames[H],clTeeColor);
  with BarSeries3 do
  for H:=1 to 12 do Add( Random(100),ShortMonthNames[H],clTeeColor);
  {$ENDIF}
  ComboBox1.Items.Clear;
  for H:=0 to DemoChart.SeriesCount-1 do
    ComboBox1.Items.Add(DemoChart.Series[H].Name);
  ComboBox1.ItemIndex:=0;
end;
 
procedure TForm1.RadioGroup2Click(Sender: TObject);
begin
  With DemoChart.Series[ComboBox1.ItemIndex] as TBarSeries do
    BarStyle:=TBarStyle(RadioGroup2.Itemindex);
end;
 
procedure TForm1.Button1Click(Sender: TObject);
var
  HotPDF: THotPDF;
  ChartRect: TRect;
begin
  HotPDF := THotPDF.Create(nil);
  try
    case RadioGroup1.ItemIndex of
      0: HotPDF.FileName := 'PDFChart-Behind.pdf';
      1: HotPDF.FileName := 'PDFChart-SideToSide.pdf';
      2: HotPDF.FileName := 'PDFChart-Stacked.pdf';
      3: HotPDF.FileName := 'PDFChart-Stacked100.pdf';
    end;
    HotPDF.BeginDoc;
    ChartRect.Left := 0;
    ChartRect.Right := 800;
    ChartRect.Top := 0;
    ChartRect.Bottom := 600;
    DemoChart.PrintPartialCanvas( HotPDF.CurrentPage.Canvas, ChartRect );
    HotPDF.EndDoc;
  finally
    HotPDF.Free;
  end;
end;
 
end.

Przepływ eksportu

  • Formularz tworzy przykładowe dane wykresu i pozwala użytkownikowi wybrać układ słupków.
  • Przycisk eksportu tworzy THotPDF i wybiera nazwę pliku wyjściowego na podstawie trybu wykresu.
  • ChartRect definiuje docelowy obszar rysunku na stronie PDF.
  • DemoChart.PrintPartialCanvas renderuje wykres w kanwie PDF.
  • EndDoc finalizuje plik PDF.

Zalecenia dotyczące układu

Zachowaj prostokąt wykresu proporcjonalny do obszaru wykresu na ekranie i testuj etykiety osi z długim, zlokalizowanym tekstem. Jeśli PDF jest częścią raportu, zarezerwuj miejsce na tytuł, sygnaturę czasową, źródło danych i notatki, aby wykres zachował znaczenie, gdy będzie oglądany poza oryginalną aplikacją.

[Czas formatowania: 0,0023 sekundy]

Lista kontrolna produkcji

  • Obejmij tworzenie THotPDF blokiem try/finally, aby komponent został zwolniony po nieudanym eksporcie.
  • Do testów regresji używaj deterministycznych danych wykresu zamiast Randomize.
  • Ustal, czy każdy tryb wykresu ma nadpisywać stałą nazwę pliku, czy pytać o miejsce docelowe.
  • Sprawdź wynik na pustych seriach, wartościach ujemnych i długich etykietach kategorii.

W raportach z wieloma wykresami nadaj każdemu wykresowi własną sekcję strony i zachowaj spójne skale. Czytelnicy porównują strony PDF obok siebie, więc zmiana zakresu osi lub kolejności legendy może sprawić, że poprawny eksport będzie wyglądał myląco.

Typowe pułapki

Najczęstszy błąd to traktowanie przechwycenia wykresu jak bitmapowego zrzutu ekranu. Ten przykład używa ścieżki canvas wykresu, dzięki czemu wynik jest czystszy i nie zależy od rozdzielczości ekranu. Drugim problemem jest przycinanie: prostokąt przekazywany do PrintPartialCanvas trzeba sprawdzić z największą oczekiwaną legendą i etykietami.