diff --git a/elements/timecontrol/package.json b/elements/timecontrol/package.json index f7573982c..8124754c9 100644 --- a/elements/timecontrol/package.json +++ b/elements/timecontrol/package.json @@ -28,6 +28,7 @@ "lint:fix": "eslint --ext .js,.ts . --fix" }, "dependencies": { + "dayjs": "^1.11.9", "lit": "^3.0.2", "toolcool-range-slider": "^4.0.27" } diff --git a/elements/timecontrol/src/main.ts b/elements/timecontrol/src/main.ts index 6ce3891a8..854385f3f 100644 --- a/elements/timecontrol/src/main.ts +++ b/elements/timecontrol/src/main.ts @@ -1,4 +1,4 @@ -import { LitElement, html } from "lit"; +import { LitElement, html, svg } from "lit"; import { customElement, property, state } from "lit/decorators.js"; import { Map } from "ol"; import Layer from "ol/layer/Layer"; @@ -8,6 +8,13 @@ import { style } from "./style"; import { styleEOX } from "./style.eox"; import { UrlFunction } from "ol/Tile"; +import dayjs from "dayjs"; +import dayOfYear from "dayjs/plugin/dayOfYear"; +import isoWeek from "dayjs/plugin/isoWeek"; + +dayjs.extend(dayOfYear); +dayjs.extend(isoWeek); + @customElement("eox-timecontrol") export class EOxTimeControl extends LitElement { /** @@ -206,18 +213,25 @@ export class EOxTimeControl extends LitElement { ${this.slider ? html` - +
+ + + +
` : ""} @@ -229,3 +243,118 @@ export class EOxTimeControl extends LitElement { `; } } + +@customElement("eox-sliderticks") +export class SliderTicks extends LitElement { + @property({ type: Number }) width: number = 0; + @property({ type: Array }) times: string[] = []; + + @state() height = 6; + @state() svgWidth = 0; + + connectedCallback() { + super.connectedCallback(); + window.addEventListener("resize", this.handleResize.bind(this)); + } + + disconnectedCallback() { + window.removeEventListener("resize", this.handleResize.bind(this)); + super.disconnectedCallback(); + } + + firstUpdated() { + this.handleResize(); + } + + handleResize() { + this.svgWidth = this.shadowRoot.querySelector("svg").clientWidth; + this.height = this.shadowRoot.querySelector("svg").clientHeight; + } + + get lines() { + const num = this.numLines > this.width / 2 ? this.width / 2 : this.numLines; + + const spacing = this.width / (num - 1); + return Array.from({ length: this.numLines }, (_, i) => i * spacing); + } + + get numLines() { + return this.times ? this.times.length : 0; + } + + get yearMarks(): { label: number; position: number }[] { + const yearMarks: { label: number; position: number }[] = []; + let previousYear: number = null; + + this.lines.forEach((line, index) => { + const currentTime = dayjs(this.times[index]); + const currentYear = currentTime.year(); + + // If it's the first tick or if the year has changed, add a year mark + if (index === 0 || currentYear !== previousYear) { + yearMarks.push({ + label: currentYear, + position: line, // Assuming 'line' is the position of the tick + }); + } + + // Update previousYear for the next iteration + previousYear = currentYear; + }); + + // Filter out year marks that are too close together, in favor of the second one. + return yearMarks.filter((current, i) => { + const next = yearMarks[i + 1]; + + return !(next && next.position - current.position < 25); + }); + } + + isYearLine(line: number): boolean { + // Check if this line's position is approximately equal to any year mark position + const isYearMark = this.yearMarks.some( + (yearMark) => Math.abs(yearMark.position - line) < 1.0 + ); + + return isYearMark; + } + + render() { + return html` +
+ + ${this.lines.map( + (line, index) => svg` + + ` + )} + ${this.yearMarks.map( + (year, index) => svg` + + ${year.label} + + ` + )} + +
+ `; + } +} diff --git a/elements/timecontrol/timecontrol.stories.js b/elements/timecontrol/timecontrol.stories.js index 9f9806eb1..8c5719b27 100644 --- a/elements/timecontrol/timecontrol.stories.js +++ b/elements/timecontrol/timecontrol.stories.js @@ -6,8 +6,37 @@ export default { title: "Elements/eox-timecontrol", tags: ["autodocs"], component: "eox-timecontrol", - render: () => html` +}; + +export const Primary = { + args: { + for: "eox-map#primary", + layer: "AWS_NO2-VISUALISATION", + animationProperty: "TIME", + animationValues: [ + "2022-12-05", + "2022-12-12", + "2022-12-19", + "2022-12-26", + "2023-01-16", + "2023-01-23", + "2023-01-30", + "2023-02-06", + "2023-02-13", + "2023-02-27", + "2023-03-06", + "2023-03-13", + "2023-03-20", + "2023-03-27", + "2023-04-03", + "2023-04-10", + "2023-04-17", + "2023-04-24", + ], + }, + render: (args) => html` `, }; -export const Primary = { - args: {}, +export const Slider = { + args: { + ...Primary.args, + for: "eox-map#slider", + slider: true, + }, + render: (args) => html` + + + `, };