'How can I get a URI from ApexCharts to download in PDF?

I already implemented an ApexCharts and want to output it into a PDF document.

I tried to get a download URI from chart.dataURI, but it failed with an error:

chart.dataURI is not a function

Below is the creation of the Apex bar graph and my attempt with the download URI, but it does not fetch:

var options = {
  chart: {
    height: 450,
    type: 'bar',
    width: 1000,
  },
  plotOptions: {
    bar: {
      horizontal: false,
      columnWidth: '40%',
      endingShape: 'rounded'
    },
  },
  dataLabels: {
    enabled: false
  },
  colors: ['#008000', '#d4a823', '#f92525'],
  stroke: {
    show: true,
    width: 2,
    colors: ['transparent']
  },
  series: [{
    name: 'Good',
    data: JSON.stringify(graph_data.good)
  }, {
    name: 'Okey',
    data: JSON.stringify(graph_data.ok)
  }, {
    name: 'Bad',
    data: JSON.stringify(graph_data.bad)
  }],
  xaxis: {
    categories: graph_data.month,
  },
  yaxis: {
    title: {
      text: 'Smiley Percentage'
    }
  },
  fill: {
    opacity: 1

  },
  tooltip: {
    y: {
      formatter: function(val) {
        return val + " Smileys"
      }
    }
  }
}

var chart = new ApexCharts(document.querySelector("#monthlyhistory"), options);
var dataURL = chart.dataURI().then((uri) => {  // Here shows an error
  console.log(uri);
  var pdf = new jsPDF();
  pdf.addImage(uri, 'PNG', 0, 0);
  pdf.save("download.pdf");
})}

I expect the output in PDF format, but it is not working.



Solution 1:[1]

Before calling the chart.dataURI() function, you need to render the chart (which I cannot find in your question)

The render function returns a promise, so you can chain any additional code in the then() handler of it.

Like this.

var chart = new ApexCharts(document.querySelector("#chart"), options);
chart.render().then(() => {
    chart.dataURI().then(({ imgURI, blob }) => { 
        var pdf = new jsPDF();
        pdf.addImage(imgURI, 'PNG', 0, 0);
        pdf.save("download.pdf");
    })
})

Here is the working codepen demo

Solution 2:[2]

Below is a solution with some additional code that helps us to render the chart to fit nicely within the frame of the pdf file. My previous attempts did render the chart but the chart did not fill the page with nasty white uneven borders to the side and bottom.

The 'chart' reference is based upon getting the actual instance of th current chart once rendered...

Dont forget to load the jsPDF library in the header section of the web page:

<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.5.3/jspdf.min.js"></script>

I call the function below from a button along the navbar just above the div element where I render the chart. Note I called the div element a 'chartCanvas' but it's not actually a canvas element, it's just a div with my own class parameters.

function downloadChartToPdf() {
    if (chart) {
        var canvas = document.getElementById("chartCanvas");
        var width = canvas.clientWidth;
        var height = canvas.clientHeight;
        console.log(width); // testing only...
        console.log(height); // testing only...
        // ----- Not currently in use... -----
        //var rect = canvas.getBoundingClientRect();
        //console.log(rect.width); // testing only...
        //console.log(rect.height); // testing only...
        // -------------------------------------------

        chart.dataURI().then(({ imgURI, blob }) => {
            //set the orientation
            if (width > height) {
                console.log("landscape"); // testing only...
                let pdf = new jsPDF('l', 'px', [width, height]);
                pdf.backgroundColor = '#BFBFBF';
                //then we get the dimensions from the 'pdf' file itself
                width = pdf.internal.pageSize.getWidth();
                height = pdf.internal.pageSize.getHeight();
                widthWithPadding = width - 20;
                heightWithPadding = height - 20;
                pdf.addImage(imgURI, 'PNG', 10, 10, widthWithPadding, heightWithPadding);
                pdf.save("chart.pdf");
            }
            else {
                console.log("portrait"); // testing only...
                let pdf = new jsPDF('p', 'px', [height, width]);
                pdf.backgroundColor = '#BFBFBF';
                //then we get the dimensions from the 'pdf' file itself
                width = pdf.internal.pageSize.getWidth();
                height = pdf.internal.pageSize.getHeight();
                widthWithPadding = width - 20;
                heightWithPadding = height - 20;
                pdf.addImage(imgURI, 'PNG', 10, 10, widthWithPadding, heightWithPadding);
                pdf.save("chart.pdf");
            }
        })
    }
}

Exported PDF result:

enter image description here

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 OJB1