2013-04-04 73 views
7

我想保存由谷歌圖表生成的圖表作爲PNG圖像。該代碼適用於除GeoChart外的所有圖表。圖像有時會出現,但通常只是空白。這是代碼。PhantomJs保存谷歌圖表的API的圖像GeoChart

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

<!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在終端:

phantomjs render.js chart.png 

回答

7

儘量延緩你的渲染:

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

這會延遲1000ms(1秒),並且應該有足夠的時間讓圖表正確加載。

+0

Thanx。有效 – Aayush 2013-04-04 13:49:32

4

實際上,如果您在文本模式下使用帶標記的GeoChart(而不是lat/long),那麼1秒的超時是遠遠不夠的。一個更好的解決方案是圍繞遞歸函數進行編碼,以檢查圖表是否觸發了ready事件;在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); 

,並確保你正在監視的console.log就像他們在HighCharts做phantomjs腳本:

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; 
    } 
} 

然後保持通話的setTimeout直到window.ischartready是真的(或者預定的秒數通過,你只是放棄)。

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); 
0

系統這麼想的允許我這樣基於他的回答我想補充這對@Jeroen答案評論:

1 - 你需要調用draw方法之前註冊事件。 the-ready-event

添加監聽到這個事件應該調用draw()方法之前完成,因爲是建立在聽衆面前,否則事件可能被解僱,你會不會抓住它。

2-不使用onConsoleMessage。我會使用page.onCallback(phantom on callBack)。當然,我已經調用了函數window.callPhantom