Google Geochart - same countries, different values - javascript

I got some problems with displaying values for a country. The thing is, I want to display where football players of a certain team come from. Because many of them have same nationality, geochart displays only the last name in the array when hoovering over the country, but I want it to display all the names.
This is the code:
var chart = function (item) {
body = document.getElementById("regions_div");
body.innerHTML = " ";
var places = [];
var names = [];
for (var i = 0; i<item.length; i++) {
person = item[i];
country = person.nationality;
name = person.name;
places.push(country);
names.push(name);
};
console.log(places);
console.log(names);
google.charts.load('upcoming', {'packages':['geochart']});
google.charts.setOnLoadCallback(drawRegionsMap);
function drawRegionsMap() {
var data = [];
var header = ["Country", "Name"];
data.push(header);
for (var i = 0; i < places.length; i++) {
var temp = [];
temp.push(places[i]);
temp.push(names[i]);
console.log(temp);
data.push(temp);
}
console.log(data);
var chartdata = google.visualization.arrayToDataTable(data);
var options = {};
var chart = new google.visualization.GeoChart(document.getElementById('regions_div'));
chart.draw(chartdata, options);
}
}
And the screenshot, for example this time has multiple players from England but only the last one in the array is displayed :
Thanks for help!

following is an example of building a custom tooltip to show all names at each country
the group() method is used to group the names by country
then the tooltip is updated for each row in chartdata
for all the names found for each country
see following working snippet...
google.charts.load('current', {
callback: drawRegionsMap,
packages:['geochart']
});
function drawRegionsMap() {
var container = document.getElementById('regions_div');
container.innerHTML = '';
var names = ["Sam Johnstone", "Chris Smalling", "Phil Jones", "Luke Shaw"];
var places = ["United Kingdom", "United Kingdom", "United Kingdom", "United Kingdom"];
var data = [];
var header = ["Country", "Name"];
data.push(header);
for (var i = 0; i < places.length; i++) {
var temp = [];
temp.push(places[i]);
temp.push(names[i]);
data.push(temp);
}
var chartdata = google.visualization.arrayToDataTable(data);
// group data by country, name
var groupdata = google.visualization.data.group(
chartdata,
[0, 1],
[{
aggregation: google.visualization.data.count,
column: 1,
label: "Name",
type: "number"
}]
);
// update tooltip for each chart data row
for (var i = 0; i < chartdata.getNumberOfRows(); i++) {
// find group rows for current country
var locationRows = groupdata.getFilteredRows([{
column: 0,
value: chartdata.getValue(i, 0)
}]);
// build tooltip of all names for current country
var nameTooltip = '';
locationRows.forEach(function (index) {
if (nameTooltip !== '') {
nameTooltip += ', ';
}
nameTooltip += groupdata.getValue(index, 1);
});
// update tooltip
chartdata.setValue(i, 1, nameTooltip);
}
var chart = new google.visualization.GeoChart(container);
chart.draw(chartdata);
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="regions_div"></div>

Related

How to set a value in the cells of the next column?

I have table with hundred of text entries.
I want to tag those entries according to the original text.
Eg:
TEXT (A) TAG (B)
Facebook Social Media
Instagram Social Media
Stackoverflow Good Site
I am using the code below.
But this only copies the column A into column B !!
var sheet = SpreadsheetApp.getActiveSheet();
var range = sheet.getRange('A2:A5');
var data = range.getValues();
var tag = sheet.getRange('B2:B5');
for (var i = 0; i<data.length; i++)
{
if(String(data[i][1]).match(/facebook|instagram/gi))
{
data([i][1]='Social Media');
}
if(String(data[i][1]).match(/Stack/gi))
{
data([i][1]='Good Site');
}
}
tag.setValues(data);
}
The current result :
TEXT (A) TAG (B)
Facebook Facebook
Instagram Instagram
Stackoverflow Stackoverflow
Try this:
function myfunction() {
var sheet = SpreadsheetApp.getActiveSheet();
var range = sheet.getRange('A2:A5');
var data = range.getValues();
var tag = sheet.getRange('B2:B5');
var vA= tag.getValues();
for (var i = 0; i<data.length; i++) {
if(String(data[i][0]).match(/facebook|instagram/gi)) {
vA([i][0]='Social Media');
}
if(String(data[i][0]).match(/Stack/gi)) {
vA([i][0]='Good Site');
}
}
tag.setValues(vA);
}
You are using the wrong indexes. The array that getValues() returns looks like this:
[ [ 'Facebook' ], [ 'Instagram' ], [ 'Stack Overflow' ], [ '' ] ]
So this code should work:
var sheet = SpreadsheetApp.getActiveSheet();
var range = sheet.getRange('A2:A5');
var data = range.getValues();
var tag = sheet.getRange('B2:B5');
for (var i = 0; i < data.length; i++) {
if (String(data[i][0]).match(/facebook|instagram/gi)) {
data[i][0] = 'Social Media';
}
if (String(data[i][0]).match(/Stack/gi)) {
data[i][0] = 'Good Site';
}
}
tag.setValues(data);

Google Script, find match value from one column with another column

I am try to make "Color check",
It will change color when value input is detected.
I need to find match value from one column with another column.
Find match for each value in each value in the column.
But my code dont work, can anyone help with my code?
Here is my code:
function checkScriptCheck() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var datePaymentValues = sheet.getRange("A:A").getValues();
var dateInputValues = sheet.getRange("B:B").getValues();
var datePaymentRange = sheet.getRange("A:A");
var datePaymentColumn = sheet.getRange("A:A").getColumn();
var checkResultValueColumn =sheet.getRange("C:C").getColumn()
//cleaning color
datePaymentRange.setBackground("white");
//check and coloring
for(i=0;i<datePaymentValues.length;i++){
for(j=0;j<dateInputValues.length;j++){
if(datePaymentValues[i][0]==dateInputValues[j][0]){
sheet.getRange(i+1, datePaymentColumn).setBackground("green");
sheet.getRange(i+1, checkResultValueColumn).setValue("check");
};
};
};
};
Here is the link to my sheet:
https://docs.google.com/spreadsheets/d/1DVbNaehsTWkiIkzW2nQx7w-ZB8CrPmSP5T5CpU24mbU/edit?usp=sharing
Here is some screenshoot:
Sheet Screenshoot
Code ScreenShoot
Thankyou.
Will be easier if you create a map of values to check for first.
function checkScriptCheck() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("Sheet1");
var datePaymentRange = sheet.getRange("A:A");
var datePaymentValues = datePaymentRange.getValues();
var dateInputValues = sheet.getRange("B:B").getValues();
var datePaymentColumn = datePaymentRange.getColumn();
var checkResultValueColumn =sheet.getRange("C:C").getColumn()
//cleaning color
datePaymentRange.setBackground("white");
//create map of values to check for
var inputDates = {};
for (var i = 1; i < dateInputValues.length; i++) { // Exclude header row
var inputDate = dateInputValues[i][0];
if (inputDate != "") { // Exclude blank values
inputDates[inputDate] = true;
}
}
//check and coloring
for (var i = 1; i < datePaymentValues.length; i++) { // Exclude header row
var paymentDate = datePaymentValues[i][0];
if (inputDates[paymentDate]) {
sheet.getRange(i+1, datePaymentColumn).setBackground("#00ff00");
sheet.getRange(i+1, checkResultValueColumn).setValue("check");
}
}
}

Dynamically Created Elements

So I am trying to create an expense tracker that has a list of dynamically created options.
The user will be able to:
add a new expense
select a category
add a name for the expense, and then
put how much the expense is.
I have everything working, except for I would like to display the categories with the total amount of money budgeted for each category.
Right now I have 9 categories. If a uses has 2 expenses with the same category, for example "Health & Fitness", I would like that Category to show up on the left side in a DIV that displays the total amount budgeted. If there are other categories like "Auto & Transport", I would like that to display as well with the total amount budgeted. I can't seem to figure out how to separate the totals based on the category selected.
var addListItem = document.getElementById("add-more");
addListItem.addEventListener("click", function() {
createNewItem();
});
//Display Month and Day
var today = new Date();
var dd = today.getDate();
var mm = today.getMonth()+1;
today = mm + "/" + dd;
document.getElementById("current-date").innerHTML = today;
//Creates new elements
function createNewItem() {
var u = document.getElementById("full-item-list");
var l = document.createElement("li");
var elinput = document.createElement('input');
var select = document.createElement('select');
var option1 = document.createElement('option');
var option2 = document.createElement('option');
var option3 = document.createElement('option');
var option4 = document.createElement('option');
var option5 = document.createElement('option');
var option6 = document.createElement('option');
var option7 = document.createElement('option');
var option8 = document.createElement('option');
var option9 = document.createElement('option');
var option10 = document.createElement('option');
var o1 = document.createTextNode('Category');
var o2 = document.createTextNode('Auto & Transport');
var o3 = document.createTextNode('Bills & Utilities');
var o4 = document.createTextNode('Health & Fitness');
var o5 = document.createTextNode('Home');
var o6 = document.createTextNode('Personal Care');
var o7 = document.createTextNode('Pets');
var o8 = document.createTextNode('Shopping');
var o9 = document.createTextNode('Entertainment');
var o10 = document.createTextNode('Investments');
var expenseName = document.createElement('input');
var icon = document.createElement('img');
option1.setAttribute('disabled', 'true');
option1.setAttribute('selected', 'true');
option1.appendChild(o1);
option2.appendChild(o2);
option2.setAttribute('name', 'testName');
option3.appendChild(o3);
option3.setAttribute('name', 'testName2');
option4.appendChild(o4);
option5.appendChild(o5);
option6.appendChild(o6);
option7.appendChild(o7);
option8.appendChild(o8);
option9.appendChild(o9);
option10.appendChild(o10);
select.setAttribute('type', 'select');
select.setAttribute('placeholder', 'Select a Category');
select.appendChild(option1);
select.appendChild(option2);
select.appendChild(option3);
select.appendChild(option4);
select.appendChild(option5);
select.appendChild(option6);
select.appendChild(option7);
select.appendChild(option8);
select.appendChild(option9);
select.appendChild(option10);
expenseName.setAttribute('type', 'text');
expenseName.setAttribute('placeholder', 'Expense name');
expenseName.setAttribute('class', 'expense-input-name')
expenseName.setAttribute('name', 'totalExpense');
elinput.setAttribute('type', 'number');
elinput.setAttribute('class', 'li-input');
elinput.setAttribute('placeholder', 'Enter amount');
elinput.setAttribute('name', 'qty');
l.setAttribute('class', 'list-item');
l.setAttribute('name', 'li-name');
icon.setAttribute('class', 'remove-icon');
icon.setAttribute('src', 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/375261/System_Delete.ico');
icon.setAttribute("id", "icon-id");
icon.addEventListener('click', function(e) {
thaticon(e);
}, false);
l.appendChild(select);
l.appendChild(expenseName);
l.appendChild(elinput);
l.appendChild(icon);
u.appendChild(l);
}
//Deletes elements
function thaticon(e) {
console.log("test");
var el = e.target;
var elListItem= el.parentNode;
elFullList = elListItem.parentNode;
elFullList.removeChild(elListItem);
}
//Calculates and displays results
function displayResult() {
var arr = document.getElementsByName("qty");
var wage = document.getElementById("inputWage").value;
var jumboDiv = document.getElementById("jumbo-results").style.display="block";
var tot = 0;
for (var i = 0; i < arr.length; i++) {
if (parseFloat(arr[i].value)) tot += parseFloat(arr[i].value);
}
document.getElementById("result").innerHTML = "Total Expenses: $" + tot.toFixed(2);
document.getElementById("left").innerHTML = "Left Over: $" + ((wage - tot).toFixed(2));
}
//Resets and clears entire entry
function resetForm() {
var jumboDiv = document.getElementById("jumbo-results").style.display="none";
document.getElementById("full-item-list").innerHTML = "";
document.getElementById("inputWage").value = "";
document.getElementById("result").innerHTML = "";
document.getElementById("left").innerHTML = "";
document.getElementById("number-display").innerHTML = "";
}
//Displays the selected categories by user with the total sum for each one
function displayCategory() {
}
//Capture screen shots
/*function captureScreen() {
html2canvas(document.querySelector("#capture")).then(canvas => {
document.body.appendChild(canvas)
});
}*/
You will need to create a data structure to store the category information and use that to construct your HTML elements.
The following code constructs a simple select element without any additional attributes.
var optionsArray = ['Category',
'Auto & Transport',
'Bills & Utilities',
'Health & Fitness',
'Home',
'Personal Care',
'Pets',
'Shopping',
'Entertainment',
'Investments'];
var selectElem = document.createElement('select');
selectElem.setAttribute('placeholder', 'Select a Category');
// iterate through the array of options
optionsArray.forEach(function(text){
var option = document.createElement('option');
var optionText = document.createTextNode(text);
option.appendChild(optionText);
selectElem.appendChild(option);
});
// selectElem is ready to append to the DOM
This can be improved upon by changing the elements in the array to objects and using the attributes if required.
e.g.
var optionsArray = ['Category',
'Auto & Transport',
{
'itemText' : 'Bills & Utilities',
'itemDisabled' : true,
'itemSelected' : true
},
'Health & Fitness',
'Home',
'Personal Care',
'Pets',
'Shopping',
'Entertainment',
'Investments'];
var selectElem = document.createElement('select');
selectElem.setAttribute('placeholder', 'Select a Category');
// iterate through the array of options
optionsArray.forEach(function(item){
var text = (typeof(item) === 'string') ? item : item.itemText;
var option = document.createElement('option');
var optionText = document.createTextNode(text);
option.appendChild(optionText);
if (typeof(item) === 'object') {
// handle custom attributes
Object.keys(item).forEach(function(key){
switch(key) {
case 'itemDisabled' :
if (item[key]) {
option.setAttribute('disabled', true);
}
break;
case 'itemSelected' :
if (item[key]) {
option.setAttribute('selected', true);
}
break;
default:
break;
}
});
}
selectElem.appendChild(option);
});
// selectElem is ready to append to the DOM
The calculations for the category totals would need to be done using a data structure such as an array of objects. Iterate through the array, calculating the totals before adding the desired information to the HTML.

Getting trouble while trying Dynamic Data in jsPdf AutoTable

Am trying to print the dynamic data into the PDF using jsPdf AutoTable .But am failed to do that. I searched in many site's but no one didn't said about dynamic data into the Row's. So here my question is , Is there any way to get the Dynamic data into the table row's if it so can some one clarify me pls . Note : [ Here am not using HTML to store the Data into the Pdf, i got the data from the js directly ] .
this.print=function(){
{
var mainData =this.printData(); // Here am getting Full Json data Here
var steps = mainData.steps; // From that data am Separating what i need
var criticality = mainData.criticality;
var categories = mainData.categories;
var checkup = mainData.checkup;
// This is For to Take the Steps Data alone
$scope.getSteps = function(steps) {
var data = [];
for (var i = steps.length; i-- > 0;) {
data.push(steps[i].name+"\n"+"\n");
}
return data;
}
// Like wise am getting every single object data's
$scope.getNumbersOfSubSteps = function(steps) {
var data = 0;
for (var i = 0 ; i < steps.length; i++) {
for (var j = 0; j<steps[i].steps.length; j++) {
}
data = j ;
}
return data;
}
// this is for Sub Proceeses
$scope.getSubProcesses = function(steps) {
var data = [];
for (var i = 0 ; i < steps.length; i++) {
for (var j = 0; j<steps[i].steps.length; j++) {
data.push(steps[i].steps[j].name+"\n");
}
}
return data;
}
$scope.getCategories = function(categories) {
var data = [];
for (var i = categories.length; i-- > 0;) {
data.push(categories[i].name+"\n");
}
return data;
}
$scope.getCriticality = function(criticality) {
var data = [];
for (var i = criticality.length; i-- > 0;) {
data.push(criticality[i].name+"\n");
}
return data;
}
// Pdf Print Function Begins
var columns = ["ProcessDescription", "Steps", "#ofSubProcesses", "SubSteps","Category","Criticality","CheckUp"];
var processDescription =mainData.description;
var processes= $scope.getSteps(steps);
var NoOfSubProcess = $scope.getNumbersOfSubSteps(steps);
var subProcesses = $scope.getSubProcesses(steps);
console.log('Subprocsses length',subProcesses);
var categories = $scope.getCategories(categories);
var criticality = $scope.getCriticality(criticality);
// The Problem Begins here , Am struggling to Get the Separate data's here !
var rows = [
[processDescription,processes,NoOfSubProcess,subProcesses,categories,criticality]
];
var pdfsize='a1';
var doc = new jsPDF('p', 'pt',pdfsize);
doc.autoTable(columns, rows, {
theme: 'striped', // 'striped', 'grid' or 'plain'
styles: {
overflow: 'linebreak',
columnWidth: 'wrap'
},
beforePageContent: function(data) {
doc.text("Process Name :"+mainData.name, 40, 30);
},
columnStyles: {
1: {columnWidth: 'auto'}
}
});
doc.save(mainData.name+ pdfsize +".pdf");
}
};
You will need to replace this:
var rows = [
[processDescription,processes,NoOfSubProcess,subProcesses,categories,criticality]
];
with something like this:
var rows = [];
for (var k = 0 ; k < processes.length; k++) {
rows.push([
processDescription,
processes[k],
NoOfSubProcess,
subProcesses[k],
categories[k],
criticality[k]
]);
};
The rows parameter should be an array of arrays. What you are putting in there is basically an array of an array of arrays if I understood correctly.

Processing javascript objects with google charts

I am trying to draw a Google visualization pie chart based on below JSON. I am having issues since Google takes numerical data, instead of just plain objects.
For example, I want a pie chart based on UseCase. Pie chart will list VDI,Upgrade,DEMO and show its proportion related to total. Please help.
Here is the JSON example
[{"Id":0,"ProcessedTime":"2012/01","Approver":"zoo","POC":"POC1","UseCase":"VDI"},{"Id":0,"ProcessedTime":"2012/02","Approver":"zoo","POC":"POC1","UseCase":"Upgrade"},{"Id":0,"ProcessedTime":"2012/03","Approver":"zoo","POC":"POC2","UseCase":"DEMO"},{"Id":0,"ProcessedTime":"2012/04","Approver":"victor","POC":"POC2","UseCase":"DEMO"},{"Id":0,"ProcessedTime":"2012/05","Approver":"victor","POC":"POC3","UseCase":"VDI"},{"Id":0,"ProcessedTime":"2012/06","Approver":"victor","POC":"POC3","UseCase":"Upgrade"},{"Id":0,"ProcessedTime":"2012/05","Approver":"tom","POC":"POC3","UseCase":"VDI"},{"Id":0,"ProcessedTime":"2012/06","Approver":"tom","POC":"POC3","UseCase":"Upgrade"}]
// Full source
google.setOnLoadCallback(drawChart);
function drawChart() {
$.get('/Home/GetData', {},
function (data) {
var tdata = new google.visualization.DataTable();
tdata.addColumn('string', 'UseCase');
tdata.addColumn('int', 'Count');
// Reservation based on UseCase
var ReservationByUseCase = [];
for (var i = 0; i < data.length; i++) {
var d = data[i];
// If not part of array.. Add it
if ($.inArray(d.UseCase, ReservationByUseCase) === -1)
{
var UseCaseValue = d.UseCase;
var UseCaseCountValue = 1;
ReservationByUseCase.push({ UseCase: UseCaseValue, UseCaseCount: UseCaseCountValue });
}
// If part of the array.. Increase count
if ($.inArray(d.UseCase, ReservationByUseCase) !== -1) {
var cUseCase = ReservationByUseCase[$.inArray(d.UseCase, ReservationByUseCase)];
cUseCase.UseCaseCount = cUseCase.UseCaseCount + 1;
ReservationByUseCase[$.inArray(d.UseCase, ReservationByUseCase)] = cUseCase
}
}
for (var i = 0; i < ReservationByUseCase.length; i++) {
tdata.addColumn(ReservationByUseCase[i].UseCaseValue, ReservationByUseCase[i].UseCaseCountValue)
alert(ReservationByUseCase[i].UseCaseValue);
alert(ReservationByUseCase[i].UseCaseCountValue);
}
var options = {
title: "Reservations"
};
var chart = new google.visualization.PieChart(document.getElementById('chart_div'));
chart.draw(tdata, options);
});
}
You just need to loop through the data and add up each UseCase:
var ndata = {}
var data = [{"Id":0,"ProcessedTime":"2012/01","Approver":"zoo","POC":"POC1","UseCase":"VDI"},{"Id":0,"ProcessedTime":"2012/02","Approver":"zoo","POC":"POC1","UseCase":"Upgrade"},{"Id":0,"ProcessedTime":"2012/03","Approver":"zoo","POC":"POC2","UseCase":"DEMO"},{"Id":0,"ProcessedTime":"2012/04","Approver":"victor","POC":"POC2","UseCase":"DEMO"},{"Id":0,"ProcessedTime":"2012/05","Approver":"victor","POC":"POC3","UseCase":"VDI"},{"Id":0,"ProcessedTime":"2012/06","Approver":"victor","POC":"POC3","UseCase":"Upgrade"},{"Id":0,"ProcessedTime":"2012/05","Approver":"tom","POC":"POC3","UseCase":"VDI"},{"Id":0,"ProcessedTime":"2012/06","Approver":"tom","POC":"POC3","UseCase":"Upgrade"}];
for (i = 0; i < data.length; i++) {
var d = data[i];
if (ndata[d["UseCase"]] == null) {
ndata[d["UseCase"]] = 1
} else {
ndata[d["UseCase"]] = ndata[d["UseCase"]] + 1
}
}
console.log(ndata);
Here's a fiddle: http://jsfiddle.net/znj0kLsg/
This is what I've came up with... Will this work?
// Reservation based on UseCase
var ReservationByUseCase = [];
for (var i = 0; i < data.length; i++) {
var d = data[i];
// If not part of array.. Add it
if ($.inArray(d.UseCase, ReservationByUseCase) === -1)
{
var UseCaseValue = d.UseCase;
var UseCaseCountValue = 1;
ReservationByUseCase.push({ UseCase: UseCaseValue, UseCaseCount: UseCaseCountValue });
}
// If part of the array.. Increase count
if ($.inArray(d.UseCase, ReservationByUseCase) !== -1) {
var cUseCase = ReservationByUseCase[$.inArray(d.UseCase, ReservationByUseCase)];
cUseCase.UseCaseCount = cUseCase.UseCaseCount + 1;
ReservationByUseCase[$.inArray(d.UseCase, ReservationByUseCase)] = cUseCase
}
}

Categories

Resources