nvd3 导出到 img 裁剪图像

nvd3 export to img cropping image

我正在尝试使用本教程导出 NVD3 图表:

http://www.coffeegnome.net/converting-svg-to-png-with-canvg/

SVG to Canvas with d3.js

效果很好,但我的结果图像被裁剪为 300 x 150,我该如何导出整个图像?

我的代码是这样的:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8"/>
        <meta name="viewport" content="width=device-width, initial-scale=1">

        <title>Export D3 to image</title>

        <link rel="stylesheet" type="text/css" href="css/nv.d3.css">

        <script language="javascript" type="text/javascript" src="js/jquery.min.js"></script>
        <script language="javascript" type="text/javascript" src="js/d3.min.js"></script>
        <script language="javascript" type="text/javascript" src="js/nv.d3.js"></script>
    </head>
    <body>
        <svg id="basicChart1"></svg>
        <script>
            createGraphs();
            function createGraphs() {
                nv.addGraph(function () {
                    chart1 = nv.models.lineChart()
                            .useInteractiveGuideline(true)
                            ;

                    chart1.xAxis
                            .axisLabel('Time (ms)')
                            .tickFormat(d3.format(',r'))
                            ;

                    chart1.yAxis
                            .axisLabel('Voltage (v)')
                            .tickFormat(d3.format('.02f'))
                            ;

                    d3.select('#basicChart1')
                            .datum(data())
                            .call(chart1)
                            ;

                    nv.utils.windowResize(chart1.update);

                    return chart1;
                });

                console.log("Graficas Creadas");
            }

            function data() {
                var sin = [];

                for (var i = 0; i < 100; i++) {
                    sin.push({x: i, y: Math.sin(i / 10)});
                }

                return [
                    {
                        values: sin,
                        key: 'Sine Wave',
                        color: '#ff7f0e'
                    }
                ];
            }

// Tutorials:
// http://www.coffeegnome.net/converting-svg-to-png-with-canvg/

// Create an export button
            d3.select('body')
                    .append("button")
                    .html("Export")
                    .on("click", saveSVG)
                    .attr('class', 'btn btn-success');

            var width = 300, height = 100;


// Create the export function - this will just export
// the first svg element it finds
            function saveSVG() {

                // get styles from all required stylesheets
                // http://www.coffeegnome.net/converting-svg-to-png-with-canvg/
                var style = "\n";
                var requiredSheets = ['nv.d3.css']; // list of required CSS
                for (var i = 0; i < document.styleSheets.length; i++) {
                    var sheet = document.styleSheets[i];
                    if (sheet.href) {
                        if (requiredSheets.indexOf(sheet.href.split('/').pop()) !== -1) {
                            if (sheet.rules) {
                                for (var j = 0; j < sheet.rules.length; j++) {
                                    style += (sheet.rules[j].cssText + '\n');
                                }
                            }
                        }
                    }
                }

                var svg = d3.select("#basicChart1"),
                        serializer = new XMLSerializer();
                // prepend style to svg
                svg.insert('defs', ":first-child");
                d3.select("svg defs")
                        .append('style')
                        .attr('type', 'text/css')
                        .html(style);


                // generate IMG in new tab
                var svgStr = serializer.serializeToString(svg.node());
                var imgsrc = 'data:image/svg+xml;base64,' + btoa(unescape(encodeURIComponent(svgStr)));

                var image = new Image();
                image.src = imgsrc;
                window.open().document.write('<img src="' + image.src + '"/>');   
            }
            ;

        </script>
    </body>
</html>

我会回答我自己的问题:

问题出在 SVG 宽度和高度属性上:

<svg id="basicChart1"></svg>

所以我只需要在生成图像之前将计算出的 Width 和 Height 值添加到 svg 标签中:

            var serializer = new XMLSerializer();
            var svg = d3.select("#basicChart1");
            svg.attr('width', svg.node().clientWidth);
            svg.attr('height', svg.node().clientHeight);
            svg.insert('defs', ":first-child");
            d3.select("svg defs")
                    .append('style')
                    .attr('type', 'text/css')
                    .html(style);