Files
CuboBmsTool/qml/Controls/ChartView.qml

203 lines
6.8 KiB
QML

import QtQuick 2.12
import QtCharts 2.3
import QtQuick.Shapes 1.12
import Controls 1.0 as Controls
import Utils 1.0
ChartView {
id: chart
antialiasing: true
backgroundColor: Palette.backgroundColor
margins.left: 20
legend.visible: false
legend.alignment: Qt.AlignRight
legend.markerShape: Legend.MarkerShapeCircle
property AbstractAxis xAxis: valueAxisX
property AbstractAxis yAxis: valueAxisY
property int defaultXMax: 10
property int defaultYMax: 1
property bool autoScaling: true
property int selectedSeriesIndex: 0
property string infoXMark: ""
property string infoYMark: ""
ValueAxis {
id: valueAxisX
min: 0
max: chart.defaultXMax
tickCount: 8
gridVisible: false
gridLineColor: Palette.borderColor
labelsColor: Palette.contentTextColor
labelsFont.pixelSize: 18
color: Palette.borderColor
titleVisible: false
}
ValueAxis {
id: valueAxisY
min: 0
max: chart.defaultYMax
tickCount: 6
labelsColor: Palette.contentTextColor
labelsFont.pixelSize: 18
color: Palette.borderColor
titleVisible: false
}
Shape {
id: currentPointLine
implicitWidth: 1
implicitHeight: chart.plotArea.height
x: chart.plotArea.x
y: chart.plotArea.y
ShapePath {
strokeColor: Palette.borderColor
strokeStyle: ShapePath.SolidLine
startX: 0
startY: 0
PathLine { x: 0; y: currentPointLine.height }
}
}
Rectangle {
id: currentPointInfo
width: currentPointInfoLabel.width
height: currentPointInfoLabel.height
color: Palette.backgroundColor
border.width: 1
border.color: Palette.borderColor
opacity: 0.9
radius: 6
visible: false
Controls.SubtitleLabel {
id: currentPointInfoLabel
horizontalAlignment: Text.AlignHCenter
anchors.centerIn: parent
padding: 10
}
}
MouseArea {
id: chartMouseArea
anchors.fill: parent
acceptedButtons: Qt.LeftButton
hoverEnabled: true
property real lastMouseX: 0
property real lastMouseY: 0
property real scrollThreshold: 0
onMouseXChanged: {
if ((mouse.buttons & Qt.LeftButton) == Qt.LeftButton) {
if (mouseX - lastMouseX > scrollThreshold) {
chart.scrollLeft(mouseX - lastMouseX)
} else if (mouseX - lastMouseX < scrollThreshold) {
chart.scrollRight(lastMouseX - mouseX)
}
lastMouseX = mouseX
chart.autoScaling = false
}
updatePointInfo()
}
onMouseYChanged: {
if ((mouse.buttons & Qt.LeftButton) == Qt.LeftButton) {
if (mouseY - lastMouseY > scrollThreshold) {
chart.scrollUp(mouseY - lastMouseY)
} else if (mouseY - lastMouseY < scrollThreshold) {
chart.scrollDown(lastMouseY - mouseY)
}
lastMouseY = mouseY
chart.autoScaling = false
}
updatePointInfo()
}
onPressed: {
if (mouse.button === Qt.LeftButton) {
lastMouseX = mouseX
lastMouseY = mouseY
}
}
onWheel: {
var scaleFactor = 0.75
var area = chart.plotArea
chart.autoScaling = false
var yAxisPosition = mouseX <= chart.plotArea.x
if (yAxisPosition) {
if (wheel.angleDelta.y > 0) {
chart.zoomIn(Qt.rect(area.x, area.y + Math.round(area.height * (1 - scaleFactor) / 2), area.width, Math.round(area.height * scaleFactor)))
} else {
chart.zoomIn(Qt.rect(area.x, area.y - Math.round((area.height / scaleFactor) * (1 - scaleFactor) / 2), area.width, Math.round(area.height / scaleFactor)))
}
return
}
var xAxisPosition = mouseY >= (chart.plotArea.y + chart.plotArea.height)
if (xAxisPosition) {
if (wheel.angleDelta.y > 0) {
chart.zoomIn(Qt.rect(area.x + area.width * (1 - scaleFactor) / 2, area.y, Math.round(area.width * scaleFactor), area.height))
} else {
chart.zoomIn(Qt.rect(area.x - (area.width / scaleFactor) * (1 - scaleFactor) / 2, area.y, Math.round(area.width / scaleFactor), area.height))
}
return
}
if (wheel.angleDelta.y > 0) {
let zoomedInArea = Qt.rect(area.x + Math.round((mouseX - area.x) * (1 - scaleFactor)),
area.y + Math.round((mouseY - area.y) * (1 - scaleFactor)),
Math.round(area.width * scaleFactor),
Math.round(area.height * scaleFactor))
chart.zoomIn(zoomedInArea)
} else {
let zoomedOutArea = Qt.rect(area.x - Math.floor((mouseX - area.x) * (1 - scaleFactor)),
area.y - Math.floor((mouseY - area.y) * (1 - scaleFactor)),
Math.round(area.width * (1 + (1 - scaleFactor))),
Math.round(area.height * (1 + (1 - scaleFactor))))
chart.zoomIn(zoomedOutArea)
}
updatePointInfo()
}
function updatePointInfo() {
var currentPointVisibility = mouseX >= chart.plotArea.x && mouseX <= chart.plotArea.x + chart.plotArea.width &&
mouseY >= chart.plotArea.y && mouseY <= chart.plotArea.y + chart.plotArea.height
currentPointInfo.visible = currentPointVisibility
currentPointInfo.x = mouseX + 5
currentPointInfo.y = mouseY - currentPointInfo.height - 5
var currentX = Math.ceil(mapToValue(Qt.point(mouseX, mouseY), chart.series(selectedSeriesIndex)).x)
var selectedPoint = Qt.point(0, 0)
if (currentX < chart.series(selectedSeriesIndex).count && currentX > 0) {
selectedPoint = chart.series(selectedSeriesIndex).at(currentX)
currentPointInfoLabel.text = selectedPoint.x + " " + infoXMark + ", " + selectedPoint.y + " " + infoYMark
} else {
currentPointInfo.visible = false
}
currentPointLine.visible = currentPointVisibility
currentPointLine.x = mouseX
}
}
onSeriesAdded: if (count === 1) {
series.pointAdded.connect(function (index){ chartMouseArea.updatePointInfo() })
}
}