기술 문서

HotPDF 차트 샘플

이 HotPDF 구성 요소 예제는 Delphi TeeChart 차트를 PDF 문서로 내보냅니다. 이 예제는 대화형 VCL 차트와 배포 가능한 PDF 보고서 간의 실용적인 연결을 보여줍니다. 사용자는 폼에서 차트 스타일을 구성한 다음, 애플리케이션이 선택한 차트 상태를 PDF 페이지로 인쇄합니다.

이 코드는 대시보드, 엔지니어링 보고서, 재무 요약 및 화면 표시용으로 TeeChart를 이미 사용하는 모든 Delphi 애플리케이션에 유용합니다. 차트를 수동으로 다시 만들고 PDF 그리기 호출을 사용하는 대신, 이 예제에서는 TeeChart가 HotPDF 페이지 캔버스에 자체적으로 렌더링되도록 합니다.

이 패턴이 유용한 경우

차트 내보내기는 차트가 이미 대화식으로 설정된 뒤에 필요한 경우가 많습니다. 사용자가 누적 모드를 선택했거나, 표시할 시리즈를 바꿨거나, 데이터를 필터링했거나, 절대값과 백분율 보기를 전환했을 수 있습니다. 현재 TeeChart 상태를 캡처하면 사용자가 화면에서 검토한 결과와 PDF 출력이 일치합니다.

이 접근 방식은 보고서 코드도 작게 유지합니다. 축, 레이블, 범례, 막대 스타일, 시리즈 렌더링은 TeeChart가 담당하고, HotPDF는 PDF 문서 수명 주기와 페이지 Canvas를 처리합니다. 이런 분리는 모든 차트 규칙을 별도의 PDF 그리기 루틴에 중복 구현하는 것보다 유지 관리가 쉽습니다.

내보내기 전 확인

  • PDF에 표시할 시각적 상태로 차트를 설정합니다.
  • 대상 페이지 방향과 여백에 맞는 차트 사각형을 선택합니다.
  • PDF를 보관할 경우 보고서 제목, 필터, 날짜 범위, 데이터 원본 메모 영역을 확보합니다.
  • 기능을 배포하기 전에 긴 레이블과 현지화된 월 이름을 테스트합니다.
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.

내보내기 흐름

  • 폼은 샘플 차트 데이터를 생성하고 사용자가 막대 레이아웃을 선택할 수 있도록 합니다.
  • 내보내기 버튼은 THotPDF를 생성하고 차트 모드에 따라 출력 파일 이름을 선택합니다.
  • ChartRect는 PDF 페이지의 대상 그리기 영역을 정의합니다.
  • DemoChart.PrintPartialCanvas는 차트를 PDF 캔버스에 렌더링합니다.
  • EndDoc은 PDF 파일을 완료합니다.

레이아웃 권장 사항

차트 영역을 화면에 표시되는 차트 영역에 맞춰 가로 세로 비율을 유지하고, 긴 지역화된 텍스트로 축 레이블을 테스트하십시오. PDF가 보고서의 일부인 경우, 차트가 원래 애플리케이션 외부에서 볼 때도 의미가 유지되도록 제목, 타임스탬프, 데이터 소스 및 메모를 위한 공간을 예약하십시오.

운영 체크리스트

  • 내보내기 실패 후에도 컴포넌트가 해제되도록 THotPDF 생성을 try/finally로 감쌉니다.
  • 회귀 테스트에는 Randomize 대신 결정적인 차트 데이터를 사용합니다.
  • 각 차트 모드가 고정 파일명을 덮어쓸지, 저장 위치를 물어볼지 결정합니다.
  • 빈 시리즈, 음수 값, 긴 범주 레이블이 포함된 샘플 데이터로 결과를 검증합니다.

여러 차트가 있는 보고서에서는 각 차트에 별도 페이지 영역을 주고 페이지 간 배율 선택을 일관되게 유지합니다. 독자는 PDF 페이지를 나란히 비교하므로 축 범위나 범례 순서가 바뀌면 올바른 내보내기도 오해를 줄 수 있습니다.

흔한 문제

가장 흔한 실수는 차트 캡처를 비트맵 스크린샷처럼 다루는 것입니다. 이 예제는 차트 Canvas 경로를 사용하므로 더 깨끗한 출력을 유지하고 화면 해상도 의존성을 피합니다. 또 다른 문제는 잘림입니다. PrintPartialCanvas에 전달하는 사각형은 예상되는 가장 큰 범례와 레이블 세트로 테스트해야 합니다.