NumberRangeFilter behaves strangely with decimals in Google Charts - google-visualization

I'm having trouble getting the numberRangeFilter control for google charts to play nicely with decimals. To illustrate the problem, I've modified the example from the docs to have five data points, some with decimals. I've also set the step property of the numberRangeFilter to move by increments of 0.1.
var control = new google.visualization.ControlWrapper({
'controlType': 'NumberRangeFilter',
'containerId': 'numberRangeFilter_control_div',
'options': {
'filterColumnIndex': 1,
'ui':{
'showRangeValues':true,
'step':0.1
}
}
});
var data = google.visualization.arrayToDataTable([
['Name', 'Age'],
['Robert', 7.0],
['John', 7.5],
['Aaron', 8.0],
['Aaron', 8.3],
['Jessica', 8.7]
]);
I would expect the slider to start with all data included, move in increments of 0.1, and filter out datapoints as the range is adjusted.
However I'm seeing two unexpected behaviors instead:
1) The filter range labels don't update properly as I move the max range slider. The max range label reads 8.7 even after I slide it three steps to the left. It filters out data as expected, but the labels don't update, so it continues to read 8.7.image of slider label behavior
2)The label on the minimum of the range does not include the lowest data point, despite displaying that bar on the graph:
image of nonsensical range
Has anyone seen this before dealing with decimals in google charts? Am I doing something wrong?
Full script below:
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<div id="numberRangeFilter_dashboard_div" style="border: 1px solid #ccc">
<p> </p>
<table class="columns">
<tr>
<td>
<div id="numberRangeFilter_control_div" style="padding-left: 2em"></div>
</td>
<td>
<div id="numberRangeFilter_chart_div"></div>
</td>
</tr>
</table>
</div>
<script type="text/javascript">
google.charts.load('current', {packages:['corechart', 'table', 'gauge', 'controls']});
google.charts.setOnLoadCallback(drawNumberRangeFilter);
function drawNumberRangeFilter() {
var dashboard = new google.visualization.Dashboard(
document.getElementById('numberRangeFilter_dashboard_div'));
var control = new google.visualization.ControlWrapper({
'controlType': 'NumberRangeFilter',
'containerId': 'numberRangeFilter_control_div',
'options': {
'filterColumnIndex': 1,
'ui':{
'showRangeValues':true,
'step':0.1
}
}
});
var data = google.visualization.arrayToDataTable([
['Name', 'Age'],
['Robert', 7.0],
['John', 7.5],
['Aaron', 8.0],
['Aaron', 8.3],
['Jessica', 8.7]
]);
var chart = new google.visualization.ChartWrapper({
'chartType': 'BarChart',
'containerId': 'numberRangeFilter_chart_div',
'options': {
'width': 400,
'height': 300,
'hAxis': {'minValue': 0, 'maxValue': 60},
'chartArea': {top: 0, right: 0, bottom: 0}
}
});
dashboard.bind(control, chart);
dashboard.draw(data);
}
</script>

Workaround: display the true selected range of the numberRangeFilter controller on the page using statechange events, and modifying html on page each time the event fires. Use these new text divs instead of the standard numberRangeFilter labels.
Clumsy, but it works for me.
google.visualization.events.addListener(control, 'statechange', selectHandler);
function selectHandler(e) {
var range_selected = control.getState()
document.getElementById("lower_range_label").innerHTML = "Lower Range:"+range_selected.lowValue
document.getElementById("upper_range_label").innerHTML = "Upper Range:"+range_selected.highValue
}

Related

How to Query multiple spreadsheets and make charts on same page

I am trying to develop a small web app which query the multiple google spreadsheets and make the graphs on the same page. I can query the single spreadsheet and chart the matching data like this and it is working fine.
<html>
<head>
<title>
Test
</title>
<script src="http://www.google.com/jsapi"></script>
<script src="http://code.jquery.com/jquery-2.0.3.min.js"></script>
<script type="text/javascript" src="https://www.google.com/jsapi">
</script>
<script type="text/javascript">
google.load('visualization', '1', {'packages': ['table', 'controls', 'corechart']});
google.setOnLoadCallback(initialize);
function initialize() {
var urlMonth = 'https://docs.google.com/spreadsheets/d/1y5MgFR67kn1-GHbmeIi6wuC5hmP10x4O8vAs5RWD8Sw/edit#gid=0'
var queryStringMonthly = encodeURIComponent("select A, B, C, D, E, F, G, H, I GROUP BY A LABEL A 'Gene' ");
var queryMonthCurrent = new google.visualization.Query(urlMonth+
queryStringMonthly);
queryMonthCurrent.send(megaData);
}
function megaData(monthData) {
var monthData_table = monthData.getDataTable(firstRowIsHeader = true);
var monthData_tablePivot = new google.visualization.DataTable();
monthData_tablePivot.addColumn('string');
monthData_tablePivot.addColumn('number');
monthData_tablePivot.addColumn({type: 'string', label: 'Gene', role: 'annotation'});
var newRows = []; //
//iterate through each row
for (i = 0; i < monthData_table.getNumberOfRows(); i ++) {
var issue = monthData_table.getValue(i, 0);
//iterate through each column
for (j = 1; j < monthData_table.getNumberOfColumns(); j ++ ){
var newRow = [];
rep = monthData_table.getColumnLabel(j);
newRow.push(rep);
newRow.push(monthData_table.getValue(i, j));
newRow.push(issue);
newRows.push(newRow); //push each newRow to newRows
}
}
monthData_tablePivot.addRows( newRows);
// Create a dashboard.
var dashboard = new google.visualization.Dashboard(
document.getElementById('dashboard_div4'));
// Create filter
var issueFilter = new google.visualization.ControlWrapper({
'controlType': 'StringFilter',
'containerId': 'filter_div4',
'options': {
'filterColumnLabel': 'Gene',
'ui': {
'allowMultiple': false,
'allowNone': false,
}
},
//Set default filter value
'state': {'selectedValues': [monthData_table.getValue(0 , 1)]}
}
);
//create chart
var yearChart = new google.visualization.ChartWrapper({
'chartType': 'ColumnChart',
'containerId': 'current_year',
'options': {
'legend': 'none',
'width': 1100,
'height': 500,
hAxis: {
textStyle: {
color: 'black', // any HTML string color ('red', '#cc00cc')
fontName: 'Times New Roman', // i.e. 'Times New Roman'
fontSize: 12, // 12, 18 whatever you want (don't specify px)
bold: true, // true or false
italic: false // true of false
},
'title': 'Gene', titleTextStyle:{color:'black',fontSize: 16,bold:
true,italic: false}
},
vAxis: {title: 'Expression', titleTextStyle:{color:'black',fontSize:
16,bold: true,italic: false},
textStyle: {
color: 'black', // any HTML string color ('red', '#cc00cc')
fontName: 'Times New Roman', // i.e. 'Times New Roman'
fontSize: 12, // 12, 18 whatever you want (don't specify px)
bold: true, // true or false
italic: false // true of false
}
},
//Set the fontsize of labels so they don't show up crazily
'annotations': {'textStyle': {'opacity': 0},
//use 'line' style so to remove the line
pointer
'style': 'point',
'stemLength': 0
},
}
});
// bind charts and controls to dashboard
dashboard.bind(issueFilter, yearChart);
// Draw the dashboard.
dashboard.draw(monthData_tablePivot);
}
</script>
<style>
.SearchBar input {
height: 30px;
width: 400px;
}
</style>
</head>
<body>
<!--Div that will hold the dashboard-->
<center>
<h2>Seach gene expression</h2>
<div id="dashboard_div4" class="SearchBar" placeholder="Search">
<div id="filter_div4" > </div></center>
<div id="current_year" style="width:1100px; height: 300px;">
</div>
</div>
</html>
This repository is very close to my need but I don't know how to query the multiple spreadsheet. My another spreadsheet look like this
https://docs.google.com/spreadsheets/d/1vmPmaL78N-Ywz7s1y_VRSvQAZxjacN4mo7uKKrWrwzE/edit#gid=0

Google Charts vAxis Title not showing

I'm trying to use Google Charts and seem to be running into issues with titles not displaying. Im using a Column Chart and the vAxis title is not displaying. I also started to make a Material Line Chart and I'm running into the same issue.
Here's the Material Line Chart code:
<html>
<head>
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<script type="text/javascript">
google.charts.load('current', {packages: ['corechart','line']});
</script>
</head>
<body>
<div id="container" style="width: 550px; height: 400px; margin: 0 auto"></div>
<script language="JavaScript">
function drawChart() {
// Define the chart to be drawn.
var data = new google.visualization.DataTable();
data.addColumn('string', 'Cycle ID');
data.addColumn('number', '5A Continuous');
data.addColumn('number', '10A Continuous');
data.addColumn('number', '20A Continuous');
data.addColumn('number', '10A Pulse');
data.addColumn('number', '20A Pulse');
data.addRows([
['1', 2548, 2319, 828, 2348, 2192],
['2', 2537, 2306, 829, 2362, 2187],
['3', 2533, 2301, 833, 2347, 2170],
['4', 2530, 2300, 833, 2343, 2156],
['5', 2526, 2297, 837, 2339, 2147],
['6', 2519, 2294, 839, 2340, 2142],
['7', 2510, 2287, 838, 2356, 2146],
['8', 2506, 2276, 839, 2359, 2139],
['9', 2504, 2275, 840, 2346, 2127],
['10', 2500, 2274, 838, 2336, 2119],
]);
var formatter = new google.visualization.NumberFormat({
pattern: '####'
});
formatter.format(data, 1);
formatter.format(data, 2);
formatter.format(data, 3);
formatter.format(data, 4);
formatter.format(data, 5);
// Set chart options
var options = {
chart: {
title: 'LG HG2 Battery Performance Over Cycles',
},
hAxis: {
title: 'Cycle ID',
},
vAxis: {
title: 'Milliamp Hours',
},
'width':550,
'height':400,
lineWidth: 20,
};
// Instantiate and draw the chart.
var chart = new google.charts.Line(document.getElementById('container'));
chart.draw(data, options);
}
google.charts.setOnLoadCallback(drawChart);
</script>
</body>
</html>
Here's the Column Chart Code:
<html>
<head>
<!--Load the AJAX API-->
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<script type="text/javascript">
// Load the Visualization API and the corechart package.
google.charts.load('current', {'packages':['corechart']});
// Set a callback to run when the Google Visualization API is loaded.
google.charts.setOnLoadCallback(drawChart);
// create and populate data table,
function drawChart() {
// Create the data table.
var data = google.visualization.arrayToDataTable([
['Test', 'Average mAh', { role: 'style' }],
['Manufacturer Specification', 3000, '#804000' ],
['10A Continuous', 2249.970, '#804000' ],
['20A Continuous', 678.349, '#804000'],
['10A Pulsed', 2327.558, '#804000'],
['20A Pulsed', 2080.586, '#804000'],
]);
var formatter = new google.visualization.NumberFormat({
pattern: '####'
});
formatter.format(data, 1);
// Set chart options
var options = {'title':'Tested Average mAh Ratings - LG HG2',
'width':800,
'height':600,
legend: {position: 'none'},
bar: {groupWidth: '90%'},
vAxis: { gridlines: { count: 8 }, minValue: 500}
};
var chart = new google.visualization.ColumnChart(document.getElementById('chart_div'));
chart.draw(data, options);
}
</script>
</head>
<body>
<div id="chart_div"></div>
</body>
</html>
Any help is greatly appreciated!
Material charts are in beta and you must use a converter function on your options to ensure they work properly. Here is an example:
chart.draw(data, google.charts.Line.convertOptions(options));
For your column chart, you must explicitly set the vaxis.title option like so:
vAxis: { title: 'Average mAh', gridlines: { count: 8 }, minValue: 500}
I'm creating a chart in Google Script and couldn't set the vAxis title either, and similarly couldn't modify some other attributes.
I found success by modifying vAxes[0] instead.
chart.setOption('vAxes', {0: {title: 'title Text'} } )
or if you're using an options variable:
vAxes: { 0: { title: 'Milliamp Hours' } }
Hope this helps anyone with the same issue.

Google Charts: manually set focus on column of data in Column Chart

I am making a custom legend for a Google Charts ColumnChart. I would like it to have the same behavior as the native legend. The native legend has behavior on click and mouseover. When a legend key is clicked, the column of values is selected. I can do this in my custom legend by calling
myChartWrapper.getChart().setSelection([{column: 4}]);
When a legend key is moused over, the column of values gets an outline. I would like to trigger that same outline when mousing over the key in my custom legend.
Is there a way to set that focussed column similar to setting the selection?
I thought I might be able to do it by calling events.trigger(), but I can't get anything to happen at all with that. For example, these don't seem to do anything.
// did nothing:
google.visualization.events.trigger(myChartWrapper, 'select', [{column: 4}]);
// did nothing:
google.visualization.events.trigger(myChartWrapper.getChart(), 'onmouseover', [{column: 4}]);
attempt to cause focus appearance via event trigger
google.charts.load('current', {
callback: function () {
var dataTable = new google.visualization.DataTable({
cols: [
{label: 'Month', type: 'string'},
{label: 'Amount', type: 'number'}
],
rows: [
{c:[{v: 'April'}, {v: 279899811.34}]},
{c:[{v: 'May'}, {v: 205855811}]},
{c:[{v: 'June'}, {v: 10009811}]},
{c:[{v: 'July'}, {v: 79979811}]},
{c:[{v: 'August'}, {v: 175789911}]},
{c:[{v: 'September'}, {v: 99899811}]},
{c:[{v: 'October'}, {v: 149899811}]},
{c:[{v: 'November'}, {v: 80899811}]},
{c:[{v: 'December'}, {v: 60899811}]},
{c:[{v: 'January'}, {v: 225899811}]},
{c:[{v: 'February'}, {v: 148899811}]},
{c:[{v: 'March'}, {v: 150899811}]}
]
});
var chartWrapper = new google.visualization.ChartWrapper({
chartType: 'ColumnChart',
containerId: 'chart_div',
dataTable: dataTable,
options: {
legend: {
position: 'bottom'
},
vAxis: {
format: 'short'
}
}
});
google.visualization.events.addOneTimeListener(chartWrapper, 'ready', function () {
// mouseover for custom div
document.getElementById('hover_div').addEventListener('mouseover', function () {
// trigger onmouseover for chart, pass props
google.visualization.events.trigger(chartWrapper.getChart(), 'onmouseover', {
'column': 1,
'row': null,
'test': 'over'
});
}, false);
// mouseout
document.getElementById('hover_div').addEventListener('mouseout', function () {
google.visualization.events.trigger(chartWrapper.getChart(), 'onmouseout', {
'column': 1,
'row': null,
'test': 'out'
});
}, false);
// chart event listeners
google.visualization.events.addListener(chartWrapper.getChart(), 'onmouseover', function (props) {
document.getElementById('msg_div').innerHTML = JSON.stringify(props);
});
google.visualization.events.addListener(chartWrapper.getChart(), 'onmouseout', function (props) {
document.getElementById('msg_div').innerHTML = JSON.stringify(props);
});
});
chartWrapper.draw();
},
packages:['controls', 'corechart']
});
#hover_div {
background-color: magenta;
border: 1px solid lime;
color: cyan;
height: 200px;
text-align: center;
width: 200px;
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>
<div id="hover_div">HOVER THIS DIV</div>
<div id="msg_div"></div>
Here's a hacky way to highlight bars in a bar chart. It's not a proper solution because it doesn't trigger the chart's native highlight. Instead, it's a way to create your own highlight by manipulating the stroke of the rects with jQuery. I approximated the highlight by setting the stroke to be 2px and grey. The actual highlight appears to be a blur effect with svg. To enhance the highlighting, I applied a slight transparency to the rects themselves.
On mouseover, I get the set of rects for all the bars, and then the subset for the particular column. It turned out to be tricky to get the right set of rects on mouseover, because the user might have selected a bar. When you select a bar with the mouse (i.e., click on it), the rect for it moves around, so you have to select the rects anew each time you mouseover. Plus selecting adds another rect for the white outline, which needs to be filtered out.
For the custom legend, I used colors from the Google Charts palette, which you get here.
I didn't add the part that would trigger a selection on clicking the legend. For that, I will follow this method.
The solution also only works with bar charts. You'd have to do something else with line charts, or other types. So the value of this solution may be limited.
google.charts.load('current', {packages: ['corechart']});
google.charts.setOnLoadCallback(draw_chart);
function draw_chart() {
// Create DataTable object from DataTable constructor or arrayToDatable()
var data = new google.visualization.DataTable({"rows":[{"c":[{"v":"Sacramento"},{"v":97},{"v":79},{"v":67},{"v":100}]},{"c":[{"v":"Montpelier"},{"v":96},{"v":74},{"v":32},{"v":96}]},{"c":[{"v":"Juneau"},{"v":24},{"v":44},{"v":54},{"v":64}]},{"c":[{"v":"Montgomery"},{"v":26},{"v":69},{"v":51},{"v":56}]},{"c":[{"v":"Little Rock"},{"v":87},{"v":69},{"v":78},{"v":41}]}],"cols":[{"type":"string","id":"cities","label":"cities"},{"type":"number","id":"A","label":"A"},{"type":"number","id":"B","label":"B"},{"type":"number","id":"C","label":"C"},{"type":"number","id":"D","label":"D"}]});
// Add formatters, if any
// Create ChartWrapper
var my_chart = new google.visualization.ChartWrapper({
"containerId": "chart_id",
"dataTable": data,
"chartType": "ColumnChart",
"options": {"bar": {"groupWidth": 67}, "chartArea": {"width": 440, "top": 20, "height": 295, "left": 60}, "height": 375, "width": 500, "fontSize": 12, "legend": "none"}
});
var bar_rect_set;
var num_rows = 5;
var num_cols = 4;
var num_series = num_rows * num_cols;
var parent_g;
function get_bar_rect_set() {
// get all the rects in the parent except for the white outline rects
// on selected bars, if any.
bar_rect_set = parent_g.find('rect[fill!="#ffffff"]');
}
google.visualization.events.addOneTimeListener(my_chart, 'ready', function () {
// Get an initial collection of the bar rects, along with their parent.
// Hereafter, get the bar rects with the method above.
// get all rects three layers down, including gridlines and axis
var g_set_1 = $("svg g g g rect");
// slice out the gridlines at the beginning and the axis line at the end
bar_rect_set = g_set_1.slice(g_set_1.length - num_series - 1, g_set_1.length - 1);
parent_g = $(bar_rect_set[0]).parent();
});
my_chart.draw();
function highlight_bars(series_num) {
if (series_num > num_cols - 1) {
return false;
}
get_bar_rect_set();
var start_index = series_num * num_rows;
var end_index = start_index + num_rows;
var series_g_set = bar_rect_set.slice(start_index, end_index)
var styles = {'stroke-width': "1.5px", "stroke": "#AAAAAA", "opacity": .8};
series_g_set.css(styles);
}
function remove_highlight() {
var styles = {'stroke-width': "0", "opacity": 1};
bar_rect_set.css(styles);
}
$("#legend tr").each(function(index, row) {
$(row).mouseover(function() {
highlight_bars(index);
}).mouseout(function() {
remove_highlight();
});
});
}
.color_bar {
width:24px;
height:12px;
margin-right:5px;
vertical-align:middle;
}
#legend td {
font-size:12;
height:19px;
font-family:"Arial";
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="https://www.gstatic.com/charts/loader.js"></script>
<table id="legend">
<tr>
<td><div class='color_bar' style="background-color:#3366cc"></div></td>
<td>A</td>
</tr>
<tr>
<td><div class='color_bar' style="background-color:#dc3912"></div></td>
<td>B</td>
</tr>
<tr>
<td><div class='color_bar' style="background-color:#ff9900"></div></td>
<td>C</td>
</tr>
<tr>
<td><div class='color_bar' style="background-color:#109618"></div></td>
<td>D</td>
</tr>
</table>
<div id="chart_id" ></div>

Combining two types of Category Filter in Google Charts API

I wanted to enable users to filter the results being displayed on the chart. Google API provides CategoryFilter which enforces filtering by rows. Here is my code which works perfectly fine
<html>
<head>
<!--Load the Ajax API-->
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<script type="text/javascript">
// Load the Visualization API and the piechart package.
google.load('visualization', '1', {'packages':['controls']});
// Set a callback to run when the Google Visualization API is loaded.
google.setOnLoadCallback(drawChart);
function drawChart() {
// Create our data table out of JSON data loaded from server.
var data = new google.visualization.DataTable(<?=$jsonTable?>);
var countryPicker = new google.visualization.ControlWrapper({
controlType: 'CategoryFilter',
containerId: 'negeri',
dataTable: data,
options: {
filterColumnLabel: 'Negeri',
ui: {
labelStacking: 'vertical',
allowTyping: false,
allowMultiple: true
}
},
// Define an initial state, i.e. a set of metrics to be initially selected.
state: {'selectedValues': ['Kedah', 'Johor']}
});
var chart = new google.visualization.ChartWrapper({
chartType: 'ColumnChart',
containerId: 'chart_div',
options: {
title: 'Statistik Negeri vs. Kategori Sukan',
width: 1000,
height: 1000,
hAxis: {title: 'Negeri', titleTextStyle: {color: 'blue'}},
vAxis: {title: 'Jumlah Kategori', titleTextStyle: {color: 'blue'}}
}
});
// Create the dashboard.
new google.visualization.Dashboard(document.getElementById('dashboard')).
// Configure the controls so that:
// - the 'Country' selection drives the 'Region' one,
// - the 'Region' selection drives the 'City' one,
// - and finally the 'City' output drives the chart
bind(countryPicker, chart).
// Draw the dashboard
draw(data);
}
</script>
</head>
<body>
<div id="dashboard">
<div id="negeri"></div>
<div id="chart_div"></div>
</div>
</body>
</html>
However in my datatable, I would also want to filter by columns. These two types of filtering should work together. (dependent; by bind() function). I have referred to #asgallant http://jsfiddle.net/asgallant/WaUu2/ and that is the feature that I wanted to combine with.
How can I possibly combine them? I have tried combining setChartView() by #asgallant with google's dashboard() but it's not working.
<html>
<head>
<!--Load the Ajax API-->
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<script type="text/javascript">
// Load the Visualization API and the piechart package.
google.load('visualization', '1', {'packages':['controls']});
// Set a callback to run when the Google Visualization API is loaded.
google.setOnLoadCallback(drawChart);
function drawChart() {
// Create our data table out of JSON data loaded from server.
var data = new google.visualization.DataTable(<?=$jsonTable?>);
var columnsTable = new google.visualization.DataTable();
columnsTable.addColumn('number', 'colIndex');
columnsTable.addColumn('string', 'colLabel');
var initState= {selectedValues: []};
// put the columns into this data table (skip column 0)
for (var i = 1; i < data.getNumberOfColumns(); i++) {
columnsTable.addRow([i, data.getColumnLabel(i)]);
// you can comment out this next line if you want to have a default selection other than the whole list
initState.selectedValues.push(data.getColumnLabel(i));
}
var countryPicker = new google.visualization.ControlWrapper({
controlType: 'CategoryFilter',
containerId: 'negeri',
dataTable: data,
options: {
filterColumnLabel: 'Negeri',
ui: {
labelStacking: 'vertical',
allowTyping: false,
allowMultiple: true
}
},
// Define an initial state, i.e. a set of metrics to be initially selected.
state: {'selectedValues': ['Kedah', 'Johor']}
});
var columnFilter = new google.visualization.ControlWrapper({
controlType: 'CategoryFilter',
containerId: 'colFilter_div',
dataTable: columnsTable,
options: {
filterColumnLabel: 'colLabel',
ui: {
label: 'Kategori Sukan',
allowTyping: false,
allowMultiple: true,
allowNone: false,
selectedValuesLayout: 'belowStacked'
}
},
state: initState
});
var chart = new google.visualization.ChartWrapper({
chartType: 'ColumnChart',
containerId: 'chart_div',
options: {
title: 'Statistik Negeri vs. Kategori Sukan',
width: 1000,
height: 1000,
hAxis: {title: 'Negeri', titleTextStyle: {color: 'blue'}},
vAxis: {title: 'Jumlah Kategori', titleTextStyle: {color: 'blue'}}
}
});
// Create the dashboard.
new google.visualization.Dashboard(document.getElementById('dashboard')).
// Configure the controls so that:
// - the 'Country' selection drives the 'Region' one,
// - the 'Region' selection drives the 'City' one,
// - and finally the 'City' output drives the chart
bind(countryPicker, columnFilter).
bind(columnFilter, chart).
// Draw the dashboard
draw(data);
}
</script>
</head>
<body>
<div id="dashboard">
<div id="negeri"></div>
<div id="chart_div"></div>
</div>
</body>
</html>
You want to bind your countryPicker filter to the chart as normal, but do not bind the columnFilter control to anything - the setChartView function handles everything for the columnFilter. You need to tweak a couple other lines to make it work with a dashboard, but nothing major. This is what it should look like:
function drawChart() {
// Create our data table out of JSON data loaded from server.
var data = new google.visualization.DataTable(<?=$jsonTable?>);
var columnsTable = new google.visualization.DataTable();
columnsTable.addColumn('number', 'colIndex');
columnsTable.addColumn('string', 'colLabel');
var initState= {selectedValues: []};
// put the columns into this data table (skip column 0)
for (var i = 1; i < data.getNumberOfColumns(); i++) {
columnsTable.addRow([i, data.getColumnLabel(i)]);
// you can comment out this next line if you want to have a default selection other than the whole list
initState.selectedValues.push(data.getColumnLabel(i));
}
var countryPicker = new google.visualization.ControlWrapper({
controlType: 'CategoryFilter',
containerId: 'negeri',
dataTable: data,
options: {
filterColumnLabel: 'Negeri',
ui: {
labelStacking: 'vertical',
allowTyping: false,
allowMultiple: true
}
},
// Define an initial state, i.e. a set of metrics to be initially selected.
state: {'selectedValues': ['Kedah', 'Johor']}
});
var columnFilter = new google.visualization.ControlWrapper({
controlType: 'CategoryFilter',
containerId: 'colFilter_div',
dataTable: columnsTable,
options: {
filterColumnLabel: 'colLabel',
ui: {
label: 'Kategori Sukan',
allowTyping: false,
allowMultiple: true,
allowNone: false,
selectedValuesLayout: 'belowStacked'
}
},
state: initState
});
var chart = new google.visualization.ChartWrapper({
chartType: 'ColumnChart',
containerId: 'chart_div',
options: {
title: 'Statistik Negeri vs. Kategori Sukan',
width: 1000,
height: 1000,
hAxis: {title: 'Negeri', titleTextStyle: {color: 'blue'}},
vAxis: {title: 'Jumlah Kategori', titleTextStyle: {color: 'blue'}}
}
});
// Create the dashboard.
var dashboard = new google.visualization.Dashboard(document.getElementById('dashboard')).
bind(countryPicker, chart);
function setChartView () {
var state = columnFilter.getState();
var row;
var view = {
columns: [0]
};
for (var i = 0; i < state.selectedValues.length; i++) {
row = columnsTable.getFilteredRows([{column: 1, value: state.selectedValues[i]}])[0];
view.columns.push(columnsTable.getValue(row, 0));
}
// sort the indices into their original order
view.columns.sort(function (a, b) {
return (a - b);
});
chart.setView(view);
chart.draw();
}
google.visualization.events.addListener(columnFilter, 'statechange', setChartView);
var runOnce = google.visualization.events.addListener(dashboard, 'ready', function () {
google.visualization.events.removeListener(runOnce);
setChartView();
});
columnFilter.draw();
dashboard.draw(data);
}
google.load('visualization', '1', {packages:['corechart'], callback: drawChart});

google visualization change label on all values on x-axis

I have a bunch of products which I use ColumnChart to show the product name on the x-axis and then two different values that the products have on my y-axis. Since there are a bunch of products it gets pretty messy if I show all of them at once on the ColumnChart therefore I use the ChartRangeFilter Control to be able to have a window of products.
Now my problem is that ChartRangeFilter can't use strings on the axises. But I don't want to display the product id on the x-axis, so is it possible to change the lable when it is displayd?
Hope you can understand what I mean. Below is some code to test in the google code playground
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
<title>
Google Visualization API Sample
</title>
<script type="text/javascript" src="http://www.google.com/jsapi"></script>
<script type="text/javascript">
google.load('visualization', '1.1', {packages: ['corechart', 'controls']});
</script>
<script type="text/javascript">
function drawVisualization() {
var dashboard = new google.visualization.Dashboard(
document.getElementById('dashboard'));
var control = new google.visualization.ControlWrapper({
'controlType': 'ChartRangeFilter',
'containerId': 'control',
'options': {
// Filter by the date axis.
'filterColumnIndex': 0,
'ui': {
'chartType': 'LineChart',
'chartOptions': {
'chartArea': {'width': '90%'},
'hAxis': {'baselineColor': 'none'}
},
'chartView': {
'columns': [0, 1, 2]
},
'minRangeSize': 1
}
},
// Initial range: 1 to 4.
'state': {'range': {'start': 1, 'end': 4}}
});
var chart = new google.visualization.ChartWrapper({
'chartType': 'ColumnChart',
'containerId': 'chart',
'options': {
// Use the same chart area width as the control for axis alignment.
'chartArea': {'height': '80%', 'width': '90%'},
'hAxis': {'slantedText': false},
'vAxis': {'viewWindow': {'min': 0, 'max': 20}},
'legend': {'position': 'none'}
}
});
var data = new google.visualization.DataTable();
data.addColumn('number', 'Product ID');
data.addColumn('number', 'value1');
data.addColumn('number', 'valu2');
data.addRow([1, 11, 12]);
data.addRow([2, 15, 12]);
data.addRow([3, 10, 11]);
data.addRow([4, 11, 9]);
data.addRow([5, 8, 12]);
data.addRow([6, 4, 9]);
data.addRow([7, 8, 15]);
data.addRow([8, 8, 11]);
data.addRow([9, 8, 9]);
dashboard.bind(control, chart);
dashboard.draw(data);
}
google.setOnLoadCallback(drawVisualization);
</script>
</head>
<body>
<div id="dashboard">
<div id="chart" style='width: 915px; height: 300px;'></div>
<div id="control" style='width: 915px; height: 50px;'></div>
</div>
</body>
</html>
Thanks in advance!
You can use a DataView to get around this problem. In the ControlWrapper, set the view.columns parameter like this:
var control = new google.visualization.ControlWrapper({
'controlType': 'ChartRangeFilter',
'containerId': 'control',
'options': {
// Filter by the date axis.
'filterColumnIndex': 0,
'ui': {
'chartType': 'LineChart',
'chartOptions': {
'chartArea': {'width': '90%'},
'hAxis': {'baselineColor': 'none'}
},
'chartView': {
'columns': [0, 1, 2]
},
'minRangeSize': 1
}
},
// Initial range: 1 to 4.
'state': {'range': {'start': 1, 'end': 4}},
view: {
columns: [{
type: 'number',
calc: function (dt, row) {
return {v: row, f: dt.getFormattedValue(row, 0)};
}
}, 1, 2]
}
});
then reverse the process in the ChartWrapper's view.columns:
var chart = new google.visualization.ChartWrapper({
'chartType': 'ColumnChart',
'containerId': 'chart',
'options': {
// Use the same chart area width as the control for axis alignment.
'chartArea': {'height': '80%', 'width': '90%'},
'hAxis': {'slantedText': false},
'vAxis': {'viewWindow': {'min': 0, 'max': 20}},
'legend': {'position': 'none'}
},
view: {
columns: [{
type: 'string',
label: data.getColumnLabel(0),
calc: function (dt, row) {
return dt.getFormattedValue(row, 0);
}
}, 1, 2]
}
});
That should get you what you want.
This code assumes you have a DataTable with 3 columns: a string (product name) and two number columns (value1 and value2). Here is a demo: http://jsfiddle.net/asgallant/55agF/
change the color of the text as of background
hAxis: {textStyle: {color: 'white'}},