From 8d18248185d21e04f34933f5e9c2fe2e2fcce5ca Mon Sep 17 00:00:00 2001 From: andig Date: Fri, 17 Feb 2023 07:46:44 +0100 Subject: [PATCH] Add PV tooltip (#6226) --- .../Energyflow/Energyflow.story.vue | 1 + .../js/components/Energyflow/Energyflow.vue | 89 +++++++++++++------ .../components/Energyflow/EnergyflowEntry.vue | 79 +++++++++------- .../components/Energyflow/Visualization.vue | 4 +- assets/js/components/Site.vue | 1 + 5 files changed, 109 insertions(+), 65 deletions(-) diff --git a/assets/js/components/Energyflow/Energyflow.story.vue b/assets/js/components/Energyflow/Energyflow.story.vue index c8b30c825..5d436d6ba 100644 --- a/assets/js/components/Energyflow/Energyflow.story.vue +++ b/assets/js/components/Energyflow/Energyflow.story.vue @@ -14,6 +14,7 @@ import Energyflow from "./Energyflow.vue"; :loadpointsPower="4200" :activeLoadpointsCount="3" siteTitle="Home" + :pv="[{ power: 5000 }, { power: 2300 }]" /> diff --git a/assets/js/components/Energyflow/Energyflow.vue b/assets/js/components/Energyflow/Energyflow.vue index 8dce4c924..456adebbc 100644 --- a/assets/js/components/Energyflow/Energyflow.vue +++ b/assets/js/components/Energyflow/Energyflow.vue @@ -16,7 +16,7 @@ :pvProduction="pvProduction" :homePower="homePower" :batterySoc="batterySoc" - :valuesInKw="valuesInKw" + :powerInKw="powerInKw" :vehicleIcons="vehicleIcons" /> @@ -56,26 +56,28 @@ :name="$t('main.energyflow.pvProduction')" icon="sun" :power="pvProduction" - :valuesInKw="valuesInKw" + :powerTooltip="pvTooltip" + :powerInKw="powerInKw" /> @@ -93,11 +95,12 @@ :name="$t('main.energyflow.homePower')" icon="home" :power="homePower" - :valuesInKw="valuesInKw" - :price="tariffEffectivePrice" - :currency="currency" - :co2="tariffEffectiveCo2" - :tooltip="detailsTooltip(tariffEffectivePrice, tariffEffectiveCo2)" + :powerInKw="powerInKw" + :details="detailsValue(tariffEffectivePrice, tariffEffectiveCo2)" + :detailsFmt="detailsFmt" + :detailsTooltip=" + detailsTooltip(tariffEffectivePrice, tariffEffectiveCo2) + " /> @@ -146,6 +152,7 @@ import EnergyflowEntry from "./EnergyflowEntry.vue"; import formatter from "../../mixins/formatter"; import AnimatedNumber from "../AnimatedNumber.vue"; import settings from "../../settings"; +import { showGridPrice, showGridCo2 } from "../../gridDetails"; export default { name: "Energyflow", @@ -156,6 +163,7 @@ export default { gridPower: { type: Number, default: 0 }, homePower: { type: Number, default: 0 }, pvConfigured: Boolean, + pv: { type: Array }, pvPower: { type: Number, default: 0 }, loadpointsPower: { type: Number, default: 0 }, activeLoadpointsCount: { type: Number, default: 0 }, @@ -199,7 +207,7 @@ export default { pvExport: function () { return Math.max(0, this.gridPower * -1); }, - valuesInKw: function () { + powerInKw: function () { return this.gridImport + this.selfConsumption + this.pvExport > 1000; }, inPower: function () { @@ -211,6 +219,12 @@ export default { detailsHeight: function () { return this.detailsOpen ? this.detailsCompleteHeight + "px" : 0; }, + pvTooltip() { + if (!Array.isArray(this.pv) || this.pv.length <= 1) { + return; + } + return this.pv.map(({ power }) => this.fmtKw(power, this.powerInKw)); + }, batteryTooltip() { if (!Array.isArray(this.battery)) { return; @@ -221,6 +235,9 @@ export default { return this.$t("main.energyflow.batteryTooltip", { energy, total, soc }); }); }, + batteryFmt() { + return (soc) => `${Math.round(soc)}%`; + }, }, mounted() { window.addEventListener("resize", this.updateHeight); @@ -243,8 +260,22 @@ export default { } return result; }, + detailsValue(price, co2) { + if (showGridPrice() && !isNaN(price)) { + return price; + } + if (showGridCo2() && !isNaN(co2)) { + return co2; + } + }, + detailsFmt(value) { + if (showGridPrice()) { + return this.fmtPricePerKWh(value, this.currency, true); + } + return this.fmtCo2Short(value); + }, kw: function (watt) { - return this.fmtKw(watt, this.valuesInKw); + return this.fmtKw(watt, this.powerInKw); }, toggleDetails: function () { this.updateHeight(); diff --git a/assets/js/components/Energyflow/EnergyflowEntry.vue b/assets/js/components/Energyflow/EnergyflowEntry.vue index 56a485a85..8e6c339bb 100644 --- a/assets/js/components/Energyflow/EnergyflowEntry.vue +++ b/assets/js/components/Energyflow/EnergyflowEntry.vue @@ -10,11 +10,11 @@
- - - {{ soc }}% + +
+
+
-
@@ -28,7 +28,6 @@ import BatteryIcon from "./BatteryIcon.vue"; import formatter from "../../mixins/formatter"; import AnimatedNumber from "../AnimatedNumber.vue"; import VehicleIcon from "../VehicleIcon"; -import { showGridPrice, showGridCo2 } from "../../gridDetails"; export default { name: "EnergyflowEntry", @@ -37,17 +36,17 @@ export default { props: { name: { type: String }, icon: { type: String }, - power: { type: Number }, - soc: { type: Number }, - price: { type: Number }, - co2: { type: Number }, - valuesInKw: { type: Boolean }, vehicleIcons: { type: Array }, - currency: { type: String }, - tooltip: { type: Array }, + power: { type: Number }, + powerTooltip: { type: Array }, + powerInKw: { type: Boolean }, + soc: { type: Number }, + details: { type: Number }, + detailsFmt: { type: Function }, + detailsTooltip: { type: Array }, }, data() { - return { tooltipInstance: null }; + return { powerTooltipInstance: null, detailsTooltipInstance: null }; }, computed: { active: function () { @@ -59,42 +58,54 @@ export default { isVehicle: function () { return this.icon === "vehicle"; }, - hasSoc: function () { - return this.isBattery && !isNaN(this.soc); - }, }, watch: { - tooltip(newVal, oldVal) { + powerTooltip(newVal, oldVal) { if (JSON.stringify(newVal) !== JSON.stringify(oldVal)) { - this.updateTooltip(); + this.updatePowerTooltip(); + } + }, + detailsTooltip(newVal, oldVal) { + if (JSON.stringify(newVal) !== JSON.stringify(oldVal)) { + this.updateDetailsTooltip(); } }, }, mounted: function () { - this.updateTooltip(); + this.updatePowerTooltip(); + this.updateDetailsTooltip(); }, methods: { - showPrice() { - return showGridPrice() && !isNaN(this.price); - }, - showCo2() { - return showGridCo2() && !isNaN(this.co2); - }, kw: function (watt) { - return this.fmtKw(watt, this.valuesInKw); + return this.fmtKw(watt, this.powerInKw); }, - fmtPrice: function (price) { - return this.fmtPricePerKWh(price, this.currency, true); + updatePowerTooltip() { + this.powerTooltipInstance = this.updateTooltip( + this.powerTooltipInstance, + this.powerTooltip, + this.$refs.power + ); }, - updateTooltip: function () { - if (!Array.isArray(this.tooltip) || !this.tooltip.length) { + updateDetailsTooltip() { + this.detailsTooltipInstance = this.updateTooltip( + this.detailsTooltipInstance, + this.detailsTooltip, + this.$refs.details + ); + }, + updateTooltip: function (instance, content, ref) { + if (!Array.isArray(content) || !content.length) { + if (instance) { + instance.dispose(); + } return; } - if (!this.tooltipInstance) { - this.tooltipInstance = new Tooltip(this.$refs.details, { html: true }); + if (!instance) { + instance = new Tooltip(ref, { html: true }); } - const html = `
${this.tooltip.join("
")}
`; - this.tooltipInstance.setContent({ ".tooltip-inner": html }); + const html = `
${content.join("
")}
`; + instance.setContent({ ".tooltip-inner": html }); + return instance; }, }, }; diff --git a/assets/js/components/Energyflow/Visualization.vue b/assets/js/components/Energyflow/Visualization.vue index b9a8120dd..fb4cd91d6 100644 --- a/assets/js/components/Energyflow/Visualization.vue +++ b/assets/js/components/Energyflow/Visualization.vue @@ -98,7 +98,7 @@ export default { pvProduction: { type: Number, default: 0 }, homePower: { type: Number, default: 0 }, batterySoc: { type: Number, default: 0 }, - valuesInKw: { type: Boolean, default: false }, + powerInKw: { type: Boolean, default: false }, vehicleIcons: { type: Array }, }, data: function () { @@ -148,7 +148,7 @@ export default { }, fmtBarValue: function (watt) { const valueInKw = this.powerLabelEnoughSpace(watt); - return this.fmtKw(watt, this.valuesInKw, valueInKw); + return this.fmtKw(watt, this.powerInKw, valueInKw); }, powerLabelAvailableSpace(power) { if (this.totalAdjusted === 0) return 0; diff --git a/assets/js/components/Site.vue b/assets/js/components/Site.vue index b05872137..c039640d4 100644 --- a/assets/js/components/Site.vue +++ b/assets/js/components/Site.vue @@ -58,6 +58,7 @@ export default { homePower: Number, pvConfigured: Boolean, pvPower: Number, + pv: Array, batteryConfigured: Boolean, batteryPower: Number, batterySoc: Number,