I am using the AmCharts. I need to display value in the balloon text , that value is not a value field.
For example : X axis Value 0 , Y axis 1, (0,1) is 2 ; (1,2) is 5.
I need to display the Difference between the values (0,1) and (1,2) - that means "3" as Balloon in the point (1,2). Any ideas ?
Yes, the chart on your screenshot is possible to implement.
At first, add additional fields to your chart data, for example, labelGraph1, labelGraph2. Then you can use the labelText property of the AmCharts.AmGraph object.
var chartData = [{
title: "Apples",
value1: 24,
value2: 28,
labelGraph1: null,
labelGraph2: null
}, {
title: "Bananas",
value1: 27,
value2: 31,
labelGraph1: null,
labelGraph2: null
}, {
title: "Cherries",
value1: 27,
value2: 39,
labelGraph1: null,
labelGraph2: null
}];
for(var i = 0; i < chartData.length; i++) {
chartData[i].labelGraph1 = chartData[i].value1;
chartData[i].labelGraph2 = chartData[i].value2 - chartData[i].value1;
}
var chart;
AmCharts.ready(function () {
// SERIAL CHART
chart = new AmCharts.AmSerialChart();
chart.dataProvider = chartData;
chart.categoryField = "title";
// GRAPHS
var graph1 = new AmCharts.AmGraph();
graph1.valueField = "value1";
graph1.type = "line";
graph1.fillAlphas = 0.6;
graph1.labelText = "[[labelGraph1]]";
chart.addGraph(graph1);
var graph2 = new AmCharts.AmGraph();
graph2.valueField = "value2";
graph2.type = "line";
graph2.fillAlphas = 0.6;
graph2.labelText = "[[labelGraph2]]";
chart.addGraph(graph2);
// WRITE
chart.write("chartdiv")
});
The only one difficulty is to calculate values of the displayed fields.
I did it so, and you should change that function according to your data:
for(var i = 0; i < chartData.length; i++) {
chartData[i].labelGraph1 = chartData[i].value1;
chartData[i].labelGraph2 = chartData[i].value2 - chartData[i].value1;
}
Related
I'm creating a data entry form to a database sheet, previously I've managed to create a single cell data entry form. But now I'm going to create a data entry form that is entered in the range B6:N10. How do I modify it?
function SIMPAN1() {
var Sheet = SpreadsheetApp.openById("1hnezkq89bgVUvimYDdAfWDVY01f7ekFN3T6TY3Ui6oA");
var sheetInput = Sheet.getSheetByName('INPUT');
var sheetDb = Sheet.getSheetByName('DATABASE');
var lastRow = sheetDb.getRange("B1").getDataRegion().getLastRow();
lastRow += 1
var data1 = [[tgl1 = sheetInput.getRange('B6').getValue(),
nama1 = sheetInput.getRange('C6').getValue(),
kls1 = sheetInput.getRange('D6').getValue(),
srthfl1 = sheetInput.getRange('E6').getValue(),
aythfl1 = sheetInput.getRange('F6').getValue(),
nilaithfz1 = sheetInput.getRange('G6').getValue(),
jldsrt1 = sheetInput.getRange('H6').getValue(),
hlmayt1 = sheetInput.getRange('I6').getValue(),
mtri1 = sheetInput.getRange('J6').getValue(),
nilaitrtl1 = sheetInput.getRange('K6').getValue(),
prgst1 = sheetInput.getRange('L6').getValue(),
prgda1 = sheetInput.getRange('M6').getValue(),
ket1 = sheetInput.getRange('N6').getValue(),]];
sheetDb.getRange("B" + lastRow + ":N" + lastRow).setValues(data1);
}
Try this:
function SIMPAN1() {
const ss = SpreadsheetApp.openById("ssid");
const ish = ss.getSheetByName('INPUT');
const dsh = ss.getSheetByName('DATABASE');
const ivs = ish.getRange(6, 2, 1, 13).getValues();
dsh.getRange(dsh.getLastRow() + 1, 2, ivs.length, ivs[0].length).setValues(ivs);
}
I used the .combine command to convert two image collections into a two-band image collection (in the last line) to use in a function in the next step. This command is executed but writes 0 elements in the console. Where does this problem come from?
code link :
https://code.earthengine.google.com/5ebed42b397e764e3229e3f224c8b643
code :
var Rad1 = ee.ImageCollection('ECMWF/ERA5_LAND/HOURLY')
.filter(ee.Filter.date('2018-10-24','2019-05-20'))
.select('surface_solar_radiation_downwards');
var Rad2 = ee.ImageCollection('ECMWF/ERA5_LAND/HOURLY')
.filter(ee.Filter.date('2019-05-20','2019-06-30'))
.select('surface_solar_radiation_downwards');
var Rad1_Mj = Rad1.map(function(img){
var bands = img.multiply(0.000001);
var clip = bands.clip(geometry);
return clip
.copyProperties(img,['system:time_start','system:time_end']); });
//print(Rad1_Mj);
var Rad2_Mj = Rad2.map(function(img){
var bands = img.multiply(0.000001);
var clip = bands.clip(geometry);
return clip
.copyProperties(img,['system:time_start','system:time_end']); });
//print(Rad2_Mj);
// time frame change function for median collection
var daily_product_median = function(collection, start, count, interval, units){
var sequence = ee.List.sequence(0, ee.Number(count).subtract(1));
var origin_date = ee.Date(start);
return ee.ImageCollection(sequence.map(function(i){
var start_date = origin_date.advance(ee.Number(interval).multiply(i),units);
var end_date =
origin_date.advance(ee.Number(interval).multiply(ee.Number(i).add(1)),units);
return collection.filterDate(start_date, end_date).median()
.set('system:time_start',start_date.millis())
.set('system:time_end',end_date.millis());
}))};
// daily radiation product
var daily_Rad_1 = daily_product_median(Rad1_Mj,'2018-10-24', 208 , 24 , 'hour');
// print(daily_Rad_1);
//Map.addLayer(daily_Rad_1, {min: 17.38, max: 26.07, palette :
['white','yellow','orange']},
'Daily solar shortwave radiation 1' );
var daily_Rad_2 = daily_product_median(Rad2_Mj,'2019-05-20', 41 , 24 , 'hour');
// print(daily_Rad_2);
// Map.addLayer(daily_Rad_2, {min: 23.77, max: 26.64, palette :
['white','yellow','orange']},
'Daily solar shortwave radiation 2');
var daily_Rad_total = daily_Rad_1.merge(daily_Rad_2);
//print(daily_Rad_total);
var START = '2018-10-24';
var END = '2019-06-30';
var DATES = [ '2018-12-19', '2018-12-29', '2019-01-23', '2019-02-12', '2019-03-04',
'2019-03-19', '2019-04-08', '2019-04-13', '2019-05-13', '2019-05-18', '2019-05-23',
'2019-05-28', '2019-06-02', '2019-06-07', '2019-06-12', '2019-06-17', '2019-06-22',
'2019-06-27'];
var addTime = function(x) {
return x.set('Date', ee.Date(x.get('system:time_start')).format("YYYY-MM-dd"))};
var final_Rad = ee.ImageCollection(daily_Rad_total)
.filter(ee.Filter.date(START, END))
.map(addTime)
.filter(ee.Filter.inList('Date',ee.List(DATES)));
print(final_Rad);
var ndvi = function(img){
var bands = img.select(['B2','B3','B4','B8']).multiply(0.0001)
.clip(geometry);
var index = bands.normalizedDifference(['B8','B4']);
return index
.copyProperties(img,['system:time_start','system:time_end','system:index']);
};
var S2 = ee.ImageCollection('COPERNICUS/S2_SR')
.filterBounds(geometry)
.filterDate('2018-10-24','2019-06-30')
.filter(ee.Filter.lte('CLOUDY_PIXEL_PERCENTAGE',20))
.map(ndvi);
print(S2);
var NDVI_and_Rad = S2.combine(final_Rad, false);
print(NDVI_and_Rad);
Try it here
You may use merge instead of combine to get a new image collection
var Rad1 = ee.ImageCollection('ECMWF/ERA5_LAND/HOURLY')
.filter(ee.Filter.date('2018-10-24','2019-05-20'))
.select('surface_solar_radiation_downwards');
var Rad2 = ee.ImageCollection('ECMWF/ERA5_LAND/HOURLY')
.filter(ee.Filter.date('2019-05-20','2019-06-30'))
.select('surface_solar_radiation_downwards');
var Rad1_Mj = Rad1.map(function(img){
var bands = img.multiply(0.000001);
var clip = bands.clip(geometry);
return clip
.copyProperties(img,['system:time_start','system:time_end']); });
//print(Rad1_Mj);
var Rad2_Mj = Rad2.map(function(img){
var bands = img.multiply(0.000001);
var clip = bands.clip(geometry);
return clip
.copyProperties(img,['system:time_start','system:time_end']); });
//print(Rad2_Mj);
// time frame change function for median collection
var daily_product_median = function(collection, start, count, interval, units){
var sequence = ee.List.sequence(0, ee.Number(count).subtract(1));
var origin_date = ee.Date(start);
return ee.ImageCollection(sequence.map(function(i){
var start_date = origin_date.advance(ee.Number(interval).multiply(i),units);
var end_date = origin_date.advance(ee.Number(interval).multiply(ee.Number(i).add(1)),units);
return collection.filterDate(start_date, end_date).median()
.set('system:time_start',start_date.millis())
.set('system:time_end',end_date.millis());
}))};
// daily radiation product
var daily_Rad_1 = daily_product_median(Rad1_Mj,'2018-10-24', 208 , 24 , 'hour');
// print(daily_Rad_1);
//Map.addLayer(daily_Rad_1, {min: 17.38, max: 26.07, palette : ['white','yellow','orange']}, 'Daily solar shortwave radiation 1' );
var daily_Rad_2 = daily_product_median(Rad2_Mj,'2019-05-20', 41 , 24 , 'hour');
// print(daily_Rad_2);
// Map.addLayer(daily_Rad_2, {min: 23.77, max: 26.64, palette : ['white','yellow','orange']}, 'Daily solar shortwave radiation 2');
var daily_Rad_total = daily_Rad_1.merge(daily_Rad_2);
//print(daily_Rad_total);
var START = '2018-10-24';
var END = '2019-06-30';
var DATES = [ '2018-12-19', '2018-12-29', '2019-01-23', '2019-02-12', '2019-03-04',
'2019-03-19', '2019-04-08', '2019-04-13', '2019-05-13', '2019-05-18', '2019-05-23',
'2019-05-28', '2019-06-02', '2019-06-07', '2019-06-12', '2019-06-17', '2019-06-22',
'2019-06-27'];
var addTime = function(x) {
return x.set('Date', ee.Date(x.get('system:time_start')).format("YYYY-MM-dd"))};
var final_Rad = ee.ImageCollection(daily_Rad_total)
.filter(ee.Filter.date(START, END))
.map(addTime)
.filter(ee.Filter.inList('Date',ee.List(DATES)));
print("final_Rad",final_Rad);
var ndvi = function(img){
var bands = img.select(['B2','B3','B4','B8']).multiply(0.0001)
.clip(geometry);
var index = bands.normalizedDifference(['B8','B4']);
return index
.copyProperties(img,['system:time_start','system:time_end','system:index']);
};
var S2 = ee.ImageCollection('COPERNICUS/S2_SR')
.filterBounds(geometry)
.filterDate('2018-10-24','2019-06-30')
.filter(ee.Filter.lte('CLOUDY_PIXEL_PERCENTAGE',20))
.map(ndvi);
print("S2", S2);
var NDVI_and_Rad = S2.merge(final_Rad);
print('Both image collection', NDVI_and_Rad);
I want to make a list of last months dates in cell A5:A35.
I am currently just using formulas but it is going to list all the days regardless of count in the month. So when I make the sheet for November, it's going to have December 1st on the list. I don't want that.
I tried scripting to get the current month and searching the range for that month but it's not working and seems convoluted. There must be a cleaner way.
I just want to programmatically list the days in the prior month.
I have this
Code function won't work on mobile
function assignDates() {
const cell = sheet.getRange('A5:A35');
cell.setFormula(=EOMONTH(TODAY(),-2)+D5
d5 is a hidden column with 1,2,3... etc. It's a really cheap way to do it.
It will list 31 days regardless of the length of the month.
Now to deal with this, I tried to make a script to get the current month and then delete entries that contain that but it does not work.
//check to see if dates fall within month
function dateCheck(sheet){
var sheet = SpreadsheetApp.getActive().getSheetByName('test');
//get current month
var month = Utilities.formatDate(new Date(), "GMT-5", "MMMM")
// Delete days that fall out of range
var dayRange = sheet.getRange('A5:A36').getDisplayValues();
dayRange.forEach((date) => { if (date.toString().includes(month))
{ sheet.getRangeList(dayRange).clearContent() } })
}
=SEQUENCE(DAYS(EOMONTH(TODAY(),)+1,EOMONTH(TODAY(),-1)+1),1,EOMONTH(TODAY(),-1)+1)
DAYS to calculate number of days in this month
EOMONTH to get end date of last month and this month
SEQUENCE to create sequence of dates.
You need to change TODAY() to a static date string, if you don't want the sequence to change every month.
Get Last Month and This Month Calendar on a Spreadsheet
Code:
function getCalendar() {
const ss = SpreadsheetApp.getActive()
const sh = ss.getActiveSheet();
sh.clear();
let oA = [];
oA.push(monthlyCalendar(new Date().getMonth() - 1, null, true));//helper function
oA.push(monthlyCalendar(new Date().getMonth(), null, true));//helper function
//oA.push(monthlyCalendar(new Date().getMonth() + 1, null, true));
oA.forEach((obj, i) => {
if (i == 0) {
sh.getRange(1, 1, 2, obj.cA[0].length).setFontWeight('bold');
sh.getRange(1, 1, obj.cA.length, obj.cA[0].length).setValues(obj.cA);
} else {
let sr = sh.getLastRow() + 2;
sh.getRange(sr, 1, 2, obj.cA[0].length).setFontWeight('bold');
sh.getRange(sr, 1, obj.cA.length, obj.cA[0].length).setValues(obj.cA);
if (obj.roff && obj.coff) {
sh.getRange(sr, 1).offset(obj.roff, obj.coff).setFontWeight('bold').setFontColor('red');//sets the current date to bold and red
}
}
});
}
Helper Function:
function monthlyCalendar(m, wsd, ret) {
var m = m || new Date().getMonth();
var wsd = wsd || 1;//defaults to Monday
var ret = ret || false;
const td = new Date();
const [cy,cm,cd] = [td.getFullYear(),td.getMonth(),td.getDate()];
const dA = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
const oA = [...Array.from(Array(7).keys(), idx => dA[(idx + wsd) % 7])]
let dObj = {};
let midx = {};
let rObj = {cA:null,roff:null,coff:null};
oA.forEach(function (e, i) { dObj[e] = i; });
const mA = [...Array.from(new Array(12).keys(), x => Utilities.formatDate(new Date(2021, x, 15), Session.getScriptTimeZone(), "MMM"))];
mA.forEach((e, i) => { midx[i] = i; })
let cA = [];
let bA = [];
let wA = [null, null, null, null, null, null, null];
const ss = SpreadsheetApp.getActive();
const sh = ss.getActiveSheet();
sh.clear();
const year = new Date().getFullYear();
let i = midx[m % 12];
let month = new Date(year, i, 1).getMonth();
let dates = new Date(year, i + 1, 0).getDate();
cA.push([mA[month], dates, '', '', '', '', '']);
bA.push(['#ffffff', '#ffffff', '#ffffff', '#ffffff', '#ffffff', '#ffffff', '#ffffff']);
cA.push(oA)
//bA.push(['#ffff00', '#ffff00', '#ffff00', '#ffff00', '#ffff00', '#ffff00', '#ffff00']);
let d = [];
let ddd = [];
for (let j = 0; j < dates; j++) {
let day = new Date(year, i, j + 1).getDay();
let date = new Date(year, i, j + 1).getDate();
if (day < wA.length) {
wA[dObj[dA[day]]] = date;
}
if(cy == year && cm == month && cd == date) {
rObj.roff = cA.length;
rObj.coff = dObj[dA[day]];
}
if (dA[day] == oA[wA.length - 1] || date == dates) {
cA.push(wA);
//bA.push(['#ffffff', '#ffffff', '#ffffff', '#ffffff', '#ffffff', '#ffffff', '#ffffff']);
wA = ['', '', '', '', '', '', ''];
}
}
if (!ret) {
rObj.cA = cA;
sh.getRange(1, 1, rObj.cA.length, rObj.cA[0].length).setValues(cA);
if (rObj.roff && rObj.coff) {
sh.getRange(1, 1).offset(rObj.roff, rObj.coff).setFontWeight('bold').setFontColor('red');
}
} else {
rObj.cA = cA;
return rObj;
}
}
Demo:
Nice challenge!
Enter the following function on A5:
=arrayformula(if(eomonth(today(),-2)+row(A5:A35)+1-row()>eomonth(today(),-1),"",eomonth(today(),-2)+row(A5:A35)+1-row()))
It will retrieve all dates from the 1st until the last date of the last month (related to today()). until 31th, 30th, 28th, or 29th dynamically!
Cheers!
If you need a script here you go:
function myFunction() {
var today = new Date();
var year = today.getFullYear();
var month = today.getMonth(); // 0 -> January, 1 -> February, etc...
// get the number of days of the previous month
// 'zero day' of a month is the last day of a previous month
var len = new Date(year, month, 0).getDate();
// make an array with dates (strings, actually)
var options = { year: 'numeric', month: 'numeric', day: 'numeric' };
var dates = new Array(len).fill('').map((_, day) =>
[new Date(year, month-1, day+1).toLocaleString('en-US', options)])
// put the array on the sheet
SpreadsheetApp.getActiveSheet().getRange(5,1,len,1).setValues(dates);
}
Dates is a tricky thing always.
I have an array of dictionaries that appears as below and I want to sort and store it such that the objects are sorted based on the 'value' of the 'Like' key ? How do I do this in Swift ? Thanks.
{
Dislike = 0;
Like = 5;
userName = T; }
{
Dislike = 0;
Like = 0;
userName = S; }
{
Dislike = 0;
Like = 10;
userName = N; }
I suppose that's an array of dictionaries?
If it is the case, you can sort them as follows
//AnyObject in case your number is an NSNumber
var array: [[String:AnyObject?]] = yourArray
array.sort{ $0["Like"]!! > $1["Like"]!! }
basically it mutates the array and sort based on the "Like" key.
This data structure looks really weird you know. I think it is a [[String: Any]]. It should be declared like this:
let data: [[String: Any]] = [
[
"Dislike": 0,
"Like": 5,
"username": "T"],
[
"Dislike": 0,
"Like": 0,
"username": "S"],
[
"Dislike": 0,
"Like": 10,
"username": "N"],
]
To sort it, simply use the sort function. In the closure, you should return whether the first parameter should be ordered before the second parameter. In this case, you would like to only compare the values corresponding to the key "Like". The closure body would look something like this: (pseudocode)
firstParameter["Like"] < secondParameter["Like"]
as I said, that is pseudocode. The real code is a little more complicated:
data.sort { ($0["Like"]! as! Int) < ($1["Like"] as! Int) }
Sweeper and Edder are right, it looks like an array of structs. You can also omit the semicolon.
struct s {
var Dislike: Int = 0
var Like: Int = 0
var userName: String = ""
}
var myArray = [s]()
var i = s()
i.Dislike = 0
i.Like = 5
i.userName = "T"
myArray.append(i)
i.Dislike = 0
i.Like = 0
i.userName = "S"
myArray.append(i)
i.Dislike = 0
i.Like = 10
i.userName = "N"
myArray.append(i)
myArray.sort{$0.Like < $1.Like}
I have to to draw a chart from the following json string:
{
"d":{
"results":[
{
"_metadata":{
"uri": "http://www.something.com/hi",
"type" : "something.preview.hi"
}, "Period", "1988", "Age": 20, "Size" : 80
},
"_metadata":{
"uri": "http://www.something.com/hi",
"type" : "something.preview.hi"
}, "Period", "1989", "Age": 25, "Size" : 90
}
] }}
I use jquery.flot.js library to draw the chart. Here is the example to draw the chart and it works fine:
var d1 = [];
for (var i = 0; i < 14; i += 0.5)
d1.push([i, Math.sin(i)]);
var d2 = [[0, 3], [4, 8], [8, 5], [9, 13]];
myChart.setDataArray(d1);
myChart.setDataArray(d2);
According to example I have converted the json to an array of object:
var results = $.parseJSON(responseText)["d"]["results"];
var sampleData = [];
for (var i = 0, len = results.length; i < len; i++) {
var result = results[i];
sampleData.push({ Perioden: result.Perioden,
Size: result.Size,
Age: result.Age});
}
var myData = [];
for (var i in sampleData) {
myData.push([sampleData[i].Period, sampleData[i].Age]);
}
var myData1 = [];
for (var i in sampleData) {
myData1.push([sampleData[i].Period, sampleData[i].Size]);
}
myChart.setDataArray(myData);
myChart.setDataArray(myData1);
but I get the error that the data format is wrong for the data chart.
Can anyody see what is the different between my code and the example?
I guess that your json is well formated. but the exemple you are providing is not (trailing "i" after second "uri2 line
and "," instead of ":" after "Period"
second thing, you have Period in your json and Perioden is your js code. check that you are using the same name everywhere
then you can try to console.log(myData, myData1) to see if you have the expected results
tell us if it's enough or if you have another problem
Try this:
var myData = [];
sampleData.forEach(function(item){
myData.push([item.Perioden, item.Age]);
});