From b21db1ef93afb491b41e22283b3e39153dbf8a0b Mon Sep 17 00:00:00 2001 From: Michael Zanetti Date: Mon, 25 Apr 2022 01:27:35 +0200 Subject: [PATCH] Improvements in the energy view --- nymea-app/ui/StyleBase.qml | 5 +- .../ui/mainviews/energy/ConsumerStats.qml | 6 +- .../ui/mainviews/energy/ConsumersHistory.qml | 6 +- .../ui/mainviews/energy/ConsumersPieChart.qml | 164 ++++++++++++------ .../CurrentConsumptionBalancePieChart.qml | 7 +- .../CurrentProductionBalancePieChart.qml | 7 +- nymea-app/ui/utils/NymeaUtils.qml | 25 +++ 7 files changed, 155 insertions(+), 65 deletions(-) diff --git a/nymea-app/ui/StyleBase.qml b/nymea-app/ui/StyleBase.qml index d4160e71..c5cdc7c0 100644 --- a/nymea-app/ui/StyleBase.qml +++ b/nymea-app/ui/StyleBase.qml @@ -7,6 +7,7 @@ Item { property color accentColor: "#57baae" property color iconColor: "#808080" + property color generationBaseColor: red property color tileBackgroundColor: Qt.tint(backgroundColor, Qt.rgba(foregroundColor.r, foregroundColor.g, foregroundColor.b, 0.05)) property color tileForegroundColor: foregroundColor @@ -106,14 +107,14 @@ Item { } property color red: "indianred" - property color green: "mediumseagreen" + property color green: "#5ccd5c" property color yellow: "gold" property color white: "white" property color gray: "gray" property color darkGray: "darkGray" property color blue: "deepskyblue" property color darkBlue: "royalblue" - property color orange: "#f6a625" + property color orange: "#cd955c" property color purple: "#6d5fd5" property color lime: "#99ca53" property color pink: "orchid" diff --git a/nymea-app/ui/mainviews/energy/ConsumerStats.qml b/nymea-app/ui/mainviews/energy/ConsumerStats.qml index 72c77a09..0add797c 100644 --- a/nymea-app/ui/mainviews/energy/ConsumerStats.qml +++ b/nymea-app/ui/mainviews/energy/ConsumerStats.qml @@ -285,7 +285,8 @@ StatsBase { for (var j = 0; j < consumers.count; j++) { var consumer = consumers.get(j) var barSet = barSeries.append(consumer.name, []) - barSet.color = root.colors[j % root.colors.length] +// barSet.color = root.colors[j % root.colors.length] + barSet.color = NymeaUtils.generateColor(Style.generationBaseColor, j) barSet.borderColor = barSet.color barSet.borderWith = 0 map[consumer.id] = barSet @@ -472,7 +473,8 @@ StatsBase { Rectangle { width: Style.extraSmallFont.pixelSize height: width - color: root.colors[model.indexInModel % root.colors.length] +// color: root.colors[model.indexInModel % root.colors.length] + color: NymeaUtils.generateColor(Style.generationBaseColor, model.indexInModel) } Label { text: "%1: %2 kWh".arg(model.name).arg(model.value) diff --git a/nymea-app/ui/mainviews/energy/ConsumersHistory.qml b/nymea-app/ui/mainviews/energy/ConsumersHistory.qml index 170effb6..a09bdfc1 100644 --- a/nymea-app/ui/mainviews/energy/ConsumersHistory.qml +++ b/nymea-app/ui/mainviews/energy/ConsumersHistory.qml @@ -135,7 +135,8 @@ Item { var series = chartView.createSeries(ChartView.SeriesTypeArea, thing.name, dateTimeAxis, valueAxis) series.lowerSeries = baseSeries series.upperSeries = lineSeriesComponent.createObject(series) - series.color = root.colors[i % root.colors.length] +// series.color = root.colors[i % root.colors.length] + series.color = NymeaUtils.generateColor(Style.generationBaseColor, i) series.borderWidth = 0; series.borderColor = series.color @@ -335,7 +336,8 @@ Item { Rectangle { width: Style.extraSmallFont.pixelSize height: width - color: index >= 0 ? root.colors[index % root.colors.length] : "white" +// color: index >= 0 ? root.colors[index % root.colors.length] : "white" + color: index >= 0 ? NymeaUtils.generateColor(Style.generationBaseColor, index) : "white" } Label { diff --git a/nymea-app/ui/mainviews/energy/ConsumersPieChart.qml b/nymea-app/ui/mainviews/energy/ConsumersPieChart.qml index a2b45f18..c62926f4 100644 --- a/nymea-app/ui/mainviews/energy/ConsumersPieChart.qml +++ b/nymea-app/ui/mainviews/energy/ConsumersPieChart.qml @@ -5,6 +5,7 @@ import QtQuick.Layouts 1.2 import QtGraphicalEffects 1.0 import QtCharts 2.2 import Nymea 1.0 +import "qrc:/ui/components" ChartView { id: root @@ -14,6 +15,11 @@ ChartView { titleColor: Style.foregroundColor legend.visible: false + margins.left: 0 + margins.right: 0 + margins.bottom: 0 + margins.top: 0 + property EnergyManager energyManager: null property ThingsProxy consumers: null property var colors: null @@ -73,10 +79,12 @@ ChartView { var colorMap = {} for (var i = 0; i < consumers.count; i++) { var consumer = consumers.get(i) - colorMap[consumer] = root.colors[i % root.colors.length] let currentPowerState = consumer.stateByName("currentPower") let slice = consumersBalanceSeries.append(consumer.name, currentPowerState.value) - slice.color = root.colors[i % root.colors.length] + print("***** slice border width", slice.borderWidth) +// slice.color = root.colors[i % root.colors.length] + slice.color = NymeaUtils.generateColor(Style.generationBaseColor, i) + colorMap[consumer] = slice.color currentPowerState.valueChanged.connect(function() { slice.value = currentPowerState.value }) @@ -97,79 +105,121 @@ ChartView { PieSeries { id: consumersBalanceSeries - size: 0.9 + size: 0.88 holeSize: 0.7 } - - ColumnLayout { + Flickable { id: centerLayout x: root.plotArea.x + (root.plotArea.width - width) / 2 y: root.plotArea.y + (root.plotArea.height - height) / 2 - width: root.plotArea.width * 0.65 -// height: root.plotArea.height * 0.65 - spacing: Style.smallMargins - property int maximumHeight: root.plotArea.height * 0.65 + width: Math.min(root.plotArea.width, root.plotArea.width) * 0.65 + height: Math.min(contentColumn.height + topMargin + bottomMargin, width) + topMargin: Style.smallIconSize + bottomMargin: Style.smallIconSize + opacity: 0 +// property int maximumHeight: root.plotArea.height * 0.65 + + contentHeight: contentColumn.implicitHeight ColumnLayout { - Layout.fillWidth: true - spacing: 0 - visible: root.rootMeter - Label { - text: qsTr("Total") - font: Style.smallFont - Layout.fillWidth: true - horizontalAlignment: Text.AlignHCenter - } - - Label { - text: "%1 %2" - .arg((energyManager.currentPowerConsumption / (energyManager.currentPowerConsumption > 1000 ? 1000 : 1)).toFixed(1)) - .arg(energyManager.currentPowerConsumption > 1000 ? "kW" : "W") - Layout.fillWidth: true - horizontalAlignment: Text.AlignHCenter - font: Style.bigFont - } - } - - ListView { - Layout.fillWidth: true - Layout.preferredHeight: count * (Style.smallMargins + Style.extraSmallFont.pixelSize + Style.smallFont.pixelSize) - Layout.maximumHeight: centerLayout.maximumHeight - y - clip: true + id: contentColumn + width: parent.width spacing: Style.smallMargins - model: ThingsProxy { - id: sortedConsumers - engine: _engine - parentProxy: root.consumers - sortStateName: "currentPower" - sortOrder: Qt.DescendingOrder - } - delegate: ColumnLayout { - id: consumerDelegate - width: parent ? parent.width : 0 + ColumnLayout { + Layout.fillWidth: true spacing: 0 - property Thing consumer: consumers.getThing(model.id) - property State currentPowerState: consumer ? consumer.stateByName("currentPower") : null - property double value: currentPowerState ? currentPowerState.value : 0 + visible: root.rootMeter + Label { + text: qsTr("Total") + font: Style.smallFont + Layout.topMargin: Style.smallMargins + Layout.fillWidth: true + horizontalAlignment: Text.AlignHCenter + } Label { - text: model.name - Layout.fillWidth: true - horizontalAlignment: Text.AlignHCenter - font: Style.extraSmallFont - } - Label { - color: d.thingsColorMap.hasOwnProperty(consumer) ? d.thingsColorMap[consumer] : "transparent" text: "%1 %2" - .arg((consumerDelegate.value / (consumerDelegate.value > 1000 ? 1000 : 1)).toFixed(1)) - .arg(consumerDelegate.value > 1000 ? "kWh" : "W") + .arg((energyManager.currentPowerConsumption / (energyManager.currentPowerConsumption > 1000 ? 1000 : 1)).toFixed(1)) + .arg(energyManager.currentPowerConsumption > 1000 ? "kW" : "W") Layout.fillWidth: true horizontalAlignment: Text.AlignHCenter - font: Style.smallFont + font: Style.bigFont + } + } + + Repeater { + model: ThingsProxy { + id: sortedConsumers + engine: _engine + parentProxy: root.consumers + sortStateName: "currentPower" + sortOrder: Qt.DescendingOrder + } + + delegate: ColumnLayout { + id: consumerDelegate + width: parent ? parent.width : 0 + spacing: 0 + property Thing consumer: consumers.getThing(model.id) + property State currentPowerState: consumer ? consumer.stateByName("currentPower") : null + property double value: currentPowerState ? currentPowerState.value : 0 + + Label { + text: model.name + Layout.fillWidth: true + horizontalAlignment: Text.AlignHCenter + font: Style.extraSmallFont + } + Label { + color: d.thingsColorMap.hasOwnProperty(consumer) ? d.thingsColorMap[consumer] : "transparent" + text: "%1 %2" + .arg((consumerDelegate.value / (consumerDelegate.value > 1000 ? 1000 : 1)).toFixed(1)) + .arg(consumerDelegate.value > 1000 ? "kWh" : "W") + Layout.fillWidth: true + horizontalAlignment: Text.AlignHCenter + font: Style.smallFont + } } } } + } + + Rectangle { + id: innerMask + anchors.fill: centerLayout + radius: width / 2 + visible: false + gradient: Gradient { + GradientStop { position: 0; color: "transparent" } + GradientStop { position: 1-(centerLayout.height - downArrow.height * 1.5) / centerLayout.height; color: "red" } + GradientStop { position: (centerLayout.height - downArrow.height * 1.5) / centerLayout.height; color: "red" } + GradientStop { position: 1; color: "transparent" } + } + } + + OpacityMask { + anchors.fill: centerLayout + source: centerLayout + maskSource: innerMask + } + + ColorIcon { + id: upArrow + anchors { top: centerLayout.top; horizontalCenter: centerLayout.horizontalCenter } + size: Style.smallIconSize + name: "up" + visible: !centerLayout.atYBeginning + } + ColorIcon { + id: downArrow + anchors { bottom: centerLayout.bottom; horizontalCenter: centerLayout.horizontalCenter } + size: Style.smallIconSize + name: "down" + visible: !centerLayout.atYEnd + } + + } diff --git a/nymea-app/ui/mainviews/energy/CurrentConsumptionBalancePieChart.qml b/nymea-app/ui/mainviews/energy/CurrentConsumptionBalancePieChart.qml index 7c8755fb..668ce6b9 100644 --- a/nymea-app/ui/mainviews/energy/CurrentConsumptionBalancePieChart.qml +++ b/nymea-app/ui/mainviews/energy/CurrentConsumptionBalancePieChart.qml @@ -14,6 +14,11 @@ ChartView { titleColor: Style.foregroundColor legend.visible: false + margins.left: 0 + margins.right: 0 + margins.bottom: 0 + margins.top: 0 + property EnergyManager energyManager: null ThingsProxy { @@ -24,7 +29,7 @@ ChartView { PieSeries { id: consumptionBalanceSeries - size: 0.9 + size: 0.88 holeSize: 0.7 property double fromGrid: Math.max(0, energyManager.currentPowerAcquisition) diff --git a/nymea-app/ui/mainviews/energy/CurrentProductionBalancePieChart.qml b/nymea-app/ui/mainviews/energy/CurrentProductionBalancePieChart.qml index 2ecf1c6e..f9e1b221 100644 --- a/nymea-app/ui/mainviews/energy/CurrentProductionBalancePieChart.qml +++ b/nymea-app/ui/mainviews/energy/CurrentProductionBalancePieChart.qml @@ -14,6 +14,11 @@ ChartView { titleColor: Style.foregroundColor legend.visible: false + margins.left: 0 + margins.right: 0 + margins.bottom: 0 + margins.top: 0 + property EnergyManager energyManager: null ThingsProxy { @@ -23,7 +28,7 @@ ChartView { } PieSeries { id: productionBalanceSeries - size: 0.9 + size: 0.88 holeSize: 0.7 property double toGrid: Math.abs(Math.min(0, energyManager.currentPowerAcquisition)) diff --git a/nymea-app/ui/utils/NymeaUtils.qml b/nymea-app/ui/utils/NymeaUtils.qml index 575323b6..a1dc1ddd 100644 --- a/nymea-app/ui/utils/NymeaUtils.qml +++ b/nymea-app/ui/utils/NymeaUtils.qml @@ -149,4 +149,29 @@ Item { property bool inhibitChartsAnimation: PlatformHelper.deviceModel.startsWith("SM-G950") // Samsung S8 has a buggy GPU driver :( property int chartsAnimationOptions: !inhibitChartsAnimation ? ChartView.SeriesAnimations : ChartView.NoAnimation + + function generateColor(baseColor, index) { + var stepSize = 30 + var baseHSV = rgb2hsv(baseColor.r, baseColor.g, baseColor.b) + var currentHue = baseHSV[0] + var handledColors = [currentHue] + for (var i = 0; i < index; i++) { + while (handledColors.indexOf(currentHue) >= 0) { + currentHue = (currentHue + 60) % 360 + + if (handledColors.indexOf(currentHue) >= 0) { + currentHue += /*60 + */stepSize + stepSize = Math.max(1, stepSize / 2) + } + } + handledColors.push(currentHue) + } + return Qt.hsva(currentHue / 360, baseHSV[1], baseHSV[2], 1); + } + + function rgb2hsv(r,g,b) { + var v=Math.max(r,g,b), c=v-Math.min(r,g,b); + var h= c && ((v==r) ? (g-b)/c : ((v==g) ? 2+(b-r)/c : 4+(r-g)/c)); + return [60*(h<0?h+6:h), v&&c/v, v]; + } }