qml ChartView zoom in rect

2022. 3. 8. 09:41Programming/Qt

반응형

마우스 위치에서 확대

Qt qml의 ChartView를 이용하여 그래프를 그리는 작업을 하던 중 zoom 기능을 추가하고 싶었다.

 

기본으로 제공하는 zoomIn() , zoomOut() 기능을 차트 가운데에서만 확대할 수 있는 기능만 가지고 있었다.

내가 원하는 건 마우스 위치에서 확대 되는 것이기 때문에 zoomIn(), zoomOut()은 소용이 없었다.

 

그래서 ChartView에서 제공하는 zoomIn(rect rectangle)을 이용해서 구현하였다.

 

지정한 사각형을 현재 차트에 가득차게 확대해주는 함수다.

즉, 현재 차트보다 지정한 사각형의 크기가 작아야 확대되고 크면 축소된다.

사각형은 왼쪽 위의 x, y 좌표와 너비 높이 순으로 지정한다.

하지만 한가지 문제가 있었다. 내가 원하는 건 한 점을 지정하고 그 자리에서 계속 확대되는 것이였다. 하지만 그래프가 확대되면서 점의 위치는 변하게 됬다.

이때 한가지 생각을 더 하면 되는데 그건 scroll 기능이다.

확대하면서 변한 위치만큼 그래프의 좌표를 옮겨 주면 가능하다.

구현 예제이다.

import QtQuick
import QtQuick.Window
import QtQuick.Controls
import QtCharts
import QtQuick.Layouts

Window {
    id: window
    width: 800
    height: 500
    visible: true
    title: qsTr("2D scatter plot view")

    ChartView {
        id: chartView
        anchors.fill: parent
        antialiasing: true

        LineSeries {
            name: "LineSeries"
            XYPoint { x: 0; y: 0 }
            XYPoint { x: 1.1; y: 2.1 }
            XYPoint { x: 1.9; y: 3.3 }
            XYPoint { x: 2.1; y: 2.1 }
            XYPoint { x: 2.9; y: 4.9 }
            XYPoint { x: 3.4; y: 3.0 }
            XYPoint { x: 4.1; y: 3.3 }
        }

        MouseArea{
            anchors.fill: parent
            onDoubleClicked: chartView.zoomReset();
            onWheel: (wheel)=> {
                         if((wheel.x <= chartView.plotArea.x + chartView.plotArea.width) && (wheel.x >= chartView.plotArea.x) && //plotArea에서만 zoom기능 하기위해
                            (wheel.y <= chartView.plotArea.y + chartView.plotArea.height) && (wheel.y >= chartView.plotArea.y)){
                             if(wheel.angleDelta.y >= 0) { // wheel을 올리면 확대
                                 chartView.zoomIn(Qt.rect(wheel.x, wheel.y, (chartView.plotArea.width*0.8), (chartView.plotArea.height*0.8)));
                                 chartView.scrollLeft(wheel.x - chartView.plotArea.x);
                                 chartView.scrollDown(- wheel.y + chartView.plotArea.y);
                             }
                             else { // wheel을 내리며 축소
                                 console.log(wheel.y, chartView.plotArea.y)
                                 chartView.zoomIn(Qt.rect(wheel.x, wheel.y, (chartView.plotArea.width*1.2), (chartView.plotArea.height*1.2)));
                                 chartView.scrollLeft(wheel.x - chartView.plotArea.x);
                                 chartView.scrollDown(- wheel.y + chartView.plotArea.y);
                             }
                         }
                     }
        }
    }
}

출처 - https://doc.qt.io/qt-6/qml-qtcharts-chartview.html#zoomIn-method-1

출처 - https://doc.qt.io/qt-6/qml-qtqml-qt.html#rect-method

반응형