Sometimes a chart looks a bit odd or doesn't convey all the information it could. Sometimes this is due to the way the original data is presented to make the chart.
Rows and Columns
The following two charts were created from the same data. For the first chart the data is arranged vertically. It consists of 3 columns, the semester, then the number of male then female students. In the second chart, the data is arranged horizontally with 3 rows, the semester, then the number of female then male students.
The data is the same but because of the way it is presented very different charts are produced.
Original data arranged vertically:
Original data arranged horizontally:
The above charts were drawn using the simple drawChart() method, and the code used is:
<script type="text/javascript">
var hvChart = (function() {
google.charts.load(['current']);
var myString = [];
myString[0] = '{"containerId": "verticalColumn_div",' + '"dataSourceUrl": "https://docs.google.com/spreadsheets/d/1tswaWUAbeBijHq4o505w0h7TmbD-qGhR3jBactcbGq0/gviz/tq?gid=1786091632&headers=1",' + '"query":"SELECT B,C,D ORDER BY A",' + '"chartType": "ColumnChart"' + '}';
myString[1] = '{"containerId": "horizontalColumn_div",' + '"dataSourceUrl": "https://docs.google.com/spreadsheets/d/1tswaWUAbeBijHq4o505w0h7TmbD-qGhR3jBactcbGq0/gviz/tq?gid=707970259&headers=1",' + '"query":"SELECT A,B,C,D,E,F,G,H,I,J,K,L ORDER BY A",' + '"chartType": "ColumnChart"' + '}';
var strLength = myString.length;
for (i=0; i < strLength; i++){
processChart(i);
}
function processChart(i) {
setTimeout(function() {
function drawVisualization() {
var newString = myString[i]
google.visualization.drawChart(newString);
}
google.charts.setOnLoadCallback(drawVisualization);
}, 0);
}
})();
</script>
If the data comes from a spreadsheet then both Microsoft Excel and Google Sheets have a transpose function to rotate the rows and columns.
Another method is to use the Pivot clause in the Query Language if that is being used.
As far as I know, DrawChart() does not use variables to hold the data table or any views created, bur both chartdraw() and ChartWrapper do.
In the following example the chartdraw() method is used. The data comes from a single Google Sheet, is drawn, rotated and then drawn again.
Original Data
Rotated Data
The code for the above example is:
<script type="text/javascript">
var rotateChart = (function() {
google.charts.load('current', {packages: ['corechart']});
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
var queryString = encodeURIComponent('SELECT A,B,C,D,E,F,G,H,I,J,K,L ORDER BY A');
var query = new google.visualization.Query('https://docs.google.com/spreadsheets/d/1tswaWUAbeBijHq4o505w0h7TmbD-qGhR3jBactcbGq0/gviz/tq?gid=707970259&headers=1&tq=' + queryString);
query.send(handleQueryResponse);
}
function handleQueryResponse(response) {
if (response.isError()) {
alert('Error in query: ' + response.getMessage() + ' ' + response.getDetailedMessage());
return;
}
var originalData = response.getDataTable();
var originalChart = new google.visualization.ColumnChart(document.getElementById('originalData_div'));
originalChart.draw(originalData);
//Rotate originalData to rotatedData
var rotatedData = new google.visualization.DataTable();
rotatedData.addColumn('string', 'data label'); // change this label to whatever is appropriate for you
for (var i = 0; i < originalData.getNumberOfRows(); i++) {
rotatedData.addColumn('number', originalData.getValue(i, 0));
}
for (var i = 1; i < originalData.getNumberOfColumns(); i++) {
var row = [originalData.getColumnLabel(i)];
for (var j = 0; j < originalData.getNumberOfRows(); j++) {
row.push(originalData.getValue(j, i));
}
rotatedData.addRow(row);
var rotatedChart = new google.visualization.ColumnChart(document.getElementById('rotatedData_div'));
rotatedChart.draw(rotatedData);
}
}
})();
</script>
In Switch axis in google.visualization.Query() object a user pointed out a problem when transposing data like this. The code only deals with the values of the cells (v) but not the formatting (f). The simple solution is to change the line
Of course it's always possible to setp back through the created table and add new formatting.
Let the User Choose!
Some data drawn as some chart types makes no sense at all, but sometimes it's useful to allow the user to choose to rotate the data. The following example uses a simple checkbox to toggle the rotation on or off.
In the above example there are two data tables, originalData and rotatedData. The state of the checkbox determines which one is used and an event handler determines when the state of that is changed.
One gotcha is that a new visualization must be created whenever the charts are redrawn or they do not get redrawn properly.
The HTML for the checkbox is:
<input type="checkbox" id="toggleRotate">
<label for="toggleRotate">Toggle the data rotation</label>
The code for the above example is:
<script type="text/javascript">
var userChart = (function() {
google.charts.load('current', {packages: ['corechart']});
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
var queryString = encodeURIComponent('SELECT B,C,D ORDER BY A');
var query = new google.visualization.Query('https://docs.google.com/spreadsheets/d/1tswaWUAbeBijHq4o505w0h7TmbD-qGhR3jBactcbGq0/gviz/tq?gid=1786091632&headers=1&tq=' + queryString);
query.send(handleQueryResponse);
}
function handleQueryResponse(response) {
if (response.isError()) {
alert('Error in query: ' + response.getMessage() + ' ' + response.getDetailedMessage());
return;
}
var originalData = response.getDataTable();
//Rotate originalData to rotatedData
var rotatedData = new google.visualization.DataTable();
rotatedData.addColumn('string', 'data label'); // change this label to whatever is appropriate for you
for (var i = 0; i < originalData.getNumberOfRows(); i++) {
rotatedData.addColumn('number', originalData.getValue(i, 0));
}
for (var i = 1; i < originalData.getNumberOfColumns(); i++) {
var row = [originalData.getColumnLabel(i)];
for (var j = 0; j < originalData.getNumberOfRows(); j++) {
row.push(originalData.getValue(j, i));
}
rotatedData.addRow(row);
checkchkbox();
function checkchkbox(){
var getState = document.getElementById("toggleRotate");
// The visualization MUST be remade for each redrawing
if (getState.checked){
var originalChart = new google.visualization.ColumnChart(document.getElementById('userChart_div')); originalChart.draw(originalData);}
else {
var rotatedChart = new google.visualization.ColumnChart(document.getElementById('userChart_div')); rotatedChart.draw(rotatedData);}
}
// Add event handler to checkbox
var chkbox = document.getElementById("toggleRotate");
chkbox.addEventListener ("change", checkchkbox, false);
}
}
})();
</script>
This page created January 30, 2021; last modified April 23, 2022