Add delay and spinner for station map, common const and component for delay
This commit is contained in:
@@ -2,9 +2,10 @@ import moment from "moment";
|
|||||||
import { Accessor, Component, createResource, createSignal } from "solid-js";
|
import { Accessor, Component, createResource, createSignal } from "solid-js";
|
||||||
|
|
||||||
import "../../css/Result.css"
|
import "../../css/Result.css"
|
||||||
import { apiHost } from "../../consts";
|
import { FETCH_DELAY_MS, apiHost } from "../../consts";
|
||||||
import { isQueryResult } from "../helpers";
|
import { isQueryResult } from "../helpers";
|
||||||
import { Result } from "./Result";
|
import { Result } from "./Result";
|
||||||
|
import { LoadingSpinner } from "../../components/LoadingSpinner";
|
||||||
|
|
||||||
export const QueryResult: Component<{
|
export const QueryResult: Component<{
|
||||||
getCities: Accessor<Set<string>>,
|
getCities: Accessor<Set<string>>,
|
||||||
@@ -21,7 +22,7 @@ export const QueryResult: Component<{
|
|||||||
|
|
||||||
const fetchQuery = async (timestamp: number) => {
|
const fetchQuery = async (timestamp: number) => {
|
||||||
if (cities() === "") return new Error("ERROR: Select cities!");
|
if (cities() === "") return new Error("ERROR: Select cities!");
|
||||||
await new Promise(resolve => setTimeout(resolve, 500))
|
await new Promise(resolve => setTimeout(resolve, FETCH_DELAY_MS))
|
||||||
const response = await fetch(`${apiHost}/api/query/city/${cities()}/${queryStart()}-${queryEnd()}/${props.getGranularity()}/${props.getField()}/${props.getKey()}`);
|
const response = await fetch(`${apiHost}/api/query/city/${cities()}/${queryStart()}-${queryEnd()}/${props.getGranularity()}/${props.getField()}/${props.getKey()}`);
|
||||||
const json = await response.json();
|
const json = await response.json();
|
||||||
return json;
|
return json;
|
||||||
@@ -37,12 +38,7 @@ export const QueryResult: Component<{
|
|||||||
value="Query Data"
|
value="Query Data"
|
||||||
onClick={() => setTimestamp(Date.now())}
|
onClick={() => setTimestamp(Date.now())}
|
||||||
/>
|
/>
|
||||||
{ queryResource.loading && (
|
{ queryResource.loading && <LoadingSpinner text="Loading query" /> }
|
||||||
<div>
|
|
||||||
<span class="spinner"></span>
|
|
||||||
<span style={{ "padding-left": "16px" }}>Loading query</span>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
{ queryResource.error && (
|
{ queryResource.error && (
|
||||||
<div>Error while querying: ${queryResource.error}</div>
|
<div>Error while querying: ${queryResource.error}</div>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
import { Component } from "solid-js";
|
||||||
|
|
||||||
|
export const LoadingSpinner: Component<{ text: string; }> = ({ text }) => {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<span class="spinner"></span>
|
||||||
|
<span style={{ "padding-left": "16px" }}>{ text }</span>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -13,6 +13,8 @@ export const CityChart: Component<{
|
|||||||
const [getCanvas, setCanvas] = createSignal<HTMLCanvasElement>();
|
const [getCanvas, setCanvas] = createSignal<HTMLCanvasElement>();
|
||||||
const [getIsLarge, setIsLarge] = createSignal(false);
|
const [getIsLarge, setIsLarge] = createSignal(false);
|
||||||
|
|
||||||
|
console.log("props.data()", props.data());
|
||||||
|
|
||||||
let chart: Chart | undefined;
|
let chart: Chart | undefined;
|
||||||
const data: [string, number | null][] = props.data().map(([dateStr, value]) => [
|
const data: [string, number | null][] = props.data().map(([dateStr, value]) => [
|
||||||
formatDateString(dateStr),
|
formatDateString(dateStr),
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ export const apiHost = import.meta.env.MODE === "development"
|
|||||||
? import.meta.env.VITE_API_HOST : `${protocol}//${host}:${port}`;
|
? import.meta.env.VITE_API_HOST : `${protocol}//${host}:${port}`;
|
||||||
// export const apiHost = import.meta.env.VITE_API_HOST;
|
// export const apiHost = import.meta.env.VITE_API_HOST;
|
||||||
|
|
||||||
|
export const FETCH_DELAY_MS = 500; // delays by 500ms for server requests, so user sees that something is loading
|
||||||
|
|
||||||
export const cityList = ["Ainaži", "Alūksne", "Bauska", "Dagda", "Daugavgrīva", "Daugavpils", "Dobele", "Gulbene", "Jelgava", "Kalnciems", "Kolka", "Kuldīga", "Lielpēči", "Liepāja", "Madona", "Mērsrags", "Pāvilosta", "Piedruja", "Priekuļi", "Rēzekne", "Rīga", "Rucava", "Rūjiena", "Saldus", "Sigulda", "Sīļi", "Skrīveri", "Skulte", "Stende", "Ventspils", "Vičaki", "Zīlāni", "Zosēni"];
|
export const cityList = ["Ainaži", "Alūksne", "Bauska", "Dagda", "Daugavgrīva", "Daugavpils", "Dobele", "Gulbene", "Jelgava", "Kalnciems", "Kolka", "Kuldīga", "Lielpēči", "Liepāja", "Madona", "Mērsrags", "Pāvilosta", "Piedruja", "Priekuļi", "Rēzekne", "Rīga", "Rucava", "Rūjiena", "Saldus", "Sigulda", "Sīļi", "Skrīveri", "Skulte", "Stende", "Ventspils", "Vičaki", "Zīlāni", "Zosēni"];
|
||||||
|
|
||||||
export const weatherField = ["tempMax", "tempMin", "tempAvg", "precipitation", "windAvg", "windMax", "visibilityMin", "visibilityAvg", "snowAvg", "atmPressire", "dewPoint", "humidity", "sunDuration", "phenomena"];
|
export const weatherField = ["tempMax", "tempMin", "tempAvg", "precipitation", "windAvg", "windMax", "visibilityMin", "visibilityAvg", "snowAvg", "atmPressire", "dewPoint", "humidity", "sunDuration", "phenomena"];
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
import { Accessor, Component, createResource, createSignal } from "solid-js";
|
import { Accessor, Component, createResource, createSignal } from "solid-js";
|
||||||
|
|
||||||
import { apiHost } from "../../consts";
|
import { FETCH_DELAY_MS, apiHost } from "../../consts";
|
||||||
import { Result } from "./Result";
|
import { Result } from "./Result";
|
||||||
|
import { LoadingSpinner } from "../../components/LoadingSpinner";
|
||||||
|
|
||||||
|
|
||||||
export const QueryResult: Component<{
|
export const QueryResult: Component<{
|
||||||
@@ -16,7 +17,7 @@ export const QueryResult: Component<{
|
|||||||
|
|
||||||
const fetchQuery = async (timestamp: number) => {
|
const fetchQuery = async (timestamp: number) => {
|
||||||
if (props.getFields().length === 0) return new Error("ERROR: Select weather parameters!");
|
if (props.getFields().length === 0) return new Error("ERROR: Select weather parameters!");
|
||||||
await new Promise(resolve => setTimeout(resolve, 500))
|
await new Promise(resolve => setTimeout(resolve, FETCH_DELAY_MS))
|
||||||
const response = await fetch(`${apiHost}/api/query/country/${queryStart()}-${queryEnd()}/${props.getFields().join(",")}`);
|
const response = await fetch(`${apiHost}/api/query/country/${queryStart()}-${queryEnd()}/${props.getFields().join(",")}`);
|
||||||
const json = await response.json();
|
const json = await response.json();
|
||||||
return json;
|
return json;
|
||||||
@@ -32,12 +33,7 @@ export const QueryResult: Component<{
|
|||||||
value="Query Data"
|
value="Query Data"
|
||||||
onClick={() => setTimestamp(Date.now())}
|
onClick={() => setTimestamp(Date.now())}
|
||||||
/>
|
/>
|
||||||
{ queryResource.loading && (
|
{ queryResource.loading && <LoadingSpinner text="Loading query" /> }
|
||||||
<div>
|
|
||||||
<span class="spinner"></span>
|
|
||||||
<span style={{ "padding-left": "16px" }}>Loading query</span>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
{ queryResource.error && (
|
{ queryResource.error && (
|
||||||
<div>Error while querying: ${queryResource.error}</div>
|
<div>Error while querying: ${queryResource.error}</div>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
import { Accessor, Component, createResource, createSignal, Setter } from "solid-js";
|
import { Accessor, Component, createResource, createSignal, Setter } from "solid-js";
|
||||||
|
|
||||||
import { apiHost } from "../consts";
|
import { apiHost, FETCH_DELAY_MS } from "../consts";
|
||||||
|
|
||||||
import "../css/spinner.css";
|
import "../css/spinner.css";
|
||||||
import { Calendar } from "./Calendar";
|
import { Calendar } from "./Calendar";
|
||||||
|
import { LoadingSpinner } from "../components/LoadingSpinner";
|
||||||
|
|
||||||
export const DateList: Component<{getDate: Accessor<Date>, setDate: Setter<Date>;}> = (props) => {
|
export const DateList: Component<{getDate: Accessor<Date>, setDate: Setter<Date>;}> = (props) => {
|
||||||
const [getCurrentMonth, setCurrentMonth] = createSignal(new Date());
|
const [getCurrentMonth, setCurrentMonth] = createSignal(new Date());
|
||||||
@@ -14,7 +15,7 @@ export const DateList: Component<{getDate: Accessor<Date>, setDate: Setter<Date>
|
|||||||
moment(getCurrentMonth()).subtract(1, "months").format("yyyyMM"),
|
moment(getCurrentMonth()).subtract(1, "months").format("yyyyMM"),
|
||||||
moment(getCurrentMonth()).add(1, "months").format("yyyyMM"),
|
moment(getCurrentMonth()).add(1, "months").format("yyyyMM"),
|
||||||
];
|
];
|
||||||
await new Promise(resolve => setTimeout(resolve, 500))
|
await new Promise(resolve => setTimeout(resolve, FETCH_DELAY_MS))
|
||||||
const response = await fetch(`${apiHost}/api/show/months/${months.join(",")}`);
|
const response = await fetch(`${apiHost}/api/show/months/${months.join(",")}`);
|
||||||
const json = await response.json();
|
const json = await response.json();
|
||||||
return json;
|
return json;
|
||||||
@@ -24,12 +25,7 @@ export const DateList: Component<{getDate: Accessor<Date>, setDate: Setter<Date>
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
{ datesResource.loading && (
|
{ datesResource.loading && <LoadingSpinner text="Loading calendar..." /> }
|
||||||
<div>
|
|
||||||
<span class="spinner"></span>
|
|
||||||
<span style={{ "padding-left": "16px" }}>Loading dates</span>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
{ datesResource.error && (
|
{ datesResource.error && (
|
||||||
<div>Error while loading dates: ${datesResource.error}</div>
|
<div>Error while loading dates: ${datesResource.error}</div>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
import { Accessor, Component, createResource, JSXElement } from "solid-js";
|
import { Accessor, Component, createResource, JSXElement } from "solid-js";
|
||||||
import { apiHost } from "../consts";
|
import { apiHost, FETCH_DELAY_MS } from "../consts";
|
||||||
import { PrettifyCSV } from "./PrettifyCSV";
|
import { PrettifyCSV } from "./PrettifyCSV";
|
||||||
|
import { LoadingSpinner } from "../components/LoadingSpinner";
|
||||||
|
|
||||||
export const FileContent: Component<{getFileName: Accessor<string>}> = (props) => {
|
export const FileContent: Component<{getFileName: Accessor<string>}> = (props) => {
|
||||||
const fetchFileContent = async (fileName: string) => {
|
const fetchFileContent = async (fileName: string) => {
|
||||||
if (fileName === "") return;
|
if (fileName === "") return;
|
||||||
await new Promise(resolve => setTimeout(resolve, 500))
|
await new Promise(resolve => setTimeout(resolve, FETCH_DELAY_MS))
|
||||||
const response = await fetch(`${apiHost}/api/show/datetime/${fileName}`);
|
const response = await fetch(`${apiHost}/api/show/datetime/${fileName}`);
|
||||||
const text = await response.json();
|
const text = await response.json();
|
||||||
return text;
|
return text;
|
||||||
@@ -16,12 +17,7 @@ export const FileContent: Component<{getFileName: Accessor<string>}> = (props) =
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
{ contentResource.loading && (
|
{ contentResource.loading && <LoadingSpinner text="Loading date-time weather" /> }
|
||||||
<div>
|
|
||||||
<span class="spinner"></span>
|
|
||||||
<span style={{ "padding-left": "16px" }}>load content</span>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
{ contentResource.error && (
|
{ contentResource.error && (
|
||||||
<div>Error while loading file content: ${contentResource.error}</div>
|
<div>Error while loading file content: ${contentResource.error}</div>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -1,15 +1,16 @@
|
|||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
import { Accessor, Component, createResource, Setter } from "solid-js";
|
import { Accessor, Component, createResource, Setter } from "solid-js";
|
||||||
import { apiHost } from "../consts";
|
import { apiHost, FETCH_DELAY_MS } from "../consts";
|
||||||
|
|
||||||
import "../css/spinner.css";
|
import "../css/spinner.css";
|
||||||
|
import { LoadingSpinner } from "../components/LoadingSpinner";
|
||||||
|
|
||||||
export const FileNameList: Component<{
|
export const FileNameList: Component<{
|
||||||
getDate: Accessor<Date>,
|
getDate: Accessor<Date>,
|
||||||
setFileName: Setter<string>,
|
setFileName: Setter<string>,
|
||||||
}> = (props) => {
|
}> = (props) => {
|
||||||
const fetchFileNames = async (fetchDate: Date) => {
|
const fetchFileNames = async (fetchDate: Date) => {
|
||||||
await new Promise(resolve => setTimeout(resolve, 500))
|
await new Promise(resolve => setTimeout(resolve, FETCH_DELAY_MS))
|
||||||
const response = await fetch(`${apiHost}/api/show/date/${moment(fetchDate).format("YYYYMMDD")}`);
|
const response = await fetch(`${apiHost}/api/show/date/${moment(fetchDate).format("YYYYMMDD")}`);
|
||||||
const json = await response.json();
|
const json = await response.json();
|
||||||
return json;
|
return json;
|
||||||
@@ -23,12 +24,7 @@ export const FileNameList: Component<{
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
{ fileNameResource.loading && (
|
{ fileNameResource.loading && <LoadingSpinner text={"Loading date: "+moment(props.getDate()).format("YYYYMMDD")} /> }
|
||||||
<div>
|
|
||||||
<span class="spinner"></span>
|
|
||||||
<span style={{ "padding-left": "16px" }}>loading {moment(props.getDate()).format("YYYYMMDD")}</span>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
{ fileNameResource.error && (
|
{ fileNameResource.error && (
|
||||||
<div>Error while loading file names: ${fileNameResource.error}</div>
|
<div>Error while loading file names: ${fileNameResource.error}</div>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -4,7 +4,8 @@ import { coordToCity } from "./coordToCity";
|
|||||||
import { cityCoords } from "./cityCoords";
|
import { cityCoords } from "./cityCoords";
|
||||||
import mapUrl from "../assets/map_1000x570.webp";
|
import mapUrl from "../assets/map_1000x570.webp";
|
||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
import { apiHost } from "../consts";
|
import { FETCH_DELAY_MS, apiHost } from "../consts";
|
||||||
|
import { LoadingSpinner } from "../components/LoadingSpinner";
|
||||||
|
|
||||||
export const MapResult: Component<{
|
export const MapResult: Component<{
|
||||||
setCity: Setter<string | undefined>,
|
setCity: Setter<string | undefined>,
|
||||||
@@ -49,6 +50,8 @@ export const MapResult: Component<{
|
|||||||
|
|
||||||
const [meteoValues] = createResource(citiesFieldDate, async ([cities, field, start, end]: [Set<string>, string, Date, Date]) => {
|
const [meteoValues] = createResource(citiesFieldDate, async ([cities, field, start, end]: [Set<string>, string, Date, Date]) => {
|
||||||
if (cities.size === 0) return;
|
if (cities.size === 0) return;
|
||||||
|
await new Promise(resolve => setTimeout(resolve, FETCH_DELAY_MS));
|
||||||
|
|
||||||
const queryStart = moment(start).format("YYYYMMDD_HHmm");
|
const queryStart = moment(start).format("YYYYMMDD_HHmm");
|
||||||
const queryEnd = moment(end).format("YYYYMMDD_HHmm");
|
const queryEnd = moment(end).format("YYYYMMDD_HHmm");
|
||||||
let aggregate: string = "avg";
|
let aggregate: string = "avg";
|
||||||
@@ -74,7 +77,17 @@ export const MapResult: Component<{
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
return <canvas ref={setCanvas} width={1000} height={570} />;
|
return (
|
||||||
|
<div>
|
||||||
|
{ meteoValues.loading && <LoadingSpinner text="Drawing map..." /> }
|
||||||
|
<canvas
|
||||||
|
ref={setCanvas}
|
||||||
|
style={{ display: meteoValues.loading ? "none" : "block" }}
|
||||||
|
width={1000}
|
||||||
|
height={570}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function drawOnMap(
|
function drawOnMap(
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { Accessor, Component, createResource } from "solid-js";
|
import { Accessor, Component, createResource } from "solid-js";
|
||||||
import { apiHost } from "../consts";
|
import { FETCH_DELAY_MS, apiHost } from "../consts";
|
||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
import { CityChart } from "../components/chart/CityChart";
|
import { CityChart } from "../components/chart/CityChart";
|
||||||
|
|
||||||
@@ -14,7 +14,7 @@ export const Result: Component<{
|
|||||||
|
|
||||||
const fetchList = async ([city, field, getStart, getEnd]: [string | undefined, string, Date, Date]) => {
|
const fetchList = async ([city, field, getStart, getEnd]: [string | undefined, string, Date, Date]) => {
|
||||||
if (city === undefined) return undefined;
|
if (city === undefined) return undefined;
|
||||||
await new Promise(resolve => setTimeout(resolve, 500));
|
await new Promise(resolve => setTimeout(resolve, FETCH_DELAY_MS));
|
||||||
const response = await fetch(`${apiHost}/api/query/city/${city}/${queryStart()}-${queryEnd()}/hour/${field}/list`);
|
const response = await fetch(`${apiHost}/api/query/city/${city}/${queryStart()}-${queryEnd()}/hour/${field}/list`);
|
||||||
const json = await response.json();
|
const json = await response.json();
|
||||||
return json;
|
return json;
|
||||||
@@ -22,7 +22,7 @@ export const Result: Component<{
|
|||||||
|
|
||||||
const fetchMeteo = async ([city, getStart, getEnd]: [string | undefined, Date, Date]) => {
|
const fetchMeteo = async ([city, getStart, getEnd]: [string | undefined, Date, Date]) => {
|
||||||
if (city === undefined) return undefined;
|
if (city === undefined) return undefined;
|
||||||
await new Promise(resolve => setTimeout(resolve, 500));
|
await new Promise(resolve => setTimeout(resolve, FETCH_DELAY_MS));
|
||||||
const response = await fetch(`${apiHost}/api/query/city/${city}/${queryStart()}-${queryEnd()}/allFields`);
|
const response = await fetch(`${apiHost}/api/query/city/${city}/${queryStart()}-${queryEnd()}/allFields`);
|
||||||
const json = await response.json();
|
const json = await response.json();
|
||||||
return json;
|
return json;
|
||||||
@@ -63,10 +63,10 @@ export const Result: Component<{
|
|||||||
}
|
}
|
||||||
{ listResource() && props.getCity() && !listResource.loading &&
|
{ listResource() && props.getCity() && !listResource.loading &&
|
||||||
<div>
|
<div>
|
||||||
<h3>{ props.getCity() }</h3>
|
<h3>{ props.getCity() }: { props.getField() }</h3>
|
||||||
<CityChart
|
<CityChart
|
||||||
city={() => listResource().query.cities[0]}
|
city={() => listResource().query.cities[0]}
|
||||||
data={() => listResource().result[listResource().query.cities[0]]}
|
data={() => listResource().result[listResource().query.cities[0]] ?? []}
|
||||||
query={() => listResource().query}
|
query={() => listResource().query}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user