先看效果图:
之前写过关于在LineSeries中实现十字交叉定位数据,上一篇:鼠标动态跟随数值LineSeries(十字交叉定位),该方法需要鼠标放置在图表折线上时由Hovered信号返回位置点数据。但如果是AreaSeries时,使用该方法返回的则是面积图内部点的位置,无法实现上图中的效果,因此使用MouseArea实现,思路为:
1、MouseArea获取鼠标位置(X1,Y1),此时的Y1值不是面积图包络的位置;
2、先使用mapToValue获得该鼠标位置处AreaSeries横坐标的值;
3、由该横坐标值获得面积图包络线LineSeries对应点的值
4、将该值通过mapToPosition获得该值对应点位置(X2,Y2)
5、以(X1,Y2)为十字中心点绘制两条相互垂直的直线
QML:
ChartView{
id:heightChartView
anchors.fill: parent
ValueAxis {
id: valueAxis
min: 0
max: 15
tickCount: 15
labelFormat: "%.0f"
}
AreaSeries {//面积图Series
id:heightAreaSeries
name:"test"
axisX: valueAxis
upperSeries: LineSeries{//面积图包络Series
id:heightLineSeries
XYPoint { x: 0; y: 100 }
XYPoint { x: 1; y: 90 }
XYPoint { x: 2; y: 70 }
XYPoint { x: 3; y: 60 }
XYPoint { x: 4; y: 51 }
XYPoint { x: 5; y: 60 }
XYPoint { x: 6; y: 100 }
XYPoint { x: 7; y: 120 }
XYPoint { x: 8; y: 110 }
XYPoint { x: 9; y: 80 }
XYPoint { x: 10; y: 140 }
XYPoint { x: 11; y: 60 }
XYPoint { x: 12; y: 110 }
XYPoint { x: 13; y: 70 }
XYPoint { x: 14; y: 40 }
XYPoint { x: 15; y: 80 }
}
}
MouseArea{
anchors.fill: heightChartView
hoverEnabled: true
onPositionChanged: {//获取鼠标移动时的相对位置
var areaPoint = heightChartView.mapToValue(Qt.point(mouse.x,mouse.y),heightAreaSeries)//使用mapToValue获得该鼠标位置处AreaSeries横坐标的值
var value = heightLineSeries.at(areaPoint.x)//由该横坐标值获得面积图包络线LineSeries对应点的值
var chartPosition = heightChartView.mapToPosition(value,heightAreaSeries)//将该值通过mapToPosition获得该值对应点位置(X2,Y2)
myCanvas.xx = mouse.x
myCanvas.yy = chartPosition.y
myCanvas.requestPaint()
}
onExited:{//检测鼠标是否离开图表区域
myCanvas.xx = 0
myCanvas.yy = 0
myCanvas.requestPaint()
}
}
Canvas{
id:myCanvas
anchors.fill: heightChartView
property double xx: 0
property double yy: 0
onPaint: {
if(xx+yy>0){
var ctx = getContext("2d")//绘制十字交叉的竖线
ctx.clearRect(0,0,parent.width,parent.height)
ctx.strokeStyle = '#ccf48993'
ctx.lineWidth = 3
ctx.beginPath()
ctx.moveTo(xx,heightChartView.plotArea.y)
ctx.lineTo(xx,heightChartView.plotArea.height+heightChartView.plotArea.y)
ctx.stroke()
ctx.beginPath()//绘制十字交叉的横线
ctx.moveTo(heightChartView.plotArea.x,yy)
ctx.lineTo(heightChartView.plotArea.x+heightChartView.plotArea.width,yy)
ctx.stroke()
}else{//鼠标离开图表区域时,清除十字线
var ctx = getContext("2d")
ctx.clearRect(0,0,parent.width,parent.height)
}
}
}
}