TimeSliderViewModel.js 8.9 KB

12345
  1. /*
  2. All material copyright ESRI, All Rights Reserved, unless otherwise specified.
  3. See https://js.arcgis.com/4.24/esri/copyright.txt for details.
  4. */
  5. import{_ as t}from"../../chunks/tslib.es6.js";import e from"../../TimeExtent.js";import i from"../../TimeInterval.js";import n from"../../core/Collection.js";import s from"../../core/Evented.js";import{HandleOwnerMixin as r}from"../../core/HandleOwner.js";import o from"../../core/Logger.js";import{isSome as l,isNone as a,unwrap as m,applySome as u,abortMaybe as p}from"../../core/maybe.js";import{after as d,isAbortError as h,createTask as c}from"../../core/promiseUtils.js";import{watch as f,whenOnce as g,initial as T,syncAndInitial as v}from"../../core/reactiveUtils.js";import{offsetDate as w}from"../../core/timeUtils.js";import{property as _}from"../../core/accessorSupport/decorators/property.js";import"../../core/arrayUtils.js";import"../../core/has.js";import{ensureType as x}from"../../core/accessorSupport/ensureType.js";import{subclass as y}from"../../core/accessorSupport/decorators/subclass.js";import E from"../../webdoc/Widgets.js";import b from"../../webdoc/widgets/TimeSlider.js";import{getFullTimeExtentFromWebDocument as S,getModeFromTimeSlider as C,getStopsFromTimeSlider as j,getTimeExtentFromTimeSlider as W}from"./utils.js";var A;const D=1e4;function M(t){return l(t)&&void 0!==t.count}function I(t){return l(t)&&void 0!==t.interval}function R(t){return l(t)&&void 0!==t.dates}function V(t){return"esri.WebMap"===t.declaredClass}const k="esri.widgets.Popup.PopupViewModel",O=o.getLogger(k);let B=A=class extends(r(s.EventedAccessor)){constructor(t){super(t),this._animationController=null,this._isViewTimeExtentInitialized=!1,this._loadingWebDocument=!1,this._timerId=null,this._updateTimeSliderTask=null,this.actions=new n,this.view=null}initialize(){this.handles.add([f((()=>this.effectiveStops),(()=>{a(this.timeExtent)&&this._set("timeExtent",this._getDefaultTimeExtent())}),T),f((()=>u(this.view,(t=>t.map))),(t=>{this._updateTimeSliderTask=p(this._updateTimeSliderTask),this._updateTimeSliderTask=c((async e=>{this._loadingWebDocument=!0,await this._updateTimeSliderFromMap(t,e),this._loadingWebDocument=!1}))}),T),f((()=>this.view),((t,e)=>{this._unregisterWidget(e),this._registerWidget(t)}),v),f((()=>this.timeExtent),(t=>{if(a(this.view))return;const e=this.view.timeExtent;(a(t)||t.isAllTime)&&(a(e)||e.isAllTime)||l(t)&&l(e)&&t.equals(e)||(this.view.timeExtent=m(t))}),T),f((()=>u(this.view,(t=>t.timeExtent))),(t=>{this._isViewTimeExtentInitialized?(a(t)||t.isAllTime)&&(a(this.timeExtent)||this.timeExtent.isAllTime)||l(t)&&l(this.timeExtent)&&t.equals(this.timeExtent)||(this.timeExtent=t):this._isViewTimeExtentInitialized=!0}))])}destroy(){l(this._timerId)&&(clearInterval(this._timerId),this._timerId=null),this._unregisterWidget(this.view),this.view=null,l(this._animationController)&&(this._animationController.abort(),this._animationController=null),l(this._updateTimeSliderTask)&&(this._updateTimeSliderTask.abort(),this._updateTimeSliderTask=null)}get effectiveStops(){const{fullTimeExtent:t,stops:e}=this;if(R(e)){const{dates:i}=e;if(null==i||0===i.length)return null;const n=i.sort(((t,e)=>t.getTime()-e.getTime()));if(a(t))return n;const{start:s,end:r}=t;if(a(s)||a(r))return n;return n.filter((t=>!(t.getTime()<s.getTime()||t.getTime()>r.getTime())))}if(M(e)){const i=e.timeExtent??m(t);return this._divideTimeExtentByCount(i,e.count)}if(I(e)){const i=e.timeExtent??m(t);return this._divideTimeExtentByInterval(i,e.interval)}return[]}set fullTimeExtent(t){this._override("fullTimeExtent",t)}set loop(t){this._override("loop",t)}set mode(t){this._override("mode",t)}set playRate(t){t<=0||t>36e5||("playing"===this.state&&this._startAnimation(),this._override("playRate",t))}get state(){return a(this.fullTimeExtent)||this._loadingWebDocument?"disabled":l(this._animationController)?"playing":"ready"}set stops(t){this._override("stops",t)}set timeExtent(t){this._override("timeExtent",t)}get timeExtentValues(){const{mode:t,timeExtent:e}=this;if(a(e)||e.isAllTime||e.isEmpty)return null;const{start:i,end:n}=e;switch(t){case"cumulative-from-end":case"instant":return l(i)?[i.getTime()]:null;case"cumulative-from-start":return l(n)?[n.getTime()]:null;case"time-window":return l(i)&&l(n)?[i.getTime(),n.getTime()]:null}}static async getPropertiesFromWebMap(t,e){if(a(t)||!V(t))return null;await t.load({signal:e});const i=t?.widgets?.timeSlider;if(!i)return null;const n=await S(t,e),s=i.loop,r=C(i);return{fullTimeExtent:n,loop:s,mode:r,playRate:i.stopDelay??2e3,stops:j(i),timeExtent:W(i,r)}}next(){this._step({forward:!0,allowRestart:!1})}play(){this._startAnimation()}previous(){this._step({forward:!1,allowRestart:!1})}stop(){this._stopAnimation()}triggerAction(t){this.emit("trigger-action",{action:t})}updateWebDocument(t){if(V(t)){const e=new b({currentTimeExtent:this.timeExtent,fullTimeExtent:this.fullTimeExtent,loop:this.loop,numStops:M(this.stops)?this.stops.count:null,numThumbs:"time-window"===this.mode?2:1,stopDelay:this.playRate,stopInterval:I(this.stops)?this.stops.interval:null,stops:R(this.stops)?this.stops.dates:null});t.widgets?t.widgets.timeSlider=e:t.widgets=new E({timeSlider:e})}}valuesToTimeExtent(t){if(a(t))return null;const i=t.sort(((t,e)=>t-e)).map((t=>new Date(t))),n=i.length>0?i[0]:null,s=i.length>1?i[1]:null;switch(this.mode){case"time-window":return new e({start:n,end:s});case"instant":return new e({start:n,end:n});case"cumulative-from-start":return new e({start:null,end:n});case"cumulative-from-end":return new e({start:n,end:null});default:return e.allTime}}async _animate(){try{const t=this.view,e=u(this._animationController,(t=>t.signal));await Promise.all([d(this.playRate,null,e),l(t)&&g((()=>!1===t.updating),e)])}catch(t){return h(t)||O.error(t),void(this._animationController=null)}this._step({forward:!0,allowRestart:!1}),a(this._animationController)||this._animate()}_divideTimeExtentByCount(t,e=10){if(!t||!e)return[];const{start:i,end:n}=t;if(a(i)||a(n))return[];if(e>D)return this._divideTimeExtentByCount(t);const s=[],r=i.getTime(),o=n.getTime()-r;for(let l=0;l<=e;l++)s.push(new Date(r+l/e*o));return s}_divideTimeExtentByInterval(t,e,i=D){if(!t||!e)return[];const{start:n,end:s}=t;if(a(n)||a(s))return[];if((s.getTime()-n.getTime())/e.toMilliseconds()>i)return this._divideTimeExtentByCount(t);const r=[],{value:o,unit:l}=e;let m=n;for(;m.getTime()<=s.getTime();)r.push(new Date(m.getTime())),m=w(m,o,l);return r}_getDefaultTimeExtent(){const{effectiveStops:t,mode:i}=this;if(a(t)||!i)return null;switch(i){case"time-window":return t.length>1?new e({start:t[0],end:t[1]}):null;case"cumulative-from-start":return t.length>0?new e({start:null,end:t[0]}):null;case"cumulative-from-end":return t.length>0?new e({start:t[0],end:null}):null;case"instant":return t.length>0?new e({start:t[0],end:t[0]}):null;default:return null}}_registerWidget(t){if(l(t)){t.persistableViewModels.includes(this)||t.persistableViewModels.add(this)}}_startAnimation(){this._stopAnimation(),this._animationController=new AbortController,this._step({forward:!0,allowRestart:!0}),this._animate()}_step(t){const{forward:e,allowRestart:i}=t,{effectiveStops:n}=this;if(a(this.timeExtentValues)||a(n))return;const s=n.map((t=>t.getTime())),r=this.timeExtentValues.map((t=>{const e=s.indexOf(t);if(-1!==e)return e;const i=s.reduce(((e,i)=>Math.abs(i-t)<Math.abs(e-t)?i:e));return s.indexOf(i)})),o=r.map((t=>t+(e?1:-1))),l=o.some((t=>t<0||t>s.length-1)),{loop:m,state:u}=this;if(l)if(m||i){const t=Math.min(...r),i=Math.max(...r),n=(e?r.map((e=>e-t)):r.map((t=>t+(s.length-1-i)))).map((t=>s[t]));this.timeExtent=this.valuesToTimeExtent(n)}else"playing"===u&&this.stop();else{const t=o.map((t=>s[t]));this.timeExtent=this.valuesToTimeExtent(t)}}_stopAnimation(){l(this._animationController)&&(this._animationController.abort(),this._animationController=null)}_unregisterWidget(t){l(t)&&t.persistableViewModels.remove(this)}async _updateTimeSliderFromMap(t,e){const i=await A.getPropertiesFromWebMap(t,e);if(!a(i))for(const n in i)this._isOverridden(n)||(this[n]=i[n])}};t([_()],B.prototype,"_animationController",void 0),t([_()],B.prototype,"_loadingWebDocument",void 0),t([_({type:n})],B.prototype,"actions",void 0),t([_({readOnly:!0})],B.prototype,"effectiveStops",null),t([_({type:e,value:null})],B.prototype,"fullTimeExtent",null),t([_({nonNullable:!0,value:!1})],B.prototype,"loop",null),t([_({nonNullable:!0,value:"time-window"})],B.prototype,"mode",null),t([_({nonNullable:!0,value:1e3})],B.prototype,"playRate",null),t([_({readOnly:!0})],B.prototype,"state",null),t([_({cast:t=>a(t)?null:(I(t)&&(t.interval=x(i,t.interval)),(I(t)||M(t))&&(t.timeExtent=x(e,t.timeExtent)),t),value:{count:10}})],B.prototype,"stops",null),t([_({type:e,value:null})],B.prototype,"timeExtent",null),t([_({readOnly:!0})],B.prototype,"timeExtentValues",null),t([_()],B.prototype,"view",void 0),t([_()],B.prototype,"next",null),t([_()],B.prototype,"play",null),t([_()],B.prototype,"previous",null),t([_()],B.prototype,"stop",null),t([_()],B.prototype,"updateWebDocument",null),B=A=t([y(k)],B);const P=B;export{P as default};