ChartView与LineSeries搭配实现曲线局部缩放功能

效果图:

ChartView与LineSeries搭配实现曲线局部缩放功能_第1张图片

上一篇文章实现的时候还不知道有QtChart这个模块......好好看了下资料就想做个例子实现一下这功能,比较了下代码量...恩,直接看代码:

    Rectangle {
        id: view_rect
        anchors.fill: parent
//        anchors.topMargin: 40
        ChartView {
            id: view
            title: "Two Series, Common Axes"
            anchors.fill: parent
            legend.visible: false
            antialiasing: true
            property point hoveredPoint: Qt.point( 0, 0 )
            property bool hovered: false
            ValueAxis {
                id: axisX
                min: 0
                max: 50
                tickCount: 5
            }

            ValueAxis {
                id: axisY
                min: -0.5
                max: 1.5
            }

            LineSeries {
                id: series1
                axisX: axisX
                axisY: axisY
                onHovered: {
//                    view.hoveredPoint = point
//                    view.hovered = state
                }
            }

            MouseArea {
                anchors.fill: parent
                hoverEnabled: true
                onPositionChanged: {
                    var point = Qt.point( 0, 0 )
                    point.x = mouse.x
                    point.y = mouse.y
                    var hoveredPoint = view.mapToValue( point, series1 )
                    if( hoveredPoint.x >= 0 && hoveredPoint.x <= 50 ) {
                        view.hovered = true
                        view.hoveredPoint = hoveredPoint
                    } else {
                        view.hovered = false
                    }
                }

                onWheel: {
                    if( view.hovered ) {
                        if( wheel.angleDelta.y > 0 ) {
                            if( axisX.max - axisX.min <= 2 ) {
                                return
                            }
                            view.zoomIn( view.hoveredPoint )
                        } else {
                            view.zoomOut( view.hoveredPoint )
                            if( axisX.min <= 0 ) {
                                axisX.min = 0
                            }
                            if( axisX.max >= 50 ) {
                                axisX.max = 50
                            }
                        }
                    }
                }
            }

            function zoomIn( hoveredPoint ) {
                if( hoveredPoint.x - axisX.min <= 1 ) {
                    return
                }
                var scale = parseFloat( ( hoveredPoint.x - axisX.min ) / ( axisX.max - axisX.min ) )
                axisX.min++
                axisX.max = ( hoveredPoint.x - axisX.min ) / scale + axisX.min
            }

            function zoomOut( hoveredPoint ) {
                var scale = parseFloat( ( hoveredPoint.x - axisX.min ) / ( axisX.max - axisX.min ) )
                axisX.min--
                axisX.max = ( hoveredPoint.x - axisX.min ) / scale + axisX.min
            }
        }

        // Add data dynamically to the series
        Component.onCompleted: {
            for (var i = 0; i <= 50; i++) {
                series1.append(i, Math.random());
            }
        }
    }

实现该功能最关键在于获取鼠标位置对应的坐标值, ChartView提供一个方法mapToValue,指明一个point与series,就可获得这个point对应series的坐标值。现在通过一个覆盖整个ChartView的MouseArea获取mouse,转换成point,当鼠标在坐标轴内移动时,就可记录到hoveredPoint内。

放大功能我写在zoomIn函数内,这里每次放大的值只是将最小值+1,可自己调整。注意一点的是hoverPoint.x是不能小于axisX.min的,所以我在放大前做了判断;

缩小功能我写在zoomOut函数内,这边是想让曲线饱满的覆盖在整个坐标内,所以对两个极端做了判断,超出范围就将边界值赋值给它;

你可能感兴趣的:(Qt,ChartView,LineSeries,QML)