2013-04-04 10 views
7

Sto provando a salvare il grafico generato dai grafici di Google come immagine png. Il codice funziona bene per tutti i grafici tranne GeoChart. L'immagine a volte appare ma spesso è solo vuota. Ecco il codice.PhantomJs per salvare l'immagine png dell'API GeoChart 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 nel terminale:

phantomjs render.js chart.png 

risposta

7

tenta di ritardare la vostra resa:

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

Questo lo ritarderà di 1000 ms (1 secondo) e dovrebbe essere sufficiente per il caricamento corretto del grafico.

+0

Grazie. ha funzionato – Aayush

4

In realtà, un timeout di 1 secondo non è sufficiente se si utilizza GeoChart con indicatori in modalità testo (anziché lat/long). Una soluzione migliore è codificare attorno a una funzione ricorsiva che controlla se l'evento pronto è stato attivato dal grafico; fare questo in un 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); 

e assicurarsi che si sta monitorando il console.log come fanno nei Highcharts phantomjs script:

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

e poi tenere chiamare setTimeout fino window.ischartready è vero (o passa un numero predefinito di secondi e ti arrendi).

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

Il sistema dosen't mi permetto di commentare @Jeroen risposta così in base alla sua risposta mi piacerebbe aggiungere questo:

1- È necessario registrare l'evento prima di chiamare il metodo draw. the-ready-event

L'aggiunta di un listener per questo evento dovrebbe essere fatto prima di chiamare il metodo draw(), perché altrimenti l'evento potrebbe essere licenziato prima che l'ascoltatore è impostato e non si prenderà esso.

2- Invece di utilizzare onConsoleMessage. Vorrei usare page.onCallback (phantom on callBack). E, naturalmente, sulla funzione chartready chiamerei window.callPhantom

Problemi correlati