This article will help you to combine multiple charts into one single PDF file. Here I have created an example using two types of charts: AmChart and HighChart.
Reference for both these charts are given below:
- AmChart: https://www.amcharts.com/demos/
- High Charts: https://www.highcharts.com/demo
HTML content to create the chart. I have used the jspdf jQuery to create pdf using jquery https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.3.5/jspdf.min.js
<style> .Charts { width: 100%; height: 500px; } </style> <!-- Resources --> <script src="https://www.amcharts.com/lib/4/core.js"></script> <script src="https://www.amcharts.com/lib/4/charts.js"></script> <script src="https://www.amcharts.com/lib/4/themes/animated.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.3.5/jspdf.min.js"></script> <script src="https://code.highcharts.com/highcharts.js"></script> <script src="https://code.highcharts.com/modules/heatmap.js"></script> <script src="https://code.highcharts.com/modules/exporting.js"></script> <script src="https://code.highcharts.com/modules/no-data-to-display.js"></script> <div class="container body-content"> <h2>Charts</h2> <button class="btn btn-primary" id="btnexport">Export To PDF</button> <div class="col-md-12"> <div id="Columnchartdiv" class="Charts"></div> </div> <div class="col-md-12"> <div id="LineHighchartdiv" class="Charts"></div> </div> <div class="col-md-6"> <div id="PieChartdiv" class="Charts"></div> </div> </div> @section scripts{ <script src="~/Scripts/ChartJS.js"></script> }
To generate the chart, the following code is written in the ChartJS.js file. You can see I have used two arrays and added our chart object to that array. This array will be later used in our export process.
var imagesArray = []; var HighChartArray = []; //Column Chart using Amchart JS am4core.ready(function () { am4core.useTheme(am4themes_animated); var chart = am4core.create("Columnchartdiv", am4charts.XYChart); chart.data = [ { "country": "USA - 1", "visits": 2020 }, { "country": "Japan", "visits": 1909 }, { "country": "Germany", "visits": 1322 }, { "country": "UAE", "visits": 1122 }, { "country": "Paris", "visits": 1114 }, { "country": "India", "visits": 1020 }, { "country": "Spain", "visits": 985 }, { "country": "Netherlands", "visits": 665 }, { "country": "Russia", "visits": 580 }, { "country": "Canada", "visits": 441 }, { "country": "Brazil", "visits": 395 }, { "country": "China", "visits": 1985 }]; var categoryAxis = chart.xAxes.push(new am4charts.CategoryAxis()); categoryAxis.dataFields.category = "country"; categoryAxis.renderer.grid.template.location = 0; categoryAxis.renderer.minGridDistance = 30; categoryAxis.renderer.labels.template.adapter.add("dy", function (dy, target) { if (target.dataItem && target.dataItem.index & 2 == 2) { return dy + 25; } return dy; }); var valueAxis = chart.yAxes.push(new am4charts.ValueAxis()); var series = chart.series.push(new am4charts.ColumnSeries()); series.dataFields.valueY = "visits"; series.dataFields.categoryX = "country"; series.name = "Visits"; series.columns.template.tooltipText = "{categoryX}: [bold]{valueY}[/]"; series.columns.template.fillOpacity = .8; var columnTemplate = series.columns.template; columnTemplate.strokeWidth = 2; columnTemplate.strokeOpacity = 1; }); //Line Chart using High Chart HighChartArray.push(Highcharts.chart('LineHighchartdiv', { title: { text: 'Student Growth by Class, 2015-2022' }, subtitle: { text: '' }, exporting: { enabled: false }, yAxis: { title: { text: 'Number of Students' } }, plotOptions: { series: { label: { connectorAllowed: false }, pointStart: 2015 } }, series: [{ name: 'Junior KG', data: [43935, 52504, 57178, 69659, 97032, 119933, 137134, 154176] }, { name: 'Senior KG', data: [24917, 24065, 29743, 29852, 32491, 30283, 38122, 40435] }, { name: 'Primary', data: [11745, 17723, 16006, 19772, 20186, 24378, 32148, 39388] }, { name: 'Secondary', data: [null, 1235, 7989, 12160, 15113, 22453, 34401, null] }, { name: 'Higher Secondary', data: [12909, 5949, 8106, 11249, 8980, 11817, 18275, 18112] }], responsive: { rules: [{ condition: { maxWidth: 500 }, chartOptions: { legend: { layout: 'horizontal', align: 'center', verticalAlign: 'bottom' } } }] } })); //Pie Chart using High Chart HighChartArray.push(Highcharts.chart('PieChartdiv', { chart: { plotBackgroundColor: null, plotBorderWidth: null, plotShadow: false, type: 'pie' }, exporting: { enabled: false }, title: { text: 'Browser usage in February, 2020' }, tooltip: { pointFormat: '{series.name}: <b>{point.percentage:.1f}%</b>' }, plotOptions: { pie: { allowPointSelect: true, cursor: 'pointer', dataLabels: { enabled: false }, showInLegend: true } }, series: [{ name: 'Brands', colorByPoint: true, data: [{ name: 'Chrome', y: 61.41, sliced: true, selected: true }, { name: 'Firefox', y: 10.85 }, { name: 'Internet Explorer', y: 11.84 }, { name: 'Edge', y: 4.67 }, { name: 'Safari', y: 4.18 }, { name: 'Opera', y: 1.6 }, { name: 'Other', y: 2.61 }] }] }));
Now I have created one function to export all the Amchart to images and stored it in one array.
function SaveAmChart4() { //Amchart 4 Export var Amchart4ids = ["Columnchartdiv"]; var charts4 = {}, charts_remaining = Amchart4ids.length; for (var j = 0; j < Amchart4ids.length; j++) { for (var y = 0; y < am4core.registry.baseSprites.length; y++) { if (am4core.registry.baseSprites[y].htmlContainer.id == Amchart4ids[j]) charts4[Amchart4ids[j]] = am4core.registry.baseSprites[y]; } } for (var z in charts4) { var chart4 = charts4[z]; chart4.exporting.getImage("png").then(function (imgData) { imagesArray.push(imgData); console.log(imgData); charts_remaining--; if (charts_remaining == 0) { save_chart(); } }); } }
After that, we have other functions that will export all the highcharts to image. Both amchart and highchart have different export property so we need two functions here.
function save_chart() { var charts_remaining = HighChartArray.length; for (var i = 0; i < HighChartArray.length; i++) { var chart = HighChartArray[i]; var render_width = 1000; var render_height = render_width * chart.chartHeight / chart.chartWidth; var svg = chart.getSVG({ exporting: { sourceWidth: chart.chartWidth, sourceHeight: chart.chartHeight } }); var canvas = document.createElement('canvas'); canvas.height = render_height; canvas.width = render_width; var image = new Image; image.onload = function () { canvas.getContext('2d').drawImage(this, 0, 0, render_width, render_height); var data = canvas.toDataURL("image/png"); imagesArray.push(data); charts_remaining--; if (charts_remaining == 0) { createPDF(); } }; image.src = 'data:image/svg+xml;base64,' + window.btoa(svg); } }
Now we will have our final export function.
function createPDF() { var doc = new jsPDF("p", "mm", "a4"); var width = doc.internal.pageSize.width; var height = doc.internal.pageSize.height; var StartX = 10; doc.setFont("arial", "normal"); doc.setTextColor(136, 136, 136); // color for fonts doc.setFontSize(16); doc.text(20, 10, 'AmChart Column Chart'); doc.setDrawColor(136, 136, 136); // color for line doc.line(10, 15, parseInt(width) - 10, 15); doc.addImage(imagesArray[0], 'JPEG', StartX, 20, parseInt(width) - 20, 100); doc.setFont("arial", "normal"); doc.setTextColor(136, 136, 136); // doc.setFontSize(16); doc.text(20, 140, 'Highchart Line Chart'); doc.setDrawColor(136, 136, 136); doc.line(10, 145, parseInt(width) - 10, 145); doc.addImage(imagesArray[1], 'JPEG', StartX, 150, parseInt(width) - 20, 100); doc.addPage(); // New page doc.setFont("arial", "normal"); doc.setTextColor(136, 136, 136); // color for fonts doc.setFontSize(16); doc.text(20, 10, 'HighChart Pie Chart'); doc.addImage(imagesArray[2], 'JPEG', StartX, 20, parseInt((parseInt(width) - 10) / 2), parseInt((parseInt(width) - 20) / 2)); doc.save('SamplePDF.pdf'); // Change the name of the pdf file. }
Now call the first function (SaveAmChart4()) from the click event of our export button
$("#btnexport").click(function () { SaveAmChart4(); });
Your output will be something like this: