用QML写一个折线图控件,横坐标单位为时间,纵坐标数值,该控件可以通过手指进行缩放,从而调整横纵坐标比例重新显示
时间: 2024-05-16 17:12:34 浏览: 158
自编Qml时间控件(实用)
5星 · 资源好评率100%
以下是一个简单的QML折线图控件示例,可以通过手指进行缩放,并且可以根据缩放比例重新计算横纵坐标的范围。
```qml
import QtQuick 2.15
import QtCharts 2.3
ChartView {
id: chartView
title: "折线图"
antialiasing: true
animationOptions: ChartView.AllAnimations
legend.visible: false
margins.left: 0
margins.right: 0
margins.top: 0
margins.bottom: 0
property real zoomFactor: 1.0
property bool isPinching: false
property point lastPos: Qt.point(0, 0)
property real minX: 0
property real maxX: 10
property real minY: 0
property real maxY: 100
function updateRange() {
var xRange = maxX - minX
var yRange = maxY - minY
var xRatio = chartView.width / xRange / zoomFactor
var yRatio = chartView.height / yRange / zoomFactor
chartView.axisX.min = minX - (chartView.width / xRatio - xRange) / 2
chartView.axisX.max = maxX + (chartView.width / xRatio - xRange) / 2
chartView.axisY.min = minY - (chartView.height / yRatio - yRange) / 2
chartView.axisY.max = maxY + (chartView.height / yRatio - yRange) / 2
}
LineSeries {
id: lineSeries
XYPoint { x: 0; y: 50 }
XYPoint { x: 1; y: 60 }
XYPoint { x: 2; y: 40 }
XYPoint { x: 3; y: 70 }
XYPoint { x: 4; y: 30 }
XYPoint { x: 5; y: 80 }
XYPoint { x: 6; y: 20 }
XYPoint { x: 7; y: 90 }
XYPoint { x: 8; y: 10 }
XYPoint { x: 9; y: 100 }
}
AreaSeries {
id: areaSeries
useOpenGL: true
borderColor: "transparent"
brush.gradient: Gradient {
GradientStop { position: 0; color: "steelblue" }
GradientStop { position: 1; color: "transparent" }
}
XYPoint { x: 0; y: 50 }
XYPoint { x: 1; y: 60 }
XYPoint { x: 2; y: 40 }
XYPoint { x: 3; y: 70 }
XYPoint { x: 4; y: 30 }
XYPoint { x: 5; y: 80 }
XYPoint { x: 6; y: 20 }
XYPoint { x: 7; y: 90 }
XYPoint { x: 8; y: 10 }
XYPoint { x: 9; y: 100 }
}
Component.onCompleted: {
updateRange()
}
onPinchStarted: {
isPinching = true
}
onPinchUpdated: {
var factor = event.scale / chartView.zoomFactor
chartView.zoomFactor = event.scale
chartView.axisX.min = chartView.axisX.min + (event.center.x - chartView.width / 2) / chartView.width * (maxX - minX) / factor
chartView.axisX.max = chartView.axisX.max - (chartView.width / 2 - event.center.x) / chartView.width * (maxX - minX) / factor
chartView.axisY.min = chartView.axisY.min + (event.center.y - chartView.height / 2) / chartView.height * (maxY - minY) / factor
chartView.axisY.max = chartView.axisY.max - (chartView.height / 2 - event.center.y) / chartView.height * (maxY - minY) / factor
}
onPinchFinished: {
isPinching = false
}
onPositionChanged: {
if (isPinching) {
var deltaX = event.position.x - lastPos.x
var deltaY = event.position.y - lastPos.y
chartView.axisX.min = chartView.axisX.min - deltaX / chartView.width * (maxX - minX) / chartView.zoomFactor
chartView.axisX.max = chartView.axisX.max - deltaX / chartView.width * (maxX - minX) / chartView.zoomFactor
chartView.axisY.min = chartView.axisY.min + deltaY / chartView.height * (maxY - minY) / chartView.zoomFactor
chartView.axisY.max = chartView.axisY.max + deltaY / chartView.height * (maxY - minY) / chartView.zoomFactor
}
lastPos = event.position
}
onWidthChanged: {
updateRange()
}
onHeightChanged: {
updateRange()
}
Axes {
id: axes
horizontalAxis: ValueAxis {
id: valueAxisX
min: chartView.minX
max: chartView.maxX
labelFormat: "%.1f"
tickCount: 11
}
verticalAxis: ValueAxis {
id: valueAxisY
min: chartView.minY
max: chartView.maxY
labelFormat: "%.0f"
tickCount: 11
}
}
}
```
该控件主要通过`ChartView`和`ValueAxis`组件实现,其中`LineSeries`和`AreaSeries`用于绘制折线和填充区域。控件定义了`zoomFactor`、`isPinching`、`lastPos`、`minX`、`maxX`、`minY`和`maxY`等属性,通过`onPinchStarted`、`onPinchUpdated`和`onPinchFinished`处理手指缩放的事件,通过`onPositionChanged`处理手指拖拽的事件,在每次缩放或拖拽后重新计算横纵坐标范围,并更新`ValueAxis`的`min`和`max`属性。
阅读全文