Skip to content

Commit f01c202

Browse files
History graph card: allow color customization for "line" graphs (home-assistant#51802)
* add "color" option * add GraphEntityConfig type * add "color" option * add "color" option * add "color" option * typescript-eslint/no-shadow * linter * add graphEntitiesConfigStruct * import graphEntitiesConfigStruct * typo in import * leftout * Create order-properties-graph.ts * use common orderPropertiesGraphCard() * Apply suggestions from code review Co-authored-by: Petar Petrov <MindFreeze@users.noreply.github.com> * Add missing Struct type import --------- Co-authored-by: Petar Petrov <MindFreeze@users.noreply.github.com>
1 parent ac6439b commit f01c202

7 files changed

Lines changed: 186 additions & 48 deletions

File tree

src/components/chart/state-history-chart-line.ts

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,11 @@ export class StateHistoryChartLine extends LitElement {
6060

6161
@property({ attribute: false }) public names?: Record<string, string>;
6262

63+
@property({ attribute: false }) public colors?: Record<
64+
string,
65+
string | undefined
66+
>;
67+
6368
@property() public unit?: string;
6469

6570
@property() public identifier?: string;
@@ -435,9 +440,11 @@ export class StateHistoryChartLine extends LitElement {
435440
this._chartTime = new Date();
436441
const endTime = this.endTime;
437442
const names = this.names || {};
443+
const colors = this.colors || {};
438444
entityStates.forEach((states, dataIdx) => {
439445
const domain = states.domain;
440446
const name = names[states.entity_id] || states.name;
447+
const color = colors[states.entity_id];
441448
// array containing [value1, value2, etc]
442449
let prevValues: any[] | null = null;
443450

@@ -468,11 +475,11 @@ export class StateHistoryChartLine extends LitElement {
468475
const addDataSet = (
469476
id: string,
470477
nameY: string,
471-
color?: string,
478+
clr?: string,
472479
fill = false
473480
) => {
474-
if (!color) {
475-
color = getGraphColorByIndex(colorIndex, computedStyles);
481+
if (!clr) {
482+
clr = getGraphColorByIndex(colorIndex, computedStyles);
476483
colorIndex++;
477484
}
478485
data.push({
@@ -481,7 +488,7 @@ export class StateHistoryChartLine extends LitElement {
481488
type: "line",
482489
cursor: "default",
483490
name: nameY,
484-
color,
491+
color: clr,
485492
symbol: "circle",
486493
symbolSize: 1,
487494
step: "end",
@@ -492,7 +499,7 @@ export class StateHistoryChartLine extends LitElement {
492499
},
493500
areaStyle: fill
494501
? {
495-
color: color + "7F",
502+
color: clr + "7F",
496503
}
497504
: undefined,
498505
tooltip: {
@@ -740,7 +747,7 @@ export class StateHistoryChartLine extends LitElement {
740747
pushData(new Date(entityState.last_changed), series);
741748
});
742749
} else {
743-
addDataSet(states.entity_id, name);
750+
addDataSet(states.entity_id, name, color);
744751

745752
let lastValue: number;
746753
let lastDate: Date;

src/components/chart/state-history-charts.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,11 @@ export class StateHistoryCharts extends LitElement {
5252

5353
@property({ attribute: false }) public names?: Record<string, string>;
5454

55+
@property({ attribute: false }) public colors?: Record<
56+
string,
57+
string | undefined
58+
>;
59+
5560
@property({ type: Boolean, reflect: true }) public virtualize = false;
5661

5762
@property({ attribute: false }) public endTime?: Date;
@@ -181,6 +186,7 @@ export class StateHistoryCharts extends LitElement {
181186
.endTime=${this._computedEndTime}
182187
.paddingYAxis=${this._maxYWidth}
183188
.names=${this.names}
189+
.colors=${this.colors}
184190
.chartIndex=${index}
185191
.clickForMoreInfo=${this.clickForMoreInfo}
186192
.logarithmicScale=${this.logarithmicScale}

src/panels/lovelace/cards/hui-history-graph-card.ts

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import type { PropertyValues } from "lit";
22
import { LitElement, css, html, nothing } from "lit";
33
import { customElement, property, state } from "lit/decorators";
44
import { classMap } from "lit/directives/class-map";
5+
import { theme2hex } from "../../../common/color/convert-color";
56
import { isComponentLoaded } from "../../../common/config/is_component_loaded";
67
import { createSearchParam } from "../../../common/url/search-params";
78
import "../../../components/chart/state-history-charts";
@@ -21,9 +22,8 @@ import { getSensorNumericDeviceClasses } from "../../../data/sensor";
2122
import type { HomeAssistant } from "../../../types";
2223
import { hasConfigOrEntitiesChanged } from "../common/has-changed";
2324
import { processConfigEntities } from "../common/process-config-entities";
24-
import type { EntityConfig } from "../entity-rows/types";
2525
import type { LovelaceCard, LovelaceGridOptions } from "../types";
26-
import type { HistoryGraphCardConfig } from "./types";
26+
import type { GraphEntityConfig, HistoryGraphCardConfig } from "./types";
2727

2828
export const DEFAULT_HOURS_TO_SHOW = 24;
2929

@@ -51,9 +51,11 @@ export class HuiHistoryGraphCard extends LitElement implements LovelaceCard {
5151

5252
private _names: Record<string, string> = {};
5353

54+
private _colors: Record<string, string | undefined> = {};
55+
5456
private _entityIds: string[] = [];
5557

56-
private _entities: EntityConfig[] = [];
58+
private _entities: GraphEntityConfig[] = [];
5759

5860
private _historyLinkId = `history-${Math.random().toString(36).substring(2, 9)}`;
5961

@@ -95,6 +97,7 @@ export class HuiHistoryGraphCard extends LitElement implements LovelaceCard {
9597

9698
this._config = config;
9799
this._computeNames();
100+
this._computeColors();
98101
}
99102

100103
private _computeNames() {
@@ -110,6 +113,19 @@ export class HuiHistoryGraphCard extends LitElement implements LovelaceCard {
110113
});
111114
}
112115

116+
private _computeColors() {
117+
if (!this._config) {
118+
return;
119+
}
120+
this._colors = {};
121+
this._entities.forEach((entity) => {
122+
// if color = undefined, it is automatically defined inside a chart component
123+
this._colors[entity.entity] = entity.color
124+
? theme2hex(entity.color)
125+
: undefined;
126+
});
127+
}
128+
113129
public willUpdate(changedProps: PropertyValues<this>) {
114130
super.willUpdate(changedProps);
115131
if (changedProps.has("hass")) {
@@ -371,6 +387,7 @@ export class HuiHistoryGraphCard extends LitElement implements LovelaceCard {
371387
.minYAxis=${this._config.min_y_axis}
372388
.maxYAxis=${this._config.max_y_axis}
373389
.fitYData=${this._config.fit_y_data || false}
390+
.colors=${this._colors}
374391
.height=${hasFixedHeight ? "100%" : undefined}
375392
.narrow=${narrow}
376393
.expandLegend=${this._config.expand_legend}

src/panels/lovelace/cards/types.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -458,8 +458,14 @@ export interface MediaControlCardConfig extends LovelaceCardConfig {
458458
theme?: string;
459459
}
460460

461+
export interface GraphEntityConfig {
462+
entity: string;
463+
name?: string | EntityNameItem | EntityNameItem[];
464+
color?: string;
465+
}
466+
461467
export interface HistoryGraphCardConfig extends LovelaceCardConfig {
462-
entities: (EntityConfig | string)[];
468+
entities: (GraphEntityConfig | string)[];
463469
hours_to_show?: number;
464470
title?: string;
465471
show_names?: boolean;

0 commit comments

Comments
 (0)