javascriptreactjschartsapexchartsreact-apexcharts

Apexcharts download chart as an image (PNG) when external button is clicked


I have a simple react apex chart that I need to download it's image. Apex toolbar does that but I want to invoke the same behaviour using an external button. This is my code. How can this be done?

CODE SANDBOX

import React, { useState } from "react";
import "./styles.css";
import Chart from "react-apexcharts";

export default function App() {
  const [state, setState] = useState({
    options: {
      chart: {
        id: "LineGraph1",
        zoom: {
          enabled: false
        },
        toolbar: { show: true }
      },
      dataLabels: {
        enabled: false
      },
      xaxis: {
        categories: [1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999]
      }
    },
    series: [
      {
        name: "series-1",
        data: [30, 40, 45, 50, 49, 60, 70, 91]
      }
    ]
  });

  async function downloadSVG(chartId) {
    console.log(window.Apex._chartInstances);
    const chartInstance = window.Apex._chartInstances.find(
      (chart) => chart.id === chartId
    );
    console.log("chartInstance ", chartInstance);
    const base64 = await chartInstance.chart.dataURI();
    console.log("base 64", base64);
    // chartInstance.dataURI().then(({ imgURI, blob }) => {
    //   console.log("URI ", imgURI, " ", blob);
    // });
    const blob = await (await fetch(base64)).blob();
    const x = await fetch(base64)
      .then((res) => res.blob())
      .then((blob) => console.log(blob))
      .catch((err) => console.log(err));
    return blob;
  }

  return (
    <div className="App">
      <Chart
        options={state.options}
        series={state.series}
        type="area"
        height="280"
      />
      <button onClick={() => downloadSVG("LineGraph1")}>Download svg</button>
    </div>
  );
}

Solution

  •   async function downloadSVG(chartId) {
        console.log(window.Apex._chartInstances);
        const chartInstance = window.Apex._chartInstances.find(
          (chart) => chart.id === chartId
        );
        console.log("chartInstance ", chartInstance);
        const base64 = await chartInstance.chart.dataURI();
        console.log("base 64", base64.imgURI);
        const downloadLink = document.createElement("a");
        downloadLink.href = base64.imgURI;
        downloadLink.download = "image.png";
    
        // Add the anchor element to the document
        document.body.appendChild(downloadLink);
    
        // Simulate a click event to initiate the download
        downloadLink.click();
    
        // Remove the anchor element from the document
        document.body.removeChild(downloadLink);
      }
    

    This is tested and worked in your sandbox.