diff --git a/src/components/chart/ha-chart-base.ts b/src/components/chart/ha-chart-base.ts
index 1bcfa3871f..edccd2d22c 100644
--- a/src/components/chart/ha-chart-base.ts
+++ b/src/components/chart/ha-chart-base.ts
@@ -5,10 +5,18 @@ import type {
ChartOptions,
TooltipModel,
} from "chart.js";
-import { css, CSSResultGroup, html, LitElement, PropertyValues } from "lit";
+import {
+ css,
+ CSSResultGroup,
+ html,
+ nothing,
+ LitElement,
+ PropertyValues,
+} from "lit";
import { customElement, property, state } from "lit/decorators";
import { classMap } from "lit/directives/class-map";
import { styleMap } from "lit/directives/style-map";
+import { fireEvent } from "../../common/dom/fire_event";
import { clamp } from "../../common/number/clamp";
import { HomeAssistant } from "../../types";
import { debounce } from "../../common/util/debounce";
@@ -27,6 +35,11 @@ interface Tooltip
left: string;
}
+export interface ChartDatasetExtra {
+ show_legend?: boolean;
+ legend_label?: string;
+}
+
@customElement("ha-chart-base")
export class HaChartBase extends LitElement {
public chart?: Chart;
@@ -38,6 +51,8 @@ export class HaChartBase extends LitElement {
@property({ attribute: false }) public data: ChartData = { datasets: [] };
+ @property({ attribute: false }) public extraData?: ChartDatasetExtra[];
+
@property({ attribute: false }) public options?: ChartOptions;
@property({ attribute: false }) public plugins?: any[];
@@ -46,6 +61,8 @@ export class HaChartBase extends LitElement {
@property({ type: Number }) public paddingYAxis = 0;
+ @property({ type: Boolean }) public externalHidden = false;
+
@state() private _chartHeight?: number;
@state() private _tooltip?: Tooltip;
@@ -148,6 +165,19 @@ export class HaChartBase extends LitElement {
}
}
+ if (changedProps.has("data")) {
+ if (this.externalHidden) {
+ this._hiddenDatasets = new Set();
+ if (this.data?.datasets) {
+ this.data.datasets.forEach((dataset, index) => {
+ if (dataset.hidden) {
+ this._hiddenDatasets.add(index);
+ }
+ });
+ }
+ }
+ }
+
if (!this.hasUpdated || !this.chart) {
return;
}
@@ -157,7 +187,7 @@ export class HaChartBase extends LitElement {
return;
}
if (changedProps.has("data")) {
- if (this._hiddenDatasets.size) {
+ if (this._hiddenDatasets.size && !this.externalHidden) {
this.data.datasets.forEach((dataset, index) => {
dataset.hidden = this._hiddenDatasets.has(index);
});
@@ -175,25 +205,30 @@ export class HaChartBase extends LitElement {
${this.options?.plugins?.legend?.display === true
? html`
- ${this.data.datasets.map(
- (dataset, index) =>
- html`-
-
+ this.extraData?.[index]?.show_legend === false
+ ? nothing
+ : html`
- ${dataset.label}
- `
+ .title=${this.extraData?.[index]?.legend_label ??
+ dataset.label}
+ >
+
+
+ ${this.extraData?.[index]?.legend_label ??
+ dataset.label}
+
+ `
)}
`
@@ -339,9 +374,19 @@ export class HaChartBase extends LitElement {
if (this.chart.isDatasetVisible(index)) {
this.chart.setDatasetVisibility(index, false);
this._hiddenDatasets.add(index);
+ if (this.externalHidden) {
+ fireEvent(this, "dataset-hidden", {
+ index,
+ });
+ }
} else {
this.chart.setDatasetVisibility(index, true);
this._hiddenDatasets.delete(index);
+ if (this.externalHidden) {
+ fireEvent(this, "dataset-unhidden", {
+ index,
+ });
+ }
}
this.chart.update("none");
this.requestUpdate("_hiddenDatasets");
@@ -486,4 +531,8 @@ declare global {
interface HTMLElementTagNameMap {
"ha-chart-base": HaChartBase;
}
+ interface HASSDomEvents {
+ "dataset-hidden": { index: number };
+ "dataset-unhidden": { index: number };
+ }
}
diff --git a/src/components/chart/statistics-chart.ts b/src/components/chart/statistics-chart.ts
index 0e2fa2a9f5..0c5597878c 100644
--- a/src/components/chart/statistics-chart.ts
+++ b/src/components/chart/statistics-chart.ts
@@ -32,7 +32,11 @@ import {
} from "../../data/recorder";
import type { HomeAssistant } from "../../types";
import "./ha-chart-base";
-import type { ChartResizeOptions, HaChartBase } from "./ha-chart-base";
+import type {
+ ChartResizeOptions,
+ ChartDatasetExtra,
+ HaChartBase,
+} from "./ha-chart-base";
export const supportedStatTypeMap: Record = {
mean: "mean",
@@ -79,10 +83,14 @@ export class StatisticsChart extends LitElement {
@state() private _chartData: ChartData = { datasets: [] };
+ @state() private _chartDatasetExtra: ChartDatasetExtra[] = [];
+
@state() private _statisticIds: string[] = [];
@state() private _chartOptions?: ChartOptions;
+ @state() private _hiddenStats = new Set();
+
@query("ha-chart-base") private _chart?: HaChartBase;
private _computedStyle?: CSSStyleDeclaration;
@@ -96,6 +104,9 @@ export class StatisticsChart extends LitElement {
}
public willUpdate(changedProps: PropertyValues) {
+ if (changedProps.has("legendMode")) {
+ this._hiddenStats.clear();
+ }
if (
!this.hasUpdated ||
changedProps.has("unit") ||
@@ -110,7 +121,8 @@ export class StatisticsChart extends LitElement {
changedProps.has("statisticsData") ||
changedProps.has("statTypes") ||
changedProps.has("chartType") ||
- changedProps.has("hideLegend")
+ changedProps.has("hideLegend") ||
+ changedProps.has("_hiddenStats")
) {
this._generateData();
}
@@ -145,14 +157,30 @@ export class StatisticsChart extends LitElement {
return html`
`;
}
+ private _datasetHidden(ev) {
+ ev.stopPropagation();
+ this._hiddenStats.add(this._statisticIds[ev.detail.index]);
+ this.requestUpdate("_hiddenStats");
+ }
+
+ private _datasetUnhidden(ev) {
+ ev.stopPropagation();
+ this._hiddenStats.delete(this._statisticIds[ev.detail.index]);
+ this.requestUpdate("_hiddenStats");
+ }
+
private _createOptions(unit?: string) {
this._chartOptions = {
parsing: false,
@@ -274,6 +302,7 @@ export class StatisticsChart extends LitElement {
let colorIndex = 0;
const statisticsData = Object.entries(this.statisticsData);
const totalDataSets: ChartDataset<"line">[] = [];
+ const totalDatasetExtras: ChartDatasetExtra[] = [];
const statisticIds: string[] = [];
let endTime: Date;
@@ -324,6 +353,7 @@ export class StatisticsChart extends LitElement {
// The datasets for the current statistic
const statDataSets: ChartDataset<"line">[] = [];
+ const statDatasetExtras: ChartDatasetExtra[] = [];
const pushData = (
start: Date,
@@ -384,9 +414,20 @@ export class StatisticsChart extends LitElement {
})
: this.statTypes;
+ let displayed_legend = false;
sortedTypes.forEach((type) => {
if (statisticsHaveType(stats, type)) {
const band = drawBands && (type === "min" || type === "max");
+ if (!this.hideLegend) {
+ const show_legend = hasMean
+ ? type === "mean"
+ : displayed_legend === false;
+ statDatasetExtras.push({
+ legend_label: name,
+ show_legend,
+ });
+ displayed_legend = displayed_legend || show_legend;
+ }
statTypes.push(type);
statDataSets.push({
label: name
@@ -408,6 +449,9 @@ export class StatisticsChart extends LitElement {
band && hasMean ? color + (this.hideLegend ? "00" : "7F") : color,
backgroundColor: band ? color + "3F" : color + "7F",
pointRadius: 0,
+ hidden: !this.hideLegend
+ ? this._hiddenStats.has(statistic_id)
+ : false,
data: [],
// @ts-ignore
unit: meta?.unit_of_measurement,
@@ -446,6 +490,7 @@ export class StatisticsChart extends LitElement {
// Concat two arrays
Array.prototype.push.apply(totalDataSets, statDataSets);
+ Array.prototype.push.apply(totalDatasetExtras, statDatasetExtras);
});
if (unit) {
@@ -455,6 +500,7 @@ export class StatisticsChart extends LitElement {
this._chartData = {
datasets: totalDataSets,
};
+ this._chartDatasetExtra = totalDatasetExtras;
this._statisticIds = statisticIds;
}