From da228d8772b15187525f5f86e6e45a45e7dace75 Mon Sep 17 00:00:00 2001 From: frlequ Date: Wed, 16 Oct 2024 22:11:54 +0200 Subject: [PATCH] Fix circles not updating --- dist/network-tariff-card.js | 9 +- src/network-tariff-card.js | 312 ++++++++++++++++-------------------- 2 files changed, 146 insertions(+), 175 deletions(-) diff --git a/dist/network-tariff-card.js b/dist/network-tariff-card.js index cb93dfb..021989f 100644 --- a/dist/network-tariff-card.js +++ b/dist/network-tariff-card.js @@ -46,7 +46,6 @@ class NetworkTariffCard extends LitElement { return false; // Default to true if offsetHours is not present })(), outerRadius: config.outerRadius || 40, innerRadius: config.innerRadius || 32, name: config.name || '', colorMap: Object.assign({}, config.colorMap // User-defined colors will overwrite defaults ) }, config); - //this.attachShadow({ mode: 'open' }); } // The createSegment function now calculates each path segment of the donut chart createSegment(i, totalSegments, outerRadius, innerRadius, strokeColor, strokeWidth, textColor, offsetHours, showHours) { @@ -81,6 +80,13 @@ class NetworkTariffCard extends LitElement { ${showHours ? `${i + 1}` : ''} `; } + // Check if 'hass' has changed + updated(changedProperties) { + if (changedProperties.has('hass')) { + this.firstUpdated(); // Call update whenever 'hass' changes + } + } + // Draw SVG firstUpdated() { const svg = this.shadowRoot.querySelector(".circle-clock"); // Access the entity from Home Assistant's hass object @@ -177,3 +183,4 @@ NetworkTariffCard.styles = css ` } `; customElements.define('network-tariff-card', NetworkTariffCard); +console.info("%c NETWORK-TARIFF-CARD %c Version: " + "v1.0.4".padEnd(7, " "), "color: orange; font-weight: bold; background: black", "color: white; font-weight: bold; background: dimgray"); diff --git a/src/network-tariff-card.js b/src/network-tariff-card.js index 56af69d..a06dbf1 100644 --- a/src/network-tariff-card.js +++ b/src/network-tariff-card.js @@ -1,18 +1,141 @@ -import { - LitElement, - html, - css, -} from "https://unpkg.com/lit-element@2.0.1/lit-element.js?module"; - +import { LitElement, html, css, } from "https://unpkg.com/lit-element@2.0.1/lit-element.js?module"; class NetworkTariffCard extends LitElement { - static get properties() { - return { - hass: { type: Object }, - config: { type: Object }, - }; - } - - static styles = css` + constructor() { + super(...arguments); + // Declare variables globally + this.entity = null; + this.blocksArray = []; + this.defaultColorMap = { + 1: '#03045e', + 2: '#0077b6', + 3: '#00b4d8', + 4: '#90e0ef', + 5: '#caf0f8' + }; + this.colorMap = null; + } + static get properties() { + return { + hass: { type: Object }, + config: { type: Object }, + }; + } + setConfig(config) { + if (!config.entity) { + throw new Error('You need to define an entity'); + } + this.config = Object.assign({ showHours: (() => { + if (config.showHours !== undefined) { // Check if showHours is present + if (typeof config.showHours === 'boolean') { + return config.showHours; // Return the valid boolean value + } + else { + throw new Error(`Invalid value for showHours: ${config.showHours}. It must be a boolean. True or False.`); + } + } + return true; // Default to true if showHours is not present + })(), offsetHours: (() => { + if (config.offsetHours !== undefined) { // Check if offsetHours is present + if (typeof config.offsetHours === 'boolean') { + return config.offsetHours; // Return the valid boolean value + } + else { + throw new Error(`Invalid value for offsetHours: ${config.offsetHours}. It must be a boolean. True or False.`); + } + } + return false; // Default to true if offsetHours is not present + })(), outerRadius: config.outerRadius || 40, innerRadius: config.innerRadius || 32, name: config.name || '', colorMap: Object.assign({}, config.colorMap // User-defined colors will overwrite defaults + ) }, config); + + } + // The createSegment function now calculates each path segment of the donut chart + createSegment(i, totalSegments, outerRadius, innerRadius, strokeColor, strokeWidth, textColor, offsetHours, showHours) { + const angle = (2 * Math.PI) / totalSegments; // Angle per segment + const offset = showHours ? 0 : 5; + const offsetAngle = offsetHours ? 0.132 : 0; + // Calculate coordinates for the outer arc + const x1 = 50 + (outerRadius + offset) * Math.cos(i * angle - Math.PI / 2); + const y1 = 50 + (outerRadius + offset) * Math.sin(i * angle - Math.PI / 2); + const x2 = 50 + (outerRadius + offset) * Math.cos((i + 1) * angle - Math.PI / 2); + const y2 = 50 + (outerRadius + offset) * Math.sin((i + 1) * angle - Math.PI / 2); + // Calculate coordinates for the inner arc (the hole) + const x3 = 50 + (innerRadius + offset) * Math.cos((i + 1) * angle - Math.PI / 2); + const y3 = 50 + (innerRadius + offset) * Math.sin((i + 1) * angle - Math.PI / 2); + const x4 = 50 + (innerRadius + offset) * Math.cos(i * angle - Math.PI / 2); + const y4 = 50 + (innerRadius + offset) * Math.sin(i * angle - Math.PI / 2); + const segmentValue = this.blocksArray[i]; + // Determine the segment color + const segmentColor = (this.colorMap[segmentValue] !== undefined ? this.colorMap[segmentValue] : this.defaultColorMap[segmentValue]) || '#000'; // Default to black if no match + // Calculate the position for the number label + const labelRadius = outerRadius + 5; // Slightly outside the outer radius + const labelX = 50 + labelRadius * Math.cos((i + 0.5) * angle - Math.PI / 2 + offsetAngle); + const labelY = 50 + labelRadius * Math.sin((i + 0.5) * angle - Math.PI / 2 + offsetAngle); + // Create the donut segment path and number label + return ` + + ${showHours ? `${i + 1}` : ''} + `; + } + + // Check if 'hass' has changed + updated(changedProperties) { + if (changedProperties.has('hass')) { + this.firstUpdated(); // Call update whenever 'hass' changes + } + } + + // Draw SVG + firstUpdated() { + const svg = this.shadowRoot.querySelector(".circle-clock"); + // Access the entity from Home Assistant's hass object + this.entity = this.hass.states[this.config.entity]; + if (!this.entity) + return; // Exit if the entity is not available + const state = this.entity ? this.entity.state : 'Unavailable'; + this.blocks = this.entity.attributes.blocks || Array(24).fill(1); + this.blocksArray = Array.isArray(this.blocks) ? this.blocks : this.blocks.split(',').map(Number); + + const now = new Date(); + const currentHour = now.getHours(); + //const colorMap = this.config.colorMap; + this.colorMap = this.config.colorMap; + const totalSegments = 24; + const outerRadius = this.config.outerRadius !== undefined ? this.config.outerRadius : 40; + const innerRadius = this.config.innerRadius !== undefined ? this.config.innerRadius : 32; + const offsetHours = this.config.offsetHours !== undefined ? this.config.offsetHours : false; + const showHours = this.config.showHours !== undefined ? this.config.showHours : true; + const strokeColor = "rgba(0, 0, 0, 1)"; // Line separating each segment + const strokeWidth = 0.3; + const textColor = "rgba(150, 150, 150, 1)"; + // Create daily blocks + const segments = Array.from({ length: totalSegments }, (_, i) => this.createSegment(i, totalSegments, outerRadius, innerRadius, strokeColor, strokeWidth, textColor, offsetHours, showHours)).join(''); + // Create current hour section + const currentHourSegment = this.createSegment(currentHour, totalSegments, innerRadius - 1, innerRadius - 5, 'black', 0.3, 'rgba(0, 0, 0, 0)', offsetHours, showHours); + // Render out + svg.innerHTML = segments + currentHourSegment; + } + render() { + const entity = this.hass.states[this.config.entity]; + const state = entity ? entity.state : 'Unavailable'; + return html ` + +
+
${this.config.name || 'Entity'}
+
+
${state}
+ +
+
+
+ `; + } +} +NetworkTariffCard.styles = css ` .tariffcard { display: flex; justify-content: center; @@ -63,164 +186,5 @@ class NetworkTariffCard extends LitElement { z-index: 1; } `; - - setConfig(config) { - - if (!config.entity) { - throw new Error('You need to define an entity'); - } - - this.config = { - showHours: (() => { - if (config.showHours !== undefined) { // Check if showHours is present - if (typeof config.showHours === 'boolean') { - return config.showHours; // Return the valid boolean value - } else { - throw new Error(`Invalid value for showHours: ${config.showHours}. It must be a boolean. True or False.`); - } - } - return true; // Default to true if showHours is not present - })(), - offsetHours: (() => { - if (config.offsetHours !== undefined) { // Check if offsetHours is present - if (typeof config.offsetHours === 'boolean') { - return config.offsetHours; // Return the valid boolean value - } else { - throw new Error(`Invalid value for offsetHours: ${config.offsetHours}. It must be a boolean. True or False.`); - } - } - return false; // Default to true if offsetHours is not present - })(), - outerRadius: config.outerRadius || 40, // Default hole size, can be adjusted - innerRadius: config.innerRadius || 32, // Default hole size, can be adjusted - name: config.name || '', - colorMap: { - - ...config.colorMap // User-defined colors will overwrite defaults - }, - ...config - }; - - //this.attachShadow({ mode: 'open' }); - } - - // Declare variables globally - entity = null; - blocks; - blocksArray = []; - defaultColorMap = { - 1: '#03045e', - 2: '#0077b6', - 3: '#00b4d8', - 4: '#90e0ef', - 5: '#caf0f8' - }; - colorMap = null; - - // The createSegment function now calculates each path segment of the donut chart - createSegment(i, totalSegments, outerRadius, innerRadius, strokeColor, strokeWidth, textColor, offsetHours, showHours) { - const angle = (2 * Math.PI) / totalSegments; // Angle per segment - const offset = showHours ? 0 : 5; - const offsetAngle = offsetHours ? 0.132 : 0; - - - // Calculate coordinates for the outer arc - const x1 = 50 + (outerRadius + offset) * Math.cos(i * angle - Math.PI / 2); - const y1 = 50 + (outerRadius + offset) * Math.sin(i * angle - Math.PI / 2); - const x2 = 50 + (outerRadius + offset) * Math.cos((i + 1) * angle - Math.PI / 2); - const y2 = 50 + (outerRadius + offset) * Math.sin((i + 1) * angle - Math.PI / 2); - - // Calculate coordinates for the inner arc (the hole) - const x3 = 50 + (innerRadius + offset) * Math.cos((i + 1) * angle - Math.PI / 2); - const y3 = 50 + (innerRadius + offset) * Math.sin((i + 1) * angle - Math.PI / 2); - const x4 = 50 + (innerRadius + offset) * Math.cos(i * angle - Math.PI / 2); - const y4 = 50 + (innerRadius + offset) * Math.sin(i * angle - Math.PI / 2); - - const segmentValue = this.blocksArray[i]; - - // Determine the segment color - const segmentColor = (this.colorMap[segmentValue] !== undefined ? this.colorMap[segmentValue] : this.defaultColorMap[segmentValue]) || '#000'; // Default to black if no match - - // Calculate the position for the number label - const labelRadius = outerRadius + 5; // Slightly outside the outer radius - const labelX = 50 + labelRadius * Math.cos((i + 0.5) * angle - Math.PI / 2 + offsetAngle); - const labelY = 50 + labelRadius * Math.sin((i + 0.5) * angle - Math.PI / 2 + offsetAngle); - - // Create the donut segment path and number label - return ` - - ${showHours ? `${i + 1}` : ''} - `; - } - - firstUpdated() { - const svg = this.shadowRoot.querySelector(".circle-clock"); - - // Access the entity from Home Assistant's hass object - this.entity = this.hass.states[this.config.entity]; - if (!this.entity) return; // Exit if the entity is not available - - const state = this.entity ? this.entity.state : 'Unavailable'; - this.blocks = this.entity.attributes.blocks || Array(24).fill(1); - this.blocksArray = Array.isArray(this.blocks) ? this.blocks : this.blocks.split(',').map(Number); - - const now = new Date(); - const currentHour = now.getHours(); - - - //const colorMap = this.config.colorMap; - this.colorMap = this.config.colorMap; - - - const totalSegments = 24; - - const outerRadius = this.config.outerRadius !== undefined ? this.config.outerRadius : 40; - const innerRadius = this.config.innerRadius !== undefined ? this.config.innerRadius : 32; - const offsetHours = this.config.offsetHours !== undefined ? this.config.offsetHours : false; - const showHours = this.config.showHours !== undefined ? this.config.showHours : true; - - - const strokeColor = "rgba(0, 0, 0, 1)"; // Line separating each segment - const strokeWidth = 0.3; - const textColor = "rgba(150, 150, 150, 1)"; - - - // Create daily blocks - const segments = Array.from({ length: totalSegments }, (_, i) => - this.createSegment(i, totalSegments, outerRadius, innerRadius, strokeColor, strokeWidth, textColor, offsetHours, showHours) - ).join(''); - - - // Create current hour section - const currentHourSegment = this.createSegment(currentHour, totalSegments, innerRadius - 1, innerRadius - 5, 'black', 0.3, 'rgba(0, 0, 0, 0)', offsetHours, showHours); - - - // Render out - svg.innerHTML = segments + currentHourSegment; - - } - - render() { - const entity = this.hass.states[this.config.entity]; - const state = entity ? entity.state : 'Unavailable'; - - return html` - -
-
${this.config.name || 'Entity'}
-
-
${state}
- -
-
-
- `; - } -} - customElements.define('network-tariff-card', NetworkTariffCard); +console.info("%c NETWORK-TARIFF-CARD %c Version: " + "v1.0.4".padEnd(7, " "), "color: orange; font-weight: bold; background: black", "color: white; font-weight: bold; background: dimgray"); \ No newline at end of file