mirror of
https://github.com/home-assistant/frontend.git
synced 2025-04-25 05:47:20 +00:00
Add needle option to ha-gauge and gauge card (#9637)
This commit is contained in:
parent
a4f51b0cb3
commit
03080973be
@ -13,6 +13,11 @@ const getAngle = (value: number, min: number, max: number) => {
|
||||
return (percentage * 180) / 100;
|
||||
};
|
||||
|
||||
interface LevelDefinition {
|
||||
level: number;
|
||||
stroke: string;
|
||||
}
|
||||
|
||||
@customElement("ha-gauge")
|
||||
export class Gauge extends LitElement {
|
||||
@property({ type: Number }) public min = 0;
|
||||
@ -23,6 +28,10 @@ export class Gauge extends LitElement {
|
||||
|
||||
@property() public locale!: FrontendLocaleData;
|
||||
|
||||
@property({ type: Boolean }) public needle?: boolean;
|
||||
|
||||
@property() public levels?: LevelDefinition[];
|
||||
|
||||
@property() public label = "";
|
||||
|
||||
@state() private _angle = 0;
|
||||
@ -55,18 +64,53 @@ export class Gauge extends LitElement {
|
||||
class="dial"
|
||||
d="M 10 50 A 40 40 0 0 1 90 50"
|
||||
></path>
|
||||
<path
|
||||
class="value"
|
||||
d="M 90 50.001 A 40 40 0 0 1 10 50"
|
||||
style=${ifDefined(
|
||||
!isSafari
|
||||
? styleMap({ transform: `rotate(${this._angle}deg)` })
|
||||
: undefined
|
||||
)}
|
||||
transform=${ifDefined(
|
||||
isSafari ? `rotate(${this._angle} 50 50)` : undefined
|
||||
)}
|
||||
>
|
||||
|
||||
${
|
||||
this.levels
|
||||
? this.levels
|
||||
.sort((a, b) => a.level - b.level)
|
||||
.map((level) => {
|
||||
const angle = getAngle(level.level, this.min, this.max);
|
||||
return svg`<path
|
||||
stroke="${level.stroke}"
|
||||
class="level"
|
||||
d="M
|
||||
${50 - 40 * Math.cos((angle * Math.PI) / 180)}
|
||||
${50 - 40 * Math.sin((angle * Math.PI) / 180)}
|
||||
A 40 40 0 0 1 90 50
|
||||
"
|
||||
></path>`;
|
||||
})
|
||||
: ""
|
||||
}
|
||||
${
|
||||
this.needle
|
||||
? svg`<path
|
||||
class="needle"
|
||||
d="M 25 47.5 L 2.5 50 L 25 52.5 z"
|
||||
style=${ifDefined(
|
||||
!isSafari
|
||||
? styleMap({ transform: `rotate(${this._angle}deg)` })
|
||||
: undefined
|
||||
)}
|
||||
transform=${ifDefined(
|
||||
isSafari ? `rotate(${this._angle} 50 50)` : undefined
|
||||
)}
|
||||
>
|
||||
`
|
||||
: svg`<path
|
||||
class="value"
|
||||
d="M 90 50.001 A 40 40 0 0 1 10 50"
|
||||
style=${ifDefined(
|
||||
!isSafari
|
||||
? styleMap({ transform: `rotate(${this._angle}deg)` })
|
||||
: undefined
|
||||
)}
|
||||
transform=${ifDefined(
|
||||
isSafari ? `rotate(${this._angle} 50 50)` : undefined
|
||||
)}
|
||||
>`
|
||||
}
|
||||
${
|
||||
// Workaround for https://github.com/home-assistant/frontend/issues/6467
|
||||
isSafari
|
||||
@ -117,6 +161,15 @@ export class Gauge extends LitElement {
|
||||
transform-origin: 50% 100%;
|
||||
transition: all 1s ease 0s;
|
||||
}
|
||||
.needle {
|
||||
fill: var(--primary-text-color);
|
||||
transform-origin: 50% 100%;
|
||||
transition: all 1s ease 0s;
|
||||
}
|
||||
.level {
|
||||
fill: none;
|
||||
stroke-width: 15;
|
||||
}
|
||||
.gauge {
|
||||
display: block;
|
||||
}
|
||||
|
@ -135,6 +135,8 @@ class HuiGaugeCard extends LitElement implements LovelaceCard {
|
||||
style=${styleMap({
|
||||
"--gauge-color": this._computeSeverity(entityState),
|
||||
})}
|
||||
.needle=${this._config!.needle}
|
||||
.levels=${this._config!.needle ? this._severityLevels() : undefined}
|
||||
></ha-gauge>
|
||||
<div class="name">
|
||||
${this._config.name || computeStateName(stateObj)}
|
||||
@ -200,6 +202,20 @@ class HuiGaugeCard extends LitElement implements LovelaceCard {
|
||||
return severityMap.normal;
|
||||
}
|
||||
|
||||
private _severityLevels() {
|
||||
const sections = this._config!.severity;
|
||||
|
||||
if (!sections) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const sectionsArray = Object.keys(sections);
|
||||
return sectionsArray.map((severity) => ({
|
||||
level: sections[severity],
|
||||
stroke: severityMap[severity],
|
||||
}));
|
||||
}
|
||||
|
||||
private _handleClick(): void {
|
||||
fireEvent(this, "hass-more-info", { entityId: this._config!.entity });
|
||||
}
|
||||
|
@ -164,6 +164,7 @@ export interface GaugeCardConfig extends LovelaceCardConfig {
|
||||
max?: number;
|
||||
severity?: SeverityConfig;
|
||||
theme?: string;
|
||||
needle?: boolean;
|
||||
}
|
||||
|
||||
export interface ConfigEntity extends EntityConfig {
|
||||
|
@ -1,7 +1,7 @@
|
||||
import "@polymer/paper-input/paper-input";
|
||||
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { assert, number, object, optional, string } from "superstruct";
|
||||
import { assert, boolean, number, object, optional, string } from "superstruct";
|
||||
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||
import { computeRTLDirection } from "../../../../common/util/compute_rtl";
|
||||
import "../../../../components/ha-formfield";
|
||||
@ -23,6 +23,7 @@ const cardConfigStruct = object({
|
||||
max: optional(number()),
|
||||
severity: optional(object()),
|
||||
theme: optional(string()),
|
||||
needle: optional(boolean()),
|
||||
});
|
||||
|
||||
const includeDomains = ["counter", "input_number", "number", "sensor"];
|
||||
@ -137,6 +138,17 @@ export class HuiGaugeCardEditor
|
||||
.configValue=${"max"}
|
||||
@value-changed="${this._valueChanged}"
|
||||
></paper-input>
|
||||
<ha-formfield
|
||||
.label=${this.hass.localize(
|
||||
"ui.panel.lovelace.editor.card.gauge.needle_gauge"
|
||||
)}
|
||||
.dir=${computeRTLDirection(this.hass)}
|
||||
>
|
||||
<ha-switch
|
||||
.checked="${this._config!.needle !== undefined}"
|
||||
@change="${this._toggleNeedle}"
|
||||
></ha-switch
|
||||
></ha-formfield>
|
||||
<ha-formfield
|
||||
.label=${this.hass.localize(
|
||||
"ui.panel.lovelace.editor.card.gauge.severity.define"
|
||||
@ -212,6 +224,22 @@ export class HuiGaugeCardEditor
|
||||
];
|
||||
}
|
||||
|
||||
private _toggleNeedle(ev: EntitiesEditorEvent): void {
|
||||
if (!this._config || !this.hass) {
|
||||
return;
|
||||
}
|
||||
if ((ev.target as EditorTarget).checked) {
|
||||
this._config = {
|
||||
...this._config,
|
||||
needle: true,
|
||||
};
|
||||
} else {
|
||||
this._config = { ...this._config };
|
||||
delete this._config.needle;
|
||||
}
|
||||
fireEvent(this, "config-changed", { config: this._config });
|
||||
}
|
||||
|
||||
private _toggleSeverity(ev: EntitiesEditorEvent): void {
|
||||
if (!this._config || !this.hass) {
|
||||
return;
|
||||
|
@ -3095,6 +3095,7 @@
|
||||
},
|
||||
"gauge": {
|
||||
"name": "Gauge",
|
||||
"needle_gauge": "Display as needle gauge?",
|
||||
"severity": {
|
||||
"define": "Define Severity?",
|
||||
"green": "Green",
|
||||
|
Loading…
x
Reference in New Issue
Block a user