This example demonstrates creating a PDF report with ChartDirector.
In ChartDirector, there is a
MultiPagePDF object can combine multiple charts into a PDF with multiple pages. Since a ChartDirector chart can contain free form CDML text, tables, shape and images, the MultiPagePDF can be used to build complete PDF reports.
In this example, the PDF report is generated as follows:
- A new MultiPagePDF object is created.
- An empty PieChart object with custom CDML text in large bold font is added to the MultiPagePDF as the cover page. The PieChart is configured with the output options "pagewidth = 794; pageHeight = 1123" using BaseChart.setOutputOptions. As PDF defaults to 96dpi (dot per inch), the above sets the page to A4 size (210mm x 297mm).
- A loop is used to generate MultiChart objects as pages in the MultiPagePDF. Each MultiChart object will include a page heading at the top, and contain up to two XYChart objects, and with a page number at the bottom. Each XYChart object will plot one year of data. Like the cover page, the page is set to A4 size.
perldemo\pdfreport.pl
#!/usr/bin/perl
# The ChartDirector for Perl module is assumed to be in "../lib"
use File::Basename;
use lib (dirname($0)."/../lib") =~ /(.*)/;
use perlchartdir;
#
# 5 years of random data series
#
my $r = new RanSeries(127);
my $timeStamps = $r->getDateSeries(1827, perlchartdir::chartTime(2015, 1, 1), 86400);
my $dataSeriesA = $r->getSeries(1827, 150, -10, 10);
my $dataSeriesB = $r->getSeries(1827, 200, -10, 10);
my $dataSeriesC = $r->getSeries(1827, 250, -8, 8);
#
# Draw an XYChart using data from startDate to endDate
#
sub drawXYChart
{
my ($startDate, $endDate) = @_;
my $startIndex = int(perlchartdir::bSearch($timeStamps, $startDate));
my $endIndex = int(perlchartdir::bSearch($timeStamps, $endDate) + 0.999999);
#================================================================================
# Configure overall chart appearance.
#================================================================================
# Create an XYChart object of size 640 x 350 pixels
my $c = new XYChart(640, 350);
# Set the plotarea at (55, 50) with width 80 pixels less than chart width, and height 85 pixels
# less than chart height. Use a vertical gradient from light blue (f0f6ff) to sky blue (a0c0ff)
# as background. Set border to transparent and grid lines to white (ffffff).
$c->setPlotArea(55, 50, $c->getWidth() - 80, $c->getHeight() - 85, $c->linearGradientColor(0,
50, 0, $c->getHeight() - 35, 0xf0f6ff, 0xa0c0ff), -1, $perlchartdir::Transparent, 0xffffff,
0xffffff);
# As the data can lie outside the plotarea in a zoomed chart, we need enable clipping.
$c->setClipping();
# Add a legend box at (55, 25) using horizontal layout. Use 8pts Arial Bold as font. Set the
# background and border color to Transparent and use line style legend key.
my $b = $c->addLegend(55, 25, 0, "Arial Bold", 8);
$b->setBackground($perlchartdir::Transparent);
$b->setLineStyleKey();
# Set the axis stem to transparent
$c->xAxis()->setColors($perlchartdir::Transparent);
$c->yAxis()->setColors($perlchartdir::Transparent);
# Add axis title using 10pts Arial Bold Italic font
$c->yAxis()->setTitle("Ionic Temperature (C)", "Arial Bold Italic", 10);
#================================================================================
# Add data to chart
#================================================================================
#
# In this example, we represent the data by lines. You may modify the code below to use other
# representations (areas, scatter plot, etc).
#
# Add a line layer for the lines, using a line width of 2 pixels
my $layer = $c->addLineLayer2();
$layer->setLineWidth(2);
# Now we add the 3 data series to a line layer, using the color red (ff33333), green (008800)
# and blue (3333cc)
$layer->setXData([@$timeStamps[$startIndex..$endIndex]]);
$layer->addDataSet([@$dataSeriesA[$startIndex..$endIndex]], 0xff3333, "Alpha");
$layer->addDataSet([@$dataSeriesB[$startIndex..$endIndex]], 0x008800, "Beta");
$layer->addDataSet([@$dataSeriesC[$startIndex..$endIndex]], 0x3333cc, "Gamma");
#================================================================================
# Configure axis scale and labelling
#================================================================================
# Set the x-axis scale
$c->xAxis()->setDateScale($timeStamps->[$startIndex], $timeStamps->[$endIndex]);
$c->xAxis()->setMultiFormat(perlchartdir::StartOfYearFilter(), "<*font=bold*>{value|mmm yyyy}",
perlchartdir::AllPassFilter(), "{value|mmm}");
return $c;
}
#
# Create the report
#
# The MultiPagePDF object can create PDF from multiple pages, each with one chart object. Since a
# chart object can contain text (eg. using BaseChart.addText) and other charts (eg. using
# MultiChart), that means each page can contain text and multiple charts.
my $doc = new MultiPagePDF();
# Page configuration - A4 = 210 x 297mm. The PDF default is 96 dpi (dot per inch), so the A4 size is
# equal to 794 x 1123 dots.
my $pageConfig = "pagewidth = 794; pageHeight = 1123";
# In this example, we include a cover page with only text. This is by creating an empty pie chart
# with text only.
my $firstPage = new PieChart(720, 960);
$firstPage->addText(360, 320,
"<*size=50*>ChartDirector<*br*><*size=30*>PDF Report Demonstration<*/*>", "Arial Bold", 30,
0x000000, $perlchartdir::Center);
$firstPage->setOutputOptions($pageConfig);
$doc->addPage($firstPage);
# We include 2 charts per page, with each chart showing one year of data. Each page will also have a
# header and page number
my $startYear = int(perlchartdir::getChartYMD($timeStamps->[0]) / 10000);
my $endYear = int(perlchartdir::getChartYMD($timeStamps->[scalar(@$timeStamps) - 1] - 1) / 10000);
my $pageNumber = 0;
for(my $yyyy = $startYear; $yyyy < $endYear + 1; $yyyy += 2) {
# A page contains up to two charts
my $m = new MultiChart(760, 920);
# Use addTitle to add a header
$m->addTitle("ChartDirector PDF Report Demonstration", "Arial Bold", 20);
# Create the first chart
my $c = drawXYChart(perlchartdir::chartTime($yyyy, 1, 1), perlchartdir::chartTime($yyyy + 1, 1,
1));
$c->addTitle("Year $yyyy");
$m->addChart(($m->getWidth() - $c->getWidth()) / 2, 100, $c);
if ($yyyy < $endYear) {
# Create the second chart
my $c2 = drawXYChart(perlchartdir::chartTime($yyyy + 1, 1, 1), perlchartdir::chartTime($yyyy
+ 2, 1, 1));
$c2->addTitle(sprintf("Year %s", $yyyy + 1));
$m->addChart(($m->getWidth() - $c2->getWidth()) / 2, 500, $c2);
}
# Add the page number
$pageNumber = $pageNumber + 1;
$m->addTitle2($perlchartdir::BottomCenter, $pageNumber, "Arial Bold", 8);
$m->setOutputOptions($pageConfig);
$doc->addPage($m);
}
$doc->outPDF("pdfreport.pdf");
© 2021 Advanced Software Engineering Limited. All rights reserved.