Hint about filters not being applied in road info popover
This commit is contained in:
parent
1a3b971a71
commit
c3ed4f24dd
|
@ -1,6 +1,14 @@
|
|||
import React, { useState, useCallback } from "react";
|
||||
import _ from "lodash";
|
||||
import { Segment, Menu, Header, Label, Icon, Table } from "semantic-ui-react";
|
||||
import {
|
||||
Segment,
|
||||
Menu,
|
||||
Header,
|
||||
Label,
|
||||
Icon,
|
||||
Table,
|
||||
Message,
|
||||
} from "semantic-ui-react";
|
||||
import { Layer, Source } from "react-map-gl";
|
||||
import { of, from, concat } from "rxjs";
|
||||
import { useObservable } from "rxjs-hooks";
|
||||
|
@ -9,8 +17,9 @@ import { Chart } from "components";
|
|||
import { pairwise } from "utils";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import api from 'api'
|
||||
import {colorByDistance, borderByZone} from 'mapstyles'
|
||||
import type { Location } from "types";
|
||||
import api from "api";
|
||||
import { colorByDistance, borderByZone } from "mapstyles";
|
||||
|
||||
import styles from "./styles.module.less";
|
||||
|
||||
|
@ -88,15 +97,20 @@ function RoadStatsTable({ data }) {
|
|||
}
|
||||
|
||||
function HistogramChart({ bins, counts, zone }) {
|
||||
const diff = bins[1] - bins[0]
|
||||
const diff = bins[1] - bins[0];
|
||||
const colortype = zone === "rural" ? 3 : 5;
|
||||
const data = _.zip(
|
||||
bins.slice(0, bins.length - 1).map((v) => v + diff / 2),
|
||||
counts
|
||||
).map((value) => ({
|
||||
value,
|
||||
itemStyle: {color: selectFromColorMap(colorByDistance()[3][colortype].slice(2), value[0]),},
|
||||
}))
|
||||
itemStyle: {
|
||||
color: selectFromColorMap(
|
||||
colorByDistance()[3][colortype].slice(2),
|
||||
value[0]
|
||||
),
|
||||
},
|
||||
}));
|
||||
|
||||
return (
|
||||
<Chart
|
||||
|
@ -123,7 +137,13 @@ function HistogramChart({ bins, counts, zone }) {
|
|||
);
|
||||
}
|
||||
|
||||
export default function RoadInfo({ clickLocation }) {
|
||||
export default function RoadInfo({
|
||||
clickLocation,
|
||||
hasFilters,
|
||||
}: {
|
||||
clickLocation: Location | null;
|
||||
hasFilters: boolean;
|
||||
}) {
|
||||
const { t } = useTranslation();
|
||||
const [direction, setDirection] = useState("forwards");
|
||||
|
||||
|
@ -183,6 +203,15 @@ export default function RoadInfo({ clickLocation }) {
|
|||
: info?.road.name || t("MapPage.roadInfo.unnamedWay")}
|
||||
</Header>
|
||||
|
||||
{hasFilters && (
|
||||
<Message info icon>
|
||||
<Icon name="info circle" small />
|
||||
<Message.Content>
|
||||
{t("MapPage.roadInfo.hintFiltersNotApplied")}
|
||||
</Message.Content>
|
||||
</Message>
|
||||
)}
|
||||
|
||||
{info?.road.zone && (
|
||||
<Label size="small" color={ZONE_COLORS[info?.road.zone]}>
|
||||
{t(`general.zone.${info.road.zone}`)}
|
||||
|
@ -220,9 +249,9 @@ export default function RoadInfo({ clickLocation }) {
|
|||
|
||||
{info?.[direction]?.distanceOvertaker?.histogram && (
|
||||
<>
|
||||
<Header as="h5">
|
||||
{t("MapPage.roadInfo.overtakerDistanceDistribution")}
|
||||
</Header>
|
||||
<Header as="h5">
|
||||
{t("MapPage.roadInfo.overtakerDistanceDistribution")}
|
||||
</Header>
|
||||
<HistogramChart
|
||||
{...info[direction]?.distanceOvertaker?.histogram}
|
||||
/>
|
||||
|
|
|
@ -5,10 +5,17 @@ import { Button } from "semantic-ui-react";
|
|||
import { Layer, Source } from "react-map-gl";
|
||||
import produce from "immer";
|
||||
|
||||
import {Page, Map} from 'components'
|
||||
import {useConfig} from 'config'
|
||||
import {colorByDistance, colorByCount, borderByZone, reds, isValidAttribute} from 'mapstyles'
|
||||
import {useMapConfig} from 'reducers/mapConfig'
|
||||
import type { Location } from "types";
|
||||
import { Page, Map } from "components";
|
||||
import { useConfig } from "config";
|
||||
import {
|
||||
colorByDistance,
|
||||
colorByCount,
|
||||
borderByZone,
|
||||
reds,
|
||||
isValidAttribute,
|
||||
} from "mapstyles";
|
||||
import { useMapConfig } from "reducers/mapConfig";
|
||||
|
||||
import RoadInfo from "./RoadInfo";
|
||||
import LayerSidebar from "./LayerSidebar";
|
||||
|
@ -43,20 +50,19 @@ const untaggedRoadsLayer = {
|
|||
|
||||
const getUntaggedRoadsLayer = (colorAttribute, maxCount) =>
|
||||
produce(untaggedRoadsLayer, (draft) => {
|
||||
draft.filter = ['!', isValidAttribute(colorAttribute)]
|
||||
})
|
||||
|
||||
draft.filter = ["!", isValidAttribute(colorAttribute)];
|
||||
});
|
||||
|
||||
const getRoadsLayer = (colorAttribute, maxCount) =>
|
||||
produce(untaggedRoadsLayer, (draft) => {
|
||||
draft.id = "obs_roads_normal";
|
||||
draft.filter = isValidAttribute(colorAttribute)
|
||||
draft.filter = isValidAttribute(colorAttribute);
|
||||
draft.paint["line-width"][6] = 6; // scale bigger on zoom
|
||||
draft.paint["line-color"] = colorAttribute.startsWith("distance_")
|
||||
? colorByDistance(colorAttribute)
|
||||
: colorAttribute.endsWith("_count")
|
||||
? colorByCount(colorAttribute, maxCount)
|
||||
: colorAttribute.endsWith('zone')
|
||||
: colorAttribute.endsWith("zone")
|
||||
? borderByZone()
|
||||
: "#DDD";
|
||||
draft.paint["line-opacity"][3] = 12;
|
||||
|
@ -105,10 +111,7 @@ const getEventsTextLayer = () => ({
|
|||
|
||||
function MapPage({ login }) {
|
||||
const { obsMapSource } = useConfig() || {};
|
||||
const [clickLocation, setClickLocation] = useState<{
|
||||
longitude: number;
|
||||
latitude: number;
|
||||
} | null>(null);
|
||||
const [clickLocation, setClickLocation] = useState<Location | null>(null);
|
||||
|
||||
const mapConfig = useMapConfig();
|
||||
|
||||
|
@ -135,9 +138,12 @@ function MapPage({ login }) {
|
|||
|
||||
const layers = [];
|
||||
|
||||
const untaggedRoadsLayerCustom = useMemo(() => getUntaggedRoadsLayer(attribute), [attribute])
|
||||
const untaggedRoadsLayerCustom = useMemo(
|
||||
() => getUntaggedRoadsLayer(attribute),
|
||||
[attribute]
|
||||
);
|
||||
if (mapConfig.obsRoads.show && mapConfig.obsRoads.showUntagged) {
|
||||
layers.push(untaggedRoadsLayerCustom)
|
||||
layers.push(untaggedRoadsLayerCustom);
|
||||
}
|
||||
|
||||
const roadsLayer = useMemo(
|
||||
|
@ -159,31 +165,36 @@ function MapPage({ login }) {
|
|||
return null;
|
||||
}
|
||||
|
||||
const tiles = obsMapSource?.tiles?.map(
|
||||
(tileUrl: string) => {
|
||||
const query = new URLSearchParams()
|
||||
if (login) {
|
||||
if (mapConfig.filters.currentUser) {
|
||||
query.append('user', login.username)
|
||||
}
|
||||
const tiles = obsMapSource?.tiles?.map((tileUrl: string) => {
|
||||
const query = new URLSearchParams();
|
||||
if (login) {
|
||||
if (mapConfig.filters.currentUser) {
|
||||
query.append("user", login.username);
|
||||
}
|
||||
|
||||
if (mapConfig.filters.dateMode === "range") {
|
||||
if (mapConfig.filters.startDate) {
|
||||
query.append('start', mapConfig.filters.startDate)
|
||||
}
|
||||
if (mapConfig.filters.endDate) {
|
||||
query.append('end', mapConfig.filters.endDate)
|
||||
}
|
||||
} else if (mapConfig.filters.dateMode === "threshold") {
|
||||
if (mapConfig.filters.startDate) {
|
||||
query.append(mapConfig.filters.thresholdAfter ? 'start' : 'end', mapConfig.filters.startDate)
|
||||
}
|
||||
if (mapConfig.filters.dateMode === "range") {
|
||||
if (mapConfig.filters.startDate) {
|
||||
query.append("start", mapConfig.filters.startDate);
|
||||
}
|
||||
if (mapConfig.filters.endDate) {
|
||||
query.append("end", mapConfig.filters.endDate);
|
||||
}
|
||||
} else if (mapConfig.filters.dateMode === "threshold") {
|
||||
if (mapConfig.filters.startDate) {
|
||||
query.append(
|
||||
mapConfig.filters.thresholdAfter ? "start" : "end",
|
||||
mapConfig.filters.startDate
|
||||
);
|
||||
}
|
||||
}
|
||||
const queryString = String(query)
|
||||
return tileUrl + (queryString ? '?' : '') + queryString
|
||||
}
|
||||
);
|
||||
const queryString = String(query);
|
||||
return tileUrl + (queryString ? "?" : "") + queryString;
|
||||
});
|
||||
|
||||
const hasFilters: boolean =
|
||||
login &&
|
||||
(mapConfig.filters.currentUser || mapConfig.filters.dateMode !== "none");
|
||||
|
||||
return (
|
||||
<Page fullScreen title="Map">
|
||||
|
@ -212,7 +223,7 @@ function MapPage({ login }) {
|
|||
))}
|
||||
</Source>
|
||||
|
||||
<RoadInfo {...{ clickLocation }} />
|
||||
<RoadInfo {...{ clickLocation, hasFilters }} />
|
||||
</Map>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -220,6 +231,4 @@ function MapPage({ login }) {
|
|||
);
|
||||
}
|
||||
|
||||
export default connect(
|
||||
(state) => ({login: state.login}),
|
||||
)(MapPage);
|
||||
export default connect((state) => ({ login: state.login }))(MapPage);
|
||||
|
|
|
@ -188,6 +188,7 @@ MapPage:
|
|||
mean: Durchschnitt
|
||||
|
||||
overtakerDistanceDistribution: Verteilung der Überholabstände
|
||||
hintFiltersNotApplied: Filter aus der Seiteleiste werden (noch) nicht auf diese Daten angewandt.
|
||||
|
||||
cardinalDirections:
|
||||
unknown: unbekannt
|
||||
|
|
|
@ -192,6 +192,7 @@ MapPage:
|
|||
mean: Average
|
||||
|
||||
overtakerDistanceDistribution: Overtaker distance distribution
|
||||
hintFiltersNotApplied: Filters from the sidebar are not (yet) applied on this data.
|
||||
|
||||
cardinalDirections:
|
||||
unknown: unknown
|
||||
|
|
|
@ -44,3 +44,8 @@ export type TrackComment = {
|
|||
createdAt: string
|
||||
author: UserProfile
|
||||
}
|
||||
|
||||
export type Location {
|
||||
longitude: number;
|
||||
latitude: number;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue