778 lines
29 KiB
QML
778 lines
29 KiB
QML
import QtQuick 2.0
|
|
import QtQuick.Controls 2.3
|
|
import QtQuick.Layouts 1.1
|
|
import "qrc:/ui/components"
|
|
import "qrc:/ui/customviews"
|
|
import Nymea 1.0
|
|
import Nymea.AirConditioning 1.0
|
|
import QtCharts 2.3
|
|
|
|
Page {
|
|
id: root
|
|
property AirConditioningManager acManager: null
|
|
property ZoneInfoWrapper zoneWrapper: null
|
|
readonly property ZoneInfo zone: zoneWrapper.zone
|
|
|
|
|
|
header: NymeaHeader {
|
|
text: root.zone.name
|
|
|
|
onBackPressed: {
|
|
pageStack.pop()
|
|
}
|
|
}
|
|
|
|
Component {
|
|
id: lineSeriesComponent
|
|
LineSeries { }
|
|
}
|
|
|
|
QtObject {
|
|
id: d
|
|
|
|
property date now: new Date()
|
|
|
|
property int range: 60 * 24
|
|
|
|
readonly property var startTime: {
|
|
var date = new Date(now);
|
|
date.setTime(date.getTime() - range * 60000 + 2000);
|
|
return date;
|
|
}
|
|
|
|
readonly property var endTime: {
|
|
var date = new Date(now);
|
|
date.setTime(date.getTime() + 2000)
|
|
return date;
|
|
}
|
|
}
|
|
|
|
|
|
ChartView {
|
|
id: chartView
|
|
anchors.fill: parent
|
|
|
|
backgroundColor: "transparent"
|
|
margins.left: 0
|
|
margins.right: 0
|
|
margins.top: 0
|
|
margins.bottom: Style.smallIconSize + Style.margins
|
|
|
|
legend.visible: false
|
|
legend.alignment: Qt.AlignBottom
|
|
legend.font: Style.extraSmallFont
|
|
legend.labelColor: Style.foregroundColor
|
|
|
|
ValueAxis {
|
|
id: temperatureAxis
|
|
min: 0
|
|
max: 50
|
|
labelFormat: ""
|
|
gridLineColor: Style.tileOverlayColor
|
|
labelsVisible: false
|
|
lineVisible: false
|
|
titleVisible: false
|
|
shadesVisible: false
|
|
}
|
|
|
|
ValueAxis {
|
|
id: humidityAxis
|
|
min: 0
|
|
max: 100
|
|
labelFormat: ""
|
|
gridLineColor: Style.tileOverlayColor
|
|
labelsVisible: false
|
|
lineVisible: false
|
|
titleVisible: false
|
|
shadesVisible: false
|
|
visible: false
|
|
}
|
|
|
|
ValueAxis {
|
|
id: vocAxis
|
|
min: 0
|
|
max: 1000
|
|
// max: vocRepeater.count > 0 ? vocRepeater.itemAt(0).logsModel.maxValue : 0
|
|
labelFormat: ""
|
|
gridLineColor: Style.tileOverlayColor
|
|
labelsVisible: false
|
|
lineVisible: false
|
|
titleVisible: false
|
|
shadesVisible: false
|
|
visible: false
|
|
}
|
|
|
|
ValueAxis {
|
|
id: boolAxis
|
|
min: 0
|
|
max: 1
|
|
labelFormat: ""
|
|
gridLineColor: Style.tileOverlayColor
|
|
labelsVisible: false
|
|
lineVisible: false
|
|
titleVisible: false
|
|
shadesVisible: false
|
|
visible: false
|
|
}
|
|
|
|
Item {
|
|
id: labelsLayout
|
|
x: Style.smallMargins
|
|
y: chartView.plotArea.y
|
|
height: chartView.plotArea.height
|
|
width: chartView.plotArea.x - x
|
|
Repeater {
|
|
model: temperatureAxis.tickCount
|
|
delegate: ColumnLayout {
|
|
y: index == temperatureAxis.tickCount - 1
|
|
? parent.height - height
|
|
: index == 0
|
|
? 0
|
|
: parent.height / (temperatureAxis.tickCount - 1) * index - height / 2
|
|
Label {
|
|
width: parent.width - Style.smallMargins
|
|
horizontalAlignment: Text.AlignRight
|
|
text: (temperatureAxis.max - (index * temperatureAxis.max / (temperatureAxis.tickCount - 1))) + "°C"
|
|
verticalAlignment: Text.AlignTop
|
|
font: Style.extraSmallFont
|
|
visible: tempRepeater.count > 0 || thermostatsRepeater.count > 0
|
|
color: app.interfaceToColor("temperaturesensor")
|
|
}
|
|
Label {
|
|
width: parent.width - Style.smallMargins
|
|
horizontalAlignment: Text.AlignRight
|
|
text: (humidityAxis.max - (index * humidityAxis.max / (humidityAxis.tickCount - 1))).toFixed(0) + "%"
|
|
verticalAlignment: Text.AlignTop
|
|
font: Style.extraSmallFont
|
|
visible: humidityRepeater.count > 0
|
|
color: app.interfaceToColor("humiditysensor")
|
|
}
|
|
Label {
|
|
width: parent.width - Style.smallMargins
|
|
horizontalAlignment: Text.AlignRight
|
|
text: (vocAxis.max - (index * vocAxis.max / (vocAxis.tickCount - 1))).toFixed(0) + "ppm"
|
|
verticalAlignment: Text.AlignTop
|
|
font: Style.extraSmallFont
|
|
visible: vocRepeater.count > 0
|
|
color: app.interfaceToColor("vocsensor")
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
DateTimeAxis {
|
|
id: dateTimeAxis
|
|
min: d.startTime
|
|
max: d.endTime
|
|
format: {
|
|
// switch (selectionTabs.currentValue.sampleRate) {
|
|
// case EnergyLogs.SampleRate1Min:
|
|
// case EnergyLogs.SampleRate15Mins:
|
|
return "hh:mm"
|
|
// case EnergyLogs.SampleRate1Hour:
|
|
// case EnergyLogs.SampleRate3Hours:
|
|
// case EnergyLogs.SampleRate1Day:
|
|
// return "dd.MM."
|
|
// }
|
|
}
|
|
tickCount: {
|
|
// switch (selectionTabs.currentValue.sampleRate) {
|
|
// case EnergyLogs.SampleRate1Min:
|
|
// case EnergyLogs.SampleRate15Mins:
|
|
// return root.width > 500 ? 13 : 7
|
|
// case EnergyLogs.SampleRate1Hour:
|
|
// return 7
|
|
// case EnergyLogs.SampleRate3Hours:
|
|
// case EnergyLogs.SampleRate1Day:
|
|
return root.width > 500 ? 12 : 6
|
|
// }
|
|
}
|
|
labelsFont: Style.extraSmallFont
|
|
gridVisible: false
|
|
minorGridVisible: false
|
|
lineVisible: false
|
|
shadesVisible: false
|
|
labelsColor: Style.foregroundColor
|
|
}
|
|
|
|
Repeater {
|
|
id: thermostatsRepeater
|
|
model: zoneWrapper.thermostats
|
|
delegate: Item {
|
|
id: thermostatDelegate
|
|
readonly property Thing thing: zoneWrapper.thermostats.get(index)
|
|
property XYSeries series: null
|
|
|
|
readonly property LogsModel logsModel: LogsModel {
|
|
objectName: "temp: " + thing.name
|
|
engine: typeIds.length > 0 ? _engine : null
|
|
thingId: thing.id
|
|
live: true
|
|
// graphSeries: series
|
|
viewStartTime: new Date(d.startTime.getTime() - d.range * 60000)
|
|
|
|
fetchBlockSize: 500
|
|
|
|
typeIds: {
|
|
var ret = [];
|
|
ret.push(thing.thingClass.stateTypes.findByName("temperature").id)
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
XYSeriesAdapter {
|
|
logsModel: thermostatDelegate.logsModel
|
|
xySeries: series
|
|
sampleRate: XYSeriesAdapter.SampleRate10Minutes
|
|
}
|
|
|
|
Component.onCompleted: {
|
|
series = chartView.createSeries(ChartView.SeriesTypeLine, thing.name, dateTimeAxis, temperatureAxis)
|
|
series.color = app.interfaceToColor("temperaturesensor")
|
|
series.width = 2
|
|
|
|
// series.opacity = Qt.binding(function() {
|
|
// return d.selectedSeries == null || d.selectedSeries == series ? 1 : 0.3
|
|
// })
|
|
series.borderWidth = 0;
|
|
series.borderColor = series.color
|
|
}
|
|
Component.onDestruction: {
|
|
chartView.removeSeries(series)
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
Repeater {
|
|
id: tempRepeater
|
|
model: zoneWrapper.indoorTempSensors
|
|
delegate: Item {
|
|
id: tempDelegate
|
|
readonly property Thing thing: zoneWrapper.indoorTempSensors.get(index)
|
|
property XYSeries series: null
|
|
|
|
readonly property LogsModel logsModel: LogsModel {
|
|
objectName: "temp: " + thing.name
|
|
engine: typeIds.length > 0 ? _engine : null
|
|
thingId: thing.id
|
|
live: true
|
|
// graphSeries: series
|
|
viewStartTime: new Date(d.startTime.getTime() - d.range * 60000)
|
|
|
|
fetchBlockSize: 500
|
|
|
|
typeIds: {
|
|
var ret = [];
|
|
ret.push(thing.thingClass.stateTypes.findByName("temperature").id)
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
XYSeriesAdapter {
|
|
logsModel: tempDelegate.logsModel
|
|
xySeries: series
|
|
sampleRate: XYSeriesAdapter.SampleRate10Minutes
|
|
}
|
|
|
|
Component.onCompleted: {
|
|
series = chartView.createSeries(ChartView.SeriesTypeLine, thing.name, dateTimeAxis, temperatureAxis)
|
|
series.color = app.interfaceToColor("temperaturesensor")
|
|
series.width = 1
|
|
|
|
// series.opacity = Qt.binding(function() {
|
|
// return d.selectedSeries == null || d.selectedSeries == series ? 1 : 0.3
|
|
// })
|
|
series.borderWidth = 0;
|
|
series.borderColor = series.color
|
|
}
|
|
Component.onDestruction: {
|
|
chartView.removeSeries(series)
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
Repeater {
|
|
id: humidityRepeater
|
|
model: zoneWrapper.indoorHumiditySensors
|
|
delegate: Item {
|
|
id: humidityDelegate
|
|
readonly property Thing thing: zoneWrapper.indoorHumiditySensors.get(index)
|
|
property XYSeries series: null
|
|
|
|
readonly property LogsModel logsModel: LogsModel {
|
|
objectName: "hum: " + thing.name
|
|
engine: typeIds.length > 0 ? _engine : null
|
|
thingId: thing.id
|
|
live: true
|
|
// graphSeries: series
|
|
viewStartTime: new Date(d.startTime.getTime() - d.range * 60000)
|
|
fetchBlockSize: 500
|
|
|
|
typeIds: {
|
|
var ret = [];
|
|
ret.push(thing.thingClass.stateTypes.findByName("humidity").id)
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
XYSeriesAdapter {
|
|
logsModel: humidityDelegate.logsModel
|
|
xySeries: series
|
|
sampleRate: XYSeriesAdapter.SampleRate10Minutes
|
|
}
|
|
|
|
Component.onCompleted: {
|
|
series = chartView.createSeries(ChartView.SeriesTypeLine, thing.name, dateTimeAxis, humidityAxis)
|
|
series.color = app.interfaceToColor("humiditysensor")
|
|
series.width = 1
|
|
// series.opacity = Qt.binding(function() {
|
|
// return d.selectedSeries == null || d.selectedSeries == series ? 1 : 0.3
|
|
// })
|
|
series.borderWidth = 0;
|
|
series.borderColor = series.color
|
|
}
|
|
Component.onDestruction: {
|
|
chartView.removeSeries(series)
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
Repeater {
|
|
id: vocRepeater
|
|
model: zoneWrapper.indoorVocSensors
|
|
delegate: Item {
|
|
id: vocDelegate
|
|
readonly property Thing thing: zoneWrapper.indoorVocSensors.get(index)
|
|
property XYSeries series: null
|
|
readonly property LogsModel logsModel: LogsModel {
|
|
objectName: "voc: " + thing.name
|
|
engine: typeIds.length > 0 ? _engine : null
|
|
thingId: thing.id
|
|
live: true
|
|
// graphSeries: series
|
|
viewStartTime: new Date(d.startTime.getTime() - d.range * 60000)
|
|
fetchBlockSize: 500
|
|
|
|
typeIds: {
|
|
var ret = [];
|
|
ret.push(thing.thingClass.stateTypes.findByName("voc").id)
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
XYSeriesAdapter {
|
|
logsModel: vocDelegate.logsModel
|
|
xySeries: series
|
|
sampleRate: XYSeriesAdapter.SampleRate10Minutes
|
|
}
|
|
|
|
Component.onCompleted: {
|
|
series = chartView.createSeries(ChartView.SeriesTypeLine, thing.name, dateTimeAxis, vocAxis)
|
|
series.color = app.interfaceToColor("vocsensor")
|
|
series.width = 1
|
|
// series.opacity = Qt.binding(function() {
|
|
// return d.selectedSeries == null || d.selectedSeries == series ? 1 : 0.3
|
|
// })
|
|
series.borderWidth = 0;
|
|
series.borderColor = series.color
|
|
}
|
|
Component.onDestruction: {
|
|
chartView.removeSeries(series)
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
Repeater {
|
|
model: zoneWrapper.windowSensors
|
|
delegate: Item {
|
|
id: closableDelegate
|
|
readonly property Thing thing: zoneWrapper.windowSensors.get(index)
|
|
property AreaSeries series: null
|
|
|
|
LineSeries {
|
|
id: closableUpperSeries
|
|
}
|
|
LineSeries {
|
|
id: closableLowerSeries
|
|
XYPoint {x: dateTimeAxis.min.getTime(); y: 0}
|
|
XYPoint {x: dateTimeAxis.max.getTime(); y: 0}
|
|
}
|
|
|
|
readonly property LogsModel logsModel: LogsModel {
|
|
id: logsModelNg
|
|
engine: typeIds.length ? _engine : null
|
|
thingId: thing ? thing.id : ""
|
|
typeIds: {
|
|
var ret = [];
|
|
ret.push(thing.thingClass.stateTypes.findByName("closed").id)
|
|
return ret;
|
|
}
|
|
live: true
|
|
viewStartTime: new Date(d.startTime.getTime() - d.range * 60000)
|
|
}
|
|
|
|
BoolSeriesAdapter {
|
|
logsModel: closableDelegate.logsModel
|
|
xySeries: closableUpperSeries
|
|
inverted: true
|
|
}
|
|
|
|
Component.onCompleted: {
|
|
series = chartView.createSeries(ChartView.SeriesTypeArea, thing.name, dateTimeAxis, boolAxis)
|
|
series.lowerSeries = closableLowerSeries
|
|
series.upperSeries = closableUpperSeries
|
|
series.color = Style.green
|
|
series.opacity = 0.1
|
|
// series.opacity = Qt.binding(function() {
|
|
// return d.selectedSeries == null || d.selectedSeries == series ? 1 : 0.3
|
|
// })
|
|
|
|
series.borderWidth = 0;
|
|
series.borderColor = series.color
|
|
}
|
|
Component.onDestruction: {
|
|
chartView.removeSeries(series)
|
|
}
|
|
}
|
|
}
|
|
|
|
Repeater {
|
|
model: zoneWrapper.thermostats.count
|
|
delegate: Item {
|
|
id: heatingDelegate
|
|
readonly property Thing thing: zoneWrapper.thermostats.get(index)
|
|
property AreaSeries series: null
|
|
|
|
|
|
LineSeries {
|
|
id: heatingUpperSeries
|
|
}
|
|
LineSeries {
|
|
id: heatingLowerSeries
|
|
XYPoint {x: dateTimeAxis.max.getTime(); y: 0}
|
|
XYPoint {x: dateTimeAxis.min.getTime(); y: 0}
|
|
|
|
}
|
|
|
|
readonly property LogsModel logsModel: LogsModel {
|
|
objectName: "heat: " + thing.name
|
|
engine: typeIds.length > 0 ? _engine : null
|
|
thingId: thing ? thing.id : ""
|
|
typeIds: {
|
|
var ret = [];
|
|
var heatingOnStateType = thing.thingClass.stateTypes.findByName("heatingOn")
|
|
print("**** has heatingOn")
|
|
if (heatingOnStateType) {
|
|
print("**** true")
|
|
ret.push(heatingOnStateType.id)
|
|
}
|
|
return ret;
|
|
}
|
|
live: true
|
|
// graphSeries: heatingUpperSeries
|
|
viewStartTime: dateTimeAxis.min
|
|
}
|
|
|
|
BoolSeriesAdapter {
|
|
logsModel: heatingDelegate.logsModel
|
|
xySeries: heatingUpperSeries
|
|
}
|
|
|
|
Component.onCompleted: {
|
|
series = chartView.createSeries(ChartView.SeriesTypeArea, thing.name, dateTimeAxis, boolAxis)
|
|
series.lowerSeries = heatingLowerSeries
|
|
series.upperSeries = heatingUpperSeries
|
|
series.color = Style.red
|
|
series.opacity = 0.1
|
|
// series.opacity = Qt.binding(function() {
|
|
// return d.selectedSeries == null || d.selectedSeries == series ? 1 : 0.3
|
|
// })
|
|
|
|
series.borderWidth = 0;
|
|
series.borderColor = series.color
|
|
}
|
|
Component.onDestruction: {
|
|
chartView.removeSeries(series)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
MouseArea {
|
|
id: mouseArea
|
|
anchors.fill: parent
|
|
anchors.leftMargin: chartView.plotArea.x
|
|
anchors.topMargin: chartView.plotArea.y
|
|
anchors.rightMargin: chartView.width - chartView.plotArea.width - chartView.plotArea.x
|
|
anchors.bottomMargin: chartView.height - chartView.plotArea.height - chartView.plotArea.y
|
|
|
|
hoverEnabled: true
|
|
preventStealing: tooltipping || dragging
|
|
|
|
property int startMouseX: 0
|
|
property bool dragging: false
|
|
property bool tooltipping: false
|
|
|
|
property var startDatetime: null
|
|
|
|
Timer {
|
|
interval: 300
|
|
running: mouseArea.pressed
|
|
onTriggered: {
|
|
if (!mouseArea.dragging) {
|
|
mouseArea.tooltipping = true
|
|
}
|
|
}
|
|
}
|
|
onReleased: {
|
|
mouseArea.tooltipping = false;
|
|
|
|
if (mouseArea.dragging) {
|
|
mouseArea.dragging = false;
|
|
}
|
|
}
|
|
|
|
onPressed: {
|
|
startMouseX = mouseX
|
|
startDatetime = d.now
|
|
}
|
|
|
|
|
|
onDoubleClicked: {
|
|
if (selectionTabs.currentIndex == 0) {
|
|
return;
|
|
}
|
|
|
|
var idx = Math.ceil(mouseArea.mouseX * d.visibleValues / mouseArea.width)
|
|
var timestamp = new Date(d.startTime.getTime() + (idx * d.sampleRate * 60000))
|
|
selectionTabs.currentIndex--
|
|
d.now = new Date(Math.min(new Date().getTime(), timestamp.getTime() + (d.visibleValues / 2) * d.sampleRate * 60000))
|
|
powerBalanceLogs.fetchLogs()
|
|
logsLoader.fetchLogs()
|
|
}
|
|
|
|
onMouseXChanged: {
|
|
if (!pressed || mouseArea.tooltipping) {
|
|
return;
|
|
}
|
|
if (Math.abs(startMouseX - mouseX) < 10) {
|
|
return;
|
|
}
|
|
dragging = true
|
|
|
|
var dragDelta = startMouseX - mouseX
|
|
var totalTime = d.endTime.getTime() - d.startTime.getTime()
|
|
// dragDelta : timeDelta = width : totalTime
|
|
var timeDelta = dragDelta * totalTime / mouseArea.width
|
|
print("dragging", dragDelta, totalTime, mouseArea.width)
|
|
d.now = new Date(Math.min(new Date(), new Date(startDatetime.getTime() + timeDelta)))
|
|
}
|
|
|
|
onWheel: {
|
|
startDatetime = d.now
|
|
var totalTime = d.endTime.getTime() - d.startTime.getTime()
|
|
// pixelDelta : timeDelta = width : totalTime
|
|
var timeDelta = wheel.pixelDelta.x * totalTime / mouseArea.width
|
|
print("wheeling", wheel.pixelDelta.x, totalTime, mouseArea.width)
|
|
d.now = new Date(Math.min(new Date(), new Date(startDatetime.getTime() - timeDelta)))
|
|
wheelStopTimer.restart()
|
|
}
|
|
Timer {
|
|
id: wheelStopTimer
|
|
interval: 300
|
|
repeat: false
|
|
onTriggered: {
|
|
// for (var i = 0; i < consumersRepeater.count; i++) {
|
|
// if (consumersRepeater.itemAt(i).logs.fetchingData) {
|
|
// wheelStopTimer.start()
|
|
// return;
|
|
// }
|
|
// }
|
|
|
|
// powerBalanceLogs.fetchLogs()
|
|
// logsLoader.fetchLogs()
|
|
}
|
|
}
|
|
|
|
Rectangle {
|
|
height: parent.height
|
|
width: 1
|
|
color: Style.foregroundColor
|
|
x: Math.min(mouseArea.width - 1, Math.max(0, mouseArea.mouseX))
|
|
visible: (mouseArea.containsMouse || mouseArea.tooltipping) && !mouseArea.dragging
|
|
}
|
|
|
|
Item {
|
|
id: tooltips
|
|
anchors.fill: parent
|
|
property var timestamp: new Date(((d.endTime.getTime() - d.startTime.getTime()) * mouseArea.mouseX / mouseArea.width) + d.startTime.getTime())
|
|
property int xOnRight: Math.max(0, mouseArea.mouseX) + Style.smallMargins
|
|
property int xOnLeft: Math.min(mouseArea.width, mouseArea.mouseX) - Style.smallMargins - tooltipWidth
|
|
|
|
property int tooltipWidth: 130
|
|
property int tooltipX: xOnLeft < 0 ? xOnRight : xOnLeft
|
|
|
|
onTimestampChanged: {
|
|
updateTimer.start();
|
|
}
|
|
Timer {
|
|
id: updateTimer
|
|
interval: 0
|
|
onTriggered: tooltips.update()
|
|
}
|
|
|
|
function update() {
|
|
var ordered = []
|
|
insert(thermostatTooltipRepeater, ordered);
|
|
insert(tempTooltipRepeater, ordered);
|
|
insert(humidityTooltipRepeater, ordered);
|
|
insert(vocTooltipRepeater, ordered);
|
|
|
|
for (var i = ordered.length - 1; i >= 0; i--) {
|
|
var item = ordered[i]
|
|
var newY = item.realY
|
|
|
|
if (i < ordered.length-1) {
|
|
var previous = ordered[i+1]
|
|
newY = Math.min(newY, previous.fixedY - item.height/* - Style.extraSmallMargins*/)
|
|
}
|
|
|
|
ordered[i].fixedY = newY
|
|
}
|
|
}
|
|
|
|
function insert(repeater, array) {
|
|
for (var i = 0; i < repeater.count; i++) {
|
|
var item = repeater.itemAt(i);
|
|
var insertIdx = 0;
|
|
while (array.length > insertIdx && item.realY > array[insertIdx].realY) {
|
|
insertIdx++
|
|
}
|
|
array.splice(insertIdx, 0, item)
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
Repeater {
|
|
id: thermostatTooltipRepeater
|
|
model: thermostatsRepeater.count
|
|
|
|
delegate: TooltipDelegate {
|
|
visible: (mouseArea.containsMouse || mouseArea.tooltipping) && !mouseArea.dragging
|
|
thing: thermostatsRepeater.itemAt(index).thing
|
|
entry: thermostatsRepeater.itemAt(index).logsModel.findClosest(tooltips.timestamp)
|
|
color: app.interfaceToColor("temperaturesensor")
|
|
axis: temperatureAxis
|
|
x: tooltips.tooltipX
|
|
width: tooltips.tooltipWidth
|
|
backgroundItem: chartView
|
|
backgroundRect: Qt.rect(mouseArea.x + x, mouseArea.y + y, width, height)
|
|
unit: Types.UnitDegreeCelsius
|
|
}
|
|
}
|
|
|
|
Repeater {
|
|
id: tempTooltipRepeater
|
|
model: tempRepeater.count
|
|
|
|
delegate: TooltipDelegate {
|
|
visible: (mouseArea.containsMouse || mouseArea.tooltipping) && !mouseArea.dragging
|
|
thing: tempRepeater.itemAt(index).thing
|
|
entry: tempRepeater.itemAt(index).logsModel.findClosest(tooltips.timestamp)
|
|
color: app.interfaceToColor("temperaturesensor")
|
|
axis: temperatureAxis
|
|
x: tooltips.tooltipX
|
|
width: tooltips.tooltipWidth
|
|
backgroundItem: chartView
|
|
backgroundRect: Qt.rect(mouseArea.x + x, mouseArea.y + y, width, height)
|
|
unit: Types.UnitDegreeCelsius
|
|
}
|
|
}
|
|
|
|
Repeater {
|
|
id: humidityTooltipRepeater
|
|
model: humidityRepeater.count
|
|
|
|
delegate: TooltipDelegate {
|
|
visible: (mouseArea.containsMouse || mouseArea.tooltipping) && !mouseArea.dragging
|
|
thing: humidityRepeater.itemAt(index).thing
|
|
entry: humidityRepeater.itemAt(index).logsModel.findClosest(tooltips.timestamp)
|
|
color: app.interfaceToColor("humiditysensor")
|
|
axis: humidityAxis
|
|
x: tooltips.tooltipX
|
|
width: tooltips.tooltipWidth
|
|
backgroundItem: chartView
|
|
backgroundRect: Qt.rect(mouseArea.x + x, mouseArea.y + y, width, height)
|
|
unit: Types.UnitPercentage
|
|
}
|
|
}
|
|
|
|
Repeater {
|
|
id: vocTooltipRepeater
|
|
model: vocRepeater.count
|
|
|
|
delegate: TooltipDelegate {
|
|
visible: (mouseArea.containsMouse || mouseArea.tooltipping) && !mouseArea.dragging
|
|
thing: vocRepeater.itemAt(index).thing
|
|
entry: vocRepeater.itemAt(index).logsModel.findClosest(tooltips.timestamp)
|
|
color: app.interfaceToColor("vocsensor")
|
|
axis: vocAxis
|
|
x: tooltips.tooltipX
|
|
width: tooltips.tooltipWidth
|
|
backgroundItem: chartView
|
|
backgroundRect: Qt.rect(mouseArea.x + x, mouseArea.y + y, width, height)
|
|
unit: Types.UnitPartsPerMillion
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
RowLayout {
|
|
id: legend
|
|
anchors { left: parent.left; bottom: parent.bottom; right: parent.right }
|
|
anchors.leftMargin: chartView.plotArea.x
|
|
height: Style.smallIconSize
|
|
anchors.margins: Style.margins
|
|
|
|
Repeater {
|
|
model: thermostatsRepeater.count
|
|
delegate: LegendDelegate {
|
|
thing: thermostatsRepeater.itemAt(index).thing
|
|
iconName: app.interfaceToIcon("thermostat")
|
|
color: app.interfaceToColor("temperaturesensor")
|
|
}
|
|
}
|
|
Repeater {
|
|
model: tempRepeater.count
|
|
delegate: LegendDelegate {
|
|
thing: tempRepeater.itemAt(index).thing
|
|
iconName: app.interfaceToIcon("temperaturesensor")
|
|
color: app.interfaceToColor("temperaturesensor")
|
|
}
|
|
}
|
|
Repeater {
|
|
model: humidityRepeater.count
|
|
delegate: LegendDelegate {
|
|
thing: humidityRepeater.itemAt(index).thing
|
|
iconName: app.interfaceToIcon("humiditysensor")
|
|
color: app.interfaceToColor("humiditysensor")
|
|
}
|
|
}
|
|
Repeater {
|
|
model: vocRepeater.count
|
|
delegate: LegendDelegate {
|
|
thing: vocRepeater.itemAt(index).thing
|
|
iconName: app.interfaceToIcon("vocsensor")
|
|
color: app.interfaceToColor("vocsensor")
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|