Better colors in timeline chart in more info (#14581)

This commit is contained in:
Paul Bottein 2022-12-06 18:15:59 +01:00 committed by GitHub
parent d622d9d420
commit 0001cad423
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 114 additions and 76 deletions

View File

@ -1,73 +1,14 @@
import type { ChartData, ChartDataset, ChartOptions } from "chart.js";
import { HassEntity } from "home-assistant-js-websocket";
import { css, CSSResultGroup, html, LitElement, PropertyValues } from "lit";
import { customElement, property, state } from "lit/decorators";
import { getGraphColorByIndex } from "../../common/color/colors";
import { rgb2hex } from "../../common/color/convert-color";
import { formatDateTimeWithSeconds } from "../../common/datetime/format_date_time";
import { stateActive } from "../../common/entity/state_active";
import { stateColor } from "../../common/entity/state_color";
import { numberFormatToLocale } from "../../common/number/format_number";
import { computeRTL } from "../../common/util/compute_rtl";
import { TimelineEntity } from "../../data/history";
import { HomeAssistant } from "../../types";
import { MIN_TIME_BETWEEN_UPDATES } from "./ha-chart-base";
import type { TimeLineData } from "./timeline-chart/const";
const stateColorTokenMap: Map<string, string> = new Map();
const stateColorMap: Map<string, string> = new Map();
let colorIndex = 0;
export const getStateColorToken = (
stateString: string,
entityState?: HassEntity
) => {
if (!entityState || !stateActive(entityState, stateString)) {
return `disabled`;
}
const color = stateColor(entityState, stateString);
if (color) {
return `state-${color}`;
}
return undefined;
};
const getColor = (
stateString: string,
computedStyles: CSSStyleDeclaration,
entityState?: HassEntity
) => {
const stateColorToken = getStateColorToken(stateString, entityState);
if (stateColorToken) {
if (stateColorTokenMap.has(stateColorToken)) {
return stateColorTokenMap.get(stateColorToken);
}
const value = computedStyles.getPropertyValue(
`--rgb-${stateColorToken}-color`
);
if (value) {
const parsedValue = value.split(",").map((v) => Number(v)) as [
number,
number,
number
];
const hexValue = rgb2hex(parsedValue);
stateColorTokenMap.set(stateColorToken, hexValue);
return hexValue;
}
}
if (stateColorMap.has(stateString)) {
return stateColorMap.get(stateString);
}
const color = getGraphColorByIndex(colorIndex, computedStyles);
colorIndex++;
stateColorMap.set(stateString, color);
return color;
};
import { computeTimelineColor } from "./timeline-chart/timeline-color";
@customElement("state-history-chart-timeline")
export class StateHistoryChartTimeline extends LitElement {
@ -270,7 +211,7 @@ export class StateHistoryChartTimeline extends LitElement {
start: prevLastChanged,
end: newLastChanged,
label: locState,
color: getColor(
color: computeTimelineColor(
prevState,
computedStyles,
this.hass.states[stateInfo.entity_id]
@ -288,7 +229,7 @@ export class StateHistoryChartTimeline extends LitElement {
start: prevLastChanged,
end: endTime,
label: locState,
color: getColor(
color: computeTimelineColor(
prevState,
computedStyles,
this.hass.states[stateInfo.entity_id]

View File

@ -0,0 +1,99 @@
import { HassEntity } from "home-assistant-js-websocket";
import { getGraphColorByIndex } from "../../../common/color/colors";
import { lab2hex, rgb2hex, rgb2lab } from "../../../common/color/convert-color";
import { labBrighten } from "../../../common/color/lab";
import { computeDomain } from "../../../common/entity/compute_domain";
import { stateActive } from "../../../common/entity/state_active";
import { stateColor } from "../../../common/entity/state_color";
const DOMAIN_STATE_SHADES: Record<string, Record<string, number>> = {
media_player: {
paused: 0.5,
idle: 1,
},
vacuum: {
returning: 0.5,
},
};
const cssColorMap: Map<string, [number, number, number]> = new Map();
function cssToRgb(
cssVariable: string,
computedStyles: CSSStyleDeclaration
): [number, number, number] | undefined {
if (!cssVariable.startsWith("--rgb")) {
return undefined;
}
if (cssColorMap.has(cssVariable)) {
return cssColorMap.get(cssVariable)!;
}
const value = computedStyles.getPropertyValue(cssVariable);
if (!value) return undefined;
const rgb = value.split(",").map((v) => Number(v)) as [
number,
number,
number
];
cssColorMap.set(cssVariable, rgb);
return rgb;
}
function computeTimelineStateColor(
state: string,
computedStyles: CSSStyleDeclaration,
stateObj?: HassEntity
): string | undefined {
if (!stateObj || !stateActive(stateObj, state)) {
const rgb = cssToRgb("--rgb-disabled-color", computedStyles);
if (!rgb) return undefined;
return rgb2hex(rgb);
}
const color = stateColor(stateObj, state);
if (!color) return undefined;
const domain = computeDomain(stateObj.entity_id);
const rgb = cssToRgb(`--rgb-state-${color}-color`, computedStyles);
if (!rgb) return undefined;
const shade = DOMAIN_STATE_SHADES[domain]?.[state] as number | number;
if (!shade) {
return rgb2hex(rgb);
}
return lab2hex(labBrighten(rgb2lab(rgb), shade));
}
let colorIndex = 0;
const stateColorMap: Map<string, string> = new Map();
function computeTimeLineGenericColor(
state: string,
computedStyles: CSSStyleDeclaration
): string {
if (stateColorMap.has(state)) {
return stateColorMap.get(state)!;
}
const color = getGraphColorByIndex(colorIndex, computedStyles);
colorIndex++;
stateColorMap.set(state, color);
return color;
}
export function computeTimelineColor(
state: string,
computedStyles: CSSStyleDeclaration,
stateObj?: HassEntity
): string {
return (
computeTimelineStateColor(state, computedStyles, stateObj) ||
computeTimeLineGenericColor(state, computedStyles)
);
}

View File

@ -1,5 +1,6 @@
import "@lit-labs/virtualizer";
import { VisibilityChangedEvent } from "@lit-labs/virtualizer/Virtualizer";
import type { HassEntity } from "home-assistant-js-websocket";
import {
css,
CSSResultGroup,
@ -8,37 +9,35 @@ import {
PropertyValues,
TemplateResult,
} from "lit";
import type { HassEntity } from "home-assistant-js-websocket";
import { customElement, eventOptions, property } from "lit/decorators";
import { classMap } from "lit/directives/class-map";
import { styleMap } from "lit/directives/style-map";
import { isComponentLoaded } from "../../common/config/is_component_loaded";
import { formatDate } from "../../common/datetime/format_date";
import { formatTimeWithSeconds } from "../../common/datetime/format_time";
import { restoreScroll } from "../../common/decorators/restore-scroll";
import { fireEvent } from "../../common/dom/fire_event";
import { computeDomain } from "../../common/entity/compute_domain";
import { isComponentLoaded } from "../../common/config/is_component_loaded";
import { stateActive } from "../../common/entity/state_active";
import { stateColorCss } from "../../common/entity/state_color";
import { navigate } from "../../common/navigate";
import { computeTimelineColor } from "../../components/chart/timeline-chart/timeline-color";
import "../../components/entity/state-badge";
import "../../components/ha-circular-progress";
import "../../components/ha-icon-next";
import "../../components/ha-relative-time";
import {
createHistoricState,
localizeTriggerSource,
localizeStateMessage,
localizeTriggerSource,
LogbookEntry,
} from "../../data/logbook";
import { TraceContexts } from "../../data/trace";
import {
buttonLinkStyle,
haStyle,
haStyleScrollbar,
buttonLinkStyle,
} from "../../resources/styles";
import { HomeAssistant } from "../../types";
import { brandsUrl } from "../../util/brands-url";
import "../../components/ha-icon-next";
import { navigate } from "../../common/navigate";
declare global {
interface HASSDomEvents {
@ -264,14 +263,15 @@ class HaLogbookRenderer extends LitElement {
const stateObj = this.hass.states[item.entity_id!] as
| HassEntity
| undefined;
const computedStyles = getComputedStyle(this);
const color =
stateObj && stateActive(stateObj, item.state)
? stateColorCss(stateObj, item.state)
item.state !== undefined
? computeTimelineColor(item.state, computedStyles, stateObj)
: undefined;
const style = {
"--indicator-color": color,
backgroundColor: color,
};
return html` <div class="indicator" style=${styleMap(style)}></div> `;
@ -577,9 +577,7 @@ class HaLogbookRenderer extends LitElement {
}
.indicator {
background-color: rgb(
var(--indicator-color, var(--rgb-disabled-color))
);
background-color: rgb(var(--rgb-disabled-color));
height: 8px;
width: 8px;
border-radius: 4px;