Highcharts getSVG() - 在图例中保持HTML格式

时间:2016-11-15 19:00:26

标签: javascript jquery css svg highcharts

我正在尝试将SVG用于Highchart并在返回的SVG中保留CSS格式,以便它代表当前向用户显示的Highchart。

目前,似乎如果我使用getSVG()函数,则无法正确呈现自定义HTML图例。在下面的示例中,我使用此方法并渲染SVG元素并在屏幕上呈现它以比较差异。

Example

  $(function () {

    Highcharts.chart('container', {

        exporting: {
            chartOptions: { // specific options for the exported image

                plotOptions: {
                    series: {
                        dataLabels: {
                            enabled: true
                        }
                    }
                }
            },
            scale: 3,
            fallbackToExportServer: false
        },

        title: {
            text: 'Offline export'
        },
        legend:{
            useHTML: true,
                        navigation: { enabled: false },
                        align: 'center',
                        verticalAlign: 'bottom',
                        symbolWidth: 0,
                        symbolHeight: 0,
                        labelFormatter: function() {
                            return '<ul><li>1</li><li>2</li></ul>';
                        }
        },

        subtitle: {
            text: 'Click the button to download as PNG, JPEG, SVG or PDF'
        },

        chart: {
            type: 'area'
        },

        xAxis: {
            categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
                'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
        },

        series: [{
            data: [29.9, 71.5, 106.4, 129.2, 144.0, 176.0, 135.6, 126.0, 148.5, 216.4, 194.1, 95.6, 54.4]
        }]

    });

    var chart = $('#container').highcharts();
    createSVGFromChart(chart, $('#svg'));


});

function createSVGFromChart(chart, $target){
 $target.html(chart.getSVG());
}

在foreignObject元素中呈现图例以允许正确的HTML呈现。但是,似乎这个对象没有像我想象的那样呈现。元素似乎是偏移的,不可见。进一步检查外来对象会产生以下HTML:

    <foreignObject x="0" y="0" width="200" height="200">
    <div class="highcharts-legend" style="position: absolute; left: 266px; top: 313px; opacity: 1;">
        <div style="position: absolute; left: 0px; top: 0px; opacity: 1;">
            <div style="position: absolute; left: 0px; top: 0px; opacity: 1;">
                <div class="highcharts-legend-item highcharts-area-series highcharts-color-0 highcharts-series-0" style="position: absolute; left: 8px; top: 3px; opacity: 1;"><span style="font-family: 'lucida grande', 'lucida sans unicode', arial, helvetica, sans-serif; font-size: 12px; position: absolute; white-space: nowrap; color: rgb(51, 51, 51); font-weight: bold; cursor: pointer; margin-left: 0px; margin-top: 0px; left: 5px; top: 3px; fill: rgb(51, 51, 51);"><ul><li>1</li><li>2</li></ul></span></div>
            </div>
        </div>
    </div>
</foreignObject>

我已经继续创建了一个jsfiddle(here),只在SVG中使用了foreignObject元素来查看它将呈现的内容。虽然原始图表的图例似乎可以通过绝对定位正确放置,但它们仍然无法渲染。检查内联样式后,您可以看到foreignObject的第一个子元素具有绝对定位,将其自身置于foreginElement的容器之外。我能够通过手动更改该元素的内联样式来确认这一点,以便左侧和顶部位置都为0.

所以问题是,我如何获得Highchart的SVG,因为它与任何嵌入的HTMl一起呈现,以便正确表示用户所看到的内容?

此外,getChartHTML无法解决此问题,因为它只提取HTML而不是SVG。

1 个答案:

答案 0 :(得分:0)

Highcharts正在添加foreginObject,其身体元素不是在JSFiddle中动态生成的 - 它是可见的,并且可以在查看时在导出的SVG中进行检查。在Chrome中。您可以从导出模块覆盖sanitizeSVG功能,以防止创建foreginObject

演示:http://jsfiddle.net/2juxcnsy/

  var preventDefaultSVGgetting = false,
        orygFun = Highcharts.Chart.prototype.sanitizeSVG;
  Highcharts.Chart.prototype.sanitizeSVG = function(svg, b) {
    return preventDefaultSVGgetting ? svg : orygFun(svg, b)
  };

  // the button handler
  $('#button').click(function() {
    var svg;

    preventDefaultSVGgetting = true;
    svg = chart.getSVG();
    preventDefaultSVGgetting = false;

    $('#containerContainer').prepend(svg);
  });

我能看到的唯一问题是位置是绝对的,所以如果导出的图表放在身体顶部以外的位置,那么图例将与导出的图表相对错位。