How to use sheets.spreadsheets.batchUpdate() to apply formatting? - google-api-client

I am attempting to automatically apply new formatting to my spreadsheet, however while it does not appear to cause any errors, it is not working.
My goal is to apply duration formatting to columns G and H (index 6 and 7) of my spreadsheet. I am automatically updating the spreadsheet with string data in the format without brackets:
[D]:[H]:[M]
Where D, H, and M may be single or double digit. I would like it to display in the following format without brackets on the spreadsheet:
[hh]:[mm]:[ss]
Where there is always at least two digits in each column. However, the spreadsheet seems to automatically choose formatting regardless of what formatting I request, and it chooses a decimal number format. How can I use the batchUpdate() function to apply a working duration formatting to just these two columns?
My Code attempt is below. I am using the Node.js Google API Client Library.
sheets.spreadsheets.batchUpdate({
spreadsheetId: '1AakOf_W90JdAtL0R8XeMmacWrnBx8wLKrMCdHdnNmhM',
resource: {
requests: [{
updateCells:{
range: {
startColumnIndex: 6,
endColumnIndex: 8
},
'fields': 'userEnteredFormat/numberFormat(pattern,type),effectiveFormat/numberFormat(pattern,type)',
rows:[{
values:[{
userEnteredFormat:{
numberFormat:{
pattern: '[hh]:[mm]:[ss]',
type: 'TIME'
}
},
effectiveFormat:{
numberFormat:{
pattern: '[hh]:[mm]:[ss]',
type: 'TIME'
}
}
}]
}]
}
}
]
}
}, function(err, response, responseBody){
if(err){
console.log(err);
console.log(err.code);
}
});

It would seem that the issue lies within the indexing of columns on the spreadsheet. When writing this code, I assumed that the columns were indexed starting at zero. However, it would appear that the indexing starts at -1, as columns G and H are actually represented by indices 5 and 6.

Related

How to draw box plot of columns of a table using dc.js

I have a table as follows:
The number of experiments are arbitrary but the column name's prefix is "client_" following by the client number.
I want to draw a box plot of values against the "client_#" using dc.js. The table is a csv file which is loaded using d3.csv().
There are examples using ordinary groups, however I need each column to be displayed as its own boxplot and none of the examples do this. How can I create a boxplot from each column?
This is very similar to this question:
dc.js - how to create a row chart from multiple columns
Many of the same caveats apply - it will not be possible to filter (brush) using this chart, since every row contributes to every box plot.
The difference is that we will need all the individual values, not just the sum total.
I didn't have an example to test with, but hopefully this code will work:
function column_values(dim, cols) {
var _groupAll = dim.groupAll().reduce(
function(p, v) { // add
cols.forEach(function(c) {
p[c].splice(d3.bisectLeft(p[c], v[c]), 0, v[c]);
});
return p;
},
function(p, v) { // remove
cols.forEach(function(c) {
p[c].splice(d3.bisectLeft(p[c], v[c]), 1);
});
return p;
},
function() { // init
var p = {};
cols.forEach(function(c) {
p[c] = [];
});
return p;
});
return {
all: function() {
// or _.pairs, anything to turn the object into an array
return d3.map(_groupAll.value()).entries();
}
};
}
As with the row chart question, we'll need to group all the data in one bin using groupAll - ordinary crossfilter bins won't work since every row contributes to every bin.
The init function creates an object which will be keyed by column name. Each entry is an array of the values in that column.
The add function goes through all the columns and inserts each column's value into each array in sorted order.
The remove function finds the value using binary search and removes it.
When .all() is called, the {key,value} pairs will be built from the object.
The column_values function takes either a dimension or a crossfilter object for the first parameter, and an array of column names for the second parameter. It returns a fake group with a bin for each client, where the key is the client name and the value is all of the values for that client in sorted order.
You can use column_values like this:
var boxplotColumnsGroup = column_values(cf, ['client_1', 'client_2', 'client_3', 'client_4']);
boxPlot
.dimension({}) // no valid dimension as explained in earlier question
.group(boxplotColumnsGroup);
If this does not work, please attach an example so we can debug this together.

How to remove negative symbol on values Google Charts?

i have a column chart and work fine, but i want to allways show positive number, but i force negative number to "divide" bars on top and bottom.
He a example:
Here my code
google.load('visualization','1.1',{packages:['corechart']});
google.setOnLoadCallback(function(){
var GoogleChart=new google.visualization.ColumnChart(document.getElementById( 'chart' ));
var data = google.visualization.arrayToDataTable([
["Age","Male","Female"],
["<15",{"v":0,"f":"0%"},{"v":0,"f":"0%"}],
["15-20",{"v":8.3333333333333,"f":"8,3333333333333%"},{"v":0,"f":"0%"}],
["20-25",{"v":75,"f":"75%"},{"v":-8.3333333333333,"f":"8,3333333333333%"}],
["25-30",{"v":0,"f":"0%"},{"v":0,"f":"0%"}],
["30-35",{"v":0,"f":"0%"},{"v":0,"f":"0%"}],
["35-40",{"v":0,"f":"0%"},{"v":0,"f":"0%"}],
["40-45",{"v":8.3333333333333,"f":"8,3333333333333%"},{"v":0,"f":"0%"}],
["45-50",{"v":0,"f":"0%"},{"v":0,"f":"0%"}],
["50-55",{"v":0,"f":"0%"},{"v":0,"f":"0%"}],
["55-60",{"v":0,"f":"0%"},{"v":0,"f":"0%"}],
[">60",{"v":0,"f":"0%"},{"v":0,"f":"0%"}]
]);
new google.visualization.NumberFormat({"pattern":"#,##%"}).format(data, 1);
new google.visualization.NumberFormat({"pattern":"#,##%"}).format(data, 2);
var options ={
"isStacked":true,
"hAxis":{
"title":"age"
},
"vAxis":{
"title":"Percentage",
"format":"#,##%",
"viewWindowMode":"explicit",
"viewWindow":{
"min":-100,
"max":100
}
}
};
GoogleChart.draw(data, options);
i dont know how to remove negative symbol("-").
Thanks
P.S: Google Charts 1.1
The google visualization pattern format is a subset of the ICU pattern set. By that you can specify subpatterns for both positive and negative numbers to avoid the minus sign (because if the negative subpattern is not specified, you will get the minus prefix by default) :
format: "#,##%;#,##%"
Unfortunetaly this does not work in visualization - it complains about "Too many percent/permills" - but since % is nothing but "Multiply by 100 and show as percentage" - then you can simply add ,00% as a string suffix instead :
vAxis:{
format:"#,##',00%';#,##',00%'",
...
}
new google.visualization.NumberFormat({"pattern":"#,##',00%';#,##',00%'"}).format(data, 1);
new google.visualization.NumberFormat({"pattern":"#,##',00%';#,##',00%'"}).format(data, 2);
Minus sign now removed from both the vAxis and tooltips.
demo -> http://jsfiddle.net/pcvtf7q9/

mongodb query opposite of value in range

I have a mongoDB collection with data like this
{
start: "5.3",
end: "8.10",
owner: "guy1"
}
{
start: "9.0",
end: "14.5",
owner: "guy2"
}
Suppose I wish to know who got element 6.2.
We can see that guy1 has got element 6.2 because he own element 5.3 to element 8.10.
This is opposite to
db.collection.find( { field: { $gt: value1, $lt: value2 } } );
The fields specify the start and end. The supplied data is in between the range.
Looking for the largest value of start which is smaller than the required value.
How to query this?
Negating the logic, this should work:
db.collection.find( { start : { $lte : 6.2 }, end : { $gt : 6.2 } })
The problem is you need to ensure that you have no overlapping intervals, which can be tricky, but that is a problem at the application level. Also, please make sure you're not storing doubles as strings, otherwise the $gt/$lt queries will not work as expected, i.e make sure your data looks like this instead:
{
start: 9.0,
end: 14.5,
owner: "guy2"
}
As pointed out by Michael, you should also make sure your interval logic works out, because there are different methods interval inclusion can be defined. Math notation is ) vs. ], but the discussion gets more complicated with floating point numbers where there are limits on the value of a smallest epsilon which depends on the value of the number itself...
If I understood you correctly, you can use $not operator (put your original query inside $not) or you knowing that
not (x > a and x < b) is equal to x < a or x > b
you can rewrite it with $or query

Kendo Grid Decimal Column Sorting

I want sort the kendo grid column. In the below screen shot i need sort the WBS column either ascending or descending. In that column have that values like 1.1, 1.1.1, 1.2.1, 1.2.1.1, 1.2.1.2, 1.3, 2, 2.1, 2.1.1, 2.2 etc.,
Basically you need to define an ad-hoc compare function for WBS column. This is possible using columns.sortable.compare.
Now, the question is inventing a function that is able to compare two values as you need.
It comes to my mind doing the following:
Split the original value separated by "." in an array of values. Ex: "10.1.2" becomes [ "10", "1", "2" ].
Compare one by one the values of the arrays keeping in mind that one might be shorter than the other which means that is smaller (i.e. 10.1 is smaller 10.1.1).
This would be something like:
columns : [
...
{
field: "wbs",
width: 150,
title: "WBS",
sortable: {
compare: function (a, b) {
var wbs1 = a.wbs.split(".");
var wbs2 = b.wbs.split(".");
var idx = 0;
while (wbs1.length > idx && wbs2.length > idx) {
if (+wbs1[idx] > +wbs2[idx]) return true;
if (+wbs1[idx] < +wbs2[idx]) return false;
idx++;
}
return (wbs1.length > wbs2.length);
}
}
}
...
]
NOTE: As I said before and as result of the split, what I get in the arrays are strings. So it is pretty important that we use a little trick for comparing the values as number that is prepend a +. So when I do if (+wbs1[idx] > +wbs2[idx]) I'm actually comparing the values on wbs1[idx] and wbs2[idx] as numbers.
You can see it here: http://jsfiddle.net/OnaBai/H4U7D/2/

Tablesorter ordering dates and empty dates incorrectly

My tablesorter table is not sorting dates and empty fields correctly.
I would expect empty fields to be treated like zeros, and be grouped at the top/bottom. Instead I get some dates beneath them.
$('table').tablesorter({
widthFixed: true,
// sort on the last name in ascending order
sortList: [
[2, 0]
],
dateFormat: "ddmmyyyy",
emptyTo: "zero",
sortInitialOrder: "desc",
headers: {
3: {
sorter: "shortDate"
},
4: {
sorter: "shortDate"
},
5: {
sorter: "shortDate"
},
6: {
sorter: "shortDate"
}
},
textExtraction: {
3: function (n, t, c) {
return $(n).attr('data-date');
},
4: function (n, t, c) {
return $(n).attr('data-date');
},
5: function (n, t, c) {
return $(n).attr('data-date');
}
},
widgets: ['zebra', 'columns']
});
See the fiddle here. Sort using the 'Date of birth' column.
The "shortDate" parser converts all dates into a time in milliseconds to make date comparison (using a operator or date range with the filter widget) and sorting of dates easier. In order to do that, it uses a javascript function getTime():
The value returned by the getTime method is the number of milliseconds since 1 January 1970 00:00:00 UTC.
So, the issue you are noticing is because non-date cells are treated as having a zero-value, and the date that is not sorting properly is the date "1/1/1930". Entering this date into the javascript console, you'll see this result:
new Date('1/1/1930').getTime()
// returns -1262282400000
Remember, it's the time since 1/1/1970, so the time returns a negative number, which of course is less than zero.
The simplest solution would be to just set the emptyTo option to "min", which sets the value of any empty cells to be a maximum negative number (demo):