dongmu1996 2012-12-29 09:09
浏览 38
已采纳

如何在node.js中加载Google Charts?

When I attempt to load a Google Chart in node.js, nothing happens.

I tried loading the first example from the line chart docs in both zombie.js and jsdom, but the chart never loads in either case.

The end goal is to retrieve the SVG data of the generated chart for export into an image or PDF. So if an alternate method (server side using node.js or PHP) to achieve this is possible, I'm open to suggestions.

NOTE: I have successfully generated a images of a few charts using gChartPhp, but the requirements of this project state that the embedded version be the interactive version provided by the current API and the exported version be visually IDENTICAL to the embedded one (without being interactive, obviously).

Edit: I tagged PhantomJS, since that is the solution with which I ultimately went.

Sorry for the lack of links, but the spam prevention mechanism will only allow me to post 2.

  • 写回答

1条回答 默认 最新

  • dprxj1995 2013-01-04 00:33
    关注

    It wasn't the ideal solution, but I found an alternative to node.js for accomplishing the same end goal in PhantomJS. Simply create an HTML file containing the chart (test.html) and like node.js, create a JS file containing your code (test.js). Then run your JS file with PhantomJS.

    In your JS file, open your HTML file as a webpage, then render it, either saving the image buffer to a file:

    var page = require('webpage').create();
    page.open('test.html', function () {
        page.render('test.png');
        phantom.exit();
    });
    

    Then run it:

    phantomjs test.js
    

    To dynamically create a chart, create the following JS file (test2.js):

    var system = require('system');
    var page = require('webpage').create();
    page.onCallback = function(data)
    {
        page.clipRect = data.clipRect;
        page.render('test.png');
        phantom.exit();
    };
    page.includeJs('http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js', function()
    {
        page.includeJs('https://www.google.com/jsapi', function()
        {
            page.evaluate(function(chartType, data_json, options_json)
            {
                var div = $('<div />').attr('id', 'chart').width(900).height(500).appendTo($('body'));
                google.load("visualization", "1",
                {
                    packages:[chartType == 'GeoChart' ? 'geochart' : 'corechart'],
                    callback: function()
                    {
                        data_arr = $.parseJSON(data_json);
                        data = google.visualization.arrayToDataTable(data_arr);
                        options = $.parseJSON(options_json);
                        chart = new google.visualization[chartType]($(div).get(0));
                        google.visualization.events.addListener(chart, 'ready', function()
                        {
                            window.callPhantom(
                            {
                                clipRect: $(div).get(0).getBoundingClientRect()
                            });
                        });
                        chart.draw(data, options);
                    }
                });
            }, system.args[1], system.args[2], system.args[3]);
        });
    });
    

    Then run it:

    phantomjs test2.js LineChart '[["Date","Steve","David","Other"],["Dec 31",8,5,3],["Jan 1",7,10,4],["Jan 2",9,4,3],["Jan 3",7,5,3]]' '{"hAxis.slantedText":true}'
    
    phantomjs test2.js PieChart '[["Employee","Calls"],["Steve",31],["David",24],["Other",13]]' '{"is3D":true}'
    
    phantomjs test2.js GeoChart '[["State","Calls"],["US-CA",7],["US-TX",5],["US-FL",4],["US-NY",8]]' '{"region":"US","resolution":"provinces"}'
    

    To get the image data from an external script, make a copy of test2.js (test3.js) and change

    page.render('test.png');
    

    to

    console.log(page.renderBase64('png'));
    

    Then call it (from PHP, for example):

    <?php
    
        $data = array(
            array("Employee", "Calls"),
            array("Steve", 31),
            array("David", 24),
            array("Other", 13)
        );
        $options = array(
            "is3D" => true
        );
        $command = "phantomjs test3.js PieChart '" . json_encode($data) . "' '" . json_encode($options) . "'";
        unset($output);
        $result = exec($command, $output);
        $base64_image = implode("
    ", $output);
        $image = base64_decode($base64_image);
    
    ?>
    

    NOTE: Looking back on this whole process, the problem I was having with node.js was possibly that I didn't setup callbacks or timeouts to wait until the charts were "ready".

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥20 机器学习能否像多层线性模型一样处理嵌套数据
  • ¥20 西门子S7-Graph,S7-300,梯形图
  • ¥50 用易语言http 访问不了网页
  • ¥50 safari浏览器fetch提交数据后数据丢失问题
  • ¥15 matlab不知道怎么改,求解答!!
  • ¥15 永磁直线电机的电流环pi调不出来
  • ¥15 用stata实现聚类的代码
  • ¥15 请问paddlehub能支持移动端开发吗?在Android studio上该如何部署?
  • ¥20 docker里部署springboot项目,访问不到扬声器
  • ¥15 netty整合springboot之后自动重连失效