Recharts component to PNG

前端 未结 3 1981
梦如初夏
梦如初夏 2021-01-13 00:13

I currently have a Recharts component that I would like to export as a PNG file.

                    

        
相关标签:
3条回答
  • 2021-01-13 00:35

    This function takes SVG element on input and transforms to image/png data:

    export const svgToPng = (svg, width, height) => {
    
        return new Promise((resolve, reject) => {
    
            let canvas = document.createElement('canvas');
            canvas.width = width;
            canvas.height = height;
            let ctx = canvas.getContext('2d');
    
            // Set background to white
            ctx.fillStyle = '#ffffff';
            ctx.fillRect(0, 0, width, height);
    
            let xml = new XMLSerializer().serializeToString(svg);
            let dataUrl = 'data:image/svg+xml;utf8,' + encodeURIComponent(xml);
            let img = new Image(width, height);
    
            img.onload = () => {
                ctx.drawImage(img, 0, 0);
                let imageData = canvas.toDataURL('image/png', 1.0);
                resolve(imageData)
            }
    
            img.onerror = () => reject();
    
            img.src = dataUrl;
        });
    };
    

    And how to access the Recharts SVG element? This code snippet allows you to render any Chart outside of your current visible DOM and use it's SVG:

    const exportChart = () => {
    
        // Output image size
        const WIDTH = 900;
        const HEIGHT = 250;
    
        const convertChart = async (ref) => {
    
            if (ref && ref.container) {
                let svg = ref.container.children[0];
                let pngData = await svgToPng(svg, WIDTH, HEIGHT);
                console.log('Do what you need with PNG', pngData);
            }
        };
    
        const chart = <LineChart data={...} width={WIDTH} height={HEIGHT}
            ref={ref => convertChart(ref)} />;
    
        // Render chart component into helper div
        const helperDiv = document.createElement('tmp');
        ReactDOM.render(chart, helperDiv);
    }
    
    0 讨论(0)
  • 2021-01-13 00:53

    @brammitch created a package for this (inspired by answers here):

    https://github.com/brammitch/recharts-to-png

    0 讨论(0)
  • 2021-01-13 01:00

    I was able to solve my problem by delving into the Recharts component. Recharts renders as an SVG under a wrapper so all I had to do was convert properly to save as both HTML or SVG

    // Exports the graph as embedded JS or PNG
    exportChart(asSVG) {
    
        // A Recharts component is rendered as a div that contains namely an SVG
        // which holds the chart. We can access this SVG by calling upon the first child/
        let chartSVG = ReactDOM.findDOMNode(this.currentChart).children[0];
    
        if (asSVG) {
            let svgURL = new XMLSerializer().serializeToString(chartSVG);
            let svgBlob = new Blob([svgURL], {type: "image/svg+xml;charset=utf-8"});
            FileSaver.saveAs(svgBlob, this.state.uuid + ".svg");
        } else {
            let svgBlob = new Blob([chartSVG.outerHTML], {type: "text/html;charset=utf-8"});
            FileSaver.saveAs(svgBlob, this.state.uuid + ".html");
        }
    }
    

    I am using FileSaver.js for the save prompt.

    0 讨论(0)
提交回复
热议问题