checkbox in google visualization table - javascript

Please refer to the following link:
http://jsfiddle.net/RjHMH/46/
I am using google visualization table, and making a tree table like above. Some column in child row, I attached html checkbox.
I question I am facing is that, if I click the checkbox, it is never checked. This is because in the table listener, every time a select event is triggered, it will redraw the table.
I look at the google visualization table API, and find this:
Note that the table chart only fires row selection events; however,
the code is generic, and can be used for row, column, and cell
selection events.
This means that if I click a column in row, I can never know which column I actually clicked? So I can not get the checkbox by id, and using javascript to make it checked? That sucks...

Indeed, getSelection() function does not preserve column once select event is triggered. But you could consider the following approach to preserve checkboxes states once the chart is redrawn.
First, we need to introduce object for storing checkboxes states:
var checkboxStates = {'cbox1' : false, 'cbox2': false};
Then we register ready event for saving/loading state once Google Chart is redrawn:
google.visualization.events.addOneTimeListener(table, 'ready', function(){
//...
});
And finally the following example demonstrates how to save/load state:
//load checkboxes state
for(var id in checkboxStates){
var checkbox = document.getElementById(id);
if(checkbox !== null) {
checkbox.checked = checkboxStates[id];
}
}
//save state
if(event.target.type == "checkbox"){
var checkbox = document.getElementById(event.target.id);
checkbox.checked = !event.target.checked;
checkboxStates[event.target.id] = checkbox.checked;
}
Note: Event.target is utilized to track checkboxes click events
Final example
Below is provided the modified example of yours with ability to preserve checkboxes state
google.load('visualization', '1', {
packages: ['table']
});
google.setOnLoadCallback(drawTable);
function drawTable() {
var data = new google.visualization.DataTable();
data.addColumn('string', 'id');
data.addColumn('string', 'parentId');
data.addColumn('boolean', 'visible');
data.addColumn('number', 'level');
data.addColumn('string', 'Name');
data.addColumn('number', 'Value');
data.addRows([
['1', null, true, 1, 'Foo', 10],
['1.1', '1', false, 2, 'Foo 1', 2],
['1.1.1', '1.1', false, 3, 'Foo 1a', 2],
['1.1.2', '1.1', false, 3, 'Foo 1b', 2],
['1.2', '1', false, 2, 'Foo 2', 3],
['1.3', '1', false, 2, 'Foo 3', 5],
['1.3.1', '1.3', false, 3, '<input type="checkbox" id="cbox1" value="second_checkbox">', 1],
['1.3.2', '1.3', false, 3, '<input type="checkbox" id="cbox2" value="second_checkbox">', 4],
['2', null, true, 1, 'Bar', 14],
['2.1', '2', false, 2, 'Bar 1', 6],
['2.2', '2', false, 2, 'Bar 2', 7],
['2.2.1', '2.2', false, 3, 'Bar 2a', 3],
['2.2.2', '2.2', false, 3, 'Bar 2b', 2],
['2.2.3', '2.2', false, 3, 'Bar 2c', 2]
]);
// get all rows with children
// start by finding all child rows (ie, rows with parents)
var children = data.getFilteredRows([{
column: 1,
minValue: '1'
}]);
var parentsArray = [];
var parentId;
// identify the parents of all children
for (var i = 0; i < children.length; i++) {
parentId = data.getValue(children[i], 1);
if (parentsArray.indexOf(parentId) === -1) {
parentsArray.push(parentId);
}
}
//format the parent rows
var parent = data.getFilteredRows([{
column: 3,
value: 1
}]);
for (var j = 0; j < parent.length; j++) {
parentId = data.getValue(parent[j], 0);
if (parentsArray.indexOf(parentId) !== -1) {
data.setProperty(parent[j], 4, 'className', 'parentcl close');
}
else {
data.setProperty(parent[j], 4, 'className', 'parentcl');
}
};
//format the 2level rows
var leveltwo = data.getFilteredRows([{
column: 3,
value: 2
}]);
for (var j = 0; j < leveltwo.length; j++) {
parentId = data.getValue(leveltwo[j], 0);
if (parentsArray.indexOf(parentId) !== -1) {
data.setProperty(leveltwo[j], 4, 'className', 'leveltwo close');
}
else {
data.setProperty(leveltwo[j], 4, 'className', 'leveltwo');
}
};
//format the 3level rows
var levelthree = data.getFilteredRows([{
column: 3,
value: 3
}]);
for (var j = 0; j < levelthree.length; j++) {
data.setProperty(levelthree[j], 4, 'className', 'levelthree');
};
var view = new google.visualization.DataView(data);
// hide the first four columns
view.setColumns([4, 5]);
view.setRows(data.getFilteredRows([{
column: 2,
value: true
}]));
var table = new google.visualization.Table(document.getElementById('table_div'));
var cssClassNames = {
headerRow: 'gtableheader',
oddTableRow: 'rowodd',
headerCell: 'gtableheader'
};
var options = {
showRowNumber: false,
allowHtml: true,
cssClassNames: cssClassNames,
sort: 'disable'
};
var checkboxStates = {'cbox1' : false, 'cbox2': false};
google.visualization.events.addListener(table, 'select', function () {
var sel = table.getSelection();
recurseTree(view.getTableRowIndex(sel[0].row), false);
view.setRows(data.getFilteredRows([{
column: 2,
value: true
}]));
table.setSelection(null);
google.visualization.events.addOneTimeListener(table, 'ready', function(){
//load checkboxes state
for(var id in checkboxStates){
var checkbox = document.getElementById(id);
if(checkbox !== null) {
checkbox.checked = checkboxStates[id];
}
}
//update state
if(event.target.type == "checkbox"){
var checkbox = document.getElementById(event.target.id);
checkbox.checked = !event.target.checked;
checkboxStates[event.target.id] = checkbox.checked;
}
});
table.draw(view, options);
function recurseTree(row, hideOnly) {
// get the id of the row
var id = data.getValue(row, 0);
// get the parent row
var parentrow = data.getFilteredRows([{
column: 0,
value: id
}]);
var parentlevel = data.getValue(parentrow[0], 3);
// find all child rows
var rows = data.getFilteredRows([{
column: 1,
value: id
}]);
for (var i = 0; i < rows.length; i++) {
if (data.getValue(rows[i], 2)) {
// hide the row and recurse down the tree
data.setValue(rows[i], 2, false);
switch (parentlevel) {
case 1:
data.setProperty(parentrow[0], 4, 'className', 'parentcl close');
break;
case 2:
data.setProperty(parentrow[0], 4, 'className', 'leveltwo close');
break;
default:
data.setProperty(parentrow[0], 4, 'className', 'levelthree close');
}
recurseTree(rows[i], true);
}
else if (!hideOnly) {
// if the row is hidden, show it
data.setValue(rows[i], 2, true);
switch (parentlevel) {
case 1:
data.setProperty(parentrow[0], 4, 'className', 'parentcl open');
break;
case 2:
data.setProperty(parentrow[0], 4, 'className', 'leveltwo open');
break;
default:
data.setProperty(parentrow[0], 4, 'className', 'levelthree open');
}
}
}
}
});
table.draw(view, options);
}
.parentcl{
font-weight: bold !important;
}
.close:before{
content:"→ "
}
.open:before{
content:"↘ "
}
.leveltwo{
padding-left: 20px !important;
}
.levelthree{
padding-left: 45px !important;
font-style:italic;
}
.gtableheader {
font-weight: bold;
background-color: grey;
}
.rowodd {
background-color: beige;
}
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<div id="table_div"></div>

Related

Google Visualization - Making a new DataTable from an existing DataTable?

I would like to know how to make a new DataTable from an existing DataTable?
Use case:
I have a proxyTable which is hidden and connected to a CategoryFilter. This is used used to construct other tables on the page which are all linked to one CategoryFilter.
Goal:
Include a Grand Total row in each new table which reflects summation of the filtered selection.
Initial solution:
I have tried extracting an array from sourceData, creating a new data table called dataResults, adding grand total row to dataResults, and drawing the final table. It works but seems like a lot of effort.
var sourceData = proxyTable.getDataTable();
var rowCount = sourceData.getNumberOfRows();
var colCount = sourceData.getNumberOfColumns();
var tempRow = [];
var tempArray = [];
var pushValue;
//push header row
for (var k = 0; k < colCount; k++) {
pushValue = sourceData.getColumnLabel(k);
tempRow.push(pushValue);
}
tempArray.push(tempRow);
tempRow = []; //reset
//push data rows
for (var i = 0; i < rowCount; i++) {
for (var j = 0; j < colCount; j++) {
pushValue = sourceData.getValue(i, j);
tempRow.push(pushValue);
}
tempArray.push(tempRow);
tempRow = []; //reset
}
//Create new Google DataTable from Array
var dataResults = new google.visualization.arrayToDataTable(tempArray);
My question:
How can I make a data table which contains all records from sourceData without going through the above steps I've tried?
You guidance is appreciated greatly!
Working Example:
UPDATE:
Added var dataResults = sourceData.clone(); per answer from #WhiteHat and I get an error sourceData.clone is not a function
Did I get the syntax wrong? Perhaps it's the ChartWrapper I'm using?
UPDATE 2:
Added var dataResults = sourceData.toDataTable().clone(); per answer #2 from #WhiteHat and it works.
google.charts.load('current', {
'packages': ['corechart', 'table', 'gauge', 'controls', 'charteditor']
});
$(document).ready(function() {
renderChart_onPageLoad();
});
function renderChart_onPageLoad() {
google.charts.setOnLoadCallback(function() {
drawDashboard();
});
}
function drawDashboard() {
var data = google.visualization.arrayToDataTable([
['Name', 'RoolNumber', 'Gender', 'Age', 'Donuts eaten'],
['Michael', 1, 'Male', 12, 5],
['Elisa', 2, 'Female', 20, 7],
['Robert', 3, 'Male', 7, 3],
['John', 4, 'Male', 54, 2],
['Jessica', 5, 'Female', 22, 6],
['Aaron', 6, 'Male', 3, 1],
['Margareth', 7, 'Female', 42, 8],
['Miranda', 8, 'Female', 33, 6]
]);
var dashboard = new google.visualization.Dashboard(document.getElementById('dashboard'));
var categoryPicker = new google.visualization.ControlWrapper({
controlType: 'CategoryFilter',
containerId: 'categoryPicker',
options: {
filterColumnLabel: 'Gender',
ui: {
labelStacking: 'vertical',
allowTyping: false,
allowMultiple: false
}
}
});
var proxyTable = new google.visualization.ChartWrapper({
chartType: 'Table',
containerId: 'proxyTable',
options: {
width: '500px'
}
});
var table = new google.visualization.ChartWrapper({
chartType: 'Table',
containerId: 'table',
options: {
width: '500px'
}
});
dashboard.bind([categoryPicker], [proxyTable]);
dashboard.draw(data);
google.visualization.events.addListener(dashboard, 'ready', function() {
redrawChart();
});
function redrawChart() {
var sourceData = proxyTable.getDataTable();
//WhiteHat suggestion2 - WORKS
var dataResults = sourceData.toDataTable().clone();
//WhiteHat suggestion1 - Didn't work
//var dataResults = sourceData.clone();
//INITIAL SOLUTION - works
//var rowCount = sourceData.getNumberOfRows();
//var colCount = sourceData.getNumberOfColumns();
//var tempRow = [];
//var tempArray = [];
//var pushValue;
//for (var k = 0; k < colCount; k++) {
//pushValue = sourceData.getColumnLabel(k);
//tempRow.push(pushValue);
//}
//tempArray.push(tempRow);
//tempRow = []; //reset
//push data rows
//for (var i = 0; i < rowCount; i++) {
//for (var j = 0; j < colCount; j++) {
//pushValue = sourceData.getValue(i, j);
//tempRow.push(pushValue);
//}
//tempArray.push(tempRow);
//tempRow = []; //reset
//}
//var dataResults = new google.visualization.arrayToDataTable(tempArray);
var group = google.visualization.data.group(sourceData, [{
// we need a key column to group on, but since we want all rows grouped into 1,
// then it needs a constant value
column: 0,
type: 'number',
modifier: function() {
return 1;
}
}], [{
column: 1,
id: 'SumRool',
label: 'SumRool',
type: 'number',
aggregation: google.visualization.data.sum
}, {
column: 3,
id: 'SumAge',
label: 'SumAge',
type: 'number',
aggregation: google.visualization.data.sum
}, {
// get the average age
column: 4,
id: 'SumEaten',
label: 'SumEaten',
type: 'number',
aggregation: google.visualization.data.sum
}]);
dataResults.insertRows(0, [
['Grand Total', group.getValue(0, 1), null, group.getValue(0, 2), group.getValue(0, 3)],
]);
//Set dataTable
table.setDataTable(dataResults);
table.draw();
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="dashboard">
<div id="categoryPicker"></div><br /> Proxy Table<br />
<div id="proxyTable"></div><br /> Table
<br />
<div id="table"></div><br /><br />
</div>
data table method --> clone()
var newDataTable = oldDataTable.clone();
from the docs...
clone() - Returns a clone of the data table. The result is a deep copy of the data table except for the cell properties, row properties, table properties and column properties, which are shallow copies; this means that non-primitive properties are copied by reference, but primitive properties are copied by value.

How to detect a loop in a hierarchy of javascript elements

I have a list of elements, each has an ID and a parent ID. What I want to do is detect when there is a loop in this 'hierarchy', and show which ID starts the loop.
list = [
{
id: '1',
parent: '2'
},
{
id: '2',
parent: '3'
},
{
id: '3',
parent: '4'
},
{
//This id is causing the loop
id: '4',
parent: '1'
}
]
I have tried this to build the tree, which works when there's no loop, but does not work with a loop:
function treeify(list, idAttr, parentAttr, childrenAttr) {
if (!idAttr) idAttr = 'id';
if (!parentAttr) parentAttr = 'parent';
if (!childrenAttr) childrenAttr = 'children';
var treeList = [];
var lookup = {};
list.forEach(function(obj) {
lookup[obj[idAttr]] = obj;
obj[childrenAttr] = [];
});
list.forEach(function(obj) {
if (obj[parentAttr] != null) {
lookup[obj[parentAttr]][childrenAttr].push(obj);
} else {
treeList.push(obj);
}
});
return treeList;
};
I also cannot detect when there is a loop.
I'd like to return the ID of the element that caused the loop to allow me to fix the data behind it.
You can apply white-grey-black coloring to detect nodes that are (re)visited while visiting their descendants (I've simplified your graph to a list of parent-child pairs):
graph = [
[2, 1],
[3, 2],
[1300023, 3],
[1, 1300023],
];
colors = {}
function visit(vertex) {
if (colors[vertex] === 'black') {
// black = ok
return;
}
if (colors[vertex] === 'grey') {
// grey = visited while its children are being visited
// cycle!
console.log('cycle', colors);
return;
}
// mark as being visited
colors[vertex] = 'grey';
// visit children
graph.forEach(edge => {
if (edge[0] === vertex)
visit(edge[1]);
});
// mark as visited and ok
colors[vertex] = 'black'
}
visit(1)
A nice illustration of this approach: https://algorithms.tutorialhorizon.com/graph-detect-cycle-in-a-directed-graph-using-colors/
You could collect all nodes and the childrens in object and filter all nodes by taking an array of visited nodes.
The infinite array contains all nodes which causes a circular reference.
function isCircular(id, visited = []) {
return visited.includes(id)
|| Object.keys(links[id]).some(k => isCircular(k, visited.concat(id)));
}
var list = [{ id: '1', parent: '2' }, { id: '2', parent: '3' }, { id: '3', parent: '4' }, { id: '4', parent: '1' }],
links = {},
infinite = [];
list.forEach(({ id, parent }) => {
links[parent] = links[parent] || {};
links[parent][id] = true;
});
infinite = list.filter(({ id }) => isCircular(id));
console.log(links);
console.log(infinite);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Making 2 columns distinct

I want to increase the count of 4 different variables to fill in a pie chart. But i only want it to increment the variables per unique variable in the 2 columns. I want to try to make them distinct but i do not quite understand how to. In the if statement i try to compare the value with a string. This works. After the || i try to make it distinct but i have trouble with that.
Here is my code:
function createPiechartthree(){
var columns = {};
var xmlColumns = $j('head', xml);
xmlColumns.find('headColumn').each(function(){
var columnName = $j(this).find('columnValue').text();
var columnID = $j(this).attr('columnid');
columns[columnName] = (columnID);
});
var xmlData = $j('data', xml);
xmlData.find('item').each(function(){
$j(this).find('column').each(function(){
var colID = $j(this).attr("columnid");
console.log(colID);
var value = $j(this).find('displayData').text();
if(colID == columns["Risk level client"] || colID == columns["Counterparty name"] ){
if(value === "High" || value === value){
highRiskCategory++;
}
else if(value === "Medium" || value === value){
mediumRiskCategory++;
}
else if(value === "Low" || value === value){
lowRiskCategory++;
} else if(value === "" || value === value) {
unidentified++;
}
}
})
})
1) rather than incrementing the counts manually, build an array of the values found...
var riskData = [
['Starbucks', 'High'],
['Starbucks', 'High'],
['McDonalds', 'Low'],
['Dunkin', 'Medium'],
['Dunkin', 'Medium'],
['Dunkin', 'Medium'],
['Subway', 'Low'],
['Chick-fil-a', ''],
['Chick-fil-a', '']
];
2) then filter out the duplicates...
var pieData = new google.visualization.DataTable();
pieData.addColumn('string', 'Risk Level');
var counterParty = [];
riskData.forEach(function (riskLevel) {
if (counterParty.indexOf(riskLevel[0]) === -1) {
counterParty.push(riskLevel[0]);
var rowData = (riskLevel[1] === '') ? ['Unidentified'] : [riskLevel[1]];
pieData.addRow(rowData);
}
});
3) then use google's group method to aggregate the counts...
var groupPie = google.visualization.data.group(
pieData,
[0],
[{
aggregation: google.visualization.data.count,
column: 0,
label: 'Count',
type: 'number'
}]
);
see following working snippet...
google.charts.load('current', {
callback: drawChart,
packages: ['controls']
});
function drawChart() {
// create array like this
var riskData = [
['Starbucks', 'High'],
['Starbucks', 'High'],
['McDonalds', 'Low'],
['Dunkin', 'Medium'],
['Dunkin', 'Medium'],
['Dunkin', 'Medium'],
['Subway', 'Low'],
['Chick-fil-a', ''],
['Chick-fil-a', '']
];
// for example only <--
var tableRisk = new google.visualization.ChartWrapper({
chartType: 'Table',
containerId: 'table_risk',
dataTable: google.visualization.arrayToDataTable(riskData, true)
});
tableRisk.draw();
// -->
var pieData = new google.visualization.DataTable();
pieData.addColumn('string', 'Risk Level');
var counterParty = [];
riskData.forEach(function (riskLevel) {
if (counterParty.indexOf(riskLevel[0]) === -1) {
counterParty.push(riskLevel[0]);
var rowData = (riskLevel[1] === '') ? ['Unidentified'] : [riskLevel[1]];
pieData.addRow(rowData);
}
});
// for example only <--
var tablePie = new google.visualization.ChartWrapper({
chartType: 'Table',
containerId: 'table_pie',
dataTable: pieData
});
tablePie.draw();
// -->
var groupPie = google.visualization.data.group(
pieData,
[0],
[{
aggregation: google.visualization.data.count,
column: 0,
label: 'Count',
type: 'number'
}]
);
// for example only <--
var tablePie = new google.visualization.ChartWrapper({
chartType: 'Table',
containerId: 'table_group',
dataTable: groupPie
});
tablePie.draw();
// -->
var chartPie = new google.visualization.ChartWrapper({
chartType: 'PieChart',
containerId: 'chart_pie',
dataTable: groupPie,
options: {
colors: ['red', 'orange', 'green', 'blue']
}
});
chartPie.draw();
}
div {
display: inline-block;
margin-right: 8px;
vertical-align: top;
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="table_risk"></div>
<div id="table_pie"></div>
<div id="table_group"></div>
<div id="chart_pie"></div>

Polymer 1.x: Defining "google" import

In this jsBin, I want to declaratively pre-load my element with a value of ['Colorado', 'South Dakota'] for the selected property.
When I open this jsBin, I expect to see the following:
✅ A successfully loaded page.
✅ An outline map of the U.S.
✅ A print of the selected variable in the upper left reading Colorado,South Dakota.
❌ The states of Colorado and South Dakota pre-selected and colored blue.
❌ No errors in the console.
Instead, I actually see the following:
✅ A successfully loaded page.
✅ An outline map of the U.S.
✅ A print of the selected variable in the upper left reading Colorado,South Dakota.
❌ The states of Colorado and South Dakota are not pre-selected or colored blue.
❌ The following console error:
console.error
google is not defined
Question
How can I get the value of google to be defined at the crucial location?
I have isolated the problem down to the following lines of code.
http://jsbin.com/zomejajibe/1/edit?html,console,output
_drawChart: function() {
console.log('A'); // Successfully logs to console
// The key is to get "google" defined at the following line
var dataTable = this.$.geochart._createDataTable(this.items); // "google" is not defined???
console.log('dataTable: '); // Does not successfully log because crashes above
console.log(dataTable);
this.$.geochart._chartObject.draw(dataTable, this.$.geochart.options);
},
So you have problem that the select changed trigger before the element ready.
I added timeout on the function _selectedChanged of 10 milisec so it push to the end of the event loop. You can change it to 0 milisec..
look http://jsbin.com/quzuyuwaha/1/edit?html,console,output
Specifically, #Alon added the following function:
http://jsbin.com/hulusijaje/1/edit?html,console,output
try: function(e) {
var self = this;
setTimeout(function() {
self._selectedChanged(e)
}.bind(self), 100)
},
And the full code of the solution is as follows:
http://jsbin.com/hulusijaje/1/edit?html,console,output
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<base href="https://polygit.org/components/">
<script src="webcomponentsjs/webcomponents-lite.min.js"></script>
<link href="polymer/polymer.html" rel="import">
<link href="google-chart/google-chart.html" rel="import"> </head>
<body>
<dom-module id="x-element"> <template>
<style>
google-chart {
width: 100%;
}
</style>
<button on-tap="_show">Show</button>
<div>[[selected]]</div>
<google-chart
id="geochart"
type="geo"
options="{{options}}"
data="{{items}}"
xon-google-chart-select="_onGoogleChartSelect"></google-chart>
</template>
<script>
(function() {
Polymer({
is: 'x-element',
/** /
* Fired when user selects chart item.
*
* #event us-map-select
* #param {object} detail Alpabetized array of selected state names.
/**/
properties: {
selected: {
type: Array,
notify: true,
//reflectToAttribute: true,
},
items: {
type: Array,
notify: true,
reflectToAttribute: true,
value: function() {
return [
['State', 'Select'],
['Alabama', 0],
['Alaska', 0],
['Arizona', 0],
['Arkansas', 0],
['California', 0],
['Colorado', 0],
['Connecticut', 0],
['Delaware', 0],
['Florida', 0],
['Georgia', 0],
['Hawaii', 0],
['Idaho', 0],
['Illinois', 0],
['Indiana', 0],
['Iowa', 0],
['Kansas', 0],
['Kentucky', 0],
['Louisiana', 0],
['Maine', 0],
['Maryland', 0],
['Massachusetts', 0],
['Michigan', 0],
['Minnesota', 0],
['Mississippi', 0],
['Missouri', 0],
['Montana', 0],
['Nebraska', 0],
['Nevada', 0],
['New Hampshire', 0],
['New Jersey', 0],
['New Mexico', 0],
['New York', 0],
['North Carolina', 0],
['North Dakota', 0],
['Ohio', 0],
['Oklahoma', 0],
['Oregon', 0],
['Pennsylvania', 0],
['Rhode Island', 0],
['South Carolina', 0],
['South Dakota', 0],
['Tennessee', 0],
['Texas', 0],
['Utah', 0],
['Vermont', 0],
['Virginia', 0],
['Washington', 0],
['West Virginia', 0],
['Wisconsin', 0],
['Wyoming', 0]
];
},
},
color: {
type: String, // '#455A64'
value: function() {
return 'blue';
}
},
options: {
type: Object,
notify: true,
reflectToAttribute: true,
computed: '_computeOptions(color)',
},
itemIndices: {
type: Object,
computed: '_computeItemIndices(items)',
},
},
observers: [
// '_selectedChanged(selected.*)',
'try(selected.*)'
//'_drawChart(items.*, options)',
],
ready: function() {
var _this = this;
this.$.geochart.addEventListener('google-chart-select', function(e) {
this._onGoogleChartSelect(e)
}.bind(_this));
},
_computeItemIndices: function(a) {
var out = {},
i = a.length;
while (i--) {
out[a[i][0]] = i;
}
return out;
},
_onGoogleChartSelect: function(e) {
var s = e.path[0].textContent.split('Select')[0].trim(), // e.g. 'Ohio'
temp = [],
a = this.items,
index = this.itemIndices[s], // e.g. 35
i = a.length;
this.set('items.' + index + '.1', a[index][1] ? 0 : 1);
while (i-- - 1) {
/** /
if(s === a[i][0]){
this.set('items.' + i + '.1', a[i][1] ? 0 : 1);
//this.items[i][1] = a[i][1] ? 0 : 1;
}
/**/
if (a[i][1]) {
temp.push(a[i][0]);
}
}
temp.sort();
this.set('selected', temp);
this._drawChart();
//console.log(this.selected);
},
/**/
_redrawChart: function() {
var j = 1, // iterations
s = 1, // delay in seconds
_this = this;
while (j--) {
try {
// console.log(j);
_this._drawChart();
//return;
} catch (e) {
// console.log(e.message);
setTimeout(function() {
//console.log(j);
console.log(_this.selected); // undefined
}, (s * 1000));
_this._drawChart();
}
}
},
/**/
_drawChart: function() {
console.log('A'); // Successfully logs to console
// The key is to get "google" defined at the following line
try {
var dataTable = this.$.geochart._createDataTable(this.items); // "google" is not defined???
console.log('dataTable: '); // Does not successfully log because crashes above
// console.log(dataTable);
this.$.geochart._chartObject.draw(dataTable, this.$.geochart.options);
} catch (e) {}
},
doAll: function(verb) {
verb = verb || 'clear'; // verb: 'clear'(default)|'select'
verb = (verb === 'select') ? 'select' : 'clear';
this._doAll(verb);
this._drawChart();
},
_doAll: function(verb) {
var resetSelect = (verb && verb === 'some') ? false : true;
verb = verb || 'clear'; // verb: 'clear'(default)|'select'|'some'
verb = (verb === 'select') ? 'select' : 'clear';
var temp = [];
var items = this.items,
i = items.length;
switch (verb) {
case 'select':
while (i-- - 1) {
items[i][1] = 1;
temp.push(items[i][0]);
}
break;
case 'clear':
while (i-- - 1) {
items[i][1] = 0;
}
break;
default:
break;
}
this.set('items', items);
if (resetSelect) {
temp.sort();
this.set('selected', temp);
}
},
try: function(e) {
var self = this;
setTimeout(function() {
self._selectedChanged(e)
}.bind(self), 100)
}, ////
_selectedChanged: function(e, k) {
console.log('selected');
if (k === undefined) {
console.log(e);
//// return
} else {
console.log(k);
}
var a = e.base,
i = a.length;
this._doAll('some');
while (i--) {
var index = this.itemIndices[a[i]];
this.set('items.' + index + '.1', 1);
}
this._redrawChart();
this.fire('us-map-select', this.selected);
// console.log(this.selected);//
// console.log(this.items);
},
_computeOptions: function(s) {
return {
region: 'US',
displayMode: 'regions',
resolution: 'provinces',
legend: 'none',
defaultColor: 'white',
colorAxis: {
colors: ['#E0E0E0', s],
minValue: 0,
maxValue: 1,
}
}
},
_show: function() {
//this.set('selected', ['Ohio', 'New Mexico']);
this.doAll();
//console.log(this.itemIndices);
},
});
})();
</script>
</dom-module>
<x-element xcolor="#455A64" selected='["Colorado", "South Dakota"]'></x-element>
</body>
</html>

Javascript function to sum of columns (into google dataTable)

Here I have google visualisation datatable:
How I can add here new Row and on postion [0] to put string "Sum" in position 1 will be 10, in position [2] will be 17, as sum of columns...
I start to write code but I'n not going anywhere ...
I try:
data.addRow();
for (var x=1, maxcol=data.getNumberOfColumns(); x < maxcol; x++) {
for y=1, maxrow=data.getNumberOfRows(); y < maxrow; y++) {
//WHAT NEXT ???
Try this:
var group = google.visualization.data.group(data, [{
type: 'number',
column: 0,
modifier: function () {return 0;}
}], [{
type: 'number',
column: 1,
aggregation: google.visualization.data.sum
}, {
type: 'number',
column: 2,
aggregation: google.visualization.data.sum
}]);
data.addRow(['Sum', group.getValue(0, 1), group.getValue(0, 2)]);
[Edit - added code to handle an arbitrary number of columns]
var groupColumns = [];
for (var i = 1; i < data.getNumberOfColumns(); i++) {
groupColumns.push({
type: 'number',
column: i,
aggregation: google.visualization.data.sum
});
}
var group = google.visualization.data.group(data, [{
type: 'number',
column: 0,
modifier: function () {return 0;}
}], groupColumns);
var row = ['Sum'];
for (var i = 1; i < group.getNumberOfColumns(); i++) {
row.push(group.getValue(0, i));
}
data.addRow(row);

Categories