Google Charts Dashboard - "View" property on ChartWrapper not working - javascript

I'm trying to create a Google Charts dashboard with multiple charts all based on the same dataset. Different charts require different columns of the data, though, and every time I try to limit the columns in the ChartWrapper view, I get an error. Here's my code:
google.charts.load('current', {packages: ['corechart', 'bar', 'controls']});
google.charts.setOnLoadCallback(drawDashboard);
function drawDashboard() {
var data = google.visualization.arrayToDataTable([
['Institution', 'Ineligible', 'Active', 'Closed With Outcome', 'Closed Outside Process', 'Closed Without Outcome',
'Eligibile'],
['CAC', 144, 35, 38, 4, 175, 115 ],
['SPF', 62, 2, 12, 1, 93, 4 ],
['CM', 69, 18, 10, 7, 64, 32 ],
['IP', 36, 4, 28, 24, 38, 62 ],
['EVM', 77, 7, 8, 2, 78, 19 ],
['RMC', 63, 5, 9, 1, 62, 18 ],
['MRI', 17, 5, 1, 5, 8, 3 ],
['IRM', 8, 0, 2, 1, 10, 5 ],
]);
var dashboard = new google.visualization.Dashboard(
document.getElementById('dashboard_div'));
var iamFilter = new google.visualization.ControlWrapper({
'controlType': 'CategoryFilter',
'containerId': 'iam_filter',
'options': {
'filterColumnLabel': 'IAM',
'ui': {
'caption': "Choose mechanisms",
'label': '',
'labelStacking': 'vertical',
'selectedValuesLayout': 'belowWrapping',
'cssClass': 'ChartControl',
}
},
});
var columnChart = new google.visualization.ChartWrapper({
'chartType': 'ColumnChart',
'containerId': 'id_outcomes',
'options': {
colors: ['#1b5869', '#42bb9a', '#bec3c7', '#9953b5', '#4c96da'],
animation: {
"startup": true,
duration: 1000,
easing: 'out',
},
legend: { position: 'right'},
bar: { groupWidth: '75%' },
isStacked: true,
},
'view': {'columns': [0,2,3]},
});
dashboard.bind(iamFilter, columnChart);
dashboard.draw(data);
}
In the above example, the error I get is:
Invalid column index 3. Should be an integer in the range [0-2].
But if I change it to 'view': {'columns': [0,2]}, the error I get is:
Invalid column index 2. Should be an integer in the range [0-1].
The view property works fine on the ControlWrapper, but I need it to work on the ChartWrapper, since a single ControlWrapper needs to filter data for multiple charts.
Any advice is much appreciated!

Related

Multi-colored line chart with google visualization

I'm using google line chart in my project and facing a problem that I need to change color for some segments to visualize the target status changes over time. It should look like this:
I've searched around for quite long but couldn't find a way to do that with google chart.
My workaround is to add another series to the chart and alternately set the value of the second line eq to the first line based on the status but it looks tedious.
Is there a proper way to do this? Here is a sample of my workaround solution:
function drawMultipleTrendlineChart() {
var chart;
var data = new google.visualization.DataTable();
data.addColumn('date', 'Date');
data.addColumn('number', 'Sales value A');
data.addColumn('number', 'Sales value B');
data.addRows([
[new Date(2013, 3, 11), 200, 0],
[new Date(2013, 4, 02), 500, 0],
[new Date(2013, 5, 03), 700, 0],
[new Date(2013, 6, 04), 800, 800],
[new Date(2013, 7, 05), 500, 500],
[new Date(2013, 8, 06), 900, 0],
[new Date(2014, 0, 07), 800, 0],
[new Date(2014, 1, 08), 1100, 1100],
[new Date(2014, 2, 09), 1000, 1000],
[new Date(2014, 2, 10), 1000, 0],
[new Date(2014, 3, 11), 800, 0],
]);
var formatter = new google.visualization.NumberFormat({
fractionDigits: 2,
prefix: 'R$:'
});
formatter.format(data, 1);
var dateFormatter = new google.visualization.NumberFormat({
pattern: 'MMM yyyy'
});
dateFormatter.format(data, 0);
var chartHeight = 400;
var chartWidth = 600;
var chartOptions = {
tooltip: {
isHtml: true
},
title: 'Trendlines with multiple lines',
isStacked: true,
width: chartWidth,
height: chartHeight,
colors: ['#0000D8', '#00dddd'],
hAxis: {
title: 'example title',
slantedText: false,
slantedTextAngle: 45,
textStyle: {
fontSize: 10
},
format: 'dd-MM-yyyy'
},
chartArea: {
left: 50,
top: 20,
width: (chartWidth - 10),
height: (chartHeight - 90)
}
};
chart = new google.visualization.LineChart(document.getElementById('multipleTrendChart'));
chart.draw(data, chartOptions);
}
google.load('visualization', '1', {
packages: ['corechart'],
callback: drawMultipleTrendlineChart
});
<html>
<head>
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
</script>
</head>
<body>
<div id="multipleTrendChart"></div>
</body>
</html>
After looking at this answer How to change color for negative values, I tried and this works for me. The answer is using DataView API to manipulate the data.
google.charts.load('current', {
callback: drawLineColors,
packages: ['corechart']
});
function drawLineColors() {
var data = new google.visualization.DataTable();
data.addColumn('number', 'X');
data.addColumn('number', 'Blue Team');
data.addColumn('number', 'Red Team');
data.addRows([
[0, 0, 0],
[3, 1700, 1600],
[6, 1800, 1700],
[9, 2500, 2423],
[12, 3000, 2500],
[15, 4700, 5800],
[18, 5200, 5900],
[21, 5500, 6000],
[24, 6000, 6200],
[27, 6800, 6700],
[30, 7500, 7000],
[33, 7800, 8200],
[36, 7900, 9756],
[39, 8000, 10752],
[42, 9000, 13753],
[45, 15000, 17845]
]);
var options = {
legend: {
position: 'top'
},
enableInteractivity: false,
width: 712,
height: 156,
backgroundColor: {
fill: 'transparent'
},
curveType: 'function',
hAxis: {
title: 'Time'
},
vAxis: {
title: 'Team Gold'
}
};
var dataView = new google.visualization.DataView(data);
dataView.setColumns([
// reference first column by index
0,
// variance
{
calc: function(data, row) {
return data.getValue(row, 1);
},
type: 'number',
label: 'Y'
},
// variance color
{
calc: function(data, row) {
var val = data.getValue(row, 2) - data.getValue(row, 1);
if (val >= 0) {
return '#0000FF';
}
return '#FF0000';
},
type: 'string',
role: 'style'
}
]);
var chart = new google.visualization.LineChart(document.getElementById('chart_div'));
chart.draw(dataView, options);
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>

Google chart horizontal scrollbar

Here is my chart so far:
JSFiddle
<!-- begin snippet: js hide: false console: true -->
<!-- language: lang-js -->
google.charts.load('current', {'packages':['corechart']});
google.charts.setOnLoadCallback(drawVisualization);
function drawVisualization() {
// Some raw data (not necessarily accurate)
var data = google.visualization.arrayToDataTable([
['Day', 'data1', 'data2', 'data3', 'data4', 'data1 compare', 'data2 compare', 'data3 compare', 'data4 compare', '', ''],
[0.85, 165, 938, 522, 998, null, null, null, null, 614.6, 500],
[1.15, null, null, null, null, 165, 938, 522, 998, 614.6, 510],
[1.5, 0, 0, 0, 0, 0, 0, 0, 0, null, null ],
[1.85, 135, 1120, 599, 1268, null, null, null, null, 682, 530],
[2.15, null, null, null, null, 165, 938, 522, 998, 682, 540],
[14, 135, 1120, 599, 1268, null, null, null, null, 682, 530],
[16, null, null, null, null, 165, 938, 522, 998, 682, 540]
]);
var options = {
title : 'Chart',
vAxes: [
{title: 'foo'},
{title: 'bar'}
],
//hAxis: { ticks: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]},
hAxis: {
ticks: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31],
textStyle : {
fontSize: 9 // or the number you want
}
},
seriesType: 'bars',
bar: { groupWidth: 1000 },
isStacked: true,
legend: 'none',
interpolateNulls: true,
series: {
0: {
targetAxisIndex: 0
},
4: {
targetAxisIndex: 0
},
8: {
targetAxisIndex: 1,
type: 'line'
},
9: {
targetAxisIndex: 1,
type: 'line'
}
}
};
var chart = new google.visualization.ComboChart(document.getElementById('chart_div'));
chart.draw(data, options);
}
</script>
<!-- language: lang-html -->
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div" style="width: 900px; height: 500px;"></div>
I wanted to ask if there is a way to make elements in chart make bigger, but have a horizontal scrollbar with vAxes labels fixed and always visible?
Something like this:
Google Charts has this explorer feature whereby you can scroll and zoom in/out of the Chart. However, no buttons or scroll bar will be displayed. You will have to use your mouse to drag and move horizontally on the chart displayed.
To allow this feature, simply add explorer: {axis: 'horizontal'} in your options object. You may notice that you can visit areas where there is no data displayed, to stop this add keepInBounds: true to the explorer options to give explorer: {axis: 'horizontal', keepInBounds: true}.
More information on the explorer options is available here under the table row name explorer.
If you would like a scroll bar feature, then another feature you could explore is a Google Charts ChartRangeFilter available here.
Implementation details and steps are available here and changes need to be made accordingly to your chart type.

Sum column in google viz DataTable dashboard

Here I have an simple demo: http://jsfiddle.net/36yve/
function drawVisualization() {
// Prepare the data
var data = google.visualization.arrayToDataTable([
['Name', 'Gender', 'Age', 'Donuts eaten'],
['Michael' , 'Male', 12, 5],
['Elisa', 'Female', 20, 7],
['Robert', 'Male', 7, 3],
['John', 'Male', 54, 2],
['Jessica', 'Female', 22, 6],
['Aaron', 'Male', 3, 1],
['Margareth', 'Female', 42, 8],
['Miranda', 'Female', 33, 6]
]);
// Define a slider control for the Age column.
var slider = new google.visualization.ControlWrapper({
'controlType': 'NumberRangeFilter',
'containerId': 'control1',
'options': {
'filterColumnLabel': 'Age',
'ui': {'labelStacking': 'vertical'}
}
});
// Define a category picker control for the Gender column
var categoryPicker = new google.visualization.ControlWrapper({
'controlType': 'CategoryFilter',
'containerId': 'control2',
'options': {
'filterColumnLabel': 'Gender',
'ui': {
'labelStacking': 'vertical',
'allowTyping': false,
'allowMultiple': false
}
}
});
// Define a Pie chart
var pie = new google.visualization.ChartWrapper({
'chartType': 'PieChart',
'containerId': 'chart1',
'options': {
'width': 300,
'height': 300,
'legend': 'none',
'title': 'Donuts eaten per person',
'chartArea': {'left': 15, 'top': 15, 'right': 0, 'bottom': 0},
'pieSliceText': 'label'
},
// Instruct the piechart to use colums 0 (Name) and 3 (Donuts Eaten)
// from the 'data' DataTable.
'view': {'columns': [0, 3]}
});
// Define a table
var table = new google.visualization.ChartWrapper({
'chartType': 'Table',
'containerId': 'chart2',
'options': {
'width': '300px'
}
});
// Create a dashboard
new google.visualization.Dashboard(document.getElementById('dashboard')).
// Establish bindings, declaring the both the slider and the category
// picker will drive both charts.
bind([slider, categoryPicker], [pie, table]).
// Draw the entire dashboard.
draw(data);
}
​all works fine.
What I want to know?
How I can add row at the end of table to sum column [Age and Donuts eaten] and also to work when I use filters-controls ?
is there any solution for that problem?
You need to take the Table out of the Dashboard and create a "ready" event handler for the PieChart that grabs the data used by the chart, aggregates it to get the totals, builds a new DataTable including the totals, and draws the Table using the new data:
function drawVisualization() {
// Prepare the data
var data = google.visualization.arrayToDataTable([
['Name', 'Gender', 'Age', 'Donuts eaten'],
['Michael' , 'Male', 12, 5],
['Elisa', 'Female', 20, 7],
['Robert', 'Male', 7, 3],
['John', 'Male', 54, 2],
['Jessica', 'Female', 22, 6],
['Aaron', 'Male', 3, 1],
['Margareth', 'Female', 42, 8],
['Miranda', 'Female', 33, 6]
]);
// Define a slider control for the Age column.
var slider = new google.visualization.ControlWrapper({
'controlType': 'NumberRangeFilter',
'containerId': 'control1',
'options': {
'filterColumnLabel': 'Age',
'ui': {'labelStacking': 'vertical'}
}
});
// Define a category picker control for the Gender column
var categoryPicker = new google.visualization.ControlWrapper({
'controlType': 'CategoryFilter',
'containerId': 'control2',
'options': {
'filterColumnLabel': 'Gender',
'ui': {
'labelStacking': 'vertical',
'allowTyping': false,
'allowMultiple': false
}
}
});
// Define a Pie chart
var pie = new google.visualization.ChartWrapper({
'chartType': 'PieChart',
'containerId': 'chart1',
'options': {
'width': 300,
'height': 300,
'legend': 'none',
'title': 'Donuts eaten per person',
'chartArea': {'left': 15, 'top': 15, 'right': 0, 'bottom': 0},
'pieSliceText': 'label'
},
// Instruct the piechart to use colums 0 (Name) and 3 (Donuts Eaten)
// from the 'data' DataTable.
'view': {'columns': [0, 3]}
});
// Define a table
var table = new google.visualization.ChartWrapper({
'chartType': 'Table',
'containerId': 'chart2',
'options': {
'width': '300px'
}
});
google.visualization.events.addListener(pie, 'ready', function () {
var dt = pie.getDataTable().toDataTable();
var totals = google.visualization.data.group(dt, [{
type: 'number',
column: 0,
// make all values the same
modifier: function () {return 0;}
}], [{
type: 'number',
column: 2,
aggregation: google.visualization.data.sum
}, {
type: 'number',
column: 3,
aggregation: google.visualization.data.sum
}]);
dt.addRow(['Total', null, totals.getValue(0, 1), totals.getValue(0, 2)]);
table.setDataTable(dt);
table.draw();
});
// Create a dashboard
new google.visualization.Dashboard(document.getElementById('dashboard')).
// Establish bindings, declaring the both the slider and the category
// picker will drive both charts.
bind([slider, categoryPicker], [pie]).
// Draw the entire dashboard.
draw(data);
}
see example here: http://jsfiddle.net/asgallant/x8f7J/

Google Chart API Control range and snapToData issues

Using google charts API with line chart controlled by range finder.I am stuck with two annoying issues:
The control has extra space before and after the data values it was set to follow, leaving an ugly space the control can slide to.
I can not seem to get the control to snap to data value.
If you can give me a pointer what I am doing wrong I will appreciate it a lot.
I set a JSfiddle here: http://jsfiddle.net/Db4fm/2/
Thank you very much!
JS
function drawChart() {
var activity_breakdown = [
['Text Index', 'Numeric Index', 'totals', 'Value 1', 'Value 2', 'Value 3',
'Value 4', 'Value 5', 'Value 6', 'Value 7'],
['W15', 1, 13, 2, 0, 20, 2, 1, 0, 0],
['W16', 2, 20, 0, 1, 10, 3, 0, 0, 2],
['W17', 3, 19, 3, 0, 20, 2, 0, 2, 0],
['W18', 4, 31, 0, 2, 10, 4, 1, 0, 3],
['W19', 5, 11, 1, 0, 10, 2, 0, 3, 0],
['W20', 6, 26, 0, 0, 10, 6, 0, 0, 4],
['W21', 7, 39, 2, 0, 30, 2, 1, 2, 0],
['W22', 8, 41, 0, 3, 10, 7, 0, 0, 0],
['Today', 9, 44, 0, 1, 20, 2, 1, 0, 5]
];
// Data table
var data1 = google.visualization.arrayToDataTable(activity_breakdown);
// Chart
var chart1 = new google.visualization.ChartWrapper({
chartType: 'ColumnChart',
containerId: 'chart_activity',
dataTable: data,
options: {
width: 950,
height: 300,
chartArea: {
left: 40,
top: 20,
width: 700,
height: 250
},
legend: {
position: 'right',
textStyle: {
fontSize: 13
}
}
},
view: {
columns: [0, 3, 4, 5, 6, 7, 8, 9]
}
});
var control1 = new google.visualization.ControlWrapper({
'controlType': 'ChartRangeFilter',
'containerId': 'control_activity',
'options': {
// Filter by the date axis.
'filterColumnIndex': 1,
'ui': {
'chartType': 'LineChart',
'snapToData': true, // this bugger is not working
'chartOptions': {
width: 950,
height: 50,
chartArea: {
left: 40,
top: 0,
width: 700,
height: 50
},
'hAxis': {
textPosition: 'none'
}
},
'chartView': {
'columns': [0, 2]
},
'minRangeSize': 1
}
},
'state': {
'range': {
'start': 7,
'end': 8
}
}
});
var dashboard1 = new google.visualization.Dashboard(
document.getElementById('dashboard_activity'));
// Draw
dashboard1.bind(control1, chart1);
dashboard1.draw(data1);
google.visualization.events.addListener(control1, 'statechange', function () {
var v = control1.getState();
document.getElementById('dbgchart').innerHTML = v.range.start + ' -> ' +
v.range.end;
return 0;
});
// FSM knows why but without this line this line the code will not run...
var data = new google.visualization.DataTable();
}
google.load('visualization', '1.1', {
packages: ['corechart', 'controls']
});
google.setOnLoadCallback(drawChart);
HTML
<div id="dashboard_activity">
<div id="chart_activity"></div>
<div id="control_activity"></div>
</div>
<p>Debug range: <span id="dbgchart">Init</span></p>
The space before and after your data values is a result of setting your range filter's chart's domain axis to axis 0, which is a "string" type axis. If you want the line to go edge-to-edge, the domain axis has to be a continuous data type ("number", "date", "datetime", "timeofday"). If you change the control's chart's view.columns parameter to [1, 2], the spaces will go away:
var control1 = new google.visualization.ControlWrapper({
controlType: 'ChartRangeFilter',
containerId: 'control_activity',
options: {
filterColumnIndex: 1,
ui: {
chartType: 'LineChart',
snapToData: true, // this bugger is not working
chartOptions: {
width: 950,
height: 50,
chartArea: {
left: 40,
top: 0,
width: 700,
height: 50
},
hAxis: {
textPosition: 'none'
}
},
chartView: {
columns: [1, 2]
},
minRangeSize: 1
}
},
state: {
range: {
start: 7,
end: 8
}
}
});
I couldn't replicate your problem with the ui.snapToData option.
Updated jsfiddle with fix: http://jsfiddle.net/asgallant/Db4fm/3/
Change line 67 to as follows:
'columns': [1, 2]
jsFiddle: http://jsfiddle.net/Db4fm/4/

Having trouble with getFilteredRows using Google Chart API dashboard

I'm putting together a dashboard and trying to do something that should be straight-forward. There will be Control Filters to operate at the dashboard level, but I also need to specify some additional filters (static, not through a control) to just a single table. The method for getFilteredRows seems to be the answer but it is not working.
I've mocked up the example that Google has in the Code Playground to try to get this to work. In this case, I'm trying to have the Pie chart only show those that are 20 years or older.
(link to Google Code Playground: http://code.google.com/apis/ajax/playground/?type=visualization#full_dashboard)
Code I'm trying:
function drawVisualization() {
// Prepare the data
var data = google.visualization.arrayToDataTable([
['Name', 'Gender', 'Age', 'Donuts eaten'],
['Michael' , 'Male', 12, 5],
['Elisa', 'Female', 20, 7],
['Robert', 'Male', 7, 3],
['John', 'Male', 54, 2],
['Jessica', 'Female', 22, 6],
['Aaron', 'Male', 3, 1],
['Margareth', 'Female', 42, 8],
['Miranda', 'Female', 33, 6]
]);
// Define a slider control for the Age column.
var slider = new google.visualization.ControlWrapper({
'controlType': 'NumberRangeFilter',
'containerId': 'control1',
'options': {
'filterColumnLabel': 'Age',
'ui': {'labelStacking': 'vertical'}
}
});
// Define a category picker control for the Gender column
var categoryPicker = new google.visualization.ControlWrapper({
'controlType': 'CategoryFilter',
'containerId': 'control2',
'options': {
'filterColumnLabel': 'Gender',
'ui': {
'labelStacking': 'vertical',
'allowTyping': false,
'allowMultiple': false
}
}
});
// Define a Pie chart
var pie = new google.visualization.ChartWrapper({
'chartType': 'PieChart',
'containerId': 'chart1',
'options': {
'width': 300,
'height': 300,
'legend': 'none',
'title': 'Donuts eaten per person',
'chartArea': {'left': 15, 'top': 15, 'right': 0, 'bottom': 0},
'pieSliceText': 'label'
},
// Instruct the piechart to use colums 0 (Name) and 3 (Donuts Eaten)
// from the 'data' DataTable.
'view': {
'columns': [0,3],
'rows': [
{
'calc': function(data) {
return data.getFilteredRows({column: 2, minValue: 20});
},
'type': 'number'
}]
}
});
// Define a table
var table = new google.visualization.ChartWrapper({
'chartType': 'Table',
'containerId': 'chart2',
'options': {
'width': '300px'
}
});
// Create a dashboard
new google.visualization.Dashboard(document.getElementById('dashboard')).
// Establish bindings, declaring the both the slider and the category
// picker will drive both charts.
bind([slider, categoryPicker], [pie, table]).
// Draw the entire dashboard.
draw(data);
}
The only thing I've changed from the original example is adding to the 'view' section of the Pie Chart.
Anyone have any thoughts?
Couple of small changes:
* No need for 'calc' as it is used for creating new calculated columns.
* the format of the function requires array even for a single value.
'view': {'columns': [0, 3],
'rows' : data.getFilteredRows([{column: 2, minValue: 20}])}

Categories

Resources