mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-24 09:46:36 +00:00
Fix gauge (#2274)
This commit is contained in:
parent
edef4ba2f5
commit
a6f3684846
@ -78,6 +78,10 @@ class DemoCard extends PolymerElement {
|
||||
hass.resources = demoResources;
|
||||
hass.language = "en";
|
||||
hass.states = demoStates;
|
||||
hass.themes = {
|
||||
default_theme: "default",
|
||||
themes: {},
|
||||
};
|
||||
el.hass = hass;
|
||||
}
|
||||
|
||||
|
@ -5,18 +5,19 @@ import {
|
||||
PropertyValues,
|
||||
} from "@polymer/lit-element";
|
||||
import { TemplateResult } from "lit-html";
|
||||
import { styleMap } from "lit-html/directives/styleMap";
|
||||
|
||||
import { LovelaceCard, LovelaceCardEditor } from "../types";
|
||||
import "../../../components/ha-card";
|
||||
import { LovelaceCardConfig } from "../../../data/lovelace";
|
||||
import { HomeAssistant } from "../../../types";
|
||||
import { fireEvent } from "../../../common/dom/fire_event";
|
||||
import { hasConfigOrEntityChanged } from "../common/has-changed";
|
||||
|
||||
import isValidEntityId from "../../../common/entity/valid_entity_id";
|
||||
import applyThemesOnElement from "../../../common/dom/apply_themes_on_element";
|
||||
import computeStateName from "../../../common/entity/compute_state_name";
|
||||
|
||||
import "../../../components/ha-card";
|
||||
import { LovelaceCard, LovelaceCardEditor } from "../types";
|
||||
import createErrorCardConfig from "../common/create-error-card-config";
|
||||
|
||||
export interface SeverityConfig {
|
||||
green?: number;
|
||||
@ -79,16 +80,37 @@ class HuiGaugeCard extends LitElement implements LovelaceCard {
|
||||
return html``;
|
||||
}
|
||||
const stateObj = this.hass.states[this._config.entity];
|
||||
let state;
|
||||
let error;
|
||||
|
||||
if (!stateObj) {
|
||||
error = "Entity not available: " + this._config.entity;
|
||||
} else if (isNaN(Number(stateObj.state))) {
|
||||
error = "Entity is non-numeric: " + this._config.entity;
|
||||
} else {
|
||||
state = Number(stateObj.state);
|
||||
|
||||
if (isNaN(state)) {
|
||||
error = "Entity is non-numeric: " + this._config.entity;
|
||||
}
|
||||
}
|
||||
|
||||
if (error) {
|
||||
const errorConfig = createErrorCardConfig(
|
||||
"Entity not Found!",
|
||||
this._config
|
||||
);
|
||||
const element = document.createElement("hui-error-card");
|
||||
element.setConfig(errorConfig);
|
||||
return html`
|
||||
${element}
|
||||
`;
|
||||
}
|
||||
|
||||
return html`
|
||||
${this.renderStyle()}
|
||||
<ha-card @click="${this._handleClick}">
|
||||
<ha-card
|
||||
@click="${this._handleClick}"
|
||||
style="${styleMap({ "--base-unit": this._computeBaseUnit() })}"
|
||||
>
|
||||
${
|
||||
error
|
||||
? html`
|
||||
@ -98,7 +120,15 @@ class HuiGaugeCard extends LitElement implements LovelaceCard {
|
||||
<div class="container">
|
||||
<div class="gauge-a"></div>
|
||||
<div class="gauge-b"></div>
|
||||
<div class="gauge-c" id="gauge"></div>
|
||||
<div
|
||||
class="gauge-c"
|
||||
style="${
|
||||
styleMap({
|
||||
transform: `rotate(${this._translateTurn(state)}turn)`,
|
||||
"background-color": this._computeSeverity(state),
|
||||
})
|
||||
}"
|
||||
></div>
|
||||
<div class="gauge-data">
|
||||
<div id="percent">
|
||||
${stateObj.state}
|
||||
@ -124,40 +154,63 @@ class HuiGaugeCard extends LitElement implements LovelaceCard {
|
||||
}
|
||||
|
||||
protected updated(changedProps: PropertyValues): void {
|
||||
if (
|
||||
!this._config ||
|
||||
!this.hass ||
|
||||
!this.shadowRoot!.getElementById("gauge")
|
||||
) {
|
||||
if (!this._config || !this.hass) {
|
||||
return;
|
||||
}
|
||||
const stateObj = this.hass.states[this._config.entity];
|
||||
if (isNaN(Number(stateObj.state))) {
|
||||
return;
|
||||
}
|
||||
|
||||
const turn = this._translateTurn(Number(stateObj.state), this._config);
|
||||
|
||||
this.shadowRoot!.getElementById(
|
||||
"gauge"
|
||||
)!.style.cssText = `transform: rotate(${turn}turn); background-color: ${this._computeSeverity(
|
||||
stateObj.state,
|
||||
this._config.severity!
|
||||
)}`;
|
||||
|
||||
(this.shadowRoot!.querySelector(
|
||||
"ha-card"
|
||||
)! as HTMLElement).style.setProperty(
|
||||
"--base-unit",
|
||||
this._computeBaseUnit()
|
||||
);
|
||||
|
||||
const oldHass = changedProps.get("hass") as HomeAssistant | undefined;
|
||||
|
||||
if (!oldHass || oldHass.themes !== this.hass.themes) {
|
||||
applyThemesOnElement(this, this.hass.themes, this._config.theme);
|
||||
}
|
||||
}
|
||||
|
||||
private _computeSeverity(numberValue: number): string {
|
||||
const sections = this._config!.severity;
|
||||
|
||||
if (!sections) {
|
||||
return severityMap.normal;
|
||||
}
|
||||
|
||||
const sectionsArray = Object.keys(sections);
|
||||
const sortable = sectionsArray.map((severity) => [
|
||||
severity,
|
||||
sections[severity],
|
||||
]);
|
||||
|
||||
for (const severity of sortable) {
|
||||
if (severityMap[severity[0]] == null || isNaN(severity[1])) {
|
||||
return severityMap.normal;
|
||||
}
|
||||
}
|
||||
sortable.sort((a, b) => a[1] - b[1]);
|
||||
|
||||
if (numberValue >= sortable[0][1] && numberValue < sortable[1][1]) {
|
||||
return severityMap[sortable[0][0]];
|
||||
}
|
||||
if (numberValue >= sortable[1][1] && numberValue < sortable[2][1]) {
|
||||
return severityMap[sortable[1][0]];
|
||||
}
|
||||
if (numberValue >= sortable[2][1]) {
|
||||
return severityMap[sortable[2][0]];
|
||||
}
|
||||
return severityMap.normal;
|
||||
}
|
||||
|
||||
private _translateTurn(value: number): number {
|
||||
const { min, max } = this._config!;
|
||||
const maxTurnValue = Math.min(Math.max(value, min!), max!);
|
||||
return (5 * (maxTurnValue - min!)) / (max! - min!) / 10;
|
||||
}
|
||||
|
||||
private _computeBaseUnit(): string {
|
||||
return this.clientWidth < 200 ? this.clientWidth / 5 + "px" : "50px";
|
||||
}
|
||||
|
||||
private _handleClick(): void {
|
||||
fireEvent(this, "hass-more-info", { entityId: this._config!.entity });
|
||||
}
|
||||
|
||||
private renderStyle(): TemplateResult {
|
||||
return html`
|
||||
<style>
|
||||
@ -240,53 +293,6 @@ class HuiGaugeCard extends LitElement implements LovelaceCard {
|
||||
</style>
|
||||
`;
|
||||
}
|
||||
|
||||
private _computeSeverity(stateValue: string, sections: object): string {
|
||||
const numberValue = Number(stateValue);
|
||||
|
||||
if (!sections) {
|
||||
return severityMap.normal;
|
||||
}
|
||||
|
||||
const sectionsArray = Object.keys(sections);
|
||||
const sortable = sectionsArray.map((severity) => [
|
||||
severity,
|
||||
sections[severity],
|
||||
]);
|
||||
|
||||
for (const severity of sortable) {
|
||||
if (severityMap[severity[0]] == null || isNaN(severity[1])) {
|
||||
return severityMap.normal;
|
||||
}
|
||||
}
|
||||
sortable.sort((a, b) => a[1] - b[1]);
|
||||
|
||||
if (numberValue >= sortable[0][1] && numberValue < sortable[1][1]) {
|
||||
return severityMap[sortable[0][0]];
|
||||
}
|
||||
if (numberValue >= sortable[1][1] && numberValue < sortable[2][1]) {
|
||||
return severityMap[sortable[1][0]];
|
||||
}
|
||||
if (numberValue >= sortable[2][1]) {
|
||||
return severityMap[sortable[2][0]];
|
||||
}
|
||||
return severityMap.normal;
|
||||
}
|
||||
|
||||
private _translateTurn(value: number, config: Config): number {
|
||||
const maxTurnValue = Math.min(Math.max(value, config.min!), config.max!);
|
||||
return (
|
||||
(5 * (maxTurnValue - config.min!)) / (config.max! - config.min!) / 10
|
||||
);
|
||||
}
|
||||
|
||||
private _computeBaseUnit(): string {
|
||||
return this.clientWidth < 200 ? this.clientWidth / 5 + "px" : "50px";
|
||||
}
|
||||
|
||||
private _handleClick(): void {
|
||||
fireEvent(this, "hass-more-info", { entityId: this._config!.entity });
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
|
Loading…
x
Reference in New Issue
Block a user