Using Google Charts JS Server-Side
Posted on 2015/01/08
Recently Google Charts had it's image API deprecated. NOOOOOOO! was my first reaction. But after realising I'm going to have to look for alternatives I went to work. Such is life.
Found quite a few options but longed for that sweet charts API.
Eventually I thought of something. Realised the JS api is still there, and we've got this little tool called PhantomJS ....
So I went to work to build a small service that takes input as numbers and then outputs a url to a cdn'd chart image. And it came out pretty slick ... This is how I did it.
Quick example to make .png from chart
phantom = require 'phantom'
gm = require('gm')
fs = require('fs')
# open up a phantom instance
phantom.create (ph) ->
ph.createPage (page) ->
# create the html to render
page_content = '
<style type="text/css">
html, body {
background-color: transparent;
}
.chartWithOverlay {
position: relative;
width: 700px;
}
.overlay {
width: 250px;
height: 200px;
/* position: absolute;
top: 120px;
left: 365px; */
position: absolute;
top: 0;
left: 46.5%;
top: 40%;
text-align:center;
}
</style>
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script type="text/javascript">
google.load("visualization", "1", {packages:["corechart"]});
google.setOnLoadCallback(drawChart);
function drawChart() {
var data = google.visualization.arrayToDataTable([
[\'Task\', \'Hours per Day\'],
[\'Desktop\', 234],
[\'Tablet\', 567],
[\'Mobile\', 200]
]);
var options = {
pieHole: 0.91,
legend: \'none\',
backgroundColor: \'transparent\',
pieSliceText: \'none\',
colors: [ "#363636", "#78B8C4", "#45C29D" ]
};
var chart = new google.visualization.PieChart(document.getElementById(\'piechart\'));
chart.draw(data, options);
}
</script>
</head>
<body>
<div class="chartWithOverlay">
<div id="piechart" style="width: 900px; height: 500px;"></div>
<div class="overlay">
<div style="color: #54565C;font-family:\'Arial Black\'; font-size: 43px;text-align:center;">1000</div>
<div style="color: #BEC1C4; font-family:\'Arial Black\'; font-size: 20px; letter-spacing: .15em; margin-top:-11px;text-align:center;">pageviews</div>
</div>
</div>
</body>
</html>'
# set as current page content
page.setContent page_content
# wait for page to finish loading
page.set 'onLoadFinished', ->
# render to a tmp file
page.render 'mychart.png', ->
# exit the instance
ph.exit()
process.exit(0)
This will produce the following image:
Which you can then use to show.
Live system ?
I'm currently using this technique for https://metricmailer.com which also crops the image.
But instead of immediately just returning the image. There is a microservice that accepts parameters to insert into chart. After which it creates this chart, uploads to Google Cloud Storage and outputs something like the the follow:
{ status: "ok", link: "https://storage.googleapis.com/cdn.metricmailer.com/2015/1/cce1efc0-3d9a-4c68-a452-03fb20465c3c.png" }
Then that link is just stored and used by the calling service. Pretty slick I think.
What's currently keeping me busy

Testing and keeping websites safe

Tech/product of new incubating startups

Advocate and educate on the Google Cloud

Easy prescribed book management

Loadshedding being constantly updated and watched

Secret management for PAAS

National microchip database

Youtube channel of edited meetup talks

Gaming Youtube Channel