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`
-
- this._updateStep(
- this.animationValues.findIndex(
- (v) => v === evt.detail.value
- ) - this._newTimeIndex
- )}"
- >
+
+
+ this._updateStep(
+ this.animationValues.findIndex(
+ (v) => v === evt.detail.value
+ ) - this._newTimeIndex
+ )}"
+ >
+
+
+
`
: ""}
@@ -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`
+
+
+
+ `;
+ }
+}
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`
+
+
+ `,
};