diff --git a/src/components/ha-bar.ts b/src/components/ha-bar.ts new file mode 100644 index 0000000000..b9d160bf13 --- /dev/null +++ b/src/components/ha-bar.ts @@ -0,0 +1,67 @@ +import { + css, + CSSResult, + customElement, + LitElement, + property, + svg, + TemplateResult, +} from "lit-element"; + +import { + getValueInPercentage, + normalize, + roundWithOneDecimal, +} from "../util/calculate"; + +@customElement("ha-bar") +export class HaBar extends LitElement { + @property({ type: Number }) public min = 0; + + @property({ type: Number }) public max = 100; + + @property({ type: Number }) public value!: number; + + protected render(): TemplateResult { + const valuePrecentage = roundWithOneDecimal( + getValueInPercentage( + normalize(this.value, this.min, this.max), + this.min, + this.max + ) + ); + + return svg` + + + + + + + `; + } + + static get styles(): CSSResult { + return css` + rect:first-child { + width: 100%; + fill: var(--ha-bar-background-color, var(--secondary-background-color)); + } + rect:last-child { + fill: var(--ha-bar-primary-color, var(--primary-color)); + rx: var(--ha-bar-border-radius, 4px); + } + svg { + border-radius: var(--ha-bar-border-radius, 4px); + height: 12px; + width: 100%; + } + `; + } +} + +declare global { + interface HTMLElementTagNameMap { + "ha-bar": HaBar; + } +} diff --git a/src/components/ha-gauge.ts b/src/components/ha-gauge.ts index 6cb3391f2e..5e1adbf351 100644 --- a/src/components/ha-gauge.ts +++ b/src/components/ha-gauge.ts @@ -11,23 +11,13 @@ import { styleMap } from "lit-html/directives/style-map"; import { afterNextRender } from "../common/util/render-status"; import { ifDefined } from "lit-html/directives/if-defined"; +import { getValueInPercentage, normalize } from "../util/calculate"; + const getAngle = (value: number, min: number, max: number) => { const percentage = getValueInPercentage(normalize(value, min, max), min, max); return (percentage * 180) / 100; }; -const normalize = (value: number, min: number, max: number) => { - if (value > max) return max; - if (value < min) return min; - return value; -}; - -const getValueInPercentage = (value: number, min: number, max: number) => { - const newMax = max - min; - const newVal = value - min; - return (100 * newVal) / newMax; -}; - // Workaround for https://github.com/home-assistant/frontend/issues/6467 const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent); diff --git a/src/util/calculate.ts b/src/util/calculate.ts new file mode 100644 index 0000000000..b6a1add005 --- /dev/null +++ b/src/util/calculate.ts @@ -0,0 +1,23 @@ +export const normalize = (value: number, min: number, max: number): number => { + if (isNaN(value) || isNaN(min) || isNaN(max)) { + // Not a number, return 0 + return 0; + } + if (value > max) return max; + if (value < min) return min; + return value; +}; + +export const getValueInPercentage = ( + value: number, + min: number, + max: number +): number => { + const newMax = max - min; + const newVal = value - min; + return (100 * newVal) / newMax; +}; + +export const roundWithOneDecimal = (value: number): number => { + return Math.round(value * 10) / 10; +}; diff --git a/test-mocha/util/calculate.spec.ts b/test-mocha/util/calculate.spec.ts new file mode 100644 index 0000000000..8470e27828 --- /dev/null +++ b/test-mocha/util/calculate.spec.ts @@ -0,0 +1,25 @@ +import * as assert from "assert"; +import { + getValueInPercentage, + normalize, + roundWithOneDecimal, +} from "../../src/util/calculate"; + +describe("Calculate tests", function () { + it("Test getValueInPercentage", function () { + assert.equal(getValueInPercentage(10, 0, 100), 10); + assert.equal(getValueInPercentage(120, 0, 100), 120); + assert.equal(getValueInPercentage(-10, 0, 100), -10); + assert.equal(getValueInPercentage(10.33333, 0, 100), 10.33333); + }); + it("Test normalize", function () { + assert.equal(normalize(10, 0, 100), 10); + assert.equal(normalize(1, 10, 100), 10); + assert.equal(normalize(100, 0, 10), 10); + }); + it("Test roundWithOneDecimal", function () { + assert.equal(roundWithOneDecimal(10), 10); + assert.equal(roundWithOneDecimal(10.3), 10.3); + assert.equal(roundWithOneDecimal(10.3333), 10.3); + }); +});