mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-25 18:26:35 +00:00
Add more-info click to energy table and detail device graph (#21737)
* feat: more info energy dashboard * add more info to device details usage * Add some more-info click to energy --------- Co-authored-by: Muka Schultze <samuelschultze@gmail.com> Co-authored-by: Bram Kragten <mail@bramkragten.nl>
This commit is contained in:
parent
395586ddeb
commit
cf55824899
6
src/components/chart/click_is_touch.ts
Normal file
6
src/components/chart/click_is_touch.ts
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
import type { ChartEvent } from "chart.js";
|
||||||
|
|
||||||
|
export const clickIsTouch = (event: ChartEvent): boolean =>
|
||||||
|
!(event.native instanceof MouseEvent) ||
|
||||||
|
(event.native instanceof PointerEvent &&
|
||||||
|
event.native.pointerType !== "mouse");
|
@ -16,6 +16,7 @@ import {
|
|||||||
HaChartBase,
|
HaChartBase,
|
||||||
MIN_TIME_BETWEEN_UPDATES,
|
MIN_TIME_BETWEEN_UPDATES,
|
||||||
} from "./ha-chart-base";
|
} from "./ha-chart-base";
|
||||||
|
import { clickIsTouch } from "./click_is_touch";
|
||||||
|
|
||||||
const safeParseFloat = (value) => {
|
const safeParseFloat = (value) => {
|
||||||
const parsed = parseFloat(value);
|
const parsed = parseFloat(value);
|
||||||
@ -220,12 +221,7 @@ export class StateHistoryChartLine extends LitElement {
|
|||||||
// @ts-expect-error
|
// @ts-expect-error
|
||||||
locale: numberFormatToLocale(this.hass.locale),
|
locale: numberFormatToLocale(this.hass.locale),
|
||||||
onClick: (e: any) => {
|
onClick: (e: any) => {
|
||||||
if (
|
if (!this.clickForMoreInfo || clickIsTouch(e)) {
|
||||||
!this.clickForMoreInfo ||
|
|
||||||
!(e.native instanceof MouseEvent) ||
|
|
||||||
(e.native instanceof PointerEvent &&
|
|
||||||
e.native.pointerType !== "mouse")
|
|
||||||
) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,6 +16,7 @@ import {
|
|||||||
} from "./ha-chart-base";
|
} from "./ha-chart-base";
|
||||||
import type { TimeLineData } from "./timeline-chart/const";
|
import type { TimeLineData } from "./timeline-chart/const";
|
||||||
import { computeTimelineColor } from "./timeline-chart/timeline-color";
|
import { computeTimelineColor } from "./timeline-chart/timeline-color";
|
||||||
|
import { clickIsTouch } from "./click_is_touch";
|
||||||
|
|
||||||
@customElement("state-history-chart-timeline")
|
@customElement("state-history-chart-timeline")
|
||||||
export class StateHistoryChartTimeline extends LitElement {
|
export class StateHistoryChartTimeline extends LitElement {
|
||||||
@ -224,11 +225,7 @@ export class StateHistoryChartTimeline extends LitElement {
|
|||||||
// @ts-expect-error
|
// @ts-expect-error
|
||||||
locale: numberFormatToLocale(this.hass.locale),
|
locale: numberFormatToLocale(this.hass.locale),
|
||||||
onClick: (e: any) => {
|
onClick: (e: any) => {
|
||||||
if (
|
if (!this.clickForMoreInfo || clickIsTouch(e)) {
|
||||||
!this.clickForMoreInfo ||
|
|
||||||
!(e.native instanceof MouseEvent) ||
|
|
||||||
(e.native instanceof PointerEvent && e.native.pointerType !== "mouse")
|
|
||||||
) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,6 +39,7 @@ import type {
|
|||||||
ChartDatasetExtra,
|
ChartDatasetExtra,
|
||||||
HaChartBase,
|
HaChartBase,
|
||||||
} from "./ha-chart-base";
|
} from "./ha-chart-base";
|
||||||
|
import { clickIsTouch } from "./click_is_touch";
|
||||||
|
|
||||||
export const supportedStatTypeMap: Record<StatisticType, StatisticType> = {
|
export const supportedStatTypeMap: Record<StatisticType, StatisticType> = {
|
||||||
mean: "mean",
|
mean: "mean",
|
||||||
@ -278,11 +279,7 @@ export class StatisticsChart extends LitElement {
|
|||||||
// @ts-expect-error
|
// @ts-expect-error
|
||||||
locale: numberFormatToLocale(this.hass.locale),
|
locale: numberFormatToLocale(this.hass.locale),
|
||||||
onClick: (e: any) => {
|
onClick: (e: any) => {
|
||||||
if (
|
if (!this.clickForMoreInfo || clickIsTouch(e)) {
|
||||||
!this.clickForMoreInfo ||
|
|
||||||
!(e.native instanceof MouseEvent) ||
|
|
||||||
(e.native instanceof PointerEvent && e.native.pointerType !== "mouse")
|
|
||||||
) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,6 +30,7 @@ import {
|
|||||||
getStatisticLabel,
|
getStatisticLabel,
|
||||||
Statistics,
|
Statistics,
|
||||||
StatisticsMetaData,
|
StatisticsMetaData,
|
||||||
|
isExternalStatistic,
|
||||||
} from "../../../../data/recorder";
|
} from "../../../../data/recorder";
|
||||||
import { FrontendLocaleData } from "../../../../data/translation";
|
import { FrontendLocaleData } from "../../../../data/translation";
|
||||||
import { SubscribeMixin } from "../../../../mixins/subscribe-mixin";
|
import { SubscribeMixin } from "../../../../mixins/subscribe-mixin";
|
||||||
@ -38,7 +39,9 @@ import { LovelaceCard } from "../../types";
|
|||||||
import { EnergyDevicesDetailGraphCardConfig } from "../types";
|
import { EnergyDevicesDetailGraphCardConfig } from "../types";
|
||||||
import { hasConfigChanged } from "../../common/has-changed";
|
import { hasConfigChanged } from "../../common/has-changed";
|
||||||
import { getCommonOptions } from "./common/energy-chart-options";
|
import { getCommonOptions } from "./common/energy-chart-options";
|
||||||
|
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||||
import { storage } from "../../../../common/decorators/storage";
|
import { storage } from "../../../../common/decorators/storage";
|
||||||
|
import { clickIsTouch } from "../../../../components/chart/click_is_touch";
|
||||||
|
|
||||||
const UNIT = "kWh";
|
const UNIT = "kWh";
|
||||||
|
|
||||||
@ -197,6 +200,20 @@ export class HuiEnergyDevicesDetailGraphCard
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
onClick: (event, elements, chart) => {
|
||||||
|
if (clickIsTouch(event)) return;
|
||||||
|
|
||||||
|
const index = elements[0]?.datasetIndex ?? -1;
|
||||||
|
if (index < 0) return;
|
||||||
|
|
||||||
|
const statisticId =
|
||||||
|
this._data?.prefs.device_consumption[index]?.stat_consumption;
|
||||||
|
|
||||||
|
if (!statisticId || isExternalStatistic(statisticId)) return;
|
||||||
|
|
||||||
|
fireEvent(this, "hass-more-info", { entityId: statisticId });
|
||||||
|
chart?.canvas?.dispatchEvent(new Event("mouseout")); // to hide tooltip
|
||||||
|
},
|
||||||
};
|
};
|
||||||
return options;
|
return options;
|
||||||
}
|
}
|
||||||
|
@ -31,6 +31,7 @@ import { EnergyData, getEnergyDataCollection } from "../../../../data/energy";
|
|||||||
import {
|
import {
|
||||||
calculateStatisticSumGrowth,
|
calculateStatisticSumGrowth,
|
||||||
getStatisticLabel,
|
getStatisticLabel,
|
||||||
|
isExternalStatistic,
|
||||||
} from "../../../../data/recorder";
|
} from "../../../../data/recorder";
|
||||||
import { FrontendLocaleData } from "../../../../data/translation";
|
import { FrontendLocaleData } from "../../../../data/translation";
|
||||||
import { SubscribeMixin } from "../../../../mixins/subscribe-mixin";
|
import { SubscribeMixin } from "../../../../mixins/subscribe-mixin";
|
||||||
@ -38,6 +39,7 @@ import { HomeAssistant } from "../../../../types";
|
|||||||
import { LovelaceCard } from "../../types";
|
import { LovelaceCard } from "../../types";
|
||||||
import { EnergyDevicesGraphCardConfig } from "../types";
|
import { EnergyDevicesGraphCardConfig } from "../types";
|
||||||
import { hasConfigChanged } from "../../common/has-changed";
|
import { hasConfigChanged } from "../../common/has-changed";
|
||||||
|
import { clickIsTouch } from "../../../../components/chart/click_is_touch";
|
||||||
|
|
||||||
@customElement("hui-energy-devices-graph-card")
|
@customElement("hui-energy-devices-graph-card")
|
||||||
export class HuiEnergyDevicesGraphCard
|
export class HuiEnergyDevicesGraphCard
|
||||||
@ -158,15 +160,18 @@ export class HuiEnergyDevicesGraphCard
|
|||||||
// @ts-expect-error
|
// @ts-expect-error
|
||||||
locale: numberFormatToLocale(this.hass.locale),
|
locale: numberFormatToLocale(this.hass.locale),
|
||||||
onClick: (e: any) => {
|
onClick: (e: any) => {
|
||||||
|
if (clickIsTouch(e)) return;
|
||||||
const chart = e.chart;
|
const chart = e.chart;
|
||||||
const canvasPosition = getRelativePosition(e, chart);
|
const canvasPosition = getRelativePosition(e, chart);
|
||||||
|
|
||||||
const index = Math.abs(
|
const index = Math.abs(
|
||||||
chart.scales.y.getValueForPixel(canvasPosition.y)
|
chart.scales.y.getValueForPixel(canvasPosition.y)
|
||||||
);
|
);
|
||||||
|
// @ts-ignore
|
||||||
|
const statisticId = this._chartData?.datasets[0]?.data[index]?.y;
|
||||||
|
if (!statisticId || isExternalStatistic(statisticId)) return;
|
||||||
fireEvent(this, "hass-more-info", {
|
fireEvent(this, "hass-more-info", {
|
||||||
// @ts-ignore
|
entityId: statisticId,
|
||||||
entityId: this._chartData?.datasets[0]?.data[index]?.y,
|
|
||||||
});
|
});
|
||||||
chart.canvas.dispatchEvent(new Event("mouseout")); // to hide tooltip
|
chart.canvas.dispatchEvent(new Event("mouseout")); // to hide tooltip
|
||||||
},
|
},
|
||||||
|
@ -11,6 +11,7 @@ import {
|
|||||||
PropertyValues,
|
PropertyValues,
|
||||||
} from "lit";
|
} from "lit";
|
||||||
import { customElement, property, state } from "lit/decorators";
|
import { customElement, property, state } from "lit/decorators";
|
||||||
|
import { classMap } from "lit/directives/class-map";
|
||||||
import { styleMap } from "lit/directives/style-map";
|
import { styleMap } from "lit/directives/style-map";
|
||||||
import { formatNumber } from "../../../../common/number/format_number";
|
import { formatNumber } from "../../../../common/number/format_number";
|
||||||
import { getEnergyColor } from "./common/color";
|
import { getEnergyColor } from "./common/color";
|
||||||
@ -25,12 +26,14 @@ import {
|
|||||||
import {
|
import {
|
||||||
calculateStatisticSumGrowth,
|
calculateStatisticSumGrowth,
|
||||||
getStatisticLabel,
|
getStatisticLabel,
|
||||||
|
isExternalStatistic,
|
||||||
} from "../../../../data/recorder";
|
} from "../../../../data/recorder";
|
||||||
import { SubscribeMixin } from "../../../../mixins/subscribe-mixin";
|
import { SubscribeMixin } from "../../../../mixins/subscribe-mixin";
|
||||||
import { HomeAssistant } from "../../../../types";
|
import { HomeAssistant } from "../../../../types";
|
||||||
import { LovelaceCard } from "../../types";
|
import { LovelaceCard } from "../../types";
|
||||||
import { EnergySourcesTableCardConfig } from "../types";
|
import { EnergySourcesTableCardConfig } from "../types";
|
||||||
import { hasConfigChanged } from "../../common/has-changed";
|
import { hasConfigChanged } from "../../common/has-changed";
|
||||||
|
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||||
|
|
||||||
const colorPropertyMap = {
|
const colorPropertyMap = {
|
||||||
grid_return: "--energy-grid-return-color",
|
grid_return: "--energy-grid-return-color",
|
||||||
@ -225,7 +228,13 @@ export class HuiEnergySourcesTableCard
|
|||||||
0;
|
0;
|
||||||
totalSolarCompare += compareEnergy;
|
totalSolarCompare += compareEnergy;
|
||||||
|
|
||||||
return html`<tr class="mdc-data-table__row">
|
return html`<tr
|
||||||
|
class="mdc-data-table__row ${classMap({
|
||||||
|
clickable: !isExternalStatistic(source.stat_energy_from),
|
||||||
|
})}"
|
||||||
|
@click=${this._handleMoreInfo}
|
||||||
|
.entity=${source.stat_energy_from}
|
||||||
|
>
|
||||||
<td class="mdc-data-table__cell cell-bullet">
|
<td class="mdc-data-table__cell cell-bullet">
|
||||||
<div
|
<div
|
||||||
class="bullet"
|
class="bullet"
|
||||||
@ -330,7 +339,13 @@ export class HuiEnergySourcesTableCard
|
|||||||
0;
|
0;
|
||||||
totalBatteryCompare += energyFromCompare - energyToCompare;
|
totalBatteryCompare += energyFromCompare - energyToCompare;
|
||||||
|
|
||||||
return html`<tr class="mdc-data-table__row">
|
return html`<tr
|
||||||
|
class="mdc-data-table__row ${classMap({
|
||||||
|
clickable: !isExternalStatistic(source.stat_energy_from),
|
||||||
|
})}"
|
||||||
|
@click=${this._handleMoreInfo}
|
||||||
|
.entity=${source.stat_energy_from}
|
||||||
|
>
|
||||||
<td class="mdc-data-table__cell cell-bullet">
|
<td class="mdc-data-table__cell cell-bullet">
|
||||||
<div
|
<div
|
||||||
class="bullet"
|
class="bullet"
|
||||||
@ -381,7 +396,13 @@ export class HuiEnergySourcesTableCard
|
|||||||
? html`<td class="mdc-data-table__cell"></td>`
|
? html`<td class="mdc-data-table__cell"></td>`
|
||||||
: ""}
|
: ""}
|
||||||
</tr>
|
</tr>
|
||||||
<tr class="mdc-data-table__row">
|
<tr
|
||||||
|
class="mdc-data-table__row ${classMap({
|
||||||
|
clickable: !isExternalStatistic(source.stat_energy_to),
|
||||||
|
})}"
|
||||||
|
@click=${this._handleMoreInfo}
|
||||||
|
.entity=${source.stat_energy_to}
|
||||||
|
>
|
||||||
<td class="mdc-data-table__cell cell-bullet">
|
<td class="mdc-data-table__cell cell-bullet">
|
||||||
<div
|
<div
|
||||||
class="bullet"
|
class="bullet"
|
||||||
@ -508,7 +529,13 @@ export class HuiEnergySourcesTableCard
|
|||||||
totalGridCostCompare += costCompare;
|
totalGridCostCompare += costCompare;
|
||||||
}
|
}
|
||||||
|
|
||||||
return html`<tr class="mdc-data-table__row">
|
return html`<tr
|
||||||
|
class="mdc-data-table__row ${classMap({
|
||||||
|
clickable: !isExternalStatistic(flow.stat_energy_from),
|
||||||
|
})}"
|
||||||
|
@click=${this._handleMoreInfo}
|
||||||
|
.entity=${flow.stat_energy_from}
|
||||||
|
>
|
||||||
<td class="mdc-data-table__cell cell-bullet">
|
<td class="mdc-data-table__cell cell-bullet">
|
||||||
<div
|
<div
|
||||||
class="bullet"
|
class="bullet"
|
||||||
@ -619,7 +646,13 @@ export class HuiEnergySourcesTableCard
|
|||||||
totalGridCostCompare += costCompare;
|
totalGridCostCompare += costCompare;
|
||||||
}
|
}
|
||||||
|
|
||||||
return html`<tr class="mdc-data-table__row">
|
return html`<tr
|
||||||
|
class="mdc-data-table__row ${classMap({
|
||||||
|
clickable: !isExternalStatistic(flow.stat_energy_to),
|
||||||
|
})}"
|
||||||
|
@click=${this._handleMoreInfo}
|
||||||
|
.entity=${flow.stat_energy_to}
|
||||||
|
>
|
||||||
<td class="mdc-data-table__cell cell-bullet">
|
<td class="mdc-data-table__cell cell-bullet">
|
||||||
<div
|
<div
|
||||||
class="bullet"
|
class="bullet"
|
||||||
@ -784,7 +817,13 @@ export class HuiEnergySourcesTableCard
|
|||||||
totalGasCostCompare += costCompare;
|
totalGasCostCompare += costCompare;
|
||||||
}
|
}
|
||||||
|
|
||||||
return html`<tr class="mdc-data-table__row">
|
return html`<tr
|
||||||
|
class="mdc-data-table__row ${classMap({
|
||||||
|
clickable: !isExternalStatistic(source.stat_energy_from),
|
||||||
|
})}"
|
||||||
|
@click=${this._handleMoreInfo}
|
||||||
|
.entity=${source.stat_energy_from}
|
||||||
|
>
|
||||||
<td class="mdc-data-table__cell cell-bullet">
|
<td class="mdc-data-table__cell cell-bullet">
|
||||||
<div
|
<div
|
||||||
class="bullet"
|
class="bullet"
|
||||||
@ -942,7 +981,13 @@ export class HuiEnergySourcesTableCard
|
|||||||
totalWaterCostCompare += costCompare;
|
totalWaterCostCompare += costCompare;
|
||||||
}
|
}
|
||||||
|
|
||||||
return html`<tr class="mdc-data-table__row">
|
return html`<tr
|
||||||
|
class="mdc-data-table__row ${classMap({
|
||||||
|
clickable: !isExternalStatistic(source.stat_energy_from),
|
||||||
|
})}"
|
||||||
|
@click=${this._handleMoreInfo}
|
||||||
|
.entity=${source.stat_energy_from}
|
||||||
|
>
|
||||||
<td class="mdc-data-table__cell cell-bullet">
|
<td class="mdc-data-table__cell cell-bullet">
|
||||||
<div
|
<div
|
||||||
class="bullet"
|
class="bullet"
|
||||||
@ -1111,6 +1156,13 @@ export class HuiEnergySourcesTableCard
|
|||||||
</ha-card>`;
|
</ha-card>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _handleMoreInfo(ev): void {
|
||||||
|
const entityId = ev.currentTarget?.entity;
|
||||||
|
if (entityId && !isExternalStatistic(entityId)) {
|
||||||
|
fireEvent(this, "hass-more-info", { entityId });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static get styles(): CSSResultGroup {
|
static get styles(): CSSResultGroup {
|
||||||
return css`
|
return css`
|
||||||
${unsafeCSS(dataTableStyles)}
|
${unsafeCSS(dataTableStyles)}
|
||||||
@ -1127,6 +1179,9 @@ export class HuiEnergySourcesTableCard
|
|||||||
.mdc-data-table__row:not(.mdc-data-table__row--selected):hover {
|
.mdc-data-table__row:not(.mdc-data-table__row--selected):hover {
|
||||||
background-color: rgba(var(--rgb-primary-text-color), 0.04);
|
background-color: rgba(var(--rgb-primary-text-color), 0.04);
|
||||||
}
|
}
|
||||||
|
.clickable {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
.total {
|
.total {
|
||||||
--mdc-typography-body2-font-weight: 500;
|
--mdc-typography-body2-font-weight: 500;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user