aboutsummaryrefslogtreecommitdiff
path: root/web/frontend/climb-profile.ts
diff options
context:
space:
mode:
Diffstat (limited to 'web/frontend/climb-profile.ts')
-rw-r--r--web/frontend/climb-profile.ts49
1 files changed, 17 insertions, 32 deletions
diff --git a/web/frontend/climb-profile.ts b/web/frontend/climb-profile.ts
index 6051ec1..d06d291 100644
--- a/web/frontend/climb-profile.ts
+++ b/web/frontend/climb-profile.ts
@@ -1,32 +1,21 @@
-import { drawOfficialSections, officialProfilePlot, resolveOfficialProfileColors } from "./official-climb-profile.js";
-import { officialProfileSections } from "./official-climb-profile-logic.js";
-import type { OfficialProfileSection } from "./official-climb-profile-logic.js";
-import type { ProfilePoint } from "./types.js";
+import {
+ drawOfficialSections,
+ officialProfilePlot,
+ officialProfileSections,
+ resolveOfficialProfileColors,
+} from "./official-climb-profile.js";
+import type { OfficialProfileSection, ProfileSectionPayload } from "./types.js";
interface ClimbProfilePayload {
- distanceKm: number;
- elevations: number[];
+ sections: ProfileSectionPayload[];
}
interface ClimbProfileState {
canvas: HTMLCanvasElement;
- payload: ClimbProfilePayload;
sections: OfficialProfileSection[];
hoverOutput: HTMLOutputElement;
}
-const climbProfilePoints = (payload: ClimbProfilePayload): ProfilePoint[] =>
- payload.elevations.map((elevationM, index) => ({
- distanceKm: (payload.distanceKm * index) / (payload.elevations.length - 1),
- elevationM,
- }));
-
-const climbProfileSections = (payload: ClimbProfilePayload): OfficialProfileSection[] => {
- const points = climbProfilePoints(payload);
- if (points.length < 2) return [];
- return officialProfileSections(points, 0, points.length - 1);
-};
-
const elevationAtDistance = (sections: OfficialProfileSection[], distanceKm: number): number | null => {
for (const section of sections) {
if (distanceKm >= section.startDistanceKm && distanceKm <= section.endDistanceKm) {
@@ -64,15 +53,13 @@ const drawHoverMarker = (state: ClimbProfileState, distanceKm: number): void =>
state.hoverOutput.textContent = `${distanceKm.toFixed(2)} km ยท ${Math.round(elevation)} m`;
};
-const clearHover = (state: ClimbProfileState): void => {
- drawClimbProfile(state.canvas, state.payload, state.sections);
- state.hoverOutput.textContent = "";
+const drawClimbProfile = (state: ClimbProfileState): void => {
+ drawOfficialSections(state.canvas, state.sections, resolveOfficialProfileColors());
};
-const drawClimbProfile = (canvas: HTMLCanvasElement, payload: ClimbProfilePayload, sections?: OfficialProfileSection[]): void => {
- const profileSections = sections ?? climbProfileSections(payload);
- if (profileSections.length === 0) return;
- drawOfficialSections(canvas, profileSections, resolveOfficialProfileColors());
+const clearHover = (state: ClimbProfileState): void => {
+ drawClimbProfile(state);
+ state.hoverOutput.textContent = "";
};
const bindHover = (state: ClimbProfileState): void => {
@@ -85,7 +72,7 @@ const bindHover = (state: ClimbProfileState): void => {
return;
}
const distanceKm = plot.minDistanceKm + ((x - plot.left) / (plot.right - plot.left)) * plot.distanceSpan;
- drawClimbProfile(state.canvas, state.payload, state.sections);
+ drawClimbProfile(state);
drawHoverMarker(state, distanceKm);
});
state.canvas.addEventListener("pointerleave", () => clearHover(state));
@@ -97,13 +84,11 @@ const init = (): void => {
const canvas = document.querySelector<HTMLCanvasElement>("[data-climb-profile]");
if (!payloadElement || !canvas) return;
const payload = JSON.parse(payloadElement.textContent ?? "null") as ClimbProfilePayload | null;
- if (!payload || payload.elevations.length < 2) return;
- const sections = climbProfileSections(payload);
- if (sections.length === 0) return;
+ if (!payload || payload.sections.length === 0) return;
const hoverOutput = document.querySelector<HTMLOutputElement>("[data-climb-profile-hover]");
if (!hoverOutput) return;
- const state: ClimbProfileState = { canvas, payload, sections, hoverOutput };
- drawClimbProfile(canvas, payload, sections);
+ const state: ClimbProfileState = { canvas, sections: officialProfileSections(payload.sections), hoverOutput };
+ drawClimbProfile(state);
bindHover(state);
};