1
0
mirror of https://github.com/home-assistant/frontend.git synced 2026-02-15 07:25:54 +00:00

Show the total value in energy graphs (#27265)

* Show the total value in energy graphs

* format

* Apply suggestions from code review

Co-authored-by: Bram Kragten <mail@bramkragten.nl>

---------

Co-authored-by: Bram Kragten <mail@bramkragten.nl>
This commit is contained in:
Petar Petrov
2025-10-03 14:01:29 +03:00
committed by GitHub
parent b02368b9c6
commit 76c9723c71
4 changed files with 139 additions and 9 deletions

View File

@@ -0,0 +1,34 @@
import { css, html, LitElement } from "lit";
import { customElement, property } from "lit/decorators";
import "../../../../../components/ha-tooltip";
@customElement("hui-energy-graph-chip")
export class HuiEnergyGraphChip extends LitElement {
@property({ type: String }) public tooltip?: string;
protected render() {
const id = `energy-graph-chip-${Date.now()}`;
return html`
<div class="chip" id=${id}>
<slot></slot>
</div>
<ha-tooltip for=${id} placement="top">${this.tooltip}</ha-tooltip>
`;
}
static styles = css`
.chip {
font-size: var(--ha-font-size-m);
font-weight: var(--ha-font-weight-medium);
padding: var(--ha-space-1) var(--ha-space-2);
border-radius: var(--ha-border-radius-md);
border: 1px solid var(--divider-color);
}
`;
}
declare global {
interface HTMLElementTagNameMap {
"hui-energy-graph-chip": HuiEnergyGraphChip;
}
}

View File

@@ -29,6 +29,8 @@ import {
getCompareTransform,
} from "./common/energy-chart-options";
import type { ECOption } from "../../../../resources/echarts";
import "./common/hui-energy-graph-chip";
import "../../../../components/ha-tooltip";
@customElement("hui-energy-gas-graph-card")
export class HuiEnergyGasGraphCard
@@ -51,6 +53,8 @@ export class HuiEnergyGasGraphCard
@state() private _unit?: string;
@state() private _total?: number;
protected hassSubscribeRequiredHostProps = ["_config"];
public hassSubscribe(): UnsubscribeFunc[] {
@@ -84,9 +88,16 @@ export class HuiEnergyGasGraphCard
return html`
<ha-card>
${this._config.title
? html`<h1 class="card-header">${this._config.title}</h1>`
: ""}
<div class="card-header">
<span>${this._config.title ? this._config.title : nothing}</span>
${this._total
? html`<hui-energy-graph-chip
.tooltip=${this._formatTotal(this._total)}
>
${formatNumber(this._total, this.hass.locale)} ${this._unit}
</hui-energy-graph-chip>`
: nothing}
</div>
<div
class="content ${classMap({
"has-header": !!this._config.title,
@@ -199,6 +210,24 @@ export class HuiEnergyGasGraphCard
fillDataGapsAndRoundCaps(datasets);
this._chartData = datasets;
this._total = this._processTotal(energyData.stats, gasSources);
}
private _processTotal(
statistics: Statistics,
gasSources: GasSourceTypeEnergyPreference[]
) {
return gasSources.reduce(
(sum, source) =>
sum +
(source.stat_energy_from in statistics
? statistics[source.stat_energy_from].reduce(
(acc, curr) => acc + (curr.change || 0),
0
)
: 0),
0
);
}
private _processDataSet(
@@ -288,6 +317,9 @@ export class HuiEnergyGasGraphCard
height: 100%;
}
.card-header {
display: flex;
justify-content: space-between;
align-items: center;
padding-bottom: 0;
}
.content {

View File

@@ -32,6 +32,8 @@ import {
getCommonOptions,
getCompareTransform,
} from "./common/energy-chart-options";
import "./common/hui-energy-graph-chip";
import "../../../../components/ha-tooltip";
import type { ECOption } from "../../../../resources/echarts";
@customElement("hui-energy-solar-graph-card")
@@ -53,6 +55,8 @@ export class HuiEnergySolarGraphCard
@state() private _compareEnd?: Date;
@state() private _total?: number;
protected hassSubscribeRequiredHostProps = ["_config"];
public hassSubscribe(): UnsubscribeFunc[] {
@@ -86,9 +90,16 @@ export class HuiEnergySolarGraphCard
return html`
<ha-card>
${this._config.title
? html`<h1 class="card-header">${this._config.title}</h1>`
: ""}
<div class="card-header">
<span>${this._config.title ? this._config.title : nothing}</span>
${this._total
? html`<hui-energy-graph-chip
.tooltip=${this._formatTotal(this._total)}
>
${formatNumber(this._total, this.hass.locale)} kWh
</hui-energy-graph-chip>`
: nothing}
</div>
<div
class="content ${classMap({
"has-header": !!this._config.title,
@@ -222,6 +233,24 @@ export class HuiEnergySolarGraphCard
}
this._chartData = datasets;
this._total = this._processTotal(energyData.stats, solarSources);
}
private _processTotal(
statistics: Statistics,
solarSources: SolarSourceTypeEnergyPreference[]
) {
return solarSources.reduce(
(sum, source) =>
sum +
(source.stat_energy_from in statistics
? statistics[source.stat_energy_from].reduce(
(acc, curr) => acc + (curr.change || 0),
0
)
: 0),
0
);
}
private _processDataSet(
@@ -400,6 +429,9 @@ export class HuiEnergySolarGraphCard
height: 100%;
}
.card-header {
display: flex;
justify-content: space-between;
align-items: center;
padding-bottom: 0;
}
.content {

View File

@@ -29,6 +29,8 @@ import {
} from "./common/energy-chart-options";
import type { ECOption } from "../../../../resources/echarts";
import { formatNumber } from "../../../../common/number/format_number";
import "./common/hui-energy-graph-chip";
import "../../../../components/ha-tooltip";
@customElement("hui-energy-water-graph-card")
export class HuiEnergyWaterGraphCard
@@ -51,6 +53,8 @@ export class HuiEnergyWaterGraphCard
@state() private _unit?: string;
@state() private _total?: number;
protected hassSubscribeRequiredHostProps = ["_config"];
public hassSubscribe(): UnsubscribeFunc[] {
@@ -84,9 +88,16 @@ export class HuiEnergyWaterGraphCard
return html`
<ha-card>
${this._config.title
? html`<h1 class="card-header">${this._config.title}</h1>`
: ""}
<div class="card-header">
<span>${this._config.title ? this._config.title : nothing}</span>
${this._total
? html`<hui-energy-graph-chip
.tooltip=${this._formatTotal(this._total)}
>
${formatNumber(this._total, this.hass.locale)} ${this._unit}
</hui-energy-graph-chip>`
: nothing}
</div>
<div
class="content ${classMap({
"has-header": !!this._config.title,
@@ -199,6 +210,24 @@ export class HuiEnergyWaterGraphCard
fillDataGapsAndRoundCaps(datasets);
this._chartData = datasets;
this._total = this._processTotal(energyData.stats, waterSources);
}
private _processTotal(
statistics: Statistics,
waterSources: WaterSourceTypeEnergyPreference[]
) {
return waterSources.reduce(
(sum, source) =>
sum +
(source.stat_energy_from in statistics
? statistics[source.stat_energy_from].reduce(
(acc, curr) => acc + (curr.change || 0),
0
)
: 0),
0
);
}
private _processDataSet(
@@ -288,6 +317,9 @@ export class HuiEnergyWaterGraphCard
height: 100%;
}
.card-header {
display: flex;
justify-content: space-between;
align-items: center;
padding-bottom: 0;
}
.content {