Make google chart responsive - javascript

Im using google charts in a project but im having a hard time to make them responsive.
Iǘe seen other examples on responsive charts but I cant seem to get it to work in my case.
All my charts gets rendered and after that their sizes do not change.
If someone can make this chart responsive id appreciate it. Thank you:
function drawChart() {
var data = new google.visualization.DataTable();
data.addColumn('string', 'Year');
data.addColumn('number', 'Revenue');
data.addColumn('number', 'Average Revenue');
data.addRows([
['2004', 1000, 630],
['2005', 1170, 630],
['2006', 660, 630],
['2007', 1030, 630]
]);
var options = {
title: 'Revenue by Year',
seriesType: "bars",
series: {1: {type: "line"}},
vAxis: {title: 'Year',
titleTextStyle:{color: 'red'}},
colors:['red','black']
};
var chart = new google.visualization.ComboChart(document.getElementById('chart'));
chart.draw(data, options);
}
google.load("visualization", "1", {packages:["corechart"]});
google.setOnLoadCallback(drawChart);
Fiddle for the chart:
Fiddle
If it could take up a percentage width of a parent it would be great

The solution was already given online elsewhere.
You need to call your drawChart() function whenever the window is resized to get the desired behaviour. The website flopreynat.com exactly describes this problem and solution (codepen). It describes how this can be done using JQuery:
$(window).resize(function(){
drawChart();
});
Using just Javascript, this answer on Stack Exchange by Sohnee describes how to trigger functions upon a resize event:
window.onresize = doALoadOfStuff;
function doALoadOfStuff() {
//do a load of stuff
}
All credit to both authors of the links above.

Add width_units to your option block:
var options = {
width: 80,
width_units: '%'
}

Or simply use:
var options = {
responsive: true,
}

I created a class chart, and used the window resize event like the accepted answer.
css:
.chart {
width: 100%;
min-height: 500px;
}
js:
$(window).resize(function(){
drawChart();
});
html:
<div id="barchart" class="chart"></div>

Related

Is there a way to reduce skew caused by few large y values in google line chart?

I am creating a line chart using google charts with the code below
google.charts.load('current', {'packages':['corechart']});
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
const datat = new google.visualization.DataTable();
datat.addColumn("date", "Date");
datat.addColumn("number", "New Users");
datat.addColumn({'type': 'string', 'role': 'tooltip' , 'p': {'html': true}});
for(var i=0; i<data.length; i++){
datat.addRow([new Date(data[i]['year']), parseInt(data[i]['value']), "<div style='margin: 10px; font-size:1.1em;'>Date: " + data[i]['year'] + "<br>Users: " + parseInt(data[i]['value']) + "</div>"])
}
var options = {
title: 'New Users Graph',
curveType: 'function',
legend: { position: 'none' },
titleY: "Users",
titleX: "Date",
tooltip: {isHtml: true}
};
var chart = new google.visualization.LineChart(document.getElementById('users'));
chart.draw(datat, options);
}
Because the value range is high we can see the small values are very hardly visible. Is there a way to prevent such skew? The only option i have figured out is to increase the height of the div. I have set the height to 500px, still the graph has massive skew. We cannot even exclude the outlier or the high values. Is there a way to make the graph look little more balanced so that all values are easily visible? Thanks for the insights.

Select event not fired on Google chart API for Sankey

I'm trying to hook an event to a click on a Google Sankey diagram. The Events claim to include select but it doesn't fire on Chrome or Safari. onmouseover/onmouseout/ready seem to be hooked up if the event is switched in the code below -- I get something in the console log. That is switching the line:
google.visualization.events.addListener(chart, 'select', selectHandler);
to
google.visualization.events.addListener(chart, 'onmouseover', selectHandler);
shows the event listener is connected.
I've tried this on other newer chart types like word-trees and select is connected. What have I missed?
E.g.
<html>
<head>
<script type='text/javascript' src='https://www.google.com/jsapi'</script>
<script type='text/javascript'>
google.load('visualization', '1.1', {packages:['sankey']});
google.setOnLoadCallback(drawChart);
function drawChart() {
var data = new google.visualization.DataTable();
data.addColumn('string', 'A');
data.addColumn('string', 'B');
data.addColumn('number', 'Mails');
data.addRows([
['from elvis','frank', 285],
['frank', 'to wendy', 61],
]);
var options = {width: 600};
var chart = new google.visualization.Sankey(document.getElementById('thechart'));
google.visualization.events.addListener(chart, 'select', selectHandler);
function selectHandler() {
console.log('You selected ' + JSON.stringify(chart.getSelection()));
};
chart.draw(data, options);
}
</script>
</head>
<body>
<div id='thechart' style='width: 600px; height: 300px;'></div>
</body>
</html>
You have to set correct options:
// Sets chart options.
var options = {
width: 600,
sankey: {
node: {
interactivity: true
}
}
};
I used this example https://jsfiddle.net/5mvx6bdr/
Works perfect :)
sankey: node: interactivity is set to false by default.
I think the issue here is that you are using the getSelection method for the Sankey chart event which returns an object. That object contains the node in the chart that you clicked on but you need to query the object in the right way to extract this information. I don't think it is possible to do things in a single line as attempted in the question above.
This is what worked for me when I had the same problem:
google.visualization.events.addListener(chart, 'select', function(){
var selection = chart.getSelection();
for(var key in selection) {
var value = selection[key];
console.log(value.name);
}
alert('you selected '+value.name);
});
The top answer did not work for me.
However, setting link interactivity to true did the trick.
var options = {
sankey: {
node: {
interactivity: true,
colors: this.colors
},
link: {
interactivity: true
}
}
}

How to set images as legends in Google Charts

I am trying to use images as legend in Google Charts. This is how it currently looks like:
And this is how it should look like:
This is my JavaScript code to draw the chart:
function drawChart() {
var data = google.visualization.arrayToDataTable([
['Champions', 'Games', 'Wins', 'Loses'],
['Ezreal', 21830, 12172, 9658],
['Taric', 17835, 9658, 8177],
['Graves', 13567, 6558, 7009],
['Lee Sin', 12738, 6349, 6389],
['Blitzcrank', 11965, 6132, 5833],
['Nunu', 10946, 5407, 5539],
['Sona', 9660, 5226, 4434],
['Corki', 9457, 4389, 5068],
['Jax', 8669, 4358, 4311],
['Amumu', 8396, 4743, 3653]
]);
var options = {
title: 'Most played',
backgroundColor: '#EEEEEE',
hAxis: {title: 'Champions', titleTextStyle: {color: 'red'}}
};
var chart = new google.visualization.ColumnChart(document.getElementById('most-popular'));
chart.draw(data, options);
}
I already tried to embed the <img> tags into the array like this:
['<img src="img/ezreal.png">'Ezreal', 21830, 12172, 9658]
Unfortunately, Google Charts does some kind of escape that string so that the whole HTML code is shown.
So I am looking for a way to include those images with Google Charts. If that is not possible I am looking for other JavaScript libraries which could do the job.
it is not possible! ( short answer, on mobile)

Remove padding or margins from Google Charts

// Load the Visualization API and the piechart package.
google.load('visualization', '1.0', {'packages':['corechart']});
// Set a callback to run when the Google Visualization API is loaded.
google.setOnLoadCallback(drawChart);
// Callback that creates and populates a data table,
// instantiates the pie chart, passes in the data and
// draws it.
function drawChart() {
// Create the data table.
var data = new google.visualization.DataTable();
data.addColumn('string', 'Topping');
data.addColumn('number', 'Slices');
var myData = {
'Mushrooms': 3,
'Onions': 1,
'Olives': 1,
'Zucchini': 1,
'Pepperoni': 2
};
var rows = [];
for (element in myData) {
rows.push([element + " (" + myData[element] + ")", myData[element]])
}
data.addRows(rows);
// Set chart options
var options = {'title':'How Much Pizza I Ate Last Night',
'width':450,
'height':300};
// Instantiate and draw our chart, passing in some options.
var chart = new google.visualization.PieChart(document.getElementById('chart_div'));
chart.draw(data, options);
}
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<div id="chart_div"></div>
Example fiddle
How do I remove padding or margins in this example?
By adding and tuning some configuration options listed in the API documentation, you can create a lot of different styles. For instance, here is a version that removes most of the extra blank space by setting the chartArea.width to 100% and chartArea.height to 80% and moving the legend.position to bottom:
// Set chart options
var options = {'title': 'How Much Pizza I Ate Last Night',
'width': 350,
'height': 400,
'chartArea': {'width': '100%', 'height': '80%'},
'legend': {'position': 'bottom'}
};
If you want to tune it more, try changing these values or using other properties from the link above.
I am quite late but any user searching for this can get help from it. Inside the options you can pass a new parameter called chartArea.
var options = {
chartArea:{left:10,top:20,width:"100%",height:"100%"}
};
Left and top options will define the amount of padding from left and top. Hope this will help.
I arrived here like most people with this same issue, and left shocked that none of the answer even remotely worked.
For anyone interested, here is the actual solution:
... //rest of options
width: '100%',
height: '350',
chartArea:{
left:5,
top: 20,
width: '100%',
height: '350',
}
... //rest of options
The key here has nothing to do with the "left" or "top" values. But rather that the:
Dimensions of both the chart and chart-area are SET and set to the SAME VALUE
As an amendment to my answer. The above will indeed solve the "excessive" padding/margin/whitespace problem. However, if you wish to include axes labels and/or a legend you will need to reduce the height & width of the chart area so something slightly below the outer width/height. This will "tell" the chart API that there is sufficient room to display these properties. Otherwise it will happily exclude them.
It's missing in the docs (I'm using version 43), but you can actually use the right and bottom property of the chart area:
var options = {
chartArea:{
left:10,
right:10, // !!! works !!!
bottom:20, // !!! works !!!
top:20,
width:"100%",
height:"100%"
}
};
So it's possible to use full responsive width & height and prevent any axis labels or legends from being cropped.
There's a theme available specifically for this
options: {
theme: 'maximized'
}
from the Google chart docs:
Currently only one theme is available:
'maximized' - Maximizes the area of the chart, and draws the legend and all of the labels inside the chart area. Sets the following options:
chartArea: {width: '100%', height: '100%'},
legend: {position: 'in'},
titlePosition: 'in', axisTitlesPosition: 'in',
hAxis: {textPosition: 'in'}, vAxis: {textPosition: 'in'}
There is this possibility like Aman Virk mentioned:
var options = {
chartArea:{left:10,top:20,width:"100%",height:"100%"}
};
But keep in mind that the padding and margin aren't there to bother you.
If you have the possibility to switch between different types of charts like a ColumnChart and the one with vertical columns then you need some margin for displaying the labels of those lines.
If you take away that margin then you will end up showing only a part of the labels or no labels at all.
So if you just have one chart type then you can change the margin and padding like Arman said. But if it's possible to switch don't change them.

Google chart redraw/scale on window resize

How do I redraw/rescale a google linechart on window resize?
To redraw only when the window resize is completed and avoid multiple triggers, I think is better create an event:
//create trigger to resizeEnd event
$(window).resize(function() {
if(this.resizeTO) clearTimeout(this.resizeTO);
this.resizeTO = setTimeout(function() {
$(this).trigger('resizeEnd');
}, 500);
});
//redraw graph when window resize is completed
$(window).on('resizeEnd', function() {
drawChart(data);
});
The original code by Google simply does this at the end:
var chart = new google.visualization.LineChart(document.getElementById('chart_div'));
chart.draw(data, options);
Changing it with a little javascript you can scale it when the window resizes:
function resize () {
var chart = new google.visualization.LineChart(document.getElementById('chart_div'));
chart.draw(data, options);
}
window.onload = resize;
window.onresize = resize;
Since the window.resize event fires multiple times on each resize event, I believe that the best solution is to use smartresize.js and use smartdraw(). This limits the number of chart redraw’s per window.resize.
By using the provided js you can do it as simply as this:
// Instantiate and draw our user charts, passing in some options (as you probably were doing it)
var chart = new google.visualization.LineChart(document.getElementById('div_chart'));
chart.draw(data, options);
// And then:
$(window).smartresize(function () {
chart.draw(data, options);
});
This is the simplest way I can work out of doing this without causing too much stress to the browser:
var chart1 = "done";
$(window).resize(function() {
if(chart1=="done"){
chart1 = "waiting";
setTimeout(function(){drawChart();chart1 = "done"},1000);
}
});
All it does is wait 1 second before the chart reloads and doesn't let the function call again in this waiting period. as window resize functions are called multiple times any time you change the window size this helps make the function only actually work once each time you change the window size, the rest of the calls get stopped by the if statement.
I hope this helps
There is no option in Google Visualization API to make Google Charts responsive.
But we can make Google Charts responsive as Window Resizes. To make Google Chart responsive there is jQuery library available at GitHub - jquery-smartresize licensed under MIT License, which has the ability to resize graphs on window resize event.
This project on GitHub has two script files :-
jquery.debouncedresize.js: adds a special event that fires once after the window
has been resized.
&
jquery.throttledresize.js: adds a special event that fires at a reduced rate (no
more double events from Chrome and Safari).
Here are two examples of responsive charts...
Responsive Google Pie Chart
Responsive Google Bar Chart
We can change the bottom padding of visualization_wrap to match the desired aspect ratio of chart.
Calculate as Height / Width x 100
For a 16x9 display it would be 9/16 = 0.5625 x 100 = 56.25%
For a square it'd be 100%
We can customize chartarea option of Google Chart to ensure that labels don't get cut off on resizing.
Redraw/rescale a Google linechart on window resize:
$(document).ready(function () {
$(window).resize(function(){
drawChart();
});
});
I personally prefer the following approach, if You can live with using addEventListener, and don't mind lack of support for IE < 9.
var windowResizeTimer;
window.addEventListener('resize', function(e){
clearTimeout(windowResizeTimer);
windowResizeTimer = setTimeout(function(){
chart.draw(data, options);
}, 750);
});
Note the use of the setTimeout() and clearTimeout() functions and the added delay of 750 milliseconds, which makes this slightly less intensive when multiple resize events fire in quick succession (which is often the case for browsers on desktop when resizing using a mouse).
I've been stuck on the same thing for days and I found out that adding an event works best.
window.addEventListener("resize", drawChart);
Just add this line after declaring your function and it will work fine.
Replace drawChart with the name of your function.
Try with these approaches
window.dispatchEvent(new Event('resize'))
Chartkick.charts["<id of chart element like chart-1>"].redraw()
Using Tiago Castro's answer, I have implemented a line chart to show the demonstration.
google.load('visualization', '1', {
packages: ['corechart', 'line']
});
google.setOnLoadCallback(drawBackgroundColor);
function drawBackgroundColor() {
var data = new google.visualization.DataTable();
data.addColumn('number', 'X');
data.addColumn('number', 'Compute Time');
data.addColumn('number', 'Compute Times');
console.log("--");
data.addRows([
[0, 0, 0],
[10, 10, 15],
[20, 20, 65]
]);
console.log(data);
var options = {
height: 350,
legend: {
position: 'bottom'
},
hAxis: {
title: 'Nb Curves'
},
vAxis: {
title: 'Time (ms)'
},
backgroundColor: '#f1f8e9'
};
function resize() {
var chart = new google.visualization.LineChart(document.getElementById('chart_div'));
chart.draw(data, options);
}
window.onload = resize();
window.onresize = resize;
}
<script src='https://www.google.com/jsapi'></script>
<div id="chart_div">

Categories

Resources