Google Charts table sorting via keyboard - javascript

I'm trying to use the Google Charts API on a website that must be 100% Section 508 compliant, i.e., accessible to those with disabilities.
Google Charts tables have a 'sort' function but in its default state column headers cannot be selected by the keyboard for sorting.
I can use some Javascript to inject "tabindex=0" attributes into the column header elements easily enough, and as expected, that makes the column headers focusable...but surprisingly, clicking on the enter key does nothing. Same thing happens if I make the sort arrows inside the column headers focusable - I can focus on it using TAB, but I still can't select it.
Does anyone have a solution for this? If there is no straightforward way to create a table that's sortable using only the keyboard, is there a workaround to transform a focus/keypress into an onclick?

I created a fiddle that uses jQuery to redraw the chart on a keypress:
http://jsfiddle.net/mVYeL/
Here's the relevant code:
google.load('visualization', '1.1', {
'packages': ['table']
});
google.setOnLoadCallback(drawStuff);
var table;
var data;
var options = {sortAscending:true};
function sortTable(col) {
if (options.sortColumn == col) {
options.sortAscending = !options.sortAscending;
} else {
options.sortAscending = true;
}
options.sortColumn = col;
table.draw(data, options);
}
$(document).keydown(function(e){
if (e.keyCode==49) { sortTable(0); }
if (e.keyCode==50) { sortTable(1); }
if (e.keyCode==51) { sortTable(2); }
});
function drawStuff() {
data = new google.visualization.DataTable();
data.addColumn('string', 'Name');
data.addColumn('number', 'Salary');
data.addColumn('boolean', 'Full Time Employee');
data.addRows([
['Mike', {v: 10000, f: '$10,000'}, true],
['Jim', {v:8000, f: '$8,000'}, false],
['Alice', {v: 12500, f: '$12,500'}, true],
['Bob', {v: 7000, f: '$7,000'}, true]
]);
// Instantiate and draw our chart, passing in some options.
table = new google.visualization.Table(document.getElementById('chart_div'));
table.draw(data, options);
};

Related

I want to select and highlight country on google Geochart when someone click on a html button or div

I need a country to be selected and highlighted on google Gecochart when a button or Div is clicked.
I was able to achieve that completely if someone clicks on the country on Geochart, but partially if someone clicks the button/div as the Geochart is not highlighting the country until the user moves the mouse pointer above the geochart.
I am trying to implement that using the code below
var chart='';
google.charts.load('current', {
'packages':['geochart'],
});
google.charts.setOnLoadCallback(drawRegionsMap);
function drawRegionsMap() {
var data = google.visualization.arrayToDataTable([
['Country', 'Popularity'],
['Germany', 200],
['United States', 300],
['Brazil', 400],
['Canada', 500],
['France', 600],
['RU', 700]
]);
var options = {};
var container =document.getElementById('regions_div');
chart = new google.visualization.GeoChart(container);
observer = new MutationObserver(function (nodes) {
Array.prototype.forEach.call(nodes, function (node) {
// check for new nodes
if (node.addedNodes.length > 0) {
Array.prototype.forEach.call(node.addedNodes, function (addedNode) {
// the tooltip element will also be here, we only want the group elements
if (addedNode.tagName === 'g') {
// find children of the group element
Array.prototype.forEach.call(addedNode.childNodes, function (childNode) {
// check for path element, change stroke
if (childNode.tagName === 'path') {
childNode.setAttribute('stroke', '#FF0000');
//childNode.setAttribute('fill', '#BE965C');
}
});
}
});
}
});
});
// activate mutation observer
observer.observe(container, {
childList: true,
subtree: true
});
chart.draw(data, options);
}
function myclick() {
//google.visualization.events.trigger(chart, 'select',[{ row: 3, column: null }]);
chart.setSelection([{ row: 3, column: null }]);
console.log( chart.getSelection());
}
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<div id="regions_div" style="width: 900px; height: 500px;"></div>
<div onclick="myclick()">
text
</div>
<button type="button" onclick="myclick()">Click Me!</button>
I also tried to call google.visualization.events.trigger(chart, 'select', chart.getSelection()); to trigger the selection and highlight directly but it didn't work.
Any idea how to to highlight the country when clicking on the button/div directly (without the need to move the mouse over the Gecochart)?
Thank you!
The code can also be found in this snippet https://jsfiddle.net/nmaybar/8p2zruso/
I have solved the issue by changing the version from 'current' to '49' by adjusting the following code:
google.charts.load('current', { 'packages':['geochart'],});
To:
google.charts.load('49', {'packages':['geochart'],});
I am not sure why it doesn't work with version 'current' or 'upcoming'. I think it is a bug.

Retrieve value column header google visualisation

I want to retrieve the value of the column header when a user clicks on 1 of the bars of the chart. A report should be generated with the parameters I retrieve from the chart. This is what I have so far:
google.setOnLoadCallback(drawChart);
function drawChart() {
// Create our data table out of JSON data loaded from server.
var data = new google.visualization.arrayToDataTable([
['Month', '2014', '2015'],
['Jan', 0, 200.00],
['Feb', 0, 400.00],
['Mar', 0, 700.00],
['Apr', 0, 100.00],
['May', 400.00, 900.00],
['Jun', 1100.00, 0],
['Jul', 3400.00, 0],
['Aug', 2500.00, 0],
['Sep', 2450.00, 0],
['Oct', 3170.00, 0],
['Nov', 2500.00, 0],
['Dec', 1979.00, 0]
]);
var options = {
title: 'Raised'
};
var chart = new google.charts.Bar(document.getElementById('chart_div_month'));
function selectHandler() {
var selectedItem = chart.getSelection()[0];
if (selectedItem) {
var month = data.getValue(selectedItem.row, 0);
var year = data.getValue(0, selectedItem.column);
window.location = 'report.php?submit=Submit&year=' + year + '&month=' + month;
}
}
google.visualization.events.addListener(chart, 'select', selectHandler);
chart.draw(data, options);
}
I am able to retrieve the month parameter, but not the year.
Reading about google chart tables at their API page it says that
getSelection() - Standard getSelection implementation.
Selection elements are all row elements.
Can return more than one selected row.
So getSelection() doesn't select any column, and therefore var year = data.getValue(0, selectedItem.column);won't work.
Why it is like this I don't know, as the getSelection() returns both a row and a column, but the column is always null (thought it hasn't always been like this, there are loads of examples where people show how it works, but they are all broken today).
I have seen an approach that uses standard javascript (or was it jQuery?) to detect which column is clicked (clicked, not selected) by listening for mouseclicks on tds and getting the column property that way, but I can't seem to find it.

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
}
}
}

Add Region URL to Geochart

I am creating a map using Google Geochart and need a listener so that when the user clicks on a region it loads a given URL.
My code is:
google.load('visualization', '1.1', {packages: ['geochart'], callback: drawVisualization});
function drawVisualization() {
var data = google.visualization.arrayToDataTable([
['Country', 'Value', {role: 'tooltip', p:{html:true}}],
['US', 20, 'Test'],
['Canada', 20, 'http://www.ipfa.org/council/branches/106/ipfa-canada/'],
['GB', 20, 'http://www.ipfa.org/council/branches/52/ipfa-uk/'],
]);
var chart = new google.visualization.GeoChart(document.getElementById('visualization'));
google.visualization.events.addListener(chart, 'select', function () {
var selection = chart.getSelection();
var row = selection[0].row;
var url = data.getValue(row, 3);
window.open(url);
});
chart.draw(data, {
width: 800,
height: 600,
tooltip: {
isHtml: true
}
}
);
}
The URL listener works on another map I use, what am I doing wrong to not work on this one?
There are two issues. First, you are using the wrong index to reference your URLs; they are in column 2, not column 3 (which doesn't exist):
var url = data.getValue(row, 3);
Second, one of your URL's (for the US) is an anchor tag, which won't work if passed to the window.open call. If you want anchor tags in the tooltips, set the value of the cell to the URL and formatted value of the URL column to the anchor tag:
['US', 20, {v: 'http://www.ipfa.org/council/branches/39/ipfa-americas/', f: 'Test'}]
I would also suggest testing for the length of the selection array, because it is possible for the selection array to be empty if the user clicks a region twice in a row (the second click deselects the region), which would cause this line to throw an error:
var row = selection[0].row;
I suggest using this instead:
var selection = chart.getSelection();
if (selection.length) {
var url = data.getValue(selection[0].row, 2);
window.open(url);
}

get data from selected slice of google charts PieChart

i have big trouble trying to get the value of the selected slice of a PieChart when its clicked.
The documentation says:
selection_array: An array of selected objects, each one describing a
data element in the underlying table used to create the visualization
(a DataView or a DataTable). Each object has properties row and/or
column, with the index of the row and/or column of the selected item
in the underlying DataTable. If the row property is null, then the
selection is a column; if the column property is null, then the
selection is a row; if both are non-null, then it is a specific data
*item. You can call the DataTable.getValue()* method to get the value of
the selected item. The retrieved array can be passed into
setSelection()
in my case i get null from getSelection(), then i couldnt figure out what to do to get the value i want (the label of the column corresponding to that slice).
Any answer will be very apreciated :)
the example code of what im doing:
google.load('visualization', '1', {packages: ['controls']});
google.setOnLoadCallback(drawVisualization);
var data;
var pie_area;
function drawVisualization() {
// Prepare the data
data = google.visualization.arrayToDataTable([
["rbd", "nombre", "area", "dependencia", "simceMat", "ubicacionLon", "ubicacionLat", "simceLen", "nivel"],
[22616, "Colegio Mozart", "Urbana", "Part_Sub", 228, -72.981148, -41.479872, 254, "Basico"],
[22686,"Escuela Basica Camelias","Urbana","Muni",228,-72.980075,-41.474599,253, "Medio"],
[40351,"Colegio Bosquemar","Urbana","Part_Sub",290,-72.981148,-41.479872,280, "Medio"],
[7633,"Escuela Capitan Arturo Prat Chacon","Urbana","Muni",317,-72.909565,-41.474567,314, "Basico"],
[7659,"Escuela Rural Alerce","Rural","Muni",230,-72.91767,-41.399121,249, "Basico"],
[7671,"Escuela Rural Lagunitas","Rural","Muni",261,-72.964282,-41.459485,269, "Medio"],
[7690,"Escuela Rural Rio Blanco","Rural","Muni",217,-72.638597,-41.455786,229, "Medio"],
[7700,"Colegio San Francisco Javier","Urbana","Part",305,-72.942089,-41.470351,303, "Basico"],
[7717,"Instituto Aleman de Puerto Montt","Urbana","Part",321,-72.932482,-41.470001,310, "Medio"],
[7718,"The American School","Urbana","Part",317,-72.909,-41.456,314, "Medio"]
]);
var fltArea = new google.visualization.ControlWrapper({
'controlType': 'CategoryFilter',
'containerId': 'f1',
'options': {
'filterColumnLabel': 'area',
'ui': {
'labelStacking': 'vertical',
'allowTyping': false,
'allowMultiple': false
}
}
});
pie_area = new google.visualization.ChartWrapper({
'chartType': 'PieChart',
'containerId': 'chart2',
'options': {
'width': 300,
'height': 300,
'legend': 'none',
'title': 'Area',
'pieSliceText': 'label'
},
'view': {'columns': [2]}
});
new google.visualization.Dashboard(document.getElementById('dashboard')).bind([fltArea], [pie_area]).draw(data);
google.visualization.events.addListener(pie_area, 'select', onAreaSliceSelected);
}
function onAreaSliceSelected(){
var sel = pie_area.getChart().getSelection(); //is always null
console.log('you selected '+sel); //displays you selected null
}
The issue is in how your chart/data is set up.
You are currently aggregating all the data from column 2 to generate the chart. In this case you have 7 Urbana, and 3 Rural for your values, so it aggregates those 10 rows into two categories. Since each slice of the pie refers to a set of aggregate values, and pie charts only allow a single value to be selected, you can't get the selection of three rows that way.
Additionally, your category selector doesn't provide much use as it currently is, because if you select either Urbana or Rural, you end up getting a pie chart showing 100% of a single category.
If you set up your data differently, you will properly get an array of objects whenever you select a slice, as in this example:
function drawVisualization() {
// Create and populate the data table.
var data = google.visualization.arrayToDataTable([
['Task', 'Hours per Day'],
['Work', 11],
['Eat', 2],
['Commute', 2],
['Watch TV', 2],
['Sleep', 7]
]);
// Create and draw the visualization.
pieChart = new google.visualization.PieChart(document.getElementById('visualization'));
pieChart.draw(data, {title:"So, how was your day?"});
google.visualization.events.addListener(pieChart, 'select', onAreaSliceSelected);
}
function onAreaSliceSelected(){
var sel = pieChart.getSelection(); //is always null
alert('you selected '+sel); //displays you selected null
}

Categories

Resources