mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-27 03:06:41 +00:00
Make map card trails clickable, provide time context. (#14515)
Co-authored-by: Bram Kragten <mail@bramkragten.nl>
This commit is contained in:
parent
ebcbfda92d
commit
77b8152c55
@ -23,8 +23,12 @@ import "./ha-entity-marker";
|
|||||||
const getEntityId = (entity: string | HaMapEntity): string =>
|
const getEntityId = (entity: string | HaMapEntity): string =>
|
||||||
typeof entity === "string" ? entity : entity.entity_id;
|
typeof entity === "string" ? entity : entity.entity_id;
|
||||||
|
|
||||||
|
export interface HaMapPathPoint {
|
||||||
|
point: LatLngTuple;
|
||||||
|
tooltip: string;
|
||||||
|
}
|
||||||
export interface HaMapPaths {
|
export interface HaMapPaths {
|
||||||
points: LatLngTuple[];
|
points: HaMapPathPoint[];
|
||||||
color?: string;
|
color?: string;
|
||||||
gradualOpacity?: number;
|
gradualOpacity?: number;
|
||||||
}
|
}
|
||||||
@ -247,19 +251,21 @@ export class HaMap extends ReactiveElement {
|
|||||||
|
|
||||||
// DRAW point
|
// DRAW point
|
||||||
this._mapPaths.push(
|
this._mapPaths.push(
|
||||||
Leaflet!.circleMarker(path.points[pointIndex], {
|
Leaflet!
|
||||||
radius: 3,
|
.circleMarker(path.points[pointIndex].point, {
|
||||||
color: path.color || darkPrimaryColor,
|
radius: 3,
|
||||||
opacity,
|
color: path.color || darkPrimaryColor,
|
||||||
fillOpacity: opacity,
|
opacity,
|
||||||
interactive: false,
|
fillOpacity: opacity,
|
||||||
})
|
interactive: true,
|
||||||
|
})
|
||||||
|
.bindTooltip(path.points[pointIndex].tooltip, { direction: "top" })
|
||||||
);
|
);
|
||||||
|
|
||||||
// DRAW line between this and next point
|
// DRAW line between this and next point
|
||||||
this._mapPaths.push(
|
this._mapPaths.push(
|
||||||
Leaflet!.polyline(
|
Leaflet!.polyline(
|
||||||
[path.points[pointIndex], path.points[pointIndex + 1]],
|
[path.points[pointIndex].point, path.points[pointIndex + 1].point],
|
||||||
{
|
{
|
||||||
color: path.color || darkPrimaryColor,
|
color: path.color || darkPrimaryColor,
|
||||||
opacity,
|
opacity,
|
||||||
@ -275,13 +281,15 @@ export class HaMap extends ReactiveElement {
|
|||||||
: undefined;
|
: undefined;
|
||||||
// DRAW end path point
|
// DRAW end path point
|
||||||
this._mapPaths.push(
|
this._mapPaths.push(
|
||||||
Leaflet!.circleMarker(path.points[pointIndex], {
|
Leaflet!
|
||||||
radius: 3,
|
.circleMarker(path.points[pointIndex].point, {
|
||||||
color: path.color || darkPrimaryColor,
|
radius: 3,
|
||||||
opacity,
|
color: path.color || darkPrimaryColor,
|
||||||
fillOpacity: opacity,
|
opacity,
|
||||||
interactive: false,
|
fillOpacity: opacity,
|
||||||
})
|
interactive: true,
|
||||||
|
})
|
||||||
|
.bindTooltip(path.points[pointIndex].tooltip, { direction: "top" })
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
this._mapPaths.forEach((marker) => map.addLayer(marker));
|
this._mapPaths.forEach((marker) => map.addLayer(marker));
|
||||||
@ -491,6 +499,14 @@ export class HaMap extends ReactiveElement {
|
|||||||
.leaflet-bottom {
|
.leaflet-bottom {
|
||||||
z-index: 1 !important;
|
z-index: 1 !important;
|
||||||
}
|
}
|
||||||
|
.leaflet-tooltip {
|
||||||
|
padding: 8px;
|
||||||
|
font-size: 90%;
|
||||||
|
background: rgba(80, 80, 80, 0.9) !important;
|
||||||
|
color: white !important;
|
||||||
|
border-radius: 4px;
|
||||||
|
box-shadow: none !important;
|
||||||
|
}
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,7 @@ import {
|
|||||||
import { customElement, property, query, state } from "lit/decorators";
|
import { customElement, property, query, state } from "lit/decorators";
|
||||||
import { mdiImageFilterCenterFocus } from "@mdi/js";
|
import { mdiImageFilterCenterFocus } from "@mdi/js";
|
||||||
import memoizeOne from "memoize-one";
|
import memoizeOne from "memoize-one";
|
||||||
|
import { isToday } from "date-fns";
|
||||||
import { computeDomain } from "../../../common/entity/compute_domain";
|
import { computeDomain } from "../../../common/entity/compute_domain";
|
||||||
import parseAspectRatio from "../../../common/util/parse-aspect-ratio";
|
import parseAspectRatio from "../../../common/util/parse-aspect-ratio";
|
||||||
import "../../../components/ha-card";
|
import "../../../components/ha-card";
|
||||||
@ -23,8 +24,17 @@ import { EntityConfig } from "../entity-rows/types";
|
|||||||
import { LovelaceCard } from "../types";
|
import { LovelaceCard } from "../types";
|
||||||
import { MapCardConfig } from "./types";
|
import { MapCardConfig } from "./types";
|
||||||
import "../../../components/map/ha-map";
|
import "../../../components/map/ha-map";
|
||||||
import type { HaMap, HaMapPaths } from "../../../components/map/ha-map";
|
import type {
|
||||||
|
HaMap,
|
||||||
|
HaMapPaths,
|
||||||
|
HaMapPathPoint,
|
||||||
|
} from "../../../components/map/ha-map";
|
||||||
import { getColorByIndex } from "../../../common/color/colors";
|
import { getColorByIndex } from "../../../common/color/colors";
|
||||||
|
import { formatDateTime } from "../../../common/datetime/format_date_time";
|
||||||
|
import {
|
||||||
|
formatTime,
|
||||||
|
formatTimeWeekday,
|
||||||
|
} from "../../../common/datetime/format_time";
|
||||||
|
|
||||||
const MINUTE = 60000;
|
const MINUTE = 60000;
|
||||||
|
|
||||||
@ -274,16 +284,28 @@ class HuiMapCard extends LitElement implements LovelaceCard {
|
|||||||
}
|
}
|
||||||
// filter location data from states and remove all invalid locations
|
// filter location data from states and remove all invalid locations
|
||||||
const points = entityStates.reduce(
|
const points = entityStates.reduce(
|
||||||
(accumulator: LatLngTuple[], entityState) => {
|
(accumulator: HaMapPathPoint[], entityState) => {
|
||||||
const latitude = entityState.attributes.latitude;
|
const latitude = entityState.attributes.latitude;
|
||||||
const longitude = entityState.attributes.longitude;
|
const longitude = entityState.attributes.longitude;
|
||||||
if (latitude && longitude) {
|
if (latitude && longitude) {
|
||||||
accumulator.push([latitude, longitude] as LatLngTuple);
|
const p = {} as HaMapPathPoint;
|
||||||
|
p.point = [latitude, longitude] as LatLngTuple;
|
||||||
|
const t = new Date(entityState.last_updated);
|
||||||
|
if (config.hours_to_show! > 144) {
|
||||||
|
// if showing > 6 days in the history trail, show the full
|
||||||
|
// date and time
|
||||||
|
p.tooltip = formatDateTime(t, this.hass.locale);
|
||||||
|
} else if (isToday(t)) {
|
||||||
|
p.tooltip = formatTime(t, this.hass.locale);
|
||||||
|
} else {
|
||||||
|
p.tooltip = formatTimeWeekday(t, this.hass.locale);
|
||||||
|
}
|
||||||
|
accumulator.push(p);
|
||||||
}
|
}
|
||||||
return accumulator;
|
return accumulator;
|
||||||
},
|
},
|
||||||
[]
|
[]
|
||||||
) as LatLngTuple[];
|
) as HaMapPathPoint[];
|
||||||
|
|
||||||
paths.push({
|
paths.push({
|
||||||
points,
|
points,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user