Open more-info on label click in echarts (#23921)

* Open more-info on label click in echarts

* check isExternalStatistic in energy devices click
This commit is contained in:
Petar Petrov 2025-01-29 16:44:21 +02:00 committed by GitHub
parent a2f2d64f5c
commit 25d2a5ddac
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 56 additions and 1 deletions

View File

@ -6,7 +6,11 @@ import { mdiRestart } from "@mdi/js";
import type { EChartsType } from "echarts/core"; import type { EChartsType } from "echarts/core";
import type { DataZoomComponentOption } from "echarts/components"; import type { DataZoomComponentOption } from "echarts/components";
import { ResizeController } from "@lit-labs/observers/resize-controller"; import { ResizeController } from "@lit-labs/observers/resize-controller";
import type { XAXisOption, YAXisOption } from "echarts/types/dist/shared"; import type {
ECElementEvent,
XAXisOption,
YAXisOption,
} from "echarts/types/dist/shared";
import { consume } from "@lit-labs/context"; import { consume } from "@lit-labs/context";
import { fireEvent } from "../../common/dom/fire_event"; import { fireEvent } from "../../common/dom/fire_event";
import type { HomeAssistant } from "../../types"; import type { HomeAssistant } from "../../types";
@ -197,6 +201,15 @@ export class HaChartBase extends LitElement {
const { start, end } = e.batch?.[0] ?? e; const { start, end } = e.batch?.[0] ?? e;
this._isZoomed = start !== 0 || end !== 100; this._isZoomed = start !== 0 || end !== 100;
}); });
this.chart.on("click", (e: ECElementEvent) => {
fireEvent(this, "chart-click", e);
});
this.chart.on("mousemove", (e: ECElementEvent) => {
if (e.componentType === "series" && e.componentSubType === "custom") {
// custom series do not support cursor style so we need to set it manually
this.chart?.getZr()?.setCursorStyle("default");
}
});
this.chart.setOption({ ...this._createOptions(), series: this.data }); this.chart.setOption({ ...this._createOptions(), series: this.data });
} finally { } finally {
this._loading = false; this._loading = false;
@ -318,5 +331,6 @@ declare global {
interface HASSDomEvents { interface HASSDomEvents {
"dataset-hidden": { name: string }; "dataset-hidden": { name: string };
"dataset-unhidden": { name: string }; "dataset-unhidden": { name: string };
"chart-click": ECElementEvent;
} }
} }

View File

@ -316,6 +316,7 @@ export class StateHistoryChartLine extends LitElement {
id: nameY, id: nameY,
data: [], data: [],
type: "line", type: "line",
cursor: "default",
name: nameY, name: nameY,
color, color,
symbol: "circle", symbol: "circle",

View File

@ -4,6 +4,7 @@ import { customElement, property, state } from "lit/decorators";
import type { import type {
CustomSeriesOption, CustomSeriesOption,
CustomSeriesRenderItem, CustomSeriesRenderItem,
ECElementEvent,
TooltipFormatterCallback, TooltipFormatterCallback,
TooltipPositionCallbackParams, TooltipPositionCallbackParams,
} from "echarts/types/dist/shared"; } from "echarts/types/dist/shared";
@ -67,6 +68,7 @@ export class StateHistoryChartTimeline extends LitElement {
.options=${this._chartOptions} .options=${this._chartOptions}
.height=${`${this.data.length * 30 + 30}px`} .height=${`${this.data.length * 30 + 30}px`}
.data=${this._chartData} .data=${this._chartData}
@chart-click=${this._handleChartClick}
></ha-chart-base> ></ha-chart-base>
`; `;
} }
@ -215,6 +217,7 @@ export class StateHistoryChartTimeline extends LitElement {
type: "category", type: "category",
inverse: true, inverse: true,
position: rtl ? "right" : "left", position: rtl ? "right" : "left",
triggerEvent: true,
axisTick: { axisTick: {
show: false, show: false,
}, },
@ -359,6 +362,17 @@ export class StateHistoryChartTimeline extends LitElement {
this._chartData = datasets; this._chartData = datasets;
} }
private _handleChartClick(e: CustomEvent<ECElementEvent>): void {
if (e.detail.targetType === "axisLabel") {
const dataset = this.data[e.detail.dataIndex];
if (dataset) {
fireEvent(this, "hass-more-info", {
entityId: dataset.entity_id,
});
}
}
}
static styles = css` static styles = css`
ha-chart-base { ha-chart-base {
--chart-max-height: none; --chart-max-height: none;

View File

@ -424,6 +424,7 @@ export class StatisticsChart extends LitElement {
const series: LineSeriesOption | BarSeriesOption = { const series: LineSeriesOption | BarSeriesOption = {
id: `${statistic_id}-${type}`, id: `${statistic_id}-${type}`,
type: this.chartType, type: this.chartType,
cursor: "default",
data: [], data: [],
name: name name: name
? `${name} (${this.hass.localize( ? `${name} (${this.hass.localize(

View File

@ -335,6 +335,7 @@ export class HuiEnergyDevicesDetailGraphCard
}); });
const dataset: BarSeriesOption = { const dataset: BarSeriesOption = {
type: "bar", type: "bar",
cursor: "default",
id: compare ? "compare-untracked" : "untracked", id: compare ? "compare-untracked" : "untracked",
name: this.hass.localize( name: this.hass.localize(
"ui.panel.lovelace.cards.energy.energy_devices_detail_graph.untracked_consumption" "ui.panel.lovelace.cards.energy.energy_devices_detail_graph.untracked_consumption"
@ -417,6 +418,7 @@ export class HuiEnergyDevicesDetailGraphCard
data.push({ data.push({
type: "bar", type: "bar",
cursor: "default",
id: compare id: compare
? `compare-${source.stat_consumption}` ? `compare-${source.stat_consumption}`
: source.stat_consumption, : source.stat_consumption,

View File

@ -5,6 +5,7 @@ import { customElement, property, state } from "lit/decorators";
import { classMap } from "lit/directives/class-map"; import { classMap } from "lit/directives/class-map";
import memoizeOne from "memoize-one"; import memoizeOne from "memoize-one";
import type { BarSeriesOption } from "echarts/charts"; import type { BarSeriesOption } from "echarts/charts";
import type { ECElementEvent } from "echarts/types/dist/shared";
import { getGraphColorByIndex } from "../../../../common/color/colors"; import { getGraphColorByIndex } from "../../../../common/color/colors";
import { import {
formatNumber, formatNumber,
@ -16,6 +17,7 @@ import { getEnergyDataCollection } from "../../../../data/energy";
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 type { HomeAssistant } from "../../../../types"; import type { HomeAssistant } from "../../../../types";
@ -24,6 +26,7 @@ import type { EnergyDevicesGraphCardConfig } from "../types";
import { hasConfigChanged } from "../../common/has-changed"; import { hasConfigChanged } from "../../common/has-changed";
import type { ECOption } from "../../../../resources/echarts"; import type { ECOption } from "../../../../resources/echarts";
import "../../../../components/ha-card"; import "../../../../components/ha-card";
import { fireEvent } from "../../../../common/dom/fire_event";
@customElement("hui-energy-devices-graph-card") @customElement("hui-energy-devices-graph-card")
export class HuiEnergyDevicesGraphCard export class HuiEnergyDevicesGraphCard
@ -87,6 +90,7 @@ export class HuiEnergyDevicesGraphCard
.data=${this._chartData} .data=${this._chartData}
.options=${this._createOptions(this.hass.themes?.darkMode)} .options=${this._createOptions(this.hass.themes?.darkMode)}
.height=${`${(this._chartData[0]?.data?.length || 0) * 28 + 50}px`} .height=${`${(this._chartData[0]?.data?.length || 0) * 28 + 50}px`}
@chart-click=${this._handleChartClick}
></ha-chart-base> ></ha-chart-base>
</div> </div>
</ha-card> </ha-card>
@ -117,6 +121,7 @@ export class HuiEnergyDevicesGraphCard
yAxis: { yAxis: {
type: "category", type: "category",
inverse: true, inverse: true,
triggerEvent: true,
axisLabel: { axisLabel: {
formatter: this._getDeviceName.bind(this), formatter: this._getDeviceName.bind(this),
overflow: "truncate", overflow: "truncate",
@ -167,6 +172,7 @@ export class HuiEnergyDevicesGraphCard
}, },
data: chartData, data: chartData,
barWidth: compareData ? 10 : 20, barWidth: compareData ? 10 : 20,
cursor: "default",
}, },
]; ];
@ -181,6 +187,7 @@ export class HuiEnergyDevicesGraphCard
}, },
data: chartDataCompare, data: chartDataCompare,
barWidth: 10, barWidth: 10,
cursor: "default",
}); });
} }
@ -229,6 +236,18 @@ export class HuiEnergyDevicesGraphCard
await this.updateComplete; await this.updateComplete;
} }
private _handleChartClick(e: CustomEvent<ECElementEvent>): void {
if (
e.detail.targetType === "axisLabel" &&
e.detail.value &&
!isExternalStatistic(e.detail.value as string)
) {
fireEvent(this, "hass-more-info", {
entityId: e.detail.value as string,
});
}
}
static styles = css` static styles = css`
.card-header { .card-header {
padding-bottom: 0; padding-bottom: 0;

View File

@ -248,6 +248,7 @@ export class HuiEnergyGasGraphCard
data.push({ data.push({
type: "bar", type: "bar",
cursor: "default",
id: compare id: compare
? "compare-" + source.stat_energy_from ? "compare-" + source.stat_energy_from
: source.stat_energy_from, : source.stat_energy_from,

View File

@ -267,6 +267,7 @@ export class HuiEnergySolarGraphCard
data.push({ data.push({
type: "bar", type: "bar",
cursor: "default",
id: compare id: compare
? "compare-" + source.stat_energy_from ? "compare-" + source.stat_energy_from
: source.stat_energy_from, : source.stat_energy_from,

View File

@ -502,6 +502,7 @@ export class HuiEnergyUsageGraphCard
data.push({ data.push({
id: compare ? "compare-" + statId : statId, id: compare ? "compare-" + statId : statId,
type: "bar", type: "bar",
cursor: "default",
name: name:
type in labels type in labels
? labels[type] ? labels[type]

View File

@ -246,6 +246,7 @@ export class HuiEnergyWaterGraphCard
data.push({ data.push({
type: "bar", type: "bar",
cursor: "default",
id: compare id: compare
? "compare-" + source.stat_energy_from ? "compare-" + source.stat_energy_from
: source.stat_energy_from, : source.stat_energy_from,