diff --git a/ha-vpd-chart.js b/ha-vpd-chart.js index 315199d..cb1e50d 100644 --- a/ha-vpd-chart.js +++ b/ha-vpd-chart.js @@ -48,7 +48,6 @@ class HaVpdChart extends HTMLElement { this.buildBarChart(hass); } } - setConfig(config) { this.config = config; if (!config.sensors) { @@ -73,100 +72,7 @@ class HaVpdChart extends HTMLElement { this.innerHTML = `
@@ -204,14 +110,14 @@ class HaVpdChart extends HTMLElement { let container = document.createElement('div'); - this.config.sensors.forEach((sensor, index) => { + this.config.sensors.forEach((sensor) => { let humidity = hass.states[sensor.humidity].state; let temperature = hass.states[sensor.temperature].state; - let leafTemperature = temperature - 2; + let leafTemperature = temperature - sensor.leaf_temperature_offset || 2; if (sensor.leaf_temperature !== undefined) { leafTemperature = hass.states[sensor.leaf_temperature].state; } - let vpd = sensor.vpd || this.calculateVPD(parseFloat(leafTemperature), parseFloat(temperature), parseFloat(humidity)).toFixed(2) + let vpd = hass.states[sensor.vpd].state || this.calculateVPD(parseFloat(leafTemperature), parseFloat(temperature), parseFloat(humidity)).toFixed(2) let card = document.createElement('ha-card'); card.innerHTML += `
@@ -229,7 +135,7 @@ class HaVpdChart extends HTMLElement { this.buildMouseTooltip(event.target, hass); } }); - this.addEventListener('mouseleave', (event) => { + this.addEventListener('mouseleave', () => { let tooltip = this.querySelector('.mousePointer'); let fadeOut = setInterval(function () { if (!tooltip.style.opacity) { @@ -252,149 +158,22 @@ class HaVpdChart extends HTMLElement { buildChart(hass) { // Initialize the content if it's not there yet. if (!this.content) { + this.innerHTML = ` -
+
-
-
-
- +
+
+
`; this.content = this.querySelector("div.vpd-card-container"); - - let table; - if (localStorage.getItem('vpd-table-card')) { - table = localStorage.getItem('vpd-table-card'); - } else { - table = this.buildTable(); - localStorage.setItem('vpd-table-card', table); - } - this.content.innerHTML = "
" + table + "
"; - + let table = this.buildTable(); + this.content.appendChild(table); } this.buildTooltip(this.content, hass); if (this.enable_tooltip) { @@ -403,14 +182,17 @@ class HaVpdChart extends HTMLElement { this.buildMouseTooltip(event.target, hass); } }); - this.addEventListener('mouseleave', (event) => { + this.addEventListener('mouseleave', () => { let tooltip = this.querySelector('.mousePointer'); + let banner = this.querySelector('.mouse-custom-tooltip'); let fadeOut = setInterval(function () { if (!tooltip.style.opacity) { tooltip.style.opacity = 1; + banner.style.opacity = 1; } if (tooltip.style.opacity > 0) { tooltip.style.opacity -= 0.1; + banner.style.opacity -= 0.1; } else { clearInterval(fadeOut); } @@ -484,25 +266,29 @@ class HaVpdChart extends HTMLElement { return table; } - buildTooltip(table, hass) { const fragment = document.createDocumentFragment(); const sensors = this.querySelector('#sensors'); + let vpd = 0; this.config.sensors.forEach((sensor, index) => { let humidity = hass.states[sensor.humidity].state; let temperature = hass.states[sensor.temperature].state; - let leafTemperature = temperature - 2; + let leafTemperature = temperature - sensor.leaf_temperature_offset || 2; if (sensor.leaf_temperature !== undefined) { leafTemperature = hass.states[sensor.leaf_temperature].state; } - let vpd = sensor.vpd || this.calculateVPD(parseFloat(leafTemperature), parseFloat(temperature), parseFloat(humidity)).toFixed(2) + if (sensor.vpd !== undefined) { + vpd = hass.states[sensor.vpd].state; + } else { + vpd = this.calculateVPD(parseFloat(leafTemperature), parseFloat(temperature), parseFloat(humidity)).toFixed(2); + } const relativeHumidity = this.max_humidity - humidity; // Umkehren der Berechnung const totalHumidityRange = this.max_humidity - this.min_humidity; const percentageHumidity = (relativeHumidity / totalHumidityRange) * 100; const relativeTemperature = temperature - this.min_temperature; const totalTemperatureRange = this.max_temperature - this.min_temperature; const percentageTemperature = (relativeTemperature / totalTemperatureRange) * 100; - // Check if the circle already exists, if not create a new one and set a already_created_bool to not append + let circle = document.getElementsByClassName('sensor-circle-' + index)[0] || document.createElement('div'); circle.className = 'highlight sensor-circle-' + index; circle.style.width = "10px"; @@ -536,7 +322,6 @@ class HaVpdChart extends HTMLElement { let tooltip = document.createElement('div'); tooltip.className = 'custom-tooltip'; - tooltip.innerHTML = `${sensor.name}: kPa: ${vpd} | ${this.rhText}: ${humidity}% | ${this.airText}: ${temperature}°C`; circle.appendChild(tooltip); fragment.appendChild(circle); @@ -544,27 +329,52 @@ class HaVpdChart extends HTMLElement { requestAnimationFrame(() => { sensors.replaceChildren(fragment); + this.adjustTooltipPositions(); }); } + adjustTooltipPositions() { + const containerRect = this.querySelector('#vpd-card-container').getBoundingClientRect(); + const tooltips = this.querySelectorAll('.custom-tooltip'); + tooltips.forEach(tooltip => { + const tooltipRect = tooltip.getBoundingClientRect(); + if (tooltipRect.right > containerRect.right) { + // Berechnen, wie weit das Tooltip nach links verschoben werden muss + const overflow = tooltipRect.right - containerRect.right; + tooltip.style.transform = `translateX(-${overflow}px)`; + } + }); + } buildMouseTooltip(target) { - const humidity = target.getAttribute('data-rh'); - const temperature = target.getAttribute('data-air'); - const vpd = parseFloat(target.getAttribute('data-vpd')).toFixed(2); - const percentageHumidity = ((this.max_humidity - humidity) / (this.max_humidity - this.min_humidity)) * 100; - const percentageTemperature = ((temperature - this.min_temperature) / (this.max_temperature - this.min_temperature)) * 100; - - let circle = this.querySelector('.mousePointer'); - circle.className = 'highlight mousePointer'; - circle.style.cssText = `width: 10px; height: 10px; background-color: white; border-radius: 50%; position: absolute; transform: translateX(-50%); left: ${percentageHumidity}%; bottom: ${100 - percentageTemperature}%;`; - let tooltip = circle.querySelector('.custom-tooltip') || document.createElement('div'); - tooltip.className = 'custom-tooltip'; - tooltip.innerHTML = `kPa: ${vpd} | ${this.rhText}: ${humidity}% | ${this.airText}: ${temperature}°C`; - if (!this.content.querySelector('.mousePointer')) { - circle.appendChild(tooltip); + if (this.tooltipTimeout) { + clearTimeout(this.tooltipTimeout); } - } + this.tooltipTimeout = setTimeout(() => { + const humidity = target.getAttribute('data-rh'); + const temperature = target.getAttribute('data-air'); + const vpd = parseFloat(target.getAttribute('data-vpd')).toFixed(2); + const percentageHumidity = ((this.max_humidity - humidity) / (this.max_humidity - this.min_humidity)) * 100; + const percentageTemperature = ((temperature - this.min_temperature) / (this.max_temperature - this.min_temperature)) * 100; + + let circle = this.querySelector('.mousePointer'); + circle.className = 'mousePointer highlight'; + circle.style.width = "10px"; + circle.style.height = "10px"; + circle.style.backgroundColor = "white"; + circle.style.borderRadius = "50%"; + circle.style.position = "absolute"; + circle.style.left = `${percentageHumidity}%`; + circle.style.bottom = `${100 - percentageTemperature}%`; + circle.style.opacity = 1; + circle.style.transform = "translateX(-50%)"; + let tooltip = this.querySelector('.mouse-custom-tooltip'); + tooltip.className = 'mouse-custom-tooltip'; + tooltip.innerHTML = `kPa: ${vpd} | ${this.rhText}: ${humidity}% | ${this.airText}: ${temperature}°C`; + tooltip.style.opacity = 1; + + }, 1); + } } customElements.define('ha-vpd-chart', HaVpdChart);