当使用canvg将Highchart SVG转换为PNG时,所有文本都会出现两次——如何解决

When using canvg to convert Highchart SVG into PNG, all text appears twice - how to solve?

本文关键字:两次 解决 何解决 文本 Highchart SVG canvg 转换 PNG      更新时间:2023-12-24

这是我的(截断的)SVG图像示例(使用Highcharts制作,http://www.highcharts.com/)-当我将其渲染到画布上时(使用canvg(https://github.com/gabelerner/canvg以及从这里改编的代码:https://stackoverflow.com/a/8997520/2067690)生成的PNG中的所有文本都是重复的,这意味着它的输出是双重的,一段文本紧接着又是同一文本。如何确保它只出现一次?

<svg height="400" width="1170" version="1.1" xmlns="http://www.w3.org/1999/svg">
<text zIndex="8" text-anchor="end" style="font-family:&quot;Lucida Grande&quot;, &quot;Lucida Sans Unicode&quot;, Verdana, Arial, Helvetica, sans-serif;font-size:9px;cursor:pointer;color:#909090;fill:#909090;" y="22" x="220">
  <tspan x="220">Highcharts.com</tspan>
</text>
</svg>

这个问题有点老了,但我也发现在我的图中有这个双文本错误很烦人。我查看了代码,并对其进行了修改以使用tspan。我并没有真正深入研究它,所以我不了解库中发生的所有机制,但我注意到,对于"tspan",在某个时刻,创建的对象是:

  • 一个对象,类型为"tspan",有一个text属性
  • 该对象还包含另一个对象,它是tspan的文本值(与上一个文本属性相同)

所以我所做的就是修改库的源代码。如果您搜索

// tspan 
svg.Element.tspan = function(node) {

然后你只需要在函数中添加这个(替换旧内容):

if ( node.nodeName == "tspan")
    this.text = '' ;
else
    this.text = node.value || node.text || node.textContent || '';

这解决了我的问题。我希望这能帮助到别人。

在删除了我的示例SVG图像的部分后,为了找到错误何时消失,我发现是tspan标记——一旦我去掉它们,canvg将只按预期显示一次文本。

我刚刚在导出参数中添加了textOutline:'none',它对我有效。

带解决方案的密码笔https://codepen.io/kirill-kirs/pen/qBjNdwg

 exporting: {
        sourceWidth: 1000,
        sourceHeight: 1000,
        chartOptions: {
            plotOptions: {
                series: {
                    dataLabels: {
                        enabled: true,
                        backgroundColor: 'rgba(0, 0, 0, 0.75)',
                        style: {
                            textOutline: 'none',
                            color: 'white'
                        }
                    }
                }
            }
        }
    }
<!-- Client Side Code -->
<script type="text/javascript">
    window.onload = function() {
        //1. Get the Highcharts Graph from the Div containing it
        var chart = $('#IDOfDivContainingHighchartsGraph').highcharts();
        //2. Get SVG from Hicharts Export Service
        var svgString = chart.getSVGForExport();
        //3. Save it client side div to manipulate the fetched string
        $('#exportedSVG').html(svgString);
        //4. LOGIC TO REMOVE THE DUPLICATE TSPAN TAG
        var svgTSPAN_TextElement=$("#exportedSVG text");
        for(i=0;i<svgTSPAN_TextElement.length;i++){
            childTspanElements=$(svgTSPAN_TextElement[i]).children("tspan");
            if(childTspanElements.length==2){
                childTspanElements[1].remove();
            }
        }
        //5. Get the maniupluated object as string
        svgString=$("#exportedSVG svg").get(0).outerHTML;
        //6. POST Maniiulated SVG string
        var url= '/URL/To/Server/Side.php';
        $.ajax({
            type: 'POST',
            data: {svgString:svgString, upload:1},
            url: url,
            async: false,
            success: function(data){
                //Nothing here
            }
        });
    }
</script>
//Server Side Code
<?php
if(isset($_POST["upload"])){
    $SVGData=$_POST["svgString"];
    $locationToSaveFile = "/location/to/Save/SVGFILE.svg";
    file_put_contents($locationToSaveFile, $SVGData);
    exit();
}
//By the end of this code you would have created the svg file of the hicharts on the server side
?>