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() }) } }