Select all cities and order results

This commit is contained in:
Guntis Smaukstelis
2023-06-22 19:20:21 +03:00
parent 6ce4d139a8
commit bb817e5171
7 changed files with 116 additions and 26 deletions
+19 -6
View File
@@ -1,9 +1,11 @@
import moment from "moment";
import { Accessor, Component, createResource, createSignal } from "solid-js";
import { apiHost } from "../consts";
import { apiHost, ResultKeyVal, resultOrder, ResultOrderKeys } from "../consts";
import { CityChart } from "./CityChart";
import "../css/Result.css"
import { SelectOrder } from "./SelectOrder";
export const Result: Component<{
getCities: Accessor<Set<string>>,
@@ -12,7 +14,8 @@ export const Result: Component<{
getField: Accessor<string>,
getKey: Accessor<string>,
}> = (props) => {
const cities = () => [...props.getCities()].join(",")
const cities = () => [...props.getCities()].join(",");
const citiesStr = () => [...props.getCities()].join(", ");
const startStr = () => moment(props.getStart()).format("YYYY/MM/DD, HH:mm");
const endStr = () => moment(props.getEnd()).format("YYYY/MM/DD, HH:mm");
const queryStart = () => moment(props.getStart()).format("YYYYMMDD_HHmm");
@@ -28,16 +31,25 @@ export const Result: Component<{
}
const [queryResource] = createResource(getTimestamp, fetchQuery);
const [getOrderKey, setOrderKey] = createSignal<ResultOrderKeys>("A -> Z");
return (
<div>
<h3>Aggregate by:</h3>
<input type="button" value="Query Data" onClick={() => setTimestamp(Date.now())} />
<p>cities: { cities() }</p>
<input
type="button"
class="primary"
value="Query Data"
onClick={() => setTimestamp(Date.now())}
/>
<p>cities: { citiesStr() }</p>
<p>time range: { startStr() } - { endStr() }</p>
<p>weather field: { props.getField() }</p>
<p>aggregation field: { props.getKey() }</p>
<h3>Result:</h3>
<div class="resultTitle">
<h3>Result:</h3>
<SelectOrder getter={getOrderKey} setter={setOrderKey} />
</div>
{ queryResource.loading && (
<div>
<span class="spinner"></span>
@@ -53,7 +65,8 @@ export const Result: Component<{
{ queryResource() && (
<div class="result-container">
{ Object.entries(queryResource())
.sort((a, b) => (a[0] as string) > (b[0] as string) ? 1 : -1)
.map(keyVal => [...keyVal] as ResultKeyVal)
.sort((a, b) => resultOrder[getOrderKey()](a, b))
.map(cityData => <ExportCity city={cityData[0]} value={cityData[1]} />)
}</div>
)}
+2 -1
View File
@@ -9,7 +9,7 @@ export const SelectAggregator: Component<{
}> = (props) => {
return (
<div>
<h3>Select aggregator</h3>
<h3>Select field</h3>
<select onChange={(e) => props.setField(e.target.value)}>
{ weatherField.map(field =>
<option
@@ -18,6 +18,7 @@ export const SelectAggregator: Component<{
>{field}</option>
)}
</select>
<h3>Select aggregator</h3>
<ul>
{ aggregateKey.map(key =>
<label><li><input
+37 -19
View File
@@ -1,34 +1,52 @@
import { Accessor, Component, Setter } from "solid-js";
import { Accessor, Component, createEffect, Setter } from "solid-js";
import { cityList } from "../consts";
export const SelectCity: Component<{
getCities: Accessor<Set<string>>,
setCities: Setter<Set<string>>,
}> = (props) => {
}> = ({ getCities, setCities }) => {
function handleSelect(e: MouseEvent) {
if (!e.target) return;
const target = e.target as HTMLInputElement;
const { checked: selected, value: city } = target;
const cityList = new Set([...props.getCities()]);
if (selected) cityList.add(city);
else cityList.delete(city);
const selectedCities = new Set([...getCities()]);
if (selected) selectedCities.add(city);
else selectedCities.delete(city);
props.setCities(cityList);
setCities(selectedCities);
}
function selectAll(e: MouseEvent) {
if (!e.target) return;
const target = e.target as HTMLInputElement;
const selectedCities = target.checked
? new Set([...cityList])
: new Set([]);
setCities(selectedCities);
}
return (
<ul>{cityList.map(city =>
<label>
<li>
<input
type="checkbox"
name="city"
value={city}
onClick={handleSelect}
/>
{city}
</li>
</label>
)}</ul>
<div>
Select all <input
type="checkbox"
onClick={selectAll}
/>
<ul>{cityList.map(city =>
<label>
<li>
<input
type="checkbox"
name="city"
value={city}
checked={getCities().has(city)}
onClick={handleSelect}
/>
{city}
</li>
</label>
)}
</ul>
</div>
);
};
+23
View File
@@ -0,0 +1,23 @@
import { Accessor, Component, Setter } from "solid-js";
import { resultOrder, ResultOrderKeys } from "../consts";
export const SelectOrder: Component<{
getter: Accessor<ResultOrderKeys>,
setter: Setter<ResultOrderKeys>,
}> = ({ getter, setter }) => {
return (
<div>
Order by:
<select onChange={e => setter(e.target.value as ResultOrderKeys)}>
{ Object.keys(resultOrder).map(orderKey =>
<option
value={orderKey}
selected={orderKey === getter()}
>
{orderKey}
</option>
)}
</select>
</div>
);
};
+12
View File
@@ -5,3 +5,15 @@ export const cityList = ["Ainaži", "Alūksne", "Bauska", "Dagda", "Daugavgrīva
export const weatherField = ["tempMax", "tempMin", "tempAvg", "precipitation", "windAvg", "windMax", "visibilityMin", "visibilityAvg", "snowAvg", "atmPressire", "dewPoint", "humidity", "sunDuration", "phenomena"];
export const aggregateKey = ["min", "max", "avg", "sum", "list", "distinct"];
export type ResultKeyVal = [key: string, value: number | Array<any>];
export const resultOrder = {
"A -> Z": (a: ResultKeyVal, b: ResultKeyVal) => a[0] > b[0] ? 1 : -1,
"Z -> A": (a: ResultKeyVal, b: ResultKeyVal) => a[0] > b[0] ? -1 : 1,
"Min": (a: ResultKeyVal, b: ResultKeyVal) => a[1] > b[1] ? 1 : -1,
"Max": (a: ResultKeyVal, b: ResultKeyVal) => a[1] > b[1] ? -1 : 1,
};
type ResultOrder = typeof resultOrder;
export type ResultOrderKeys = keyof ResultOrder;
+11
View File
@@ -9,3 +9,14 @@
padding: 10px;
text-align: center;
}
.resultTitle {
display: flex;
align-items: center;
justify-content: space-between;
padding: 10px 0;
}
.resultTitle h3 {
margin: 0;
}
+12
View File
@@ -11,3 +11,15 @@ code {
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
monospace;
}
.primary {
background-color: #ffcc66;
border: none;
font-weight: bold;
padding: 5px 10px;
cursor: pointer;
}
.primary:hover {
background-color: #ffb92d;
}