Hello
I was wondering if the following possible. I have a point dataset that gets updated regularly that I want to use in my dashboard. I would like the user to be able to select a time period and then the indicator automatically calculate a buffer and display the area result in my element. Is this something that can be added in the advanced formatting section of the element?
It can be done, but not in the advanced formatting. In there, you can only access the current datapoint, you can't load featuresets.
Instead, you need to calculate the buffers in a data expression, use that expression as input for your indicator, and then filter the indicator's data source using user supplied values.
So, doing this step by step:
// load your points
var p = Portal("https://xxx/portal/")
var id = "abc"
var sublayer = 1
var date_field = "Zeitstempel"
var layer = FeaturesetByPortalItem(p, id, sublayer, [date_field], true)
// define the output
var output_dict = {
geometryType: "",
fields: [
{name: "DateField", type: "esriFieldTypeDate"},
{name: "BufferArea", type: "esriFieldTypeDouble"}
],
features: []
}
// create the buffers
for(var f in layer) {
var new_f = {attributes: {
DateField: Number(f[date_field]),
BufferArea: Area(Buffer(f, 10, "meters"), "square-meters")
}}
Push(output_dict.features, new_f)
}
// return the featureset
return Featureset(Text(output_dict))
Now the user-selected date range filters the indicator's data source:
Hi Johannes
Thank you so much!! The reason why I was seeing if there was a way to process the data after the date selection is that I dont need the sum of the buffered points. I need to be able to union after the date selection to get an area calculation without any overlap. Sorry I should have added that information. You help is very much appreciated 🙂
Ah. As far as I know, there's no way to do that dynamically.
Only way I can think of is to have statically defined periods. So your users wouldn't be able to filter for "every point between these two arbitrary dates", only for "every point that falls into this predefined period".
To do this, you can use this data expression:
// load your points
var p = Portal("https://xxx/portal/")
var id = "abc"
var sublayer = 1
var date_field = "Zeitstempel"
var layer = FeaturesetByPortalItem(p, id, sublayer, [date_field], true)
// define the output
var output_dict = {
geometryType: "",
fields: [
{name: "Period", type: "esriFieldTypeString"},
{name: "TotalArea", type: "esriFieldTypeDouble"},
],
features: []
}
// define the periods as dictionary {period_name: [start, end]}
// The Union() function below takes a lot of time, so don't use too many periods!
var periods = {
"2020": [Date(2020, 0, 1), Date(2020, 11, 31)],
"2021": [Date(2021, 0, 1), Date(2021, 11, 31)],
"2022": [Date(2022, 0, 1), Date(2022, 11, 31)],
"2023": [Date(2023, 0, 1), Date(2023, 11, 31)],
"2020 - Q1": [Date(2020, 0, 1), Date(2020, 2, 31)],
"2020 - Q2": [Date(2020, 3, 1), Date(2020, 5, 30)],
"2020 - Q3": [Date(2020, 6, 1), Date(2020, 8, 30)],
"2020 - Q4": [Date(2020, 9, 1), Date(2020, 11, 31)],
}
// loop over the periods
for(var p in periods) {
// filter your points
var start = periods[p][0]
var end = periods[p][1]
var sql = `${date_field} >= @start AND ${date_field} <= @end`
var filtered_layer = Filter(layer, sql)
// buffer each point
var buffers = []
for(var f in filtered_layer) {
Push(buffers, Buffer(f, 10, "meters"))
}
// union all buffers
var unioned_buffers = Union(buffers)
// write new feature
var new_f = {attributes:{
Period: p,
TotalArea: Area(unioned_buffers, "square-meters")
}}
Push(output_dict.features, new_f)
}
// return the featureset
return Featureset(Text(output_dict))
Set the indicator's value to Sum of TotalArea.
Instead of the date selector, use a category selector. Use your period names as categories.
As action, filter the indicator's Period field.
Now your users can filter by the periods you defined and get the unioned areas.