简体   繁体   English

PhantomJs保存谷歌图表的API GeoChart的png图像

[英]PhantomJs to save png image of google chart's API GeoChart

I am trying save the chart generated by google charts as a png image. 我正在尝试将谷歌图表生成的图表保存为png图像。 The code works fine for all charts except GeoChart.The image sometimes does appears but often its just blank. 该代码适用于除GeoChart之外的所有图表。图像有时会出现,但通常只是空白。 Here is the code . 这是代码。

render.js render.js

var system = require('system');
var page = require('webpage').create();
page.open('chart.html, function () {
    page.paperSize = { format: 'A4', orientation: 'landscape'};
    page.render(system.args[1]);
    phantom.exit();
});

chart.html chart.html

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<title>Chart Generation</title>
<meta http-equiv="content-type" content="text/html; charset=utf-8" /> 
<script type='text/javascript' src='https://www.google.com/jsapi'></script>
<script type='text/javascript'>
 google.load('visualization', '1', {'packages': ['geochart']});
 google.setOnLoadCallback(drawRegionsMap);

  function drawRegionsMap() {
    var data = google.visualization.arrayToDataTable([
      ['Country', 'Popularity'],
      ['Germany', 200],
      ['United States', 300],
      ['Brazil', 400],
      ['Canada', 500],
      ['France', 600],
      ['RU', 700]
    ]);
    var options = {
      width: 400,
      height: 200
    };
    var chart = new google.visualization
      .GeoChart(document.getElementById('chart_div'));
    chart.draw(data, options);
};
</script>
</head>
<body>
<div id="chart_div" style="width: 900px; height: 500px;"></div>
</body>
</html>

Usgae in Terminal : 终点的Usgae:

phantomjs render.js chart.png

Try delaying your rendering: 尝试延迟渲染:

page.open(address, function (status) {
   window.setTimeout(function () {
        page.render(output);
        phantom.exit();
    }, 1000);
});

This will delay it by 1000ms (1 second), and should be enough time for your chart to load properly. 这将延迟1000毫秒(1秒),并且应该足够时间让图表正确加载。

Actually, a timeout of 1 second is by far not enough if you use the GeoChart with Markers in text mode (instead of lat/long). 实际上,如果你在文本模式下使用带有标记的GeoChart(而不是lat / long),则1秒的超时是不够的。 A better solution is to code around a recursive function that checks if the ready event was triggered by the chart; 更好的解决方案是围绕递归函数进行编码,该函数检查图表是否触发了ready事件; do this in a page.evaluate: 在页面中执行此操作。评估:

function chartready() {
    console.log('Google.chart.ready');
}                       
var chart = new google.visualization.ChartWrapper(settings);    
chart.draw();
google.visualization.events.addListener(chart, 'ready', chartready);

and make sure you are monitoring the console.log like they do in the HighCharts phantomjs script: 并确保您像在HighCharts phantomjs脚本中一样监视console.log:

page.onConsoleMessage = function (msg) {
  /*
  * Ugly hack, but only way to get messages out of the 'page.evaluate()'
  * sandbox. If any, please contribute with improvements on this!
  */
  if (msg === 'Google.chart.ready') {
    window.ischartready = true;
  }
}

And then keep calling setTimeout until window.ischartready is true (or a predefined number of seconds pass and you just give up). 然后继续调用setTimeout,直到window.ischartready为true(或者预定义的秒数通过,你就放弃了)。

timeoutTime=8000;//wait not longer than 8 seconds
interval = window.setInterval(function () {
    console.log('waiting');
    if (window.ischartready) {
        clearTimeout(timer);
        clearInterval(interval);
        page.render(whatever);
    }
}, 50);

// we have a timeoutTime second timeframe..
timer = window.setTimeout(function () {
    clearInterval(interval);
    exitCallback('ERROR: While rendering, there\'s is a timeout reached');
}, timeoutTime);

The system dosen't allow me to comment on @Jeroen answer so based on his answer I'd add this: 系统不允许我评论@Jeroen的答案,所以基于他的回答我会添加这个:

1- You need to register the event before calling the draw method. 1-您需要在调用draw方法之前注册该事件。 the-ready-event 该就绪事件

Adding a listener to this event should be done before calling the draw() method, because otherwise the event might be fired before the listener is set up and you will not catch it. 在调用draw()方法之前,应该在此事件中添加一个侦听器,否则事件可能会在侦听器设置之前触发,而您将无法捕获它。

2- Instead of using onConsoleMessage. 2-而不是使用onConsoleMessage。 I'd use page.onCallback ( phantom on callBack ). 我使用page.onCallback( callBack上的幻像 )。 And of course on the chartready function I'd call window.callPhantom 当然在chartready函数上我会调用window.callPhantom

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM