Export Different Type Of Chart To Same PDF Using JQuery

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:

  1. AmChart: https://www.amcharts.com/demos/
  2. 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:

Submit a Comment

Your email address will not be published. Required fields are marked *

Subscribe

Select Categories