Energyflow: keep small consumption segments visible (#30781)
This commit is contained in:
parent
4982bcc025
commit
359e053a40
2 changed files with 24 additions and 53 deletions
|
|
@ -3,6 +3,7 @@
|
|||
class="label-bar"
|
||||
:class="{
|
||||
'label-bar--hide-icon': hideIcon,
|
||||
'label-bar--hide-dot': hideDot,
|
||||
'label-bar--hidden': !value,
|
||||
'label-bar--top': top,
|
||||
'label-bar--bottom': bottom,
|
||||
|
|
@ -26,6 +27,7 @@ export default defineComponent({
|
|||
props: {
|
||||
value: { type: Number, default: 0 },
|
||||
hideIcon: { type: Boolean },
|
||||
hideDot: { type: Boolean },
|
||||
top: { type: Boolean },
|
||||
bottom: { type: Boolean },
|
||||
first: { type: Boolean },
|
||||
|
|
@ -90,6 +92,9 @@ export default defineComponent({
|
|||
border-width: 1.5rem;
|
||||
transition-delay: 400ms, 0s;
|
||||
}
|
||||
.label-bar--hide-dot .label-bar-icon {
|
||||
transform: scale(0);
|
||||
}
|
||||
.label-bar--hidden {
|
||||
opacity: 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@
|
|||
<div class="label-scale-name">In</div>
|
||||
</div>
|
||||
<div ref="site_progress" class="site-progress">
|
||||
<div class="site-progress-bar self-pv" :style="{ width: widthTotal(selfPvAdjusted) }">
|
||||
<div class="site-progress-bar self-pv" :style="{ width: widthTotal(selfPv) }">
|
||||
<AnimatedNumber
|
||||
v-if="selfPv && visualizationReady"
|
||||
class="power"
|
||||
|
|
@ -30,10 +30,7 @@
|
|||
:format="fmtBarValue"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="site-progress-bar self-battery"
|
||||
:style="{ width: widthTotal(selfBatteryAdjusted) }"
|
||||
>
|
||||
<div class="site-progress-bar self-battery" :style="{ width: widthTotal(selfBattery) }">
|
||||
<AnimatedNumber
|
||||
v-if="selfBattery && visualizationReady"
|
||||
class="power"
|
||||
|
|
@ -41,10 +38,7 @@
|
|||
:format="fmtBarValue"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="site-progress-bar grid-import"
|
||||
:style="{ width: widthTotal(gridImportAdjusted) }"
|
||||
>
|
||||
<div class="site-progress-bar grid-import" :style="{ width: widthTotal(gridImport) }">
|
||||
<AnimatedNumber
|
||||
v-if="gridImport && visualizationReady"
|
||||
class="power"
|
||||
|
|
@ -52,10 +46,7 @@
|
|||
:format="fmtBarValue"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="site-progress-bar pv-export"
|
||||
:style="{ width: widthTotal(pvExportAdjusted) }"
|
||||
>
|
||||
<div class="site-progress-bar pv-export" :style="{ width: widthTotal(pvExport) }">
|
||||
<AnimatedNumber
|
||||
v-if="pvExport && visualizationReady"
|
||||
class="power"
|
||||
|
|
@ -74,7 +65,7 @@
|
|||
:format="fmtBarValue"
|
||||
/>
|
||||
</div>
|
||||
<div v-if="totalAdjusted <= 0" class="site-progress-bar w-100 grid-import">
|
||||
<div v-if="total <= 0" class="site-progress-bar w-100 grid-import">
|
||||
<span>{{ fmtW(0, POWER_UNIT.AUTO, true) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -93,7 +84,7 @@
|
|||
<LabelBar v-bind="labelBarProps('bottom', 'batteryCharge')">
|
||||
<BatteryIcon :soc="batterySoc" :gridCharge="batteryGridCharge" />
|
||||
</LabelBar>
|
||||
<LabelBar v-bind="labelBarProps('bottom', 'gridExport')">
|
||||
<LabelBar v-bind="labelBarProps('bottom', 'pvExport')">
|
||||
<shopicon-regular-powersupply></shopicon-regular-powersupply>
|
||||
</LabelBar>
|
||||
<LabelBar v-bind="labelBarProps('bottom', 'unknownOutput')">
|
||||
|
|
@ -143,32 +134,9 @@ export default defineComponent({
|
|||
return { width: 0, transitionsEnabled: false };
|
||||
},
|
||||
computed: {
|
||||
gridExport() {
|
||||
return this.applyThreshold(this.pvExport);
|
||||
},
|
||||
totalRaw() {
|
||||
total() {
|
||||
return this.gridImport + this.selfPv + this.selfBattery + this.pvExport;
|
||||
},
|
||||
gridImportAdjusted() {
|
||||
return this.applyThreshold(this.gridImport);
|
||||
},
|
||||
selfPvAdjusted() {
|
||||
return this.applyThreshold(this.selfPv);
|
||||
},
|
||||
selfBatteryAdjusted() {
|
||||
return this.applyThreshold(this.selfBattery);
|
||||
},
|
||||
pvExportAdjusted() {
|
||||
return this.applyThreshold(this.pvExport);
|
||||
},
|
||||
totalAdjusted() {
|
||||
return (
|
||||
this.gridImportAdjusted +
|
||||
this.selfPvAdjusted +
|
||||
this.selfBatteryAdjusted +
|
||||
this.pvExportAdjusted
|
||||
);
|
||||
},
|
||||
unknownImport() {
|
||||
// input/output mismatch > 10%
|
||||
return this.applyThreshold(Math.max(0, this.outPower - this.inPower), 10);
|
||||
|
|
@ -180,12 +148,12 @@ export default defineComponent({
|
|||
unknownPower() {
|
||||
if (this.unknownImport || this.unknownOutput) {
|
||||
const total = Math.max(this.inPower, this.outPower);
|
||||
return Math.abs(total - this.totalAdjusted);
|
||||
return Math.abs(total - this.total);
|
||||
}
|
||||
return 0;
|
||||
},
|
||||
visualizationReady() {
|
||||
return this.totalAdjusted > 0 && this.width > 0;
|
||||
return this.total > 0 && this.width > 0;
|
||||
},
|
||||
},
|
||||
|
||||
|
|
@ -212,8 +180,8 @@ export default defineComponent({
|
|||
},
|
||||
methods: {
|
||||
widthTotal(power: number) {
|
||||
if (this.totalAdjusted === 0 || power === 0) return "0";
|
||||
return (100 / this.totalAdjusted) * power + "%";
|
||||
if (this.total === 0 || power === 0) return "0";
|
||||
return (100 / this.total) * power + "%";
|
||||
},
|
||||
fmtBarValue(watt: number) {
|
||||
if (!this.enoughSpaceForValue(watt)) {
|
||||
|
|
@ -223,8 +191,8 @@ export default defineComponent({
|
|||
return this.fmtW(watt, this.powerUnit, withUnit);
|
||||
},
|
||||
powerLabelAvailableSpace(power: number) {
|
||||
if (this.totalAdjusted === 0) return 0;
|
||||
const percent = (100 / this.totalAdjusted) * power;
|
||||
if (this.total === 0) return 0;
|
||||
const percent = (100 / this.total) * power;
|
||||
return (this.width / 100) * percent;
|
||||
},
|
||||
enoughSpaceForValue(power: number) {
|
||||
|
|
@ -233,13 +201,8 @@ export default defineComponent({
|
|||
enoughSpaceForUnit(power: number) {
|
||||
return this.powerLabelAvailableSpace(power) > 60;
|
||||
},
|
||||
hideLabelIcon(power: number, minWidth = 32) {
|
||||
if (this.totalAdjusted === 0) return true;
|
||||
const percent = (100 / this.totalAdjusted) * power;
|
||||
return (this.width / 100) * percent < minWidth;
|
||||
},
|
||||
applyThreshold(power: number, threshold = 2) {
|
||||
const percent = (100 / this.totalRaw) * power;
|
||||
const percent = (100 / this.total) * power;
|
||||
return percent < threshold ? 0 : power;
|
||||
},
|
||||
updateElementWidth() {
|
||||
|
|
@ -247,10 +210,13 @@ export default defineComponent({
|
|||
},
|
||||
labelBarProps(position: string, name: string, val?: number) {
|
||||
const value = val === undefined ? (this as any)[name] : val;
|
||||
const minWidth = 40;
|
||||
const space = this.powerLabelAvailableSpace(value);
|
||||
return {
|
||||
value,
|
||||
hideIcon: this.hideLabelIcon(value, minWidth),
|
||||
// shrink the icon to an anonymous dot when the bar gets narrow,
|
||||
// drop the dot once the bar is too thin to render it cleanly
|
||||
hideIcon: space < 40,
|
||||
hideDot: space < 16,
|
||||
style: { "flex-basis": this.widthTotal(value) },
|
||||
[position]: true,
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue