TimeSlider - Get Irregular Stops from Field

1102
6
Jump to solution
04-07-2021 02:58 PM
YogaYoda
New Contributor II

Looking for a little guidance on irregular stops for the TimeSlider widget. I have a point feature layer with a start_time field. Normally I use the "instant" mode and add the stops manually by adding the new date/time instance to the end of the array. For example stops: { dates: [ new Date(2021, 3, 7, 5, 25, 0), new Date(2021, 3, 7, 9, 15, 0), new Date(2021, 3, 7, 15,10, 0)) ] }.

This works fine and meets the need, but as updates to the layer are frequent I don't have the time to consistently add the new dates as they occur. Is there a method that would allow me to add each date in the field as a stop in the TimeSlider widget without having to add it manually? Each timestamp in the layer must be viewed on the slider, though multiple points may share the exact same timestamp.

Thanks!

 

 

0 Kudos
1 Solution

Accepted Solutions
UndralBatsukh
Esri Regular Contributor

Hi there, 

There are several ways of doing this. I created a simple app for you to show how to get all unique date values from your FeatureLayer and create date arrays. This way, your app should pick all changes when your layer updates. 

In the app, I am waiting for the layer to load then I am getting all unique values from the date field using smarting mapping uniqueValues  module as shown below. Then I loop through the date values and add them to dates array. Use the date array to set the TimeSlider.stops and fullTimeExtent. 

view.whenLayerView(layer).then(function (lv) {
  // get unique values from the date field 
  uniqueValues({
    layer: layer,
    field: "perimeterdatetime"
  }).then(function (response) {
    let infos = response.uniqueValueInfos;
    infos.forEach(function (info) {
      const dt = new Date(info.value);
      dates.push(dt);
    });
    timeSlider.stops = { dates };
    timeSlider.fullTimeExtent = {
       start: dates[0],
       end: dates[dates.length - 1]
     };
     const start = dates[0].getTime();
     const where = `perimeterdatetime = ${start}`;

     layerView = lv;
     layerView.filter = {
       where
     };
   });
});

 

Hope this helps,

-Undral

View solution in original post

6 Replies
UndralBatsukh
Esri Regular Contributor

Hi there, 

There are several ways of doing this. I created a simple app for you to show how to get all unique date values from your FeatureLayer and create date arrays. This way, your app should pick all changes when your layer updates. 

In the app, I am waiting for the layer to load then I am getting all unique values from the date field using smarting mapping uniqueValues  module as shown below. Then I loop through the date values and add them to dates array. Use the date array to set the TimeSlider.stops and fullTimeExtent. 

view.whenLayerView(layer).then(function (lv) {
  // get unique values from the date field 
  uniqueValues({
    layer: layer,
    field: "perimeterdatetime"
  }).then(function (response) {
    let infos = response.uniqueValueInfos;
    infos.forEach(function (info) {
      const dt = new Date(info.value);
      dates.push(dt);
    });
    timeSlider.stops = { dates };
    timeSlider.fullTimeExtent = {
       start: dates[0],
       end: dates[dates.length - 1]
     };
     const start = dates[0].getTime();
     const where = `perimeterdatetime = ${start}`;

     layerView = lv;
     layerView.filter = {
       where
     };
   });
});

 

Hope this helps,

-Undral

YogaYoda
New Contributor II

Wow, I really appreciate this. It works well for me and is exactly what I needed. Thanks!

0 Kudos
YogaYoda
New Contributor II

Thanks again for the assistance. One more quick question if you don't mind. Would it also be possible to sort the array in ascending order? Your solution works perfectly on most data I've tested it on, but on one dataset the dates array is out of order. Therefore start: dates[0], and end: dates[dates.length - 1] are creating a time extent that is different than it should be. I've tried using a few sort methods without success. Thanks again!

0 Kudos
UndralBatsukh
Esri Regular Contributor

Hi there, 

This approach appears to be working. I updated the test app to showcase this. The following is the gist of it. 

 var randomDates = [
  new Date(2021, 0, 11, 13, 52, 59, 452),
  new Date(2021, 0, 11, 13, 32, 58, 956),
  new Date(2021, 0, 12, 13, 55, 33, 216),
  new Date(2021, 0, 11, 14, 02, 56, 873),
  new Date(2021, 0, 11, 14, 22, 44, 315),
  new Date(2021, 0, 11, 14, 44,  21, 273),
  new Date(2021, 0, 11, 15, 02, 24, 093),
  new Date(2021, 0, 11, 17, 49, 56, 344),
  new Date(2021, 0, 12, 1, 08, 45, 504),
  new Date(2021, 0, 12, 1, 54, 36, 290),
  new Date(2021, 0, 12, 8, 31, 16, 087),
  new Date(2021, 0, 11, 16, 34, 05, 781),
  new Date(2000, 0, 11, 16, 36, 11, 802),
 ];
            
 var date_sort_asc = function (date1, date2) {
   if (date1 > date2) return 1;
   if (date1 < date2) return -1;
   return 0;
 };
 randomDates.sort(date_sort_asc);
 randomDates.forEach(function(dt){
 console.log(dt.toLocaleString())
});

 

0 Kudos
YogaYoda
New Contributor II

Thanks again!

0 Kudos
bogdanpalade2
New Contributor III

Hi! I have tried your solution on an imagery service but I am getting some problems. The imagery displays but the time slider shows "No time extent". All I did was to replace the feature service with the imagery service and change the date field, which in my case is called "AcquisitionDate". Is the approach different for imagery services?

Thank you!

0 Kudos