UNPKG

@arcgis/map-components

Version:
505 lines (504 loc) • 22.1 kB
/// <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 * ![timeSlider-actions-menu](https://developers.arcgis.com/javascript/latest/assets/references/core/widgets/timeslider/ellipsis.avif) 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. * * [![widgets-timeSlider-actions](https://developers.arcgis.com/javascript/latest/assets/references/core/widgets/timeslider/widgets-timeslider-actions.avif)](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"]; }; }