Issues with naming ranges for charts within the Google Spreadsheet Script - charts

I've been trying for days to create charts with an intelligent range, that differs when the data in the google spreadsheet is updated. However i succeeded doing so, i can't get the .setOption aspect to work. I want for example, a title, description etc with the chart. But this is not the main issue since i can insert there by hand.
More important however is the range name, because there isn't when i use the script. So, within the chart it is not possible to see what each column represents, and i really want to fix that. I tried to use the .setNamedRange() aspects, but that is not working.
Someone who can help me with that?
function check() {
var sheet = SpreadsheetApp.getActiveSheet();
var end = sheet.getLastRow();
var start = (end - 5);
var endnew = (end - 4);
var startnew = (end - 6);
if(sheet.getCharts().length == 0){
Logger.log("Er is geen grafiek");
var chartBuilder = sheet.newChart()
.asColumnChart().setStacked()
.addRange(sheet.getRange("A" + startnew + ":" + "A" + endnew)) // should have a name
.addRange(sheet.getRange("B" + startnew + ":" + "B" + endnew)) // should have a name
.addRange(sheet.getRange("E" + startnew + ":" + "E" + endnew)) //should have a name
.setOption('title', 'Effectief gebruik kantoorruimte') //not working
.setPosition(10, 10, 0, 0)
var chart = chartBuilder.build();
sheet.insertChart(chart);
}
else{
Logger.log("Er is wel een grafiek");
var charts = sheet.getCharts();
for (var i in charts) {
var chart = charts[i];
var ranges = chart.getRanges();
var builder = chart.modify();
for (var j in ranges) {
var range = ranges[j];
builder.removeRange(range);
builder
.addRange(sheet.getRange("A" + (start) + ":" + "A" + end)) //should have a name
.addRange(sheet.getRange("B" + (start) + ":" + "B" + end)) //should have a name
.addRange(sheet.getRange("E" + (start) + ":" + "E" + end)) // should have a name
.setOption('title', 'Effectief gebruik kantoorruimte')
.build();
sheet.updateChart(builder.build());
}
}
}
}

I'm assuming that this code is the issue?
builder
.addRange(sheet.getRange("A" + (start) + ":" + "A" + end))
Maybe try using the JavaScript toString() method to make sure that your text formula is working.
.addRange(sheet.getRange("A" + start.toString() + ":" + "A" + end.toString()))
There is a different format that you can use:
getRange(row, column, numRows, numColumns)
So, it would be:
getRange(start, 1, 1, numColumns)
That starts on row "start" in column A. It gets one row of data, and how ever many number of columns.

Related

Define editing date format in AG Grid

I have a SQL Server table which contains a DATETIME column SaleDate - and unfortunately, for now, I cannot change the datatype to just DATE (which would be sufficient).
I am trying to show data from that column in an Angular app using the Ag Grid.
For the display, I was able to use this in my Typescript code:
columnDefs = [
....
{ headerName: 'Sale', field: 'SaleDate', width: 120, editable: true,
cellRenderer: (data) => {
return data.value ? (new Date(data.value)).toLocaleDateString('de-CH', this.options) : '';
},
....
]
and it works quite nicely.
However, when I try to edit this cell, unfortunately the whole DATETIME details (including the time portion) is being displayed:
[ 2018-09-27T08:43:59 ]
That'll be quite confusing to the users.... so is there a way to also somehow set / define the format for the editing in an AG-Grid cell?
If you need to have a workaround (prepare visual and real data) for display and edit things, you should create an own cellRenderer and cellEditor for this cell.
Or you can just create a cellEditor for calendar component and valueFormatter for displaying the date.
Just my case for same requirements valueFormatter:
let result: string;
if (params.value) {
var formats = [
moment.ISO_8601
];
let date = moment(params.value, formats, true);
if (date.isValid()) {
let dateObject: Date = date.toDate();
result = ('0' + dateObject.getDate()).slice(-2) + '.'
+ ('0' + (dateObject.getMonth() + 1)).slice(-2) + '.'
+ dateObject.getFullYear();
if (element.DataType == "datetime")
result += ' ' + ('0' + dateObject.getHours()).slice(-2) + ':'
+ ('0' + dateObject.getMinutes()).slice(-2) + ':'
+ ('0' + dateObject.getSeconds()).slice(-2);
}
}
return result;
On custom cellEditor the major thing is getValue function - which will be used internally (for binding)
getValue(): any {
let value = (this.selectedDate.getFullYear() + '-'
+ ('0' + (this.selectedDate.getMonth() + 1)).slice(-2) + '-'
+ ('0' + this.selectedDate.getDate()).slice(-2)
+ 'T'
+ ('0' + this.selectedDate.getHours()).slice(-2) + ':'
+ ('0' + this.selectedDate.getMinutes()).slice(-2) + ':'
+ ('0' + this.selectedDate.getSeconds()).slice(-2));
return value;
}
And on the template, you can use any calendar template library.

highchart - average value of serie for shown period

Using Highstock, I've a serie timestamp / value
with different rangeselectors (hour, day, week, month,...) or zoomX
I want to display the average value for the displayed time period.
Now, I can compute the average of the overall series data:
for (i = 0; i < chart.series[0].yData.length; i++) {
total += chart.series[0].yData[i];
}
seriesAvg = (total / chart.series[0].yData.length).toFixed(4); // fix decimal to 4 places
$('#report1').html('<b>Average:</b>: '+ seriesAvg);
How to compute the average only on the displayed datapoints ? And to refresh automatically after zoom ?
Thank you
Use series.processedYData or series.points.
I implemented the same but I notice that processedYdata is loading also one data more than the one showed at the screen.
for that reason i added one additional command to remove the first processedYData:
processedYData.splice(0, 1);
below is the final result of the function
function showStat(objHighStockchart) {
for (j = 0; j < (json_data.length); j++) {
var seriesAvg = 0,
processedYData = objHighStockchart.series[j].processedYData;
processedYData.splice(0, 1);
var seriesMin = Math.min.apply(null, processedYData);
var seriesMax = Math.max.apply(null, processedYData);
var i = 0
var total = 0;
console.log(processedYData);
for (i = 1; i < processedYData.length; i++) {
total += processedYData[i];
}
seriesAvg = (total / processedYData.length).toFixed(2); // fix decimal to 4 places
$('#container_stat' + j).html(
'<br>Statistics for ' + objHighStockchart.series[j].name + '<br>' +
'Total: ' + total + ' logs<br>' +
'Min: ' + seriesMin + ' logs<br>' +
'Avg: ' + seriesAvg + ' logs<br>' +
'Max: ' + seriesMax + ' logs<br>'
+ '---' + processedYData
);
}
};

date format of javascript calendar

I have to add a javascript calendar in my website..but the date format is mm/dd/yy. I want to change it to yy/mm/dd. I had changed the function function f_tcalGenerDate() but i got the error invalid date format..How to change the format using this code??
function f_tcalParseDate (s_date) {
var re_date = /^\s*(\d{1,2})\/(\d{1,2})\/(\d{2,4})\s*$/;
if (!re_date.exec(s_date))
return alert ("Invalid date: '" + s_date + "'.\nAccepted format is yyyy/mm/dd.")
var n_day = Number(RegExp.$2),
n_month = Number(RegExp.$1),
n_year = Number(RegExp.$3);
if (n_year < 100)
n_year += (n_year < this.a_tpl.centyear ? 2000 : 1900);
if (n_month < 1 || n_month > 12)
return alert ("Invalid month value: '" + n_month + "'.\nAllowed range is 01-12.");
var d_numdays = new Date(n_year, n_month, 0);
if (n_day > d_numdays.getDate())
return alert("Invalid day of month value: '" + n_day + "'.\nAllowed range for selected month is 01 - " + d_numdays.getDate() + ".");
return new Date (n_year, n_month - 1, n_day);
}
// date generating function
function f_tcalGenerDate (d_date) {
return (
(d_date.getMonth() < 9 ? '0' : '') + (d_date.getMonth() + 1) + "/"
+ (d_date.getDate() < 10 ? '0' : '') + d_date.getDate() + "/"
+ d_date.getFullYear()
);
}
Put the substring in the format you want and then use the Date function to make it a valid date
Date mydate = new Date(mysubstring);

Coffeescript memoization?

I have a function that displays a number as a properly formatted price (in USD).
var showPrice = (function() {
var commaRe = /([^,$])(\d{3})\b/;
return function(price) {
var formatted = (price < 0 ? "-" : "") + "$" + Math.abs(Number(price)).toFixed(2);
while (commaRe.test(formatted)) {
formatted = formatted.replace(commaRe, "$1,$2");
}
return formatted;
}
})();
From what I've been told, repeatedly used regexes should be stored in a variable so they are compiled only once. Assuming that's still true, how should this code be rewritten in Coffeescript?
This is the equivalent in CoffeeScript
showPrice = do ->
commaRe = /([^,$])(\d{3})\b/
(price) ->
formatted = (if price < 0 then "-" else "") + "$" + Math.abs(Number price).toFixed(2)
while commaRe.test(formatted)
formatted = formatted.replace commaRe, "$1,$2"
formatted
You can translate your JavaScript code into CoffeeScript using js2coffee. For given code the result is:
showPrice = (->
commaRe = /([^,$])(\d{3})\b/
(price) ->
formatted = ((if price < 0 then "-" else "")) + "$" + Math.abs(Number(price)).toFixed(2)
formatted = formatted.replace(commaRe, "$1,$2") while commaRe.test(formatted)
formatted
)()
My own version is:
showPrice = do ->
commaRe = /([^,$])(\d{3})\b/
(price) ->
formatted = (if price < 0 then '-' else '') + '$' +
Math.abs(Number price).toFixed(2)
while commaRe.test formatted
formatted = formatted.replace commaRe, '$1,$2'
formatted
As for repeatedly used regexes, I don't know.

How to use Netbeans Variable Formatters?

By default when viewing watches/variables of objects in Netbeans, it shows its address instead of its value. This is quite tiresome since I have to expand the variable to see its real value (e.g. for Double, Integer, Date, etc). As it turns out, Netbeans has "Variable formatters" but there is hardly any documentation that i can find for it.
How would I go about displaying e.g. a simple Date variable in a human readable format in the Watches/Variables window? I don't fully understand the "Edit Variable Formatter" dialog.
I was able to properly do it for Double and Integer by using the following code snippet:
toString()
So the code seems to run in the context of the Double/Integer class. How would I refer to the actual variable if I need to do something more advanced such as:
return DateHelpers.formatDate(dateVariableName??, "yyyy-MM-dd");
In the variables view, you have a small $ icon (at the top left) which tooltip says :"Show variable value as toString() or formatted value".
Just click that, it will show you the "value" of those variables.
EDIT: If you want to add a variable formatter, it's very simple. On the variable formatter view, just click the "Add ..." button then:
In "Formatter Name" put the name of you formatter eg. "My Date formatter"
"Class Types" put your complete class name eg. java.util.Date
Select "Value formatted as a result of code snippet" and type the code to apply. For instance:
toString()
but if you want to manipulate the data or display some other thing you can. For instance:
toString() + " (" + getTime() + ")"
Which will display the time in human readable format plus the time as a long.
Don't forget to select the $ icon on the view to apply your formatter.
My answer won't solve the question. It will rather echo the previous answers. First, I haven't seen the $ sign in the variables-panel in NetBeans. Seems it was replaced with a context menu in current versions.
I haven't found the answer to the actual question, as of how you would reference the variable to debug, within the "Variable Formatters" Dialog. Something like "this" or "$1" isn't working definitely. Also the facility does not seem to know about Standard Java JRE classes like SimpleDateFormatter.
So when debugging Java JRE classes, I guess you have to live with what they're offering in terms of public methods.
Here's a workaround for the especially user friendly Date class, if you're stuck with a JDK below version 8 (as me). Just create a new Variable Formatter in NetBeans via
Tools > Options > Java > Variable Formatters > Add
Then in the "Class Types" editfield enter:
java.util.Date
Under "Value formatted as a result of code snippet" use one of the next snippets.
// German format - "dd.MM.yyyy hh:mm"
((getDate() < 10) ? ("0" + getDate()) : getDate()) + "." + ((getMonth() < 9) ? ("0" + (getMonth() + 1)) : (getMonth() + 1) ) + "." + (getYear() + 1900) + " " + ((getHours() < 10) ? "0" + getHours() : getHours()) + ":" + ((getMinutes() < 10) ? "0" + getMinutes() : getMinutes()) + ":" + ((getSeconds() < 10) ? "0" + getSeconds() : getSeconds())
// US format - "MM/dd/yyyy hh:mm"
((getMonth() < 9) ? ("0" + (getMonth() + 1)) : (getMonth() + 1) ) + "/" + ((getDate() < 10) ? ("0" + getDate()) : getDate()) + "/" + (getYear() + 1900) + " " + ((getHours() < 10) ? "0" + getHours() : getHours()) + ":" + ((getMinutes() < 10) ? "0" + getMinutes() : getMinutes()) + ":" + ((getSeconds() < 10) ? "0" + getSeconds() : getSeconds())
// ISO-8601 - "yyyy-MM-dd hh:mm"
(getYear() + 1900) + "-" + ((getMonth() < 9) ? ("0" + (getMonth() + 1)) : (getMonth() + 1) ) + "-" + ((getDate() < 10) ? ("0" + getDate()) : getDate()) + " " + ((getHours() < 10) ? ("0" + getHours()) : getHours()) + ":" + ((getMinutes() < 10) ? ("0" + getMinutes()) : getMinutes()) + ":" + ((getSeconds() < 10) ? ("0" + getSeconds()) : getSeconds())
The next snippet could also come in handy, when your lost in the the debug-output overkill of an instance of java.util.Calendar:
// German format - "dd.MM.yyyy hh:mm"
((get(5) < 10) ? ("0" + get(5)) : get(5)) + "." + ((get(2) < 9) ? ("0" + (get(2) + 1)) : (get(2) + 1) ) + "." + (get(1)) + " " + ((get(10) < 10) ? "0" + get(10) : get(10)) + ":" + ((get(12) < 10) ? "0" + get(12) : get(12)) + ":" + ((get(13) < 10) ? "0" + get(13) : get(13))
You can even put a much more complex code in the variable formatter, as long as you return a string. For example, if I have a class with two string members, name and surname I can paste the follwing code in the "Value formatted.." box:
String result;
if (name != null) {
result = name + " " + surname;
} else {
result = "<null>";
}
return result;
.. and for displaying as children the name and surname separately you can paste a code in the "Children displayed as.." box to return a String[], for example:
String[] results = new String[2];
results[0] = "name: " + name;
results[1] = "surname: " + surname;
return results;
This will display two nodes as children in the variables debug window with the name and surname
The variable itself can be referenced by this (at least it works in Netbeans 8.1).
So, let's say we want the identityHashCode of our Collection after its size:
"size = " +size() + " #" + System.identityHashCode(this)