This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets Quick WebSockets LinguistTools)
|
find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets Quick WebSockets LinguistTools Charts)
|
||||||
|
|
||||||
qt_standard_project_setup(REQUIRES 6.6 I18N_TRANSLATED_LANGUAGES de)
|
qt_standard_project_setup(REQUIRES 6.6 I18N_TRANSLATED_LANGUAGES de)
|
||||||
|
|
||||||
@@ -155,6 +155,7 @@ target_link_libraries(evcharger-app PUBLIC
|
|||||||
Qt6::Widgets
|
Qt6::Widgets
|
||||||
Qt6::Quick
|
Qt6::Quick
|
||||||
Qt6::WebSockets
|
Qt6::WebSockets
|
||||||
|
Qt6::Charts
|
||||||
qmsgpack
|
qmsgpack
|
||||||
QtZeroConf
|
QtZeroConf
|
||||||
goecommon
|
goecommon
|
||||||
|
|||||||
@@ -281,7 +281,7 @@ BaseNavigationPage {
|
|||||||
font.bold: true
|
font.bold: true
|
||||||
|
|
||||||
highlighted: true
|
highlighted: true
|
||||||
Material.accent: Material.Blue
|
//Material.accent: Material.Blue
|
||||||
|
|
||||||
display: listView.contentY < 20 ? AbstractButton.TextBesideIcon : AbstractButton.IconOnly
|
display: listView.contentY < 20 ? AbstractButton.TextBesideIcon : AbstractButton.IconOnly
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,126 @@ ScrollableTabPage {
|
|||||||
text: qsTr("Informations")
|
text: qsTr("Informations")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ChartView {
|
||||||
|
visible: categoryPowers.exists
|
||||||
|
|
||||||
|
ApiKeyValueHelper {
|
||||||
|
id: categoryNames
|
||||||
|
deviceConnection: theDeviceConnection
|
||||||
|
apiKey: "ccn"
|
||||||
|
}
|
||||||
|
|
||||||
|
ApiKeyValueHelper {
|
||||||
|
id: categoryPowers
|
||||||
|
deviceConnection: theDeviceConnection
|
||||||
|
apiKey: "ccp"
|
||||||
|
onValueChanged: {
|
||||||
|
const t = new Date();
|
||||||
|
|
||||||
|
const doit = function(category, value) {
|
||||||
|
category.append(t, value)
|
||||||
|
if (value)
|
||||||
|
category.visible = true
|
||||||
|
};
|
||||||
|
|
||||||
|
doit(category0, value[0])
|
||||||
|
doit(category1, value[1])
|
||||||
|
doit(category2, value[2])
|
||||||
|
doit(category3, value[3])
|
||||||
|
doit(category4, value[4])
|
||||||
|
|
||||||
|
// --- X axis range (last 30 seconds) ---
|
||||||
|
const now = new Date() // current time as Date
|
||||||
|
axisX.min = new Date(now.getTime() - 30*1000) // 30 sec ago
|
||||||
|
axisX.max = now
|
||||||
|
|
||||||
|
// --- Y axis auto-range ---
|
||||||
|
let minY = Number.POSITIVE_INFINITY
|
||||||
|
let maxY = Number.NEGATIVE_INFINITY
|
||||||
|
|
||||||
|
for (let s of [category0, category1, category2, category3, category4]) {
|
||||||
|
if (!s.visible)
|
||||||
|
continue
|
||||||
|
const c = s.count
|
||||||
|
if (c === 0) continue
|
||||||
|
|
||||||
|
for (let i = 0; i < c; ++i) {
|
||||||
|
const y = s.at(i).y
|
||||||
|
if (y < minY) minY = y
|
||||||
|
if (y > maxY) maxY = y
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// fallback if no data
|
||||||
|
if (!isFinite(minY)) {
|
||||||
|
minY = 0
|
||||||
|
maxY = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
// add 10% padding
|
||||||
|
const d = (maxY - minY) * 0.1
|
||||||
|
axisY.min = minY - d
|
||||||
|
axisY.max = maxY + d
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
title: "Category Powers 30sec"
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.preferredHeight: 300
|
||||||
|
antialiasing: true
|
||||||
|
|
||||||
|
DateTimeAxis {
|
||||||
|
id: axisX
|
||||||
|
format: "hh:mm:ss"
|
||||||
|
tickCount: 5
|
||||||
|
}
|
||||||
|
|
||||||
|
ValueAxis {
|
||||||
|
id: axisY
|
||||||
|
tickCount: 6
|
||||||
|
}
|
||||||
|
|
||||||
|
LineSeries {
|
||||||
|
id: category0
|
||||||
|
name: categoryNames.value[0]
|
||||||
|
axisX: axisX
|
||||||
|
axisY: axisY
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
|
||||||
|
LineSeries {
|
||||||
|
id: category1
|
||||||
|
name: categoryNames.value[1]
|
||||||
|
axisX: axisX
|
||||||
|
axisY: axisY
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
|
||||||
|
LineSeries {
|
||||||
|
id: category2
|
||||||
|
name: categoryNames.value[2]
|
||||||
|
axisX: axisX
|
||||||
|
axisY: axisY
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
|
||||||
|
LineSeries {
|
||||||
|
id: category3
|
||||||
|
name: categoryNames.value[3]
|
||||||
|
axisX: axisX
|
||||||
|
axisY: axisY
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
|
||||||
|
LineSeries {
|
||||||
|
id: category4
|
||||||
|
name: categoryNames.value[4]
|
||||||
|
axisX: axisX
|
||||||
|
axisY: axisY
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
id: statusText
|
id: statusText
|
||||||
text: qsTr("Idle")
|
text: qsTr("Idle")
|
||||||
@@ -86,28 +206,6 @@ ScrollableTabPage {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Repeater {
|
|
||||||
model: 5
|
|
||||||
|
|
||||||
ChartView {
|
|
||||||
title: "Line"
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.preferredHeight: page.height * 0.75
|
|
||||||
antialiasing: true
|
|
||||||
|
|
||||||
LineSeries {
|
|
||||||
name: "LineSeries"
|
|
||||||
XYPoint { x: 0; y: 0 }
|
|
||||||
XYPoint { x: 1.1; y: 2.1 }
|
|
||||||
XYPoint { x: 1.9; y: 3.3 }
|
|
||||||
XYPoint { x: 2.1; y: 2.1 }
|
|
||||||
XYPoint { x: 2.9; y: 4.9 }
|
|
||||||
XYPoint { x: 3.4; y: 3.0 }
|
|
||||||
XYPoint { x: 4.1; y: 3.3 }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
OpenLinkButton {
|
OpenLinkButton {
|
||||||
ApiKeyValueHelper {
|
ApiKeyValueHelper {
|
||||||
id: downloadsLink
|
id: downloadsLink
|
||||||
|
|||||||
Reference in New Issue
Block a user