Using wkhtmltopdf to output Google Charts to PDF - javascript

We have a Silverstripe project that uses the silverstripe-wkhtmltopdf module to output HTML/CSS/Javascript as PDF.
Simple Javascript like document.write works but I want to output Google Charts using their visualisation API:
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script>
google.load('visualization', '1', {packages: ['corechart', 'bar']});
</script>
The PDF wasn't showing any of the visualisation output so I used QTBrowser to debug the Javascript - as suggested here: Debugging javascript in wkhtmltopdf
The error I'm getting in QTBrowser is: Error: one or more fonts could not be loaded. from https://www.google.com/uds/api/visualization/1.0/b5ac9efed10eef460d14e653d05f5fbf/webfontloader,dygraph,format+en,default+en,ui+en,bar+en,corechart+en.I.js:737
The HTML looks correct at my end but I don't know the compatibility of QTBrowser, or how it relates to wkhtmltopdf.
Has anyone had any experience/ success with using wkhtmltopdf to output Google Charts?

Here's a good post which explains this topic and shows you how to achieve it
http://codingexplained.com/coding/php/using-google-visualization-with-wkhtmltopdf
<script type="text/javascript">
function init() {
google.load("visualization", "1.1", { packages:["corechart"], callback: 'drawCharts' });
}
function drawCharts() {
drawAccountImpressions('chart-account-impressions');
}
function drawAccountImpressions(containerId) {
var data = google.visualization.arrayToDataTable([
['Day', 'This month', 'Last month'],
['01', 1000, 400],
['05', 800, 700],
['09', 1000, 700],
['13', 1000, 400],
['17', 660, 550],
['21', 660, 500],
['23', 750, 700],
['27', 800, 900]
]);
var options = {
width: 700,
height: 400,
hAxis: { title: 'Day', titleTextStyle: { color: '#333' } },
vAxis: { minValue: 0 },
curveType: 'function',
chartArea: {
top: 30,
left: 50,
height: '70%',
width: '100%'
},
legend: 'bottom'
};
var chart = new google.visualization.LineChart(document.getElementById(containerId));
chart.draw(data, options);
}
</script>
</head>
<body onload="init()">
<div id="chart-account-impressions"></div>
</body>

Related

How to modify bar width of google chart column?

How I can modify the size of bar width of google chart column? I tried to add 'bar: { groupWidth: "20%" }' but it does nothing to the chart.
I really wanted it to make it thinner.
Here is the code that I want to use from google chart:
<html>
<head>
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<script type="text/javascript">
google.charts.load('current', {'packages':['bar']});
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
var data = google.visualization.arrayToDataTable([
['Year', 'Sales', 'Expenses', 'Profit'],
['2017', 1030, 540, 350]
]);
var options = {
chart: {
title: 'Company Performance',
subtitle: 'Sales, Expenses, and Profit: 2014-2017',
}
};
var chart = new google.charts.Bar(document.getElementById('chart_div'));
chart.draw(data, google.charts.Bar.convertOptions(options));
}
</script>
</head>
<body>
<div id="chart_div" style="width: 800px; height: 500px;"></div>
</body>
</html>
According to the documentation,
The Material Charts are in beta. The appearance and interactivity are largely final, but many of the options available in Classic Charts are not yet available in them. You can find a list of options that are not yet supported in this issue.
One of these options is the bar.groupWidth, which seems to not have support yet.
In this case, since you are working with a group of bars and there's only one array of information in data:
['2017', 1030, 540, 350]
then that option doesn't seem to work. However, if there were two or more groups, it seemed to render but in a limited way. This said, I was able to find some workarounds, each one with its own positive aspects and drawbacks.
Change from Material Charts to Classical Charts
Here you have to reconstruct the chart's code following the Classical one
Pros: options fully supported
Cons: you will change from Material Charts to Classical Charts
google.charts.load("current", { packages: ['corechart'] });
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
var data = google.visualization.arrayToDataTable([
['Type', 'Financial status',{ role: "style" }],
["Sales", 1030, "#4285f4"],
["Expenses", 540, "#db4437"],
["Profit", 350, "f4b400"],
]);
var view = new google.visualization.DataView(data);
var options = {
title: "Company Performance",
subtitle: "Sales, Expenses, and Profit: 2017",
width: 600, // chart width
bar: { groupWidth: "45%" }, // width of bars here
legend: { position: "none" },
};
var chart = new google.visualization.ColumnChart(document.getElementById("columnchart_values"));
chart.draw(view, options);
}
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<div id="columnchart_values" style="width: 900px; height: 300px;"></div>
Separate that only group of bars into single bars
Put that only group bar in different arrays and adapt your labels
Pros: the width will indeed change from 0 to 100% in groupWidth
Cons: looses colored bars
google.charts.load('current', { 'packages': ['bar'] });
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
var data = google.visualization.arrayToDataTable([
['Type', 'Financial status'],
["Sales", 1030],
["Expenses", 540],
["Profit", 350],
]);
var options = {
chart: {
title: 'Company Performance',
subtitle: 'Sales, Expenses, and Profit: 2017',
},
bar: { groupWidth: '50%' }, // change width here
width: 600, // width of the chart
height: 400 // height of the chart
};
var chart = new google.charts.Bar(document.getElementById('chart_div'));
chart.draw(data, google.charts.Bar.convertOptions(options));
}
google.charts.load('current', { 'packages': ['bar'] });
google.charts.setOnLoadCallback(drawChart);
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div" style="width: 900px; height: 300px;">
Use meaningless arrays
Put the array of information in the middle of two other meaningless arrays so
that you center your main data and gives the impression
Pros: still uses the Material Chart design
Cons: stretches the bars, doesn't provide space between bars
google.charts.load('current', { 'packages': ['bar'] });
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
var data = google.visualization.arrayToDataTable([
['Year', 'Sales', 'Expenses', 'Profit'],
[' ', 0, 0, 0], // meaningless
['2017', 1030, 540, 350],
[' ', 0, 0, 0] // meaningless
]);
var options = {
chart: {
title: 'Company Performance',
subtitle: 'Sales, Expenses, and Profit: 2017',
},
bar: { groupWidth: '90%' }, // change width of bar here,
width: 600, // width of the chart
height: 400, // height of the chart
};
var chart = new google.charts.Bar(document.getElementById('chart_div'));
chart.draw(data, google.charts.Bar.convertOptions(options));
}
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div" style="width: 900px; height: 300px;">

How to create downloadable link of google chart in image file

In the code, I am trying to add a hyperlink below the chart. As I click it, it will take me to a new tab with a google chart image for download.Any helps?
https://codepad.remoteinterview.io/KOURCFTBEG
As I viewed a lot of examples, most of them put
google.visualization.events.addListener(chart, 'ready',function() {
console.log(chart.getChart().getImageURI());
document.getElementById('png').innerHTML = '<a href="' +
chart.getChart().getImageURI() + '">Printable version</a>';
});
It seems to me that this would create a downloadable link to an image of the google chart on the <div id=png>But in my case, no link or clickable button is created.
google.charts.load('current', {'packages':['bar']});
google.charts.setOnLoadCallback(drawBar);
function drawBar() {
var data = google.visualization.arrayToDataTable([
['Year', 'Sales', 'Expenses', 'Profit'],
['2013', 1001, 401, 201],
['2014', 1000, 400, 200],
['2015', 1170, 460, 250],
['2016', 660, 1120, 300],
['2017', 1030, 540, 350]
]);
var options = {
chart: {
title: 'Company Performance',
subtitle: 'Sales, Expenses, and Profit: 2014-2017',
}
};
//---------------------------//
var chart = new google.charts.Bar(document.getElementById('chart_div'));
// Wait for the chart to finish drawing before calling the getImageURI() method.
google.visualization.events.addListener(chart, 'ready', function() {
console.log(chart.getChart().getImageURI());
document.getElementById('png').innerHTML = 'Printable version';
});
chart.draw(data, options);
}
<body>
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<script type="text/javascript" src="https://www.google.com/jsapi?autoload={'modules':[{'name':'visualization','version':'1.0','packages':['corechart']},{'name':'visualization','version':'1.0','packages':['controls']}]}"></script>
<div id="chart_div" style="width: 900px; height: 500px;"></div>
<div id='png'></div>
</body>
I followed the online source as similar as I can, but still get error like chart.getURI() is not function.
Here is the online source I referred most. Here is Fiddle.
Try this
<a href="link_to_image_download" target=_blank>Download here</a>
if you don't have a link to download, go to imgur.com and upload the image and add the share link into your href=
You can use print() as suggested by Google Developer API.
Here is the thing I assume you're looking for:
https://developers.google.com/chart/interactive/docs/printing
By removing getChart() in chart.getChart().getImageURI()and
,in package, by modifying bar to corechart can do the work.
google.charts.load('current', {'packages':['corechart']});
google.charts.setOnLoadCallback(drawBar);
function drawBar() {
var data = google.visualization.arrayToDataTable([
['Year', 'Sales', 'Expenses', 'Profit'],
['2013', 1001, 401, 201],
['2014', 1000, 400, 200],
['2015', 1170, 460, 250],
['2016', 660, 1120, 300],
['2017', 1030, 540, 350]
]);
var options = {
chart: {
title: 'Company Performance',
subtitle: 'Sales, Expenses, and Profit: 2014-2017',
}
};
//---------------------------//
var chart = new google.visualization.ColumnChart(document.getElementById('chart_div'));
// Wait for the chart to finish drawing before calling the getImageURI() method.
google.visualization.events.addListener(chart, 'ready', function() {
// console.log(chart.getImageURI());
document.getElementById('png').innerHTML = 'Printable version';
});
chart.draw(data, options);
}
<body>
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<script type="text/javascript" src="https://www.google.com/jsapi?autoload={'modules':[{'name':'visualization','version':'1.0','packages':['corechart']},{'name':'visualization','version':'1.0','packages':['controls']}]}"></script>
<div id="chart_div" style="width: 900px; height: 500px;"></div>
<div id='png'></div>
</body>

Animate the Column chart in Android application

I want to add start up animation in google Column chart on starting the chart in Android Application. I tried to run the code given at GoogleChart that is
<html>
<head>
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<script type="text/javascript">
google.charts.load('current', {'packages':['bar']});
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
var data = google.visualization.arrayToDataTable([
['Year', 'Sales', 'Expenses', 'Profit'],
['2014', 1000, 400, 200],
['2015', 1170, 460, 250],
['2016', 660, 1120, 300],
['2017', 1030, 540, 350]
]);
var options = {
chart: {
title: 'Company Performance',
subtitle: 'Sales, Expenses, and Profit: 2014-2017',
animation:{
duration: 1000,
easing: 'linear',
startup: true
},
}
};
var chart = new google.charts.Bar(document.getElementById('columnchart_material'));
chart.draw(data, options);
}
</script>
</head>
<body>
<div id="columnchart_material" style="width: 900px; height: 500px;"></div>
</body>
</html>
I have added the animation properties as:
animation: {
duration: 1000,
easing: 'linear',
startup: true
},
But the chart is not animating in Android App on the start.
I also tried to run the code in browser, the chart is working fine but is not animating.
there are several options Material charts do not support, including animation
see --> Tracking Issue for Material Chart Feature Parity #2143
Material charts --> google.charts.Bar -- packages: ['bar']
Core charts --> google.visualization.ColumnChart -- packages: ['corechart']
using a Core chart with the following option will display similar to Material
theme: 'material'
when using animation, the option is not part of any other
the code in the question has animation as part of chart -- (chart.animation)
it would be more like...
var options = {
animation:{
duration: 1000,
easing: 'linear',
startup: true
},
chart: {
title: 'Company Performance',
subtitle: 'Sales, Expenses, and Profit: 2014-2017',
}
};
see following working snippet for animation using Core chart...
google.charts.load('current', {
callback: function () {
drawChart();
window.addEventListener('resize', drawChart, false);
},
packages:['corechart']
});
function drawChart() {
var data = google.visualization.arrayToDataTable([
['Year', 'Sales', 'Expenses', 'Profit'],
['2014', 1000, 400, 200],
['2015', 1170, 460, 250],
['2016', 660, 1120, 300],
['2017', 1030, 540, 350]
]);
var options = {
animation:{
duration: 1000,
easing: 'linear',
startup: true
},
height: 600,
theme: 'material',
title: 'Company Performance'
};
var chart = new google.visualization.ColumnChart(document.getElementById('columnchart_material'));
chart.draw(data, options);
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="columnchart_material"></div>
note: Core chart does not have option for chart

Google Bar Chart Not Changing Background Color

I'm using the google Material Charts static api library and I cannot figure out why the background color I"m entering is not reflecting the change when the page loads.
Here are the options I have:
var options = {
backgroundColor: '#E8E4D8',
chart: {
title: 'Coaches by Service',
subtitle: 'Coaches by Services: From 2016-09-10 until Today'
}
};
And here is how I'm instantiating the chart:
var chart = new google.charts.Bar(document.getElementById('chart_div'));
chart.draw(data, google.charts.Bar.convertOptions(options));
The chart title and subtitle are correctly displaying, any advice as to why the background color remains as the default white would be greatly appreciated.
Is there more you can share? Appears to work here...
Maybe, check the version you're loading.
Here, I use frozen version '44', instead of 'current'.
There have been recent issues.
google.charts.load('44', {
callback: drawChart,
packages: ['bar']
});
function drawChart() {
var data = google.visualization.arrayToDataTable([
['Year', 'Sales', 'Expenses', 'Profit'],
['2014', 1000, 400, 200],
['2015', 1170, 460, 250],
['2016', 660, 1120, 300],
['2017', 1030, 540, 350]
]);
var options = {
backgroundColor: '#E8E4D8',
chart: {
title: 'Coaches by Service',
subtitle: 'Coaches by Services: From 2016-09-10 until Today'
}
};
var chart = new google.charts.Bar(document.getElementById('chart_div'));
chart.draw(data, google.charts.Bar.convertOptions(options));
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div" style="width: 900px; height: 500px;"></div>
For me it was missing google.charts.Bar.convertOptions
Originally it was like this.
chart.draw(data, options);
This works:
chart.draw(data, google.charts.Bar.convertOptions(options));

Google Charts bar chart: How to manually change the colour of every bar? (single series)

I have written a simple bar chart with Google Charts, one series, it works fine, all bars are blue:
Now I would like to manually set the colour of the every single bar (actually a green-to-red transition proportional to the value, to make it easier to understand what is good/bad).
How can I do this?
I have tried setting colors in options as described here but for some reason it does not work in my code below.
chco seems to be what I need, but it is an URL parameter... how to elegantly integrate it in JavaScript code?
google.setOnLoadCallback(drawChart);
function drawChart() {
var data = google.visualization.arrayToDataTable([
['Product', 'Score'],
['NemakiWare', 288],
['Nuxeo', 240],
['FileNet', 220],
['SharePoint', 98]
]);
var options = {
colors: ['green','blue','pink','red'],
legend: 'none',
hAxis: {
textPosition: 'none',
minValue: 0,
gridlines: {
color: 'transparent'
}
}
};
var chart = new google.visualization.BarChart(document.getElementById('chart_div'));
chart.draw(data, options);
}
<script type="text/javascript" src="https://www.google.com/jsapi?autoload={'modules':[{'name':'visualization','version':'1','packages':['corechart']}]}"></script>
<div id="chart_div" style="width: 900px; height: 500px;"></div>
There are different ways to do this but you can use the style role.
Source:
https://developers.google.com/chart/interactive/docs/gallery/columnchart#Colors
google.setOnLoadCallback(drawChart);
function drawChart() {
var data = google.visualization.arrayToDataTable([
['Product', 'Score', { role: 'style' }],
['NemakiWare', 288, 'green'],
['Nuxeo', 240, 'blue'],
['FileNet', 220, 'pink'],
['SharePoint', 98, 'red']
]);
var options = {
legend: 'none',
hAxis: {
textPosition: 'none',
minValue: 0,
gridlines: {
color: 'transparent'
}
}
};
var chart = new google.visualization.BarChart(document.getElementById('chart_div'));
chart.clearChart();
chart.draw(data, options);
}
<script type="text/javascript" src="https://www.google.com/jsapi?autoload={'modules':[{'name':'visualization','version':'1','packages':['corechart']}]}"></script>
<div id="chart_div" style="width: 900px; height: 500px;"></div>

Categories