Google Visualization - Specify Type from Query - google-visualization
I am creating a dashboard that queries a published google spreadsheet as the dataTable. The charts (column, table, and candlestick) show up just fine. However, I have added a listener event for 'sort' on the table and would like this to sort the corresponding data in the column and candlestick charts. However, when I sort the table by clicking on the header, the charts show the following error in red:
"All data columns of the same series must be of the same data type".
My spreadsheet contains a string for the first column and numbers for the other columns. However, I assume that I am getting this error message because the query is not returning the data as 'string' in the first column and 'number' in the other columns. Can I specify this? If so, how? Thanks.
EDIT: Here is my code...the addListener event at the bottom is causing the issue:
var query = new google.visualization.Query('https://docs.google.com/spreadsheet/pub?key=0AukymWvA6LlzdHpwblVtSmU3ZXJOMGhUVFZiV3NnSkE&single=true&gid=0&output=html');
query.setQuery('SELECT A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T');
query.send(function (response) {
if (response.isError()) {
alert('Error in query: ' + response.getMessage() + ' ' + response.getDetailedMessage());
return;
}
var data = response.getDataTable();
// CategoryFilter for Grade
var gradeFilter = new google.visualization.ControlWrapper({
controlType: 'CategoryFilter',
containerId: 'gradeFilter_div',
options: {
filterColumnIndex: 3
}
});
// CategoryFilter for School
var schoolFilter = new google.visualization.ControlWrapper({
controlType: 'CategoryFilter',
containerId: 'schoolFilter_div',
options: {
filterColumnIndex: 16
}
});
// CategoryFilter for Teacher
var teacherFilter = new google.visualization.ControlWrapper({
controlType: 'CategoryFilter',
containerId: 'teacherFilter_div',
options: {
filterColumnIndex: 17
}
});
// CategoryFilter for Entity
var entityFilter = new google.visualization.ControlWrapper({
controlType: 'CategoryFilter',
containerId: 'entityFilter_div',
options: {
filterColumnIndex: 18
}
});
var numberSlider = new google.visualization.ControlWrapper({
controlType: 'NumberRangeFilter',
containerId: 'rNumberRangeFilter_div',
options: {
filterColumnIndex: 19
}
});
// create a Table visualization
var rBubbleChart = new google.visualization.ChartWrapper({
chartType: 'BubbleChart',
containerId: 'rBubble_div',
options: {
title: 'Comparison of Percentiles',
height: 500,
width: 500,
chartArea:{left:"10%",top:"10%",width:"80%",height:"80%"},
backgroundColor: 'transparent',
bubble: {opacity: 0.6, stroke: 'transparent', textStyle: {fontSize: 8, color: 'transparent'}},
hAxis: {minValue: 0, maxValue: 100, gridlines: {count: 11, color: '#EEEEEE'}, title: '2013 Percentile', titleTextStyle: {fontSize:10}, textStyle: {fontSize:10}},
vAxis: {minValue: 0, maxValue: 100, gridlines: {count: 11, color: '#EEEEEE'}, title: '2014 Percentile', titleTextStyle: {fontSize:10}, textStyle: {fontSize:10}},
colors: ['#a4c2f4','#89B0F0','#6d9eeb','#558BE2','#3c78d8','#2767D2','#1155cc'],
legend: {position: 'in', alignment: 'center', textStyle: {fontSize:10}},
animation: {duration:1500, easing:'out'},
sizeAxis: {minSize: 2, minValue: 5, maxSize: 30, maxValue: 500}
},
view: {columns: [0, 1, 2, 3, 4]}
});
//Draw chart with y=x line
var hackChart = new google.visualization.ChartWrapper({
chartType: 'LineChart',
containerId: 'hack_chart_div',
dataTable: [['x', 'y'],[0, 0], [100, 100]],
options: {
height: 500,
width: 500,
chartArea:{left:"10%",top:"10%",width:"80%",height:"80%"},
hAxis: {minValue: 0, maxValue: 100, textPosition: 'none', gridlines: {count: 0}, baselineColor: 'none'},
vAxis: {minValue: 0, maxValue: 100, textPosition: 'none', gridlines: {count: 0}, baselineColor: 'none'},
colors: ['black'],
pointSize: 0,
lineWidth: 1,
enableInteractivity: false,
legend: {position: 'none'},
}
});
hackChart.draw();
var rCandlestickChart = new google.visualization.ChartWrapper({
chartType: 'CandlestickChart',
containerId: 'rCandle_div',
options: {
title: 'Distribution of Performance (Interquartile Range)',
height: 250,
width: 500,
chartArea:{left:"10%",top:"10%",width:"80%",height:"60%"},
hAxis: {textStyle: {fontSize:10}},
vAxis: {minValue: 0, maxValue: 100, title: 'Percentile', titleTextStyle: {fontSize:10}, textStyle: {fontSize:10}},
legend: {position: 'in'},
animation: {duration:1500, easing:'out'},
colors: ['#a4c2f4','#3c78d8']
},
view: {columns:[5, 6, 7, 8, 9, 10, 11, 12, 13]}
});
var rColumnChart = new google.visualization.ChartWrapper({
chartType: 'ColumnChart',
containerId: 'rColumn_div',
options: {
title: 'Percent Satisfactory',
height: 250,
width: 500,
chartArea:{left:"10%",top:"10%",width:"80%",height:"60%"},
hAxis: {textStyle: {fontSize:10}},
vAxis: {minValue: 0, maxValue: 100, title: '% Satisfactory', titleTextStyle: {fontSize:10}, textStyle: {fontSize:10}},
legend: {position: 'in'},
animation: {duration:1500, easing:'out'},
colors: ['#a4c2f4','#3c78d8']
},
view: {columns:[5, 14, 15]}
});
var rTableChart = new google.visualization.ChartWrapper({
chartType: 'Table',
containerId: 'rTable_div',
options: {
width: '300px',
height: '500px',
allowHtml: true,
cssClassNames: {tableCell: 'styleRows', headerRow: 'styleHeader'}
},
view: {columns: [16, 5, 19]}
});
var formatter = new google.visualization.BarFormat({width: 100, drawZeroLine: true, min: -20, max: 20});
formatter.format(data, 19);
// Create the dashboard.
var dashboard = new google.visualization.Dashboard(document.getElementById('dashboard')).
bind(entityFilter, [rBubbleChart, rCandlestickChart, rColumnChart, rTableChart]).
bind(schoolFilter, gradeFilter).bind(gradeFilter, teacherFilter).
bind(teacherFilter, [rBubbleChart, rCandlestickChart, rColumnChart, rTableChart]).
bind(numberSlider, [rBubbleChart, rCandlestickChart, rColumnChart, rTableChart]).
draw(data);
google.visualization.events.addListener(rTableChart, 'ready', function() {
google.visualization.events.addListener(rTableChart.getChart(), 'sort', function(event) {
data.sort([{column: event.column, desc: !event.ascending}]);
boxchartObject = rCandlestickChart.getChart();
boxchartObject.draw(data);
columnChartObject = rColumnChart.getChart();
columnChartObject.draw(data);
});
});
The problem is in the way you redraw the charts. By calling the ChartWrapper#getChart#draw method, you are bypassing all of the ChartWrapper's parameters - including the view parameter which specifies the columns to use. This is why you get the data type error. You need to redraw the Dashboard (to avoid a clash between the sorting and the filters). Use this:
var dashboard = new google.visualization.Dashboard(document.getElementById('dashboard'));
google.visualization.events.addListener(rTableChart, 'ready', function() {
google.visualization.events.addListener(rTableChart.getChart(), 'sort', function(event) {
// set the sorting options in the table so they are preserved on redraw
rTableChart.setOption('sortColumn', event.column);
rTableChart.setOption('sortAscending', event.ascending);
// convert the Table view column to a DataTable column
var col = rTableChart.getView().columns[event.column];
// sort the DataTable
data.sort([{column: col, desc: !event.ascending}]);
// redraw the dashboard
dashboard.draw(data);
});
});
dashboard.bind(schoolFilter, gradeFilter)
.bind(gradeFilter, teacherFilter)
.bind([entityFilter, teacherFilter, numberSlider], [rBubbleChart, rCandlestickChart, rColumnChart, rTableChart])
.draw(data);
To ensure that the sort event handler is set up properly, you should set up the Table wrapper's ready event before calling the Dashboard's draw method.
Update working example: http://jsfiddle.net/asgallant/t5rkJ/4/
Related
ArrayToDataTable not accepting datetime type
I have this code here for filtering my areachart by date, but it's not working correctly because arrayToDataTable is not accepting dateTime type. Any help would be appreciated. Anyone know how to fix this? This is my script: <script type="text/javascript"> google.load("visualization", "1.1", { packages: ["controls", "corechart"] }); google.setOnLoadCallback(drawChart); function drawChart() { $.ajax({ type: "POST", url: "GoogleChart.aspx/GetChartData", data: '{}', contentType: "application/json; charset=utf-8", dataType: "json", success: function (r) { var data = google.visualization.arrayToDataTable(r.d); var rangeFilter = new google.visualization.ControlWrapper({ controlType: 'ChartRangeFilter', containerId: 'filter-range', options: { filterColumnIndex: 0, ui: { chartType: 'AreaChart', chartOptions: { chartArea: { width: '100%', left: 36, right: 18 }, height: 72 } } } }); var chart = new google.visualization.ChartWrapper({ chartType: 'AreaChart', containerId: 'chart_div', options: { width: 1800, height: 600, legend: { alignment: 'end', position: 'top' }, animation: { duration: 500, easing: 'in', startup: true }, chartArea: { height: '100%', width: '100%', top: 36, left: 36, right: 18, bottom: 36 } } }); var dashboard = new google.visualization.Dashboard(document.getElementById('dashboard')); dashboard.bind(rangeFilter, chart); dashboard.draw(data); }, }); } </script>
in order to create date time values, you will need to manually change each row in the data. instead of using arrayToDataTable... var data = google.visualization.arrayToDataTable(r.d); create a blank data table, then use the column headings in the data to create the columns, and the rest to create the rows... var data = new google.visualization.DataTable(); r.d.forEach(function (row, index) { if (index === 0) { data.addColumn('date', row[0]); data.addColumn('number', row[1]); } else { data.addRow([new Date(row[0]), row[1]]); } });
how to fix this google charts bar chart error
same data are used to draw line chart and bar chart. it works fine for drawing line. but there is an error for drawing bar chart. the error is "a.getTime is not a function×". any suggestions are appreciated. here is my code: datasource.addColumn('date', 'Date'); datasource.addColumn('number', 'quantity'); datasource.addColumn('number', 'quantity'); datasource.addColumn('number', 'quantity'); for (n = 0; n < tem.length; n++) { datasource.addRows([[new Date(tem[n][0]), tem[n][1], tem[n][2], tem[n][3]]]); } *********line chart *********** chart = new google.visualization.LineChart(document.getElementById('chart_div')); var options = { actions: ['dragToZoom', 'rightClickToReset'], interpolateNulls: true, //bypass null legend: 'none', crosshair: { trigger: 'both', opacity: 0.5 }, // Display crosshairs on focus and selection. title: 'Company Performance', hAxis: { title: 'Year', titleTextStyle: { color: 'red' }, format: "YY.MM.dd", slantedText: true, slantedTextAngle: 30 }, vAxis: { viewWindowMode: 'explicit', viewWindow: { max: maxy, min: 0 } }, explorer: { axis: 'horizontal', maxZoomOut: 1 } //wheel zoom }; chart.draw(datasource, options); ***********bar chart************* chart = new google.visualization.BarChart(document.getElementById('chart_div')); var options = { title: 'Company Performance', hAxis: { title: 'Number', titleTextStyle: { color: 'red' } }, vAxis: { minValue: 0 }, explorer: { axis: 'horizontal', maxZoomOut: 1 } }; chart.draw(datasource, options);*
Google Charts: Setting padding for the hAxis
My chart is working fine as expected except that the hAxis labels have very little or no padding in between the chart itself and the legend. Is there a way to increase it? options: var options = { colors:['rgb(32, 170, 188)', 'rgb(32, 188, 77)'], lineWidth:4, areaOpacity: 0.15, width:$(window).width() * 0.5, height:$(window).width() * 0.25, animation: { "startup": true, duration: 1200, easing: 'out', }, fontName: 'Open Sans', legend: { position:'bottom', }, chartArea:{ width:'90%', height:'80%', } };
only option I can think of, would be to modify the labels once the chart is 'ready', or on 'animationfinish' in this example, the y position is increased by 4 looks kind of jumpy with the animation, there may be other options, if you know svg google.charts.load('current', { 'callback': function () { var data = google.visualization.arrayToDataTable([ ['Year', 'Sales', 'Expenses'], ['2013', 1000, 400], ['2014', 1170, 460], ['2015', 660, 1120], ['2016', 1030, 540] ]); var options = { colors:['rgb(32, 170, 188)', 'rgb(32, 188, 77)'], lineWidth:4, animation: { startup: true, duration: 1200, easing: 'out', }, areaOpacity: 0.15, fontName: 'Open Sans', legend: { position:'bottom', }, chartArea:{ } }; var container = document.getElementById('chart_div'); var chart = new google.visualization.AreaChart(container); google.visualization.events.addListener(chart, 'animationfinish', moveLabels); google.visualization.events.addListener(chart, 'ready', moveLabels); function moveLabels() { Array.prototype.forEach.call(container.getElementsByTagName('text'), function (label) { if (label.getAttribute('text-anchor') === 'middle') { label.setAttribute('y', parseFloat(label.getAttribute('y')) + 4); } }); } chart.draw(data, options); }, 'packages':['corechart'] }); <script src="https://www.gstatic.com/charts/loader.js"></script> <div id="chart_div"></div>
Google chart vAxis title being cut off and needs to move closer to axis
I'm trying to use Google charts to display the results of a survey. All seems fine, apart from the title of the vAxis is being cut off slightly and I can't work out how to move it closer to the axis. This is the code: google.load("visualization", "1.0", {packages:["bar"]}); google.setOnLoadCallback(drawChart); function drawChart() { var data = google.visualization.arrayToDataTable([ ['Question title goes here', 'Percentage Score'], ['Always', 40], ['Usually', 30], ['Rarely', 10], ['Never', 20] ]); var options = { chart: { title: 'Section Title', subtitle: 'Section subtitle', }, legend: { position: "none" }, vAxis: { title: 'Percentage', viewWindowMode:'explicit', viewWindow: { max:100, min:0 } }, bars: 'vertical', // Required for Material Bar Charts. width: 600, height: 500 }; var chart = new google.charts.Bar(document.getElementById('barchart_material')); chart.draw(data, google.charts.Bar.convertOptions(options)); }; I have a fiddle here: https://jsfiddle.net/SBComms/pa4yLcb3/
With a Core Chart, you can adjust the size of the chartArea to allow room for the title. However, this doesn't appear to work for a Material Chart. Also, I would recommend loading with loader.js vs. the older library jsapi. See following example... google.charts.load('current', { callback: drawChart, packages: ['bar', 'corechart'] }); function drawChart() { var data = google.visualization.arrayToDataTable([ ['Question title goes here', 'Percentage Score'], ['Always', 40], ['Usually', 30], ['Rarely', 10], ['Never', 20] ]); var options = { chart: { title: 'Section Title', subtitle: 'Section subtitle', }, chartArea: { backgroundColor: 'cyan', height: 400, left: 60, top: 20, width: 500 }, legend: { position: "none" }, vAxis: { title: 'Percentage', viewWindowMode:'explicit', viewWindow: { max:100, min:0 } }, bars: 'vertical', width: 600, height: 500 }; var chart = new google.charts.Bar(document.getElementById('barchart_material')); chart.draw(data, google.charts.Bar.convertOptions(options)); var chart2 = new google.visualization.ColumnChart(document.getElementById('barchart_core')); chart2.draw(data, options); }; <script src="https://www.gstatic.com/charts/loader.js"></script> <div>========MATERIAL========</div> <div id="barchart_material"></div> <div>==========CORE==========</div> <div id="barchart_core"></div>
I managed to find a real fiddle to the problem. I have updated the chart script so that the vAxis fontSize is 18: google.load("visualization", "1.0", {packages:["bar"]}); google.setOnLoadCallback(drawChart); function drawChart() { var data = google.visualization.arrayToDataTable([ ['', 'Percentage'], ['Always', 40], ['Usually', 30], ['Rarely', 10], ['Never', 20] ]); var options = { chart: { title: 'Company Performance' }, legend: { position: "none" }, vAxis: { title: 'Percentage', titleTextStyle: { fontSize: '18', }, viewWindowMode:'explicit', viewWindow: { max:100, min:0 } }, bars: 'vertical', // Required for Material Bar Charts. width: 400, height: 400 }; var chart = new google.charts.Bar(document.getElementById('barchart_material')); chart.draw(data, google.charts.Bar.convertOptions(options)); }; I have then added a CSS setting to force the font size back to normal: #barchart_material g text { font-size: 12px !important; } I have updated the fiddle here: https://jsfiddle.net/SBComms/pa4yLcb3/1/
Is it possible to show each legend in different color in google pie chart
Is it possible to show each legend in different color in google pie chart? I have 3 legends in my pie chart and i want to show each one of them in different color.
Yes, from google instructions: use the legend.textStyle option and assign it like so Object {color: 'black', fontName: <global-font-name>, fontSize: <global-font-size>} An object that specifies the legend text style. The object has this format: { color: <string>, fontName: <string>, fontSize: <number>, bold: <boolean>, italic: <boolean> } The color can be any HTML color string, for example: 'red' or '#00cc00'. Also see fontName and fontSize. so for each pi chart in the drawchart function drawChart() {//chart 1 var data = google.visualization.arrayToDataTable([ ['Language', 'Speakers (in millions)'], ['dataname1', 13], ['dataname2', 83], ]); var options = { title: 'chart 1', pieSliceText: 'label', legend.textStyle: { color: 'blue', fontName: 'arial'} }, }; var chart = new google.visualization.PieChart(document.getElementById('piechart1')); chart.draw(data, options); } function drawChart() {//chart 2 var data = google.visualization.arrayToDataTable([ ['Language', 'Speakers (in millions)'], ['dataname1', 13], ['dataname2', 83], ]); var options = { title: 'chart 2', pieSliceText: 'label', legend.textStyle: { color: 'red', fontName: 'arial'} }, }; var chart = new google.visualization.PieChart(document.getElementById('piechart2')); chart.draw(data, options); } function drawChart() {//chart 3 var data = google.visualization.arrayToDataTable([ ['Language', 'Speakers (in millions)'], ['dataname1', 13], ['dataname2', 83], ]); var options = { title: 'chart 3', pieSliceText: 'label', legend.textStyle: { color: 'green', fontName: 'arial'} }, }; var chart = new google.visualization.PieChart(document.getElementById('piechart3')); chart.draw(data, options); }