2013-04-04 1 views
7

Ich versuche, das Diagramm von Google-Charts als ein PNG-Bild generiert zu speichern. Der Code funktioniert für alle Diagramme außer GeoChart. Das Bild wird manchmal angezeigt, ist aber oft nur leer. Hier ist der Code.PhantomJs zum Speichern von PNG-Bild von Google-Diagramm 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 in Terminal:

phantomjs render.js chart.png 

Antwort

7

Versuchen Sie, Ihre Rendering Verzögerung:

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

Dies verzögert es um 1000ms (1 Sekunde) und sollte genug Zeit sein, damit Ihr Diagramm korrekt geladen wird.

+0

Danke. es funktionierte – Aayush

4

Eigentlich ist ein Timeout von 1 Sekunde bei weitem nicht genug, wenn Sie das GeoChart mit Markern im Textmodus verwenden (anstelle von lat/long). Eine bessere Lösung besteht darin, eine rekursive Funktion zu codieren, die prüft, ob das Ereignis ready vom Diagramm ausgelöst wurde. tun dies in einer 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); 

und stellen Sie sicher, dass Sie die console.log überwachen, wie sie in den HighCharts tun PhantomJS Skript:

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

Und dann halten SetTimeout bis window.ischartready Aufruf ist wahr (oder eine vordefinierte Anzahl von Sekunden vergeht und du gibst einfach auf).

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

Das System dosen't mir erlauben, auf seine Antwort auf @Jeroen Antwort kommentieren, so basiert ich das hinzufügen würde:

1- Sie müssen das Ereignis registrieren, bevor die Auslosung Methode aufrufen. the-ready-event

einen Zuhörer zu diesem Event Hinzufügen sollte vor dem Aufruf der Methode draw() erfolgen, da sonst das Ereignis ausgelöst wird, bevor der Hörer eingerichtet ist, und Sie werden es nicht fangen.

2- Anstatt onConsoleMessage zu verwenden. Ich würde page.onCallback (phantom on callBack) verwenden. Und natürlich würde ich bei der chartready-Funktion window.callPhantom anrufen

Verwandte Themen