mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-27 11:16:35 +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.resources = demoResources;
|
||||||
hass.language = "en";
|
hass.language = "en";
|
||||||
hass.states = demoStates;
|
hass.states = demoStates;
|
||||||
|
hass.themes = {
|
||||||
|
default_theme: "default",
|
||||||
|
themes: {},
|
||||||
|
};
|
||||||
el.hass = hass;
|
el.hass = hass;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,18 +5,19 @@ import {
|
|||||||
PropertyValues,
|
PropertyValues,
|
||||||
} from "@polymer/lit-element";
|
} from "@polymer/lit-element";
|
||||||
import { TemplateResult } from "lit-html";
|
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 { LovelaceCardConfig } from "../../../data/lovelace";
|
||||||
import { HomeAssistant } from "../../../types";
|
import { HomeAssistant } from "../../../types";
|
||||||
import { fireEvent } from "../../../common/dom/fire_event";
|
import { fireEvent } from "../../../common/dom/fire_event";
|
||||||
import { hasConfigOrEntityChanged } from "../common/has-changed";
|
import { hasConfigOrEntityChanged } from "../common/has-changed";
|
||||||
|
|
||||||
import isValidEntityId from "../../../common/entity/valid_entity_id";
|
import isValidEntityId from "../../../common/entity/valid_entity_id";
|
||||||
import applyThemesOnElement from "../../../common/dom/apply_themes_on_element";
|
import applyThemesOnElement from "../../../common/dom/apply_themes_on_element";
|
||||||
import computeStateName from "../../../common/entity/compute_state_name";
|
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 {
|
export interface SeverityConfig {
|
||||||
green?: number;
|
green?: number;
|
||||||
@ -79,16 +80,37 @@ class HuiGaugeCard extends LitElement implements LovelaceCard {
|
|||||||
return html``;
|
return html``;
|
||||||
}
|
}
|
||||||
const stateObj = this.hass.states[this._config.entity];
|
const stateObj = this.hass.states[this._config.entity];
|
||||||
|
let state;
|
||||||
let error;
|
let error;
|
||||||
|
|
||||||
if (!stateObj) {
|
if (!stateObj) {
|
||||||
error = "Entity not available: " + this._config.entity;
|
error = "Entity not available: " + this._config.entity;
|
||||||
} else if (isNaN(Number(stateObj.state))) {
|
} else {
|
||||||
error = "Entity is non-numeric: " + this._config.entity;
|
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`
|
return html`
|
||||||
${this.renderStyle()}
|
${this.renderStyle()}
|
||||||
<ha-card @click="${this._handleClick}">
|
<ha-card
|
||||||
|
@click="${this._handleClick}"
|
||||||
|
style="${styleMap({ "--base-unit": this._computeBaseUnit() })}"
|
||||||
|
>
|
||||||
${
|
${
|
||||||
error
|
error
|
||||||
? html`
|
? html`
|
||||||
@ -98,7 +120,15 @@ class HuiGaugeCard extends LitElement implements LovelaceCard {
|
|||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="gauge-a"></div>
|
<div class="gauge-a"></div>
|
||||||
<div class="gauge-b"></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 class="gauge-data">
|
||||||
<div id="percent">
|
<div id="percent">
|
||||||
${stateObj.state}
|
${stateObj.state}
|
||||||
@ -124,40 +154,63 @@ class HuiGaugeCard extends LitElement implements LovelaceCard {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected updated(changedProps: PropertyValues): void {
|
protected updated(changedProps: PropertyValues): void {
|
||||||
if (
|
if (!this._config || !this.hass) {
|
||||||
!this._config ||
|
|
||||||
!this.hass ||
|
|
||||||
!this.shadowRoot!.getElementById("gauge")
|
|
||||||
) {
|
|
||||||
return;
|
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;
|
const oldHass = changedProps.get("hass") as HomeAssistant | undefined;
|
||||||
|
|
||||||
if (!oldHass || oldHass.themes !== this.hass.themes) {
|
if (!oldHass || oldHass.themes !== this.hass.themes) {
|
||||||
applyThemesOnElement(this, this.hass.themes, this._config.theme);
|
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 {
|
private renderStyle(): TemplateResult {
|
||||||
return html`
|
return html`
|
||||||
<style>
|
<style>
|
||||||
@ -240,53 +293,6 @@ class HuiGaugeCard extends LitElement implements LovelaceCard {
|
|||||||
</style>
|
</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 {
|
declare global {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user