Detta HotPDF-komponentexempel exporterar ett Delphi TeeChart-diagram till ett PDF-dokument. Exemplet visar en praktisk brygga mellan interaktiv VCL-diagram och distribuerbara PDF-rapporter: användare kan konfigurera diagramstilen i formuläret, sedan skriver programmet ut det valda sjökortstillståndet till en PDF-sida.
Koden är användbar för instrumentpaneler, tekniska rapporter, ekonomiska sammanfattningar och alla Delphi-applikationer som redan använder TeeChart för visualisering på skärmen. Istället för att bygga om diagrammet manuellt med PDF-ritningsanrop låter exemplet TeeChart rendera sig själv på HotPDF-sidans arbetsyta.
När mönstret hjälper
Diagramexport behövs ofta efter att diagrammet redan har konfigurerats interaktivt. Användaren kan ha valt staplingsläge, ändrat synliga serier, filtrerat data eller växlat mellan absoluta värden och procent. Genom att fånga det aktuella TeeChart-läget matchar PDF-filen det användaren granskade på skärmen.
Samma metod håller även rapportkoden liten. TeeChart ansvarar fortsatt för axlar, etiketter, förklaringar, stapelstilar och serier, medan HotPDF hanterar PDF-dokumentets livscykel och sidans canvas. Den uppdelningen är lättare att underhålla än att duplicera varje diagramregel i en separat PDF-ritrutin.
Före export
- Ställ in diagrammet till det visuella läge som ska visas i PDF-filen.
- Välj en diagramrektangel som passar sidriktning och marginaler.
- Reservera utrymme för rapporttitel, filter, datumintervall och datakällanteckningar om PDF-filen ska arkiveras.
- Testa långa etiketter och lokaliserade månadsnamn innan exportfunktionen släpps.
|
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. |
Exportflöde
- Formuläret skapar exempeldiagramdata och låter användaren välja stapellayouten.
- Exportknappen skapar THotPDF och väljer ett utdatafilnamn baserat på diagramläget.
- ChartRect definierar målritningsområdet på PDF-sidan.
- DemoChart.PrintPartialCanvas återger diagrammet till PDF-duken.
- EndDoc slutför PDF-filen.
Layoutrekommendationer
Håll sjökortsrektangeln proportionell mot sjökortsområdet på skärmen och testa axeletiketter med lång lokaliserad text. Om PDF-filen är en del av en rapport, reservera utrymme för en titel, tidsstämpel, datakälla och anteckningar så att diagrammet förblir meningsfullt när det visas utanför det ursprungliga programmet.
Produktionschecklista
- Omslut skapandet av THotPDF med try/finally så att komponenten frigörs efter misslyckade exporter.
- Använd deterministiska diagramdata för regressionstester i stället för Randomize.
- Bestäm om varje diagramläge ska skriva över ett fast filnamn eller fråga efter mål.
- Validera resultatet med tomma serier, negativa värden och långa kategorietiketter.
För rapporter med flera diagram bör varje diagram få en egen sidsektion och skalvalen vara konsekventa mellan sidorna. Läsare jämför PDF-sidor sida vid sida, så ändrade axelintervall eller legendordning kan få en korrekt export att se missvisande ut.
Vanliga fallgropar
Det vanligaste misstaget är att behandla diagramfångsten som en bitmap-skärmbild. Exemplet använder i stället diagrammets canvasväg, vilket bevarar renare utdata och undviker beroende av skärmupplösning. Ett annat vanligt problem är klippning: rektangeln som skickas till PrintPartialCanvas bör testas med största förväntade förklaring och etiketter.