2013-04-04 6 views
7

Próbuję zapisać wykres generowany przez google charts jako obraz png. Kod działa dobrze dla wszystkich wykresów z wyjątkiem GeoChart. Obraz czasami pojawia się, ale często jest pusty. Oto kod.PhantomJs do zapisywania obrazu PNG z interfejsu Google Maps 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 w Terminalu:

phantomjs render.js chart.png 

Odpowiedz

7

Try opóźniając swój rendering:

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

Spowoduje to opóźnienie o 1000 ms (1 sekunda) i powinno wystarczyć na prawidłowe załadowanie wykresu.

+0

Thanx. zadziałało – Aayush

4

W rzeczywistości, przekroczenie limitu czasu o 1 sekundę jest zdecydowanie niewystarczające, jeśli używa się GeoChart ze znacznikami w trybie tekstowym (zamiast łacia/długa). Lepszym rozwiązaniem jest kodowanie wokół funkcji rekursywnej, która sprawdza, czy zdarzenie ready zostało wywołane przez wykres; zrobić to w 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); 

i upewnij się, że monitorowanie console.log jak robią w HighCharts phantomjs scenariusz:

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

A potem wzywasz setTimeout aż window.ischartready jest prawdziwe (lub z góry określona liczba sekund i po prostu się poddajesz).

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

System nie robi pozwalają mi komentować @Jeroen odpowiedź tak na podstawie jego odpowiedzi chciałbym dodać to:

1- Musisz zarejestrować zdarzenie przed wywołaniem metody rysowania. the-ready-event

Dodawanie słuchacza do tego wydarzenia powinno być zrobione przed wywołaniem metody draw(), ponieważ w przeciwnym razie zdarzenie może być zwolniony przed słuchaczem jest skonfigurowana i nie będzie go złapać.

2- Zamiast korzystać z wiadomości onConsoleMessage. Chciałbym użyć page.onCallback (phantom on callBack). I oczywiście na funkcji chartready, którą nazwałbym window.callPhantom

Powiązane problemy