【问题标题】:D3js Export SVG to ImageD3js 将 SVG 导出为图像
【发布时间】:2023-04-05 21:34:01
【问题描述】:

我正在使用这个 D3js line graph

我希望能够将其作为图像保存在this example所示的同一目录中

d3.select('#saveButton').on('click', function(){
    var svgString = getSVGString(svg.node());
    svgString2Image( svgString, 2*width, 2*height, 'png', save ); // passes Blob and filesize String to the callback

    function save( dataBlob, filesize ){
        saveAs( dataBlob, 'D3 vis exported to PNG.png' ); // FileSaver.js 
function
    }
});

以上运行没有错误

虽然我没有收到任何错误,但单击按钮时文件未下载。我在这里想念什么?谢谢!

【问题讨论】:

    标签: javascript d3.js svg export-to-image


    【解决方案1】:

    在您的小提琴中,您将g 附加到您的svg 并将其分配给您的变量svg

    var svg = d3.select("#priceWithMilestones")
      .append("svg")
      .attr("width", width + margin.left + margin.right)
      .attr("height", height + margin.top + margin.bottom)
      .append("g")
      .attr("transform",
         "translate(" + margin.left + "," + margin.top + ")");
    

    看起来getSVGString() 需要根节点,而不是g 元素。您可能应该更改您的代码,以便 svg 反映根 svg 元素,并创建另一个变量来存储 g 元素,但为了快速而肮脏的修复,您可以更改

    var svgString = getSVGString(svg.node());
    

    var svgString = getSVGString(d3.select('svg').node());
    

    并且应该保存。更新小提琴:https://jsfiddle.net/c19664p3/8/

    编辑: 至于导出的样式,在声明选择时,您似乎无法引用 svg 之外的选择器。此外,它看起来必须只包含一个 id 或一个类。有关更宽松的 CSS 规则导出器,请参阅我的其他答案。

    所以改变这个:

    #priceWithMilestones .line {
      fill: none;
      stroke: #14da9e;
      stroke-width: 2px;
    }
    

    到:

    .line {
      fill: none;
      stroke: #14da9e;
      stroke-width: 2px;
    }
    

    仅导出 svg 的线条样式。更新小提琴:https://jsfiddle.net/c19664p3/10/

    【讨论】:

    • 导出代码在导出 css 样式、遍历样式表并将其附加到导出的 svg 文本方面非常雄心勃勃。
    【解决方案2】:

    查看getCSSStyles 后,它似乎只检查与完全匹配的规则 id 或根 svg 及其子元素的类。我认为这是一个更宽容的实现:

    function getCSSStyles( parentElement ) {
        var nodesToCheck = [ parentElement ], i;
    
        // Add all the different nodes to check
        var childNodes = parentElement.getElementsByTagName("*");
        for (i = 0; i < childNodes.length; i++) {
            nodesToCheck.push(childNodes[i]);
        }
    
        // Extract CSS Rules
        var extractedCSSRules = [];
        for (i = 0; i < document.styleSheets.length; i++) {
            var s = document.styleSheets[i];
    
            try {
                if (!s.cssRules) continue;
            } catch( e ) {
                if (e.name !== 'SecurityError') throw e; // for Firefox
                continue;
            }
    
            var cssRules = s.cssRules;
            var ruleMatches;
            for (var r = 0; r < cssRules.length; r++) {
                ruleMatches = nodesToCheck.reduce(function (a, b) {
                    return a || b.matches(cssRules[r].selectorText);
                }, false);
                if (ruleMatches)
                    extractedCSSRules.push(cssRules[r].cssText);
            }
        }
        return extractedCSSRules.join(' ');
    }
    

    您仍然需要使用 svg 内部的规则(例如,您仍然需要在 CSS 中将 #priceWithMilestones .line 更改为 .line),但对于未来的项目,我认为它应该捕获更多元素。

    更新了所有变化的小提琴:https://jsfiddle.net/c19664p3/12/

    【讨论】:

      猜你喜欢
      • 2017-06-27
      • 2013-07-01
      • 2012-09-17
      • 1970-01-01
      • 1970-01-01
      • 2020-10-13
      • 2019-05-27
      • 1970-01-01
      • 2021-09-05
      相关资源
      最近更新 更多