Add highlighting of routes

master
Araozu 2024-09-04 11:17:13 -05:00
parent 28cbb1791b
commit 955510dae8
4 changed files with 79 additions and 17 deletions

View File

@ -2,21 +2,29 @@
{ {
"id": 1, "id": 1,
"name": "1", "name": "1",
"color": "#ea4fb2" "color": "#ea4fb2",
"hover_bg": "#ea4fb2",
"hover_on_bg": "white"
}, },
{ {
"id": 2, "id": 2,
"name": "2", "name": "2",
"color": "black" "color": "black",
"hover_bg": "black",
"hover_on_bg": "white"
}, },
{ {
"id": 3, "id": 3,
"name": "3", "name": "3",
"color": "#eab308" "color": "#eab308",
"hover_bg": "#eab308",
"hover_on_bg": "white"
}, },
{ {
"id": 4, "id": 4,
"name": "4", "name": "4",
"color": "#ff7300" "color": "#ff7300",
"hover_bg": "#ff7300",
"hover_on_bg": "white"
} }
] ]

View File

@ -7,6 +7,8 @@ export interface Line {
name: string name: string
/** Hex code */ /** Hex code */
color: string color: string
"hover_bg": string
"hover_on_bg": string
} }
export type Routes = Array<Route> export type Routes = Array<Route>

View File

@ -1,23 +1,29 @@
import { Map, map, polyline, tileLayer } from "leaflet"; import L from "leaflet";
import { createResource, For, onMount, Suspense } from "solid-js"; import { createResource, For, onMount, Suspense } from "solid-js";
import { LineSegmentsIcon } from "../icons/LineSegmentsIcon"; import { LineSegmentsIcon } from "../icons/LineSegmentsIcon";
import { Line, Lines, Route, Routes } from "../new_types"; import { Line, Lines, Route, Routes } from "../new_types";
let g_map: Map | null = null; const LINE_OPACITY = 0.8;
let global_map: L.Map | null = null;
// Stores the polyline rendered in the map.
// The first object stores Lines, the second stores routes
// Indexed by their names
const lines_store: Map<string, Map<string, L.Polyline>> = new Map();
export function Index2() { export function Index2() {
const container = <div class="h-[98vh] rounded-lg dark:opacity-60" />; const container = <div class="h-[98vh] rounded-lg dark:opacity-60" />;
onMount(() => { onMount(() => {
const l_map = map(container as HTMLElement) global_map = L.map(container as HTMLElement)
.setView([-16.40171, -71.53040], 13); .setView([-16.40171, -71.53040], 13);
g_map = l_map;
tileLayer("/tiles/{z}/{x}/{y}.jpg", { L.tileLayer("/tiles/{z}/{x}/{y}.jpg", {
maxZoom: 17, maxZoom: 17,
minZoom: 12, minZoom: 12,
attribution: "&copy; Map data <a href=\"http://www.openstreetmap.org/copyright\">OpenStreetMap</a>", attribution: "&copy; Map data <a href=\"http://www.openstreetmap.org/copyright\">OpenStreetMap</a>",
}).addTo(l_map); }).addTo(global_map);
}); });
return ( return (
@ -68,7 +74,9 @@ function LineEl(props: { line: Line }) {
}); });
return ( return (
<div style={`color: ${props.line.color}`}> <div
style={`color: ${props.line.color};--hover-bg: ${props.line.hover_bg};--hover-on-bg: ${props.line.hover_on_bg}`}
>
<LineSegmentsIcon class="px-1" fill={props.line.color} /> <LineSegmentsIcon class="px-1" fill={props.line.color} />
<span class="px-2"> <span class="px-2">
Linea {props.line.name} Linea {props.line.name}
@ -76,7 +84,11 @@ function LineEl(props: { line: Line }) {
<Suspense> <Suspense>
<For each={routesData() ?? []}> <For each={routesData() ?? []}>
{(r) => ( {(r) => (
<RouteEl route={r} color={props.line.color} /> <RouteEl
line_name={props.line.name}
route={r}
color={props.line.color}
/>
)} )}
</For> </For>
</Suspense> </Suspense>
@ -84,17 +96,57 @@ function LineEl(props: { line: Line }) {
); );
} }
function RouteEl(props: { route: Route, color: string }) { function RouteEl(props: { line_name: string, route: Route, color: string }) {
// Render the dots into the map // Render the dots into the map
const coords = props.route.points.map(([lat, lng]) => ({ lat, lng })); const coords = props.route.points.map(([lat, lng]) => ({ lat, lng }));
const line = polyline(coords, { color: props.color}); const line = L.polyline(coords, { color: props.color, opacity: LINE_OPACITY });
line.addTo(g_map!); line.addTo(global_map!);
// Store the route in the global map
// Create line map if neccesary
const line_name = props.line_name;
if (!lines_store.has(line_name)) {
lines_store.set(line_name, new Map());
}
// store
lines_store.get(line_name)!.set(props.route.name, line);
return ( return (
<div class="pl-10"> <div
class="pl-10 hover:bg-[var(--hover-bg)] hover:text-[var(--hover-on-bg)]"
onMouseEnter={() => highlight_route(props.line_name, props.route.name)}
onMouseLeave={() => unhighlight_route()}
>
Ruta {props.route.name} Ruta {props.route.name}
</div> </div>
); );
} }
function highlight_route(line_name: string, route_name: string) {
for (const [line_key, line_map] of lines_store) {
for (const [route_key, route_polilyne] of line_map) {
if (line_key === line_name && route_key === route_name) {
// Do nothing
} else {
// make transparent
route_polilyne.setStyle({
opacity: 0,
});
}
}
}
}
function unhighlight_route() {
for (const [, line_map] of lines_store) {
for (const [, route_polilyne] of line_map) {
// restore
route_polilyne.setStyle({
opacity: LINE_OPACITY,
});
}
}
}