@arcgis/map-components
Version:
ArcGIS Map Components
505 lines (504 loc) • 22.1 kB
TypeScript
/// <reference path="../../index.d.ts" />
import type WebMap from "@arcgis/core/WebMap.js";
import type Collection from "@arcgis/core/core/Collection.js";
import type TimeExtent from "@arcgis/core/time/TimeExtent.js";
import type { PublicLitElement as LitElement } from "@arcgis/lumina";
import type { ArcgisReferenceElement, IconName } from "../types.js";
import type { TimeSliderViewModelTriggerActionEvent } from "@arcgis/core/widgets/TimeSlider/TimeSliderViewModel.js";
import type { TimeSliderSettings, Action, TimeSliderMode, TimeSliderState, Stops } from "@arcgis/core/widgets/TimeSlider/types.js";
import type { MapViewOrSceneView } from "@arcgis/core/views/MapViewOrSceneView.js";
import type { Icon } from "@esri/calcite-components/components/calcite-icon";
import type { DateLabelFormatter, TimeSliderLayout } from "@arcgis/core/widgets/TimeSlider.js";
import type { TickConfig } from "@arcgis/core/widgets/Slider/types.js";
/**
* The Time Slider component simplifies visualization of temporal data in your application.
*
* @since 4.28
*/
export abstract class ArcgisTimeSlider extends LitElement {
/**
* Defines actions that will appear in a menu when the user clicks the ellipsis button
*  in the component. The
* ellipsis button will not display if this property is `null` or if the collection is empty.
* Each [Action](https://developers.arcgis.com/javascript/latest/references/core/widgets/TimeSlider/types/#Action) is defined with a unique id, a title,
* and an icon.
*
* The [@trigger-action](https://developers.arcgis.com/javascript/latest/references/core/widgets/TimeSlider/#event-trigger-action) event fires each time an action in the menu is clicked. This event
* can be used to execute custom code such as setting the [timeExtent](https://developers.arcgis.com/javascript/latest/references/core/widgets/TimeSlider/#timeExtent) to a specific date or copying the
* timeExtent to the browser's clipboard.
*
* [](https://developers.arcgis.com/javascript/latest/sample-code/sandbox/?sample=widgets-timeslider-offset)
*
* @since 4.21
* @see [Sample - TimeSlider with offset](https://developers.arcgis.com/javascript/latest/sample-code/widgets-timeslider-offset/)
* @example
* // Create a TimeSlider with two actions to snap the thumb to
* // two specific time extents.
* const timeSlider = new TimeSlider({
* container: "timeSliderDiv",
* fullTimeExtent: {
* start: new Date(2011, 0, 1),
* end: new Date(2012, 0, 1)
* },
* mode: "instant",
* actions: [
* {
* id: "quake",
* icon: "exclamation-mark-triangle",
* title: "Jump to Earthquake"
* },
* {
* id: "quake-plus-one-month",
* icon: "organization",
* title: "One month later"
* }
* ]
* });
*
* // listen to timeSlider's trigger-action event
* // check what action user clicked on and respond accordingly.
* timeSlider.on("trigger-action", (event) => {
* const quake = new Date(Date.UTC(2011, 3, 11, 8, 16, 12));
* const oneMonthLater = new Date(quake.getTime()).setMonth(quake.getMonth() + 1);
* switch(event.action.id) {
* case "quake":
* timeSlider.timeExtent = {
* start: quake,
* end: quake
* };
* break;
* case "quake-plus-one-month":
* timeSlider.timeExtent = {
* start: oneMonthLater,
* end: oneMonthLater
* };
* break;
* }
* });
*/
accessor actions: Collection<Action>;
/**
* If true, the component will not be destroyed automatically when it is
* disconnected from the document. This is useful when you want to move the
* component to a different place on the page, or temporarily hide it. If this
* is set, make sure to call the [destroy()](https://developers.arcgis.com/javascript/latest/references/map-components/components/arcgis-time-slider/#destroy) method when you are done to
* prevent memory leaks.
*
* @default false
*/
accessor autoDestroyDisabled: boolean;
/**
* When true, the component is visually withdrawn and cannot receive user interaction.
*
* @default false
* @example
* // Create a timeslider widget that is initially disabled.
* const timeSlider = new TimeSlider({
* container: "timeSliderDiv",
* fullTimeExtent: {
* start: new Date(2000, 5, 1),
* end: new Date(2010, 0, 1)
* },
* disabled: true
* });
*/
accessor disabled: boolean;
/**
* Lists the specific locations on the timeline where handle(s) will snap to when manipulated.
*
* @example
* timeSlider.effectiveStops.forEach((stop) => {
* console.log(stop);
* });
*/
get effectiveStops(): Array<Date> | null | undefined;
/**
* The temporal extent of the entire slider.
* It defines the entire time period within which you can visualize
* your time aware data using the time slider component.
*
* @example
* // Create a new TimeSlider with set dates
* const timeSlider = new TimeSlider({
* container: "timeSliderDiv",
* view: view
* });
*
* // wait for the time-aware layer to load
* layer.when(() => {
* // set up time slider properties based on layer timeInfo
* timeSlider.fullTimeExtent = layer.timeInfo.fullTimeExtent;
* timeSlider.stops = {
* interval: layer.timeInfo.interval
* };
* });
*/
accessor fullTimeExtent: TimeExtent | null | undefined;
/**
* Icon which represents the component.
* Typically used when the component is controlled by another component (e.g. by the Expand component).
*
* @default "clock"
* @since 4.27
* @see [Calcite Icons](https://developers.arcgis.com/calcite-design-system/icons/)
*/
get icon(): Icon["icon"];
set icon(value: IconName);
/**
* The component's default label.
*
* @since 4.11
*/
accessor label: string;
accessor labelFormatFunction: DateLabelFormatter | null | undefined;
/**
* Determines the layout used by the TimeSlider component.
*
* Possible values are listed below:
* | Value | Description |
* | --- | --- |
* | auto | Automatically uses the "compact" layout when the component width is less than 858 pixels. Otherwise the "wide" layout it used. |
* | compact | Component elements are oriented vertically. This layout is better suited to narrower widths. |
* | wide | Component elements are oriented laterally. This thinner design is better suited to wide applications. |
*
* @default "auto"
* @since 4.16
* @example timeSlider.layout = "compact";
*/
accessor layout: TimeSliderLayout;
/**
* When `true`, the time slider will play its animation in a loop.
*
* @default false
* @example
* // Start a time slider animation that advances every second
* // and restarts when it reaches the end.
* timeSlider.set({
* loop: true,
* playRate: 1000
* });
* timeSlider.play();
*/
accessor loop: boolean;
/**
* The time slider mode. This property is used for defining if the temporal data will be displayed
* cumulatively up to a point in time, a single instant in time, or within a time range. See
* the following table for possible values.
*
* Possible Values | Description | Example |
* ----------------------|-------------- | ------- |
* instant | The slider will show temporal data that falls on a single instance in time. Set the [timeExtent](https://developers.arcgis.com/javascript/latest/references/core/widgets/TimeSlider/#timeExtent) property's `start` and `end` dates to same date: `{start: sameDate, end: sameDate}` | <img alt="mode-instance" src="https://developers.arcgis.com/javascript/latest/assets/references/core/widgets/timeslider/mode-instance.avif"> |
* time-window | The slider will show temporal data that falls within a given time range. This is the default. Set [timeExtent](https://developers.arcgis.com/javascript/latest/references/core/widgets/TimeSlider/#timeExtent) property's `start` and `date` properties to desired dates. | <img alt="mode-instance" src="https://developers.arcgis.com/javascript/latest/assets/references/core/widgets/timeslider/mode-time-window.avif"> |
* cumulative-from-start | Similar to `time-window` with the start time is always pinned to the start of the slider. Set the [timeExtent](https://developers.arcgis.com/javascript/latest/references/core/widgets/TimeSlider/#timeExtent) property's `start` date to `null` and set `end` date to a desired date: `{start: null, end: date}` | <img alt="mode-instance" src="https://developers.arcgis.com/javascript/latest/assets/references/core/widgets/timeslider/mode-from-start.avif"> |
* cumulative-from-end | Also, similar to the `time-window` with the end time pinned to the end of the slider. Set the [timeExtent](https://developers.arcgis.com/javascript/latest/references/core/widgets/TimeSlider/#timeExtent) property's `start` date to a desired date and set `end` date to `null`: `{start: date, end: null}` | <img alt="mode-instance" src="https://developers.arcgis.com/javascript/latest/assets/references/core/widgets/timeslider/mode-from-end.avif"> |
*
* @default "time-window"
* @see [timeExtent](https://developers.arcgis.com/javascript/latest/references/core/widgets/TimeSlider/#timeExtent)
* @example
* // Create a single thumbed time slider that includes all historic content.
* const timeSlider = new TimeSlider({
* container: "timeSliderDiv",
* view: view,
* mode: "cumulative-from-start",
* fullTimeExtent: {
* start: new Date(2000, 0, 1),
* end: new Date(2010, 0, 1)
* },
* timeExtent: {
* start: null,
* end: new Date(2001, 0, 1) //end date
* }
* });
*/
accessor mode: TimeSliderMode;
/**
* The time (in milliseconds) between animation steps.
*
* > [!WARNING]
* >
* > When a [View](https://developers.arcgis.com/javascript/latest/references/core/views/View/) is associated with a TimeSlider and the TimeSlider is playing, the playback will pause before advancing if the View is still updating.
* > For example, if the `playRate` is set to 1,000 (one second) and the `View` takes 1.5 seconds to render then the TimeSlider thumb(s) will advance every
* > 1.5 seconds rather than every second.
*
* @default 1000
* @example
* // Start a time slider animation that advances
* // ten times a second and stops when it reaches the end.
* timeSlider.set({
* loop: false,
* playRate: 100
* });
* timeSlider.play();
*/
accessor playRate: number;
/**
* By assigning the `id` attribute of the Map or Scene component to this property, you can position a child component anywhere in the DOM while still maintaining a connection to the Map or Scene.
*
* @see [Associate components with a Map or Scene component](https://developers.arcgis.com/javascript/latest/programming-patterns/#associate-components-with-a-map-or-scene-component)
*/
accessor referenceElement: ArcgisReferenceElement | string | undefined;
/**
* The current state of the component.
*
* @default "disabled"
* @example
* // Display the current state of the view model.
* switch (timeSlider.viewModel.state) {
* case "disabled":
* console.log("The view is not ready or some property are not set.");
* break;
* case "ready":
* console.log("The time slider is ready for use.");
* break;
* case "playing":
* console.log("The time slider is currently animating.");
* break;
* }
*/
get state(): TimeSliderState;
/**
* Defines specific locations on the time slider where thumbs will snap to when manipulated.
* If unspecified, ten evenly spaced stops will be added.
*
* For continuous sliding, set `stops` to `null`:
* ```js
* timeSlider.stops = null;
* ```
*
* To define regularly spaced stops, parse an object with `interval` and `timeExtent` properties
* with types [TimeInterval](https://developers.arcgis.com/javascript/latest/references/core/time/TimeInterval/) and [TimeExtent](https://developers.arcgis.com/javascript/latest/references/core/time/TimeExtent/) respectively.
* The [timeExtent](https://developers.arcgis.com/javascript/latest/references/core/widgets/TimeSlider/#timeExtent) property is optional and used to confine stops to a certain date range.
* This property is useful to commence stops on a specific day of the week or month.
* If a stop definition by interval results in excess of 10,000 stops, then the view model
* will default to ten evenly spaced stops.
*
* ```js
* // Add yearly intervals starting from the beginning of the TimeSlider.
* timeSlider.stops = {
* interval: {
* value: 1,
* unit: "years"
* }
* };
* ```
* Rather than setting the stops as time intervals, the TimeSlider can be divided into evenly spaced
* stops using the `count` property. Similar to the previous method, divisions can be confined to a specific date range
* using the optional timeExtent property.
* ```js
* // Add stops at 15 evenly spaced intervals.
* timeSlider.stops = {
* count: 15
* };
* ```
* For irregularly spaced stops, simply assign an array of dates as demonstrated below.
* ```js
* // Add nine irregular stops.
* timeSlider.stops = {
* dates: [
* new Date(2000, 0, 1), new Date(2001, 3, 8), new Date(2002, 0, 10),
* new Date(2003, 12, 8), new Date(2004, 2, 19), new Date(2005, 7, 5),
* new Date(2006, 9, 11), new Date(2007, 11, 21), new Date(2008, 1, 10)
* ]
* };
* ```
* Lastly, to constrain or offset division by count or interval use the optional timeExtent property.
* ```js
* // Add yearly stops from Christmas 2019 to Christmas 2029 only
* timeSlider.stops = {
* interval: {
* value: 1,
* unit: "years"
* },
* timeExtent: {
* start: new Date(2019, 11, 25),
* end: new Date(2029, 11, 25)
* }
* };
*
* // Likewise, add stops that represent quarters of 2019 only.
* timeSlider.stops = {
* count: 4,
* timeExtent: {
* start: new Date(2019, 0, 1),
* end: new Date(2020, 0, 1)
* }
* };
* ```
*
* @default { count : 10 }
*/
accessor stops: Stops | null | undefined;
/**
* When set, overrides the default TimeSlider ticks labelling system.
* Please refer to [TickConfig](https://developers.arcgis.com/javascript/latest/references/core/widgets/Slider/types/#TickConfig) for detailed documentation
* on how to configure tick placement, style, and behavior.
*
* @since 4.16
* @example
* // By default in "en-US" the TimeSlider will display ticks with "2010, 2011, 2012, etc".
* // Overwrite TimeSlider tick configuration so that labels display "'10, '12, '14, etc" in red.
* const timeSlider = new TimeSlider({
* container: "timeSliderDiv",
* fullTimeExtent: {
* start: new Date(2010, 0, 1),
* end: new Date(2020, 0, 1)
* },
* tickConfigs: [{
* mode: "position",
* values: [
* new Date(2010, 0, 1), new Date(2012, 0, 1), new Date(2014, 0, 1),
* new Date(2016, 0, 1), new Date(2018, 0, 1), new Date(2020, 0, 1)
* ].map((date) => date.getTime()),
* labelsVisible: true,
* labelFormatFunction: (value) => {
* const date = new Date(value);
* return `'${date.getUTCFullYear() - 2000}`;
* },
* tickCreatedFunction: (value, tickElement, labelElement) => {
* tickElement.classList.add("custom-ticks");
* labelElement.classList.add("custom-labels");
* }
* }]
* };
* @example
* // this CSS goes with the snippet above.
* #timeSlider .custom-ticks {
* background-color: red;
* width: 1px;
* height: 8px;
* }
* #timeSlider .custom-labels {
* font-family: Georgia, 'Times New Roman', Times, serif;
* font-size: 15px;
* color: red;
* }
*/
accessor tickConfigs: Array<TickConfig> | null | undefined;
/**
* The current time extent of the time slider. This property can be watched for
* updates and used to update the time extent property in queries and/or the layer filters and effects.
* The following table shows the `timeExtent` values returned for each [mode](https://developers.arcgis.com/javascript/latest/references/core/widgets/TimeSlider/#mode).
*
* | Mode | The timeExtent value |
* | ------- | -------------------- |
* | `time-window` | `{start: startDate, end: endDate}` |
* | `instant` | `{start: sameDate, end: sameDate}` |
* | `cumulative-from-start` | `{start: null, end: endDate}` |
* | `cumulative-from-end` | `{start: startDate, end: null}` |
*
* @example
* // Display the time extent to the console whenever it changes.
* const timeSlider = new TimeSlider({
* container: "timeSliderDiv",
* mode: "time-window",
* fullTimeExtent: {
* start: new Date(2019, 2, 3),
* end: new Date(2019, 2, 5)
* },
* timeExtent: {
* start: new Date(2019, 2, 1),
* end: new Date(2019, 2, 28)
* }
* });
*
* reactiveUtils.watch(
* () => timeSlider.timeExtent,
* (timeExtent) => {
* console.log("Time extent now starts at", timeExtent.start, "and finishes at:", timeExtent.end);
* }
* );
*/
accessor timeExtent: TimeExtent | null | undefined;
/**
* Shows/hides time in the display.
*
* @default false
* @example
* // For time sliders with a small time extent it may be useful to display times as shown below.
* const timeSlider = new TimeSlider({
* container: "timeSliderDiv",
* mode: "time-window",
* timeVisible: true,
* fullTimeExtent: {
* start: new Date(2019, 2, 3),
* end: new Date(2019, 2, 5)
* },
* timeExtent: {
* start: new Date(2019, 2, 1),
* end: new Date(2019, 2, 28)
* }
* });
*/
accessor timeVisible: boolean;
/**
* Dates and times displayed in the component will be displayed in this time zone. By default this time zone is
* inherited from [MapView#timeZone](https://developers.arcgis.com/javascript/latest/references/core/views/MapView/#timeZone). When a MapView is not associated with the component
* then the property will fallback to the `system` time zone.
*
* **Possible Values**
*
* Value | Description |
* ----- | ----------- |
* system | Dates and times will be displayed in the timezone of the device or browser.
* unknown | Dates and time are not adjusted for any timezone. [TimeSlider](https://developers.arcgis.com/javascript/latest/references/core/widgets/TimeSlider/) will be disabled.
* Specified IANA timezone | Dates and times will be displayed in the specified IANA time zone. See [wikipedia - List of tz database time zones](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones).
*
* @since 4.28
*/
accessor timeZone: string;
/**
* The view associated with the component.
* > **Note:** The recommended approach is to fully migrate applications to use map and scene components and avoid using MapView and SceneView directly. However, if you are migrating a large application from widgets to components, you might prefer a more gradual transition. To support this use case, the SDK includes this `view` property which connects a component to a MapView or SceneView. Ultimately, once migration is complete, the arcgis-time-slider component will be associated with a map or scene component rather than using the `view` property.
*
* @example
* ```js
* // Create and then add a TimeSlider component and then listen to changes in the View's time extent.
* const timeSlider = new TimeSlider({
* container: "timeSliderDiv",
* view: view,
* mode: "instant",
* fullTimeExtent: {
* start: new Date(2000, 0, 1),
* end: new Date(2010, 0, 1)
* },
* timeExtent: {
* start: new Date(2000, 0, 1),
* end: new Date(2000, 0, 1)
* }
* });
* view.ui.add(timeSlider, "top-left");
*
* reactiveUtils.watch(
* () => view.timeExtent,
* (timeExtent) => {
* console.log("New view time is: ", timeExtent.start);
* }
* );
* ```
*/
accessor view: MapViewOrSceneView | null | undefined;
/** @param settings */
applyTimeSliderSettings(settings: TimeSliderSettings): Promise<void>;
/** Permanently destroy the component. */
destroy(): Promise<void>;
next(): Promise<void>;
play(): Promise<void>;
previous(): Promise<void>;
stop(): Promise<void>;
/** @param webmap */
updateWebDocument(webmap: WebMap): Promise<void>;
"@setterTypes": {
icon?: IconName;
};
/** Emitted when the value of a property is changed. Use this to listen to changes to properties. */
readonly arcgisPropertyChange: import("@arcgis/lumina").TargetedEvent<this, { name: "effectiveStops" | "fullTimeExtent" | "timeExtent" | "state"; }>;
/** Emitted when the component associated with a map or scene view is ready to be interacted with. */
readonly arcgisReady: import("@arcgis/lumina").TargetedEvent<this, void>;
/** Emitted when an action is triggered on the component. */
readonly arcgisTriggerAction: import("@arcgis/lumina").TargetedEvent<this, TimeSliderViewModelTriggerActionEvent>;
readonly "@eventTypes": {
arcgisPropertyChange: ArcgisTimeSlider["arcgisPropertyChange"]["detail"];
arcgisReady: ArcgisTimeSlider["arcgisReady"]["detail"];
arcgisTriggerAction: ArcgisTimeSlider["arcgisTriggerAction"]["detail"];
};
}