See all tutorials

Tutorials » Dynamic chart images in PDF files

This tutorial covers dynamic chart images generation in PDF files. The previous tutorials presented SVG charts in web pages and charts in images by using SVG content, the same SVG apporach will be used in PDF files too. Apache FOP will be used to insert a SVG pie chart into a generated PDF file.

In order to generate a dynamic chart into a PDF file, take the following tasks:

Create a SVG content in a page module

Step 1

In Webpagebytes CMS administration interface navigate to 'Page modules' section and create a new page module with the content below. This represents a pie chart SVG, it uses Freemarker script to generate the dynamic content.

The Freemarker script needs to calculate sin and cos trigonometric functions values and since these are not supported by the scripting language, the Taylor series are used.

<#assign records=wpbAppModel["data"].records  total=0/>
<#assign colors=["DD0000","00DD00","0000DD","DDDD00","225588","889900","774422"] />
<#list records as item>
   <#assign total=(total+item.value?number) />
</#list>
<svg xmlns="http://www.w3.org/2000/svg" width="250" height="250" viewBox="0 0 1000 1000">
    <#assign intAngle=0 currentAngle=0 >
 <#list records as item>
    <#assign angle=((3.1415*2*item.value?number)/total) angle2=angle*angle  angle4=angle2*angle2 angle8=angle4*angle4 radius=300/>
    <#assign largeArcFlag=0>
    <#if (angle>3.1415)>
        <#assign largeArcFlag=1>
    </#if>
    <#assign cosx=(1 - angle2/2 + angle4/24 - angle4*angle2/720 + angle8/40320 - angle8*angle2/3628800 + angle8*angle4/479001600 - angle8*angle4*angle2/87178291200) 
             sinx=(angle-angle2*angle/6 + angle4*angle/120 - angle4*angle2*angle/5040 + angle8*angle/362880 - angle8*angle2*angle/39916800 + angle8*angle4*angle/6227020800 - angle8*angle4*angle2*angle/1307674368000) >
    <#assign dx=-1*(radius - radius*cosx) >
    <#assign dy=-1*radius*sinx >
 
    <path fill="#${colors[item_index]}"  d="M 500,500 l ${radius},0 a ${radius},${radius} 0 ${largeArcFlag}, 0 ${dx?string.computer},${dy?string.computer} z" transform="rotate(-${intAngle?string.computer} 500 500)" />
    <#assign tempAngle=angle />
    <#assign angle=(currentAngle+angle/2) angle2=angle*angle  angle4=angle2*angle2 angle8=angle4*angle4 />
    <#assign currentAngle=(currentAngle+tempAngle) />
    <#assign cosx=(1 - angle2/2 + angle4/24 - angle4*angle2/720 + angle8/40320 - angle8*angle2/3628800 + angle8*angle4/479001600 -angle8*angle4*angle2/87178291200) sinx=(angle-angle2*angle/6 + angle4*angle/120 - angle4*angle2*angle/5040 + angle8*angle/362880 - angle8*angle2*angle/39916800 + angle8*angle4*angle/6227020800 - angle8*angle4*angle2*angle/1307674368000) >

    <#assign intAngle=(intAngle+360*item.value?number/total) >

    <text x="${(500+200*cosx)}" y="${(500-200*sinx)}" font-size="30" text-anchor="middle" fill="white" font-family="Verdana" kerning="-2">${(item.value?number)?string.currency}</text>

    <#if (angle<= 3.14/2)>
        <#assign position="start">
    <#elseif (angle<= 3*3.14/2)>
        <#assign position="end">
    <#else>
        <#assign position="start">
    </#if>
    <text x="${(500+340*cosx)}" y="${(500-340*sinx)}" font-size="50" text-anchor="${position}"  font-family="Verdana" > ${item.name}</text>
 </#list>

    <#assign intAngle=0 />
    <#list records as item>
        <#assign angle=((3.1415 * 2*item.value?number)/total) />
        <path stroke="#FFFFFF" stroke-width="20" d="M 500,500 l ${radius+10} 0" transform="rotate(-${intAngle?string.computer} 500 500)" />
        <#assign intAngle=(intAngle+360*item.value?number/total) >
    </#list>
</svg>

Add the SVG content to XLS-FO fragment that generates the PDF file

Step 2

The XLS-FO content that is used to generate the PDF file needs to be updated to include the SVG content representing the pie chart generated. The previous tutorial generate dynamic PDF file covered the XLS-FO content used to generate a dynamic PDF invoice example.

The code fragment below is an example to include the pie chart SVG page module. The external key will need to be updated with yours.

...
<fo:block>
    <fo:instream-foreign-object>
        <@wpbModule externalKey="1ed793fe-3122-4929-ae94-11b8f89d6406" name="svg-pie-page-module"/>
    </fo:instream-foreign-object> 
</fo:block>
...

Generate the PDF file

Step 3

Apache FOP takes XLS-FO content and converts it to various outputs, one supported output is PDF format. One previous tutorial presented how Webpagebytes CMS can be used to fetch the XLS-FO content and convert it using apache FOP, for details please see how to generate dynamic PDF.

Test the generated image bar chart

Step 4

In a browser load the url published at step 3 to see the generated PDF file that contains the invoice example with the dynamic pie chart.
PDF invoice example that contains a dynamic pie chart

Fork me on GitHub