Skip to content

Commit

Permalink
feat: translate slider ticks component from vue to lit
Browse files Browse the repository at this point in the history
  • Loading branch information
spectrachrome committed Aug 8, 2023
1 parent 4e03c0e commit 318e99a
Showing 1 changed file with 151 additions and 0 deletions.
151 changes: 151 additions & 0 deletions elements/timecontrol/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import "toolcool-range-slider";
import { style } from "./style";
import { styleEOX } from "./style.eox";
import { UrlFunction } from "ol/Tile";
import { DateTime } from 'luxon';

@customElement("eox-timecontrol")
export class EOxDrawTools extends LitElement {
Expand Down Expand Up @@ -232,3 +233,153 @@ export class EOxDrawTools extends LitElement {
`;
}
}

@customElement("eox-sliderticks")
export class SliderTicks extends LitElement {

@property({ type: Number }) width: number;
@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.length;
}

get yearMarks(): { label: number, position: number }[] {
const yearIndices: { label: number, position: number }[] = [];
let lastDecade: number = null;
let lastYear: number = null;

// Calculate first and last dates as fractions of a year
const firstTime = DateTime.fromISO(this.times[0]);
const firstYear = firstTime.year + (firstTime.ordinal / 365);
const lastTime = DateTime.fromISO(this.times[this.times.length - 1]);
const lastTimeYear = lastTime.year + (lastTime.ordinal / 365);

// Calculate the total range in fractions of a year
const totalYears = lastTimeYear - firstYear;

// If the total range of years crosses a certain threshold (e.g., 10 years),
// we will show marks for every decade.
const showDecades = totalYears > 10;

this.times.forEach((time: string) => {
const currentTime = DateTime.fromISO(time);
const currentTimeYear = currentTime.year + (currentTime.ordinal / 365);

if (showDecades) {
// If we are in a new decade, place a mark
const currentDecade = Math.floor(currentTimeYear / 10) * 10;
if (currentDecade !== lastDecade) {
yearIndices.push({
label: currentDecade,
position: ((currentTimeYear - firstYear) / totalYears) * this.width,
});
lastDecade = currentDecade;
}
} else {
// If we are in a new year, place a mark
const currentYear = Math.floor(currentTimeYear);
if (currentYear !== lastYear) {
yearIndices.push({
label: currentYear,
position: ((currentTimeYear - firstYear) / totalYears) * this.width,
});
lastYear = currentYear;
}
}
});

// Create a new array with removed overlapping labels
const nonOverlappingYearIndices = yearIndices.filter((yearMark, index, array) => {
// If it's the last item in the array, it can't overlap with a next item
if (index === array.length - 1) return true;

// Get the next item in the array
const nextYearMark = array[index + 1];

// Determine the distance between the current and next labels
const distance = nextYearMark.position - yearMark.position;

// Only keep this label if it's more than a certain distance from the next one
const minDistance = 50; // set this to the minimum acceptable distance
return distance > minDistance;
});

return nonOverlappingYearIndices;
}

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`
<div class="fill-width">
<svg
style="width: ${this.width}px; height: 30px;"
viewBox="-1 0 ${this.width + 2} ${this.height}"
>
${this.lines.map((line, index) => html`
<line
key=${index}
x1=${line}
y1="0"
x2=${line}
y2=${this.isYearLine(line) ? 12 : 6}
stroke=${this.isYearLine(line) ? '#333' : '#7596A2'}
stroke-width=${this.isYearLine(line) ? 1 : 1}
></line>
`)}
${this.yearMarks.map((year, index) => html`
<text
key=${`y${index}`}
x=${year.position - 1}
y=${this.height - 1}
fill="#555"
font-size="13"
font-weight="500"
>
${year.label}
</text>
`)}
</svg>
</div>
`;
}
}

0 comments on commit 318e99a

Please sign in to comment.