如何使用Highcharts将图表的图片保存到服务器?

15

在Highcharts中,你有一个内置的按钮可以下载当前图表(例如:http://www.highcharts.com/demo/,这个按钮:arrow)。你可以将它保存为PNG、JPEG、PDF或SVG。

我想做的是创建一个链接,将图像保存到服务器上,而不是下载它。我该怎么做?

我猜我必须修改exporting.src.js文件中的exportChart函数。它看起来像这样(但我不知道如何用javascript实现):

exportChart: function (options, chartOptions) {
        var form,
            chart = this,
            svg = chart.getSVG(chartOptions);

        // merge the options
        options = merge(chart.options.exporting, options);

        // create the form
        form = createElement('form', {
            method: 'post',
            action: options.url
        }, {
            display: NONE
        }, doc.body);

        // add the values
        each(['filename', 'type', 'width', 'svg'], function (name) {
            createElement('input', {
                type: HIDDEN,
                name: name,
                value: {
                    filename: options.filename || 'chart',
                    type: options.type,
                    width: options.width,
                    svg: svg
                }[name]
            }, null, form);
        });

        // submit
        form.submit();

        // clean up
        discardElement(form);
    },
4个回答

14

使用PhantomJS可以非常简单地完成。您可以呈现Highchart图表并将其保存为SVG、PNG、JPEG或PDF格式。下面的示例同时将演示Highcharts图表呈现为SVG和PDF:

var system = require('system');
var page = require('webpage').create();
var fs = require('fs');

// load JS libraries
page.injectJs("js/jquery.min.js");
page.injectJs("js/highcharts/highcharts.js");
page.injectJs("js/highcharts/exporting.js");

// chart demo
var args = {
    width: 600,
    height: 500
};

var svg = page.evaluate(function(opt){
    $('body').prepend('<div id="container"></div>');

    var chart = new Highcharts.Chart({
        chart: {
            renderTo: 'container',
            width: opt.width,
            height: opt.height
        },
        exporting: {
            enabled: false
        },
        title: {
            text: 'Combination chart'
        },
        xAxis: {
            categories: ['Apples', 'Oranges', 'Pears', 'Bananas', 'Plums']
        },
        yAxis: {
            title: {
                text: 'Y-values'
            }
        },
        labels: {
            items: [{
                html: 'Total fruit consumption',
                style: {
                    left: '40px',
                    top: '8px',
                    color: 'black'
                }
            }]
        },
        plotOptions: {
            line: {
                dataLabels: {
                    enabled: true
                },
                enableMouseTracking: false
            },
            series: {
                enableMouseTracking: false, 
                shadow: false, 
                animation: false
            }
        },
        series: [{
            type: 'column',
            name: 'Andrii',
            data: [3, 2, 1, 3, 4]
        }, {
            type: 'column',
            name: 'Fabian',
            data: [2, 3, 5, 7, 6]
        }, {
            type: 'column',
            name: 'Joan',
            data: [4, 3, 3, 9, 0]
        }, {
            type: 'spline',
            name: 'Average',
            data: [3, 2.67, 3, 6.33, 3.33],
            marker: {
                lineWidth: 2,
                lineColor: 'white'
            }
        }, {
            type: 'pie',
            name: 'Total consumption',
            data: [{
                name: 'Andrii',
                y: 13,
                color: '#4572A7'
            }, {
                name: 'Fabian',
                y: 23,
                color: '#AA4643'
            }, {
                name: 'Joan',
                y: 19,
                color: '#89A54E'
            }],
            center: [100, 80],
            size: 100,
            showInLegend: false,
            dataLabels: {
                enabled: false
            }
        }]
    });

    return chart.getSVG();
},  args);

// Saving SVG to a file
fs.write("demo.svg", svg);
// Saving diagram as PDF
page.render('demo.pdf');

phantom.exit();

如果你将代码保存为demo.js,那么只需运行bin/phantomjs demo.js即可生成demo.svgdemo.pdf


我正在使用数据库,如何在demo.js中动态集成我的数据?谢谢。 - Hocine Ben
如果您有一个可以执行数据库查询并以json、xml、text等格式返回项目的HTTP可访问脚本,那么集成就非常简单...只需从demo.js https://github.com/ariya/phantomjs/blob/master/examples/phantomwebintro.js调用它即可。 - gakhov
1
@HocineBen 最简单的方法就是从JS调用你的PHP脚本并解析响应: page.open('http://yourdomain.org/your.php', function (status) { var content = page.content; console.log('Content: ' + content); phantom.exit(); }); http://phantomjs.org/api/webpage/property/content.html - gakhov
@Gideon 这意味着 JQuery 没有加载。请检查您是否有 js/jquery.min.js - gakhov
我可以像使用jQuery一样使用PhantomJS而无需任何安装吗?如果不行,那我需要做什么来安装它?是否需要SSH访问? - M Argus Chopin Gyver
显示剩余2条评论

10

我刚刚使用了Nobita的方法来实现这个。我正在创建一份调查问卷,显示用户结果的图表,并上传图像到我的服务器中,然后通过电子邮件发送包含该图像的邮件。以下是需要注意的几点。

我需要对highcharts/exporting-server/index.php文件进行一些更新,具体如下:

我将目录从“temp”更改为其他内容,并且请注意它在4个不同的位置。

我必须添加“-XX:MaxHeapSize=256m”来更改shell_exec(),因为它给我带来了一个错误。

$output = shell_exec("java -XX:MaxHeapSize=256m -jar ". BATIK_PATH ." $typeString -d $outfile $width /mypathhere/results/$tempName.svg");

如果您希望下载该图像,可以保持以下内容不变:

header("Content-Disposition: attachment; filename=$filename.$ext");
header("Content-Type: $type");
echo file_get_contents($outfile);

但是,我进行了更改,因为我想要发送图像的路径,所以我删除了上面的内容,并将其替换为图像路径(请注意,我只是使用临时名称。):

echo "/mypathhere/results/$tempName.$ext";

另外,这个文件正在删除svg文件以及你创建的新文件。你需要删除删除文件的代码:

unlink($outfile);

如果你想保留svg文件,也可以删除它之前的行。

确保包含highcharts/js/modules/exporting.js。

接着,在你的JS代码中,可以按照以下方式进行操作:

var chart = new Highcharts.Chart();    
var imageURL = '';
var svg = chart.getSVG();
var dataString = 'type=image/jpeg&filename=results&width=500&svg='+svg;
$.ajax({
    type: 'POST',
    data: dataString,
    url: '/src/js/highcharts/exporting-server/',
    async: false,
    success: function(data){
        imageURL = data;
    }
});

你要发布的URL是/exporting-server/index.php的新版本,然后你可以根据自己的需要使用imageURL。


真的帮了我很多.. 对于那些没有得到输出的人,请遵循nobita的评论。如果您没有安装batik,则不会得到任何输出。或者,您可以使用图像魔术(在这种情况下,请使用shell_exec("convert /mypathhere/results/$tempName.svg $outfile"))。 - Serjas

4

我以前没有做过这个,但我相信您想要玩的是位于exporting-server文件夹中的index.php文件。 默认情况下,Highcharts提供(免费)Web服务,但您可以修改它并创建自己的Web服务来导出图表,或者对图表进行任何操作。请查看此处的说明Export module

“如果您想在自己的服务器上设置此Web服务,请从下载包中的/exporting-server目录中上传处理POST的index.php文件。

  1. 确保您的服务器上安装了PHP和Java。
  2. 将下载包中/exporting-server目录中的index.php文件上传到您的服务器。
  3. 在FTP程序中,在与index.php相同的目录中创建名为temp的目录,并将此新目录的chmod设置为777(仅适用于Linux / Unix服务器)。
  4. http://xmlgraphics.apache.org/batik/#download下载Batik。找到与您的jre版本匹配的二进制分发版。
  5. 将batik-rasterizer.jar和整个lib目录上传到Web服务器上的某个位置。在index.php文件顶部的选项中,设置路径以指向batik-rasterier.jar。
  6. 在您的图表选项中,将exporting.url选项设置为匹配您的PHP文件位置。"

0
你可以试一下。
 var chart = $('#yourchart').highcharts();
    svg = chart.getSVG();   
    var base_image = new Image();
    svg = "data:image/svg+xml,"+svg;
    base_image.src = svg;
    $('#mock').attr('src', svg);

获取 Mock 的 HTML 并发送到数据库或仅保存二进制代码。

将 Highchart 保存为二进制图像


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接