Select all cities and order results
This commit is contained in:
@@ -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>
|
||||
)}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
};
|
||||
@@ -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>
|
||||
);
|
||||
};
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
Reference in New Issue
Block a user