From d6707b7bb0ff3f9466a6da5dca46ea0c10910410 Mon Sep 17 00:00:00 2001 From: Guntis Smaukstelis Date: Sat, 6 Jan 2024 23:48:23 +0200 Subject: [PATCH] Select city on canvas --- web/src/cities/Cities.tsx | 7 +++-- web/src/cities/SelectField.tsx | 22 ---------------- web/src/components/SelectField.tsx | 19 ++++++++++++++ web/src/station/Result.tsx | 9 +++++++ web/src/station/Station.tsx | 41 ++++++++++++++++++++++++------ web/src/station/coordToCity.ts | 16 ++++++++++++ 6 files changed, 82 insertions(+), 32 deletions(-) delete mode 100644 web/src/cities/SelectField.tsx create mode 100644 web/src/components/SelectField.tsx create mode 100644 web/src/station/Result.tsx create mode 100644 web/src/station/coordToCity.ts diff --git a/web/src/cities/Cities.tsx b/web/src/cities/Cities.tsx index b0adda3..09d3eec 100644 --- a/web/src/cities/Cities.tsx +++ b/web/src/cities/Cities.tsx @@ -4,8 +4,8 @@ import { QueryResult } from "./result/QueryResult"; import { SelectCity } from "../components/SelectCity"; import { SelectTimeRange } from "../components/SelectTimeRange"; +import { SelectField } from "../components/SelectField"; -import { SelectField } from "./SelectField"; import { SelectGranularity } from "./SelectGranularity"; import { SelectKey } from "./SelectKey"; @@ -36,7 +36,10 @@ export function Cities() { />
- +
+

Select field

+ +
diff --git a/web/src/cities/SelectField.tsx b/web/src/cities/SelectField.tsx deleted file mode 100644 index d5d0254..0000000 --- a/web/src/cities/SelectField.tsx +++ /dev/null @@ -1,22 +0,0 @@ -import { Accessor, Component, Setter } from "solid-js"; - -import { weatherField } from "../consts"; - -export const SelectField: Component<{ - getField: Accessor, - setField: Setter, -}> = (props) => { - return ( -
-

Select field

- -
- ); -} \ No newline at end of file diff --git a/web/src/components/SelectField.tsx b/web/src/components/SelectField.tsx new file mode 100644 index 0000000..c019105 --- /dev/null +++ b/web/src/components/SelectField.tsx @@ -0,0 +1,19 @@ +import { Accessor, Component, Setter } from "solid-js"; + +import { weatherField } from "../consts"; + +export const SelectField: Component<{ + getField: Accessor, + setField: Setter, +}> = (props) => { + return ( + + ); +} \ No newline at end of file diff --git a/web/src/station/Result.tsx b/web/src/station/Result.tsx new file mode 100644 index 0000000..1c6a350 --- /dev/null +++ b/web/src/station/Result.tsx @@ -0,0 +1,9 @@ +import { Accessor, Component } from "solid-js"; + +export const Result: Component<{ getCity: Accessor}> = ({ getCity }) => { + return ( +
+ { getCity() } +
+ ); +} \ No newline at end of file diff --git a/web/src/station/Station.tsx b/web/src/station/Station.tsx index d24b207..d3a959c 100644 --- a/web/src/station/Station.tsx +++ b/web/src/station/Station.tsx @@ -1,21 +1,42 @@ import { Component, createEffect, createSignal, onMount } from "solid-js"; +import moment from "moment"; -import mapUrl from "../assets/map_1000x570.webp"; - -import "../css/station.css" import { cityCoords } from "./cityCoords"; import { SelectCity } from "../components/SelectCity"; +import mapUrl from "../assets/map_1000x570.webp"; +import "../css/station.css" +import { SelectField } from "../components/SelectField"; +import { coordToCity } from "./coordToCity"; +import { Result } from "./Result"; + export const Station: Component<{}> = () => { const [getCanvas, setCanvas] = createSignal(); const [getImg, setImg] = createSignal(new Image()); const [getShowCities, setShowCities] = createSignal(false); - const [getCities, setCities] = createSignal>(new Set(["Rīga", "Rēzekne", "Liepāja"])); + const [getCities, setCities] = createSignal>(new Set(["Ainaži", "Rīga", "Rēzekne", "Liepāja", "Daugavpils", "Ventspils", "Madona"])); + const [getDate, setDate] = createSignal(moment()); + const [getField, setField] = createSignal("tempMax"); + const [getCity, setCity] = createSignal(undefined); let ctx: CanvasRenderingContext2D | undefined; onMount(() => { - ctx = getCanvas()!.getContext("2d")!; + const canvas = getCanvas()!; + canvas.addEventListener("click", event => { + const rect = canvas.getBoundingClientRect(); + const scaleX = canvas.width / rect.width; + const scaleY = canvas.height / rect.height; + + const x = Math.round((event.clientX - rect.left) * scaleX); + const y = Math.round((event.clientY - rect.top) * scaleY); + + const selectedCityCoords = Object.entries(cityCoords).filter(([city]) => getCities().has(city)); + const optionalCity = coordToCity(x, y, selectedCityCoords); + setCity(optionalCity); + }); + + ctx = canvas.getContext("2d")!; const img = new Image(); img.onload = () => setImg(img); @@ -41,6 +62,8 @@ export const Station: Component<{}> = () => { value="Select stations" onClick={() => setShowCities(!getShowCities())} /> + +
@@ -48,7 +71,7 @@ export const Station: Component<{}> = () => {
- 3rd +
@@ -60,7 +83,6 @@ function drawOnMap( imgArr: [HTMLImageElement], cities: Set, ): void { - console.log("Draw cities"); ctx.drawImage(imgArr[0], 0, 0); ctx.fillStyle = "red"; ctx.font = "18px serif"; @@ -69,9 +91,12 @@ function drawOnMap( if (!coord) return; ctx.beginPath(); - ctx.arc(coord.x, coord.y, 6, 0, 2 * Math.PI); + ctx.arc(coord.x, coord.y, 4, 0, 2 * Math.PI); const cityTextSize = ctx.measureText(city); ctx.fillText(city, coord.x - cityTextSize.width/2, coord.y - 6); ctx.fill(); + // const boxWidth = 60; + // const boxHeight = 30; + // ctx.strokeRect(coord.x-boxWidth/2, coord.y-boxHeight/2, boxWidth, boxHeight); }); } \ No newline at end of file diff --git a/web/src/station/coordToCity.ts b/web/src/station/coordToCity.ts new file mode 100644 index 0000000..776c40a --- /dev/null +++ b/web/src/station/coordToCity.ts @@ -0,0 +1,16 @@ +export function coordToCity( + x: number, + y: number, + cityCoords: [string, { x: number, y: number}][], + boxWidth = 60, + boxHeight = 30, +): string | undefined { + const optionalCity = cityCoords.find(([city, coord]) => + coord.x >= x-boxWidth/2 + && coord.x <= x+boxWidth/2 + && coord.y >= y-boxHeight/2 + && coord.y <= y+boxHeight/2 + ); + + return optionalCity && optionalCity[0]; +} \ No newline at end of file