How to select the date of most recent record in featurelayer to automatically configure time slider

147
4
Jump to solution
2 weeks ago
EmilyGoldsmith
New Contributor III

Hello,

I'm in a bit of an tricky situation where a layer with automatic refreshes in one of our ArcGIS JavaScript apps  has been configured to have an incorrect, static time extent in its timeinfo - with us being unable to make changes to said layer currently. This has led our time slider to have the wrong time extent info in our ArcGIS JavaScript 4.27 app.

A quick fix I came up with was to overwrite the time extent when setting up the timeslider, which has fixed the time extent issue temporarily - see here:

 

//create time slider for layer 
        const timeSlider = new TimeSlider({
        container: "timeSlider",
        view: view,
        timeVisible: true, // show the time stamps on the timeslider
        loop: true,
        fullTimeExtent: { // entire extent of the timeSlider
          start: new Date(2003, 5, 19),
          end: new Date(2024, 5, 16)
  },
        });
      
        view.whenLayerView(layer).then((lv) => {timeSlider.fullTimeExtent.expandTo("weeks");
        timeSlider.stops = {interval: layer.timeInfo.interval};
        });

        view.ui.add(timeSlider, "bottom-left");

 

However, I would like to have a way to automatically get the most recent date from the feature layer's time field 'DATE_CREATED' and have this set to be the 'end' value in TimeSlider()'s 'fullTimeExtent.'

Does anybody know if this is possible?

Thank you.

0 Kudos
1 Solution

Accepted Solutions
EmilyGoldsmith
New Contributor III

Hi, just to give an update on this but I think I figured out how to do it by adding a statistical query to your code.

Essentially, the following queries by the 'maximum' date in the FeatureLayer and then selects this date to be the timeslider's new 'enddate.'

 

//Get the 'maximum' date (most recent)   
 const query = new Query();
    query.outStatistics = [{
  onStatisticField: "DATE_CREATED",
  outStatisticFieldName: "MAX_DATE",
  statisticType: "max"
  }];
  
//Query by the maxmimum date query set above
layer.queryFeatures(query).then((featureSet) => {
  
  const endDateAttribute = featureSet.features[0].attributes.MAX_DATE;
  console.log("Most Recent Date", endDateAttribute); //Print this date

       // Create a Date object from the attribute value
       const enddate = new Date(endDateAttribute);
              console.log("enddate" , {enddate}); //Ensure date converted successfully
          
  //create time slider for layer 
  const timeSlider = new TimeSlider({
  container: "timeSlider",
  view: view,
  timeVisible: true, // show the time stamps on the timeslider
  loop: true,
  fullTimeExtent: { // entire extent of the timeSlider
    start: new Date(2003, 5, 19),
    end: enddate}
  });

  view.whenLayerView(layer).then((lv) => {timeSlider.fullTimeExtent.expandTo("weeks");
  timeSlider.stops = {interval: layer.timeInfo.interval};
  });
  view.ui.add(timeSlider, "bottom-left"); 
});

 

A solution to why the code in my previous message didn't work is because QueryTasks have a limit of 1000 (see here.) Reading this post,  I was concerned I might have had to query by the maximum OBJECTID but this solution seems to work surprisingly well for now. Though I will keep an eye on it to ensure that it functions as it should. 

Thanks again for your help!

View solution in original post

0 Kudos
4 Replies
AngelaSchirck
Occasional Contributor II

Assuming you referenced the layer and can query its features you can try something like this:

// Assuming your layer variable holds a reference to the layer
layer.queryFeatures().then((featureSet) => {
const endDateAttribute = featureSet.features[0].attributes.DATE_CREATED;

// Create a Date object from the attribute value
const endDate = new Date(endDateAttribute);

// Create a time slider with the dynamic end date
const timeSlider = new TimeSlider({
container: "timeSlider", // ID of the HTML element where the time slider will be placed
view: view, // MapView or SceneView instance
timeVisible: true, // Show the time stamps on the time slider
loop: true, // Enable looping of time animation
fullTimeExtent: { // Entire extent of the time slider
start: new Date(2003, 5, 19), // Start date
end: endDate // End date based on the feature attribute
}
});

// When the layer view is ready, configure the time slider
view.whenLayerView(layer).then((lv) => {
timeSlider.fullTimeExtent.expandTo("weeks"); // Expand the time extent to weeks
timeSlider.stops = { interval: layer.timeInfo.interval }; // Set stops based on the layer's time interval
});

// Add the time slider to the view's UI (bottom-left position)
view.ui.add(timeSlider, "bottom-left");
});

 

 

EmilyGoldsmith
New Contributor III

Hello,

Many thanks for your help.

I gave your code a go and it was perfect in querying the earliest date in the dataset (which is at the top of the layer's table) but not the latest.

I gave finding the length of the feature layer a go and then putting that as the feature to be queried, however this just returned an error, which occurred whenever featureset.features[x] was over 999.

   //Find the length of the entire feature layer
    layer.queryFeatureCount().then(function(numFeatures){
    // prints the total count to the console
    console.log(numFeatures); //49880

layer.queryFeatures().then((featureSet) => {const endDateAttribute = featureSet.features[numFeatures].attributes.DATE_CREATED;
       
 
       // Create a Date object from the attribute value
       const enddate = new Date(endDateAttribute);
              console.log("enddate" , {enddate});
          
  //create time slider for layer 
  const timeSlider = new TimeSlider({
  container: "timeSlider",
  view: view,
  timeVisible: true, // show the time stamps on the timeslider
  loop: true,
  fullTimeExtent: { // entire extent of the timeSlider
    start: new Date(2003, 5, 18),
    end: enddate}
  });

  view.whenLayerView(layer).then((lv) => {timeSlider.fullTimeExtent.expandTo("weeks");
  timeSlider.stops = {interval: layer.timeInfo.interval};
  });
  view.ui.add(timeSlider, "bottom-left"); 
});
});

 

EmilyGoldsmith_0-1715957637295.png

I'm a bit unsure of where to go from here. Do you think I have to set a 'wait until layer loaded' function prior to ensure the query can select the latest record?

0 Kudos
EmilyGoldsmith
New Contributor III

Hi, just to give an update on this but I think I figured out how to do it by adding a statistical query to your code.

Essentially, the following queries by the 'maximum' date in the FeatureLayer and then selects this date to be the timeslider's new 'enddate.'

 

//Get the 'maximum' date (most recent)   
 const query = new Query();
    query.outStatistics = [{
  onStatisticField: "DATE_CREATED",
  outStatisticFieldName: "MAX_DATE",
  statisticType: "max"
  }];
  
//Query by the maxmimum date query set above
layer.queryFeatures(query).then((featureSet) => {
  
  const endDateAttribute = featureSet.features[0].attributes.MAX_DATE;
  console.log("Most Recent Date", endDateAttribute); //Print this date

       // Create a Date object from the attribute value
       const enddate = new Date(endDateAttribute);
              console.log("enddate" , {enddate}); //Ensure date converted successfully
          
  //create time slider for layer 
  const timeSlider = new TimeSlider({
  container: "timeSlider",
  view: view,
  timeVisible: true, // show the time stamps on the timeslider
  loop: true,
  fullTimeExtent: { // entire extent of the timeSlider
    start: new Date(2003, 5, 19),
    end: enddate}
  });

  view.whenLayerView(layer).then((lv) => {timeSlider.fullTimeExtent.expandTo("weeks");
  timeSlider.stops = {interval: layer.timeInfo.interval};
  });
  view.ui.add(timeSlider, "bottom-left"); 
});

 

A solution to why the code in my previous message didn't work is because QueryTasks have a limit of 1000 (see here.) Reading this post,  I was concerned I might have had to query by the maximum OBJECTID but this solution seems to work surprisingly well for now. Though I will keep an eye on it to ensure that it functions as it should. 

Thanks again for your help!

0 Kudos
AngelaSchirck
Occasional Contributor II

Great, glad you got it to work!

0 Kudos