如何使用QML图表的ScrolLeft和ScrollRight方法

How to use ScrolLeft and ScrollRight Methods of QML Charts

我需要使用 scrollbar 滚动 QT 图形,为此,我使用 RectangleMouseArea 创建了自己的自定义 scrollbar,可以拖动.

当我尝试使用 ScrollRightScrollLeft 方法滚动图表时,我无法 link/bind ScrollBar XChartView内容X.Following是代码:

import QtQuick 2.6
import QtQuick.Window 2.2
import QtQuick.Controls 2.2
import QtCharts 2.0

Window {
    id: window
    width: 640
    height: 480
    visible: true

    ChartView {
        id: chartview
        width: parent.width
        height: 300

        LineSeries {
            name: "LineSeries"
            axisX: ValueAxis {
                min: 0
                max: 100
                tickCount: 12
                labelFormat: "%.0f"
            }

            axisY: ValueAxis {
                min: 0
                max: 70
                tickCount: 5
                labelFormat: "%.0f"
            }
            XYPoint { x: 0; y: 0.0 }
            XYPoint { x: 1.1; y: 3.2 }
            XYPoint { x: 1.9; y: 2.4 }
            XYPoint { x: 2.1; y: 2.1 }
            XYPoint { x: 2.9; y: 2.6 }
            XYPoint { x: 3.4; y: 2.3 }
            XYPoint { x: 200.1; y: 3.1 }
        }
    }

    /* Rectangle base for horizontal scroll bar */
    Rectangle{
        id:rectHorScrollBase
        width:parent.width
        height:parent.height * 0.10
        anchors.top:chartview.bottom
        anchors.topMargin: (parent.height * 0.01)
        color:"transparent"
        visible: true

        /* Rectangle indicating scroll path*/
        Rectangle {
            id:rectHorScrollPath
            width: parent.width
            height: parent.height
            anchors.left:parent.left

            radius: 2
            color: "lightblue"
        }

        /* Actual scroll rectaangle which will be dragged */
        Rectangle {
            id: rectHorScroll
            property var prevX : 0

            anchors.top : parent.top
            width: 50
            height: parent.height
            color: "green"

            /* Mouser area to drag the rectangle and to move Chart */
            MouseArea {
                id:mouseAreaHorScroll

                anchors.fill: parent
                drag.target: parent
                drag.minimumX: 0
                drag.maximumX: chartview.width - width
                drag.axis: Drag.XAxis

                onReleased: {
                    console.log("x in Released ===",rectHorScroll.x)
                    rectHorScroll.prevX = rectHorScroll.x
                }
            }

            onXChanged: {

                // HOW TO HANDLE THE SCROLL BASED ON x ? 
                if(mouseAreaHorScroll.drag.active)
                {
                    if(x > prevX)
                    {
                        chartview.scrollRight(x) // NOT WORKING
                    }
                    else
                    {
                        chartview.scrollLeft(x) //NOT WORKING
                    }
                }
            }
        }
    }
}

1) 如何将 scrollBar X 映射到 ChartView 内容 X ?

2) scrollbar不能超过X轴的最大值和最小值。怎么做?

3) ScrollBarChartView 之间应该同步。

基本上它按预期工作。让我们分析一下你在做什么:

onXChanged: {

    // HOW TO HANDLE THE SCROLL BASED ON x ?
    if(mouseAreaHorScroll.drag.active)
    {
        if(x > prevX)
        {
            chartview.scrollRight(x) // NOT WORKING
        }
        else
        {
            chartview.scrollLeft(x) //NOT WORKING
        }
    }
}

首先,当 x 大于 prevX 时,您 scrollRight - 这非常有效。然而你 scrollRight x 像素 - 随着移动而增长,所以移动与滚动条的移动不是线性的。

scrollLeft 确实(几乎)从未被调用过,这很明显:你不更新 prevX 所以只有当 x === 0 ( = prevX)scrollLeft(0) - 这不'移动。

我们需要应用的第一个更改是在处理程序末尾更新 prevX
第二个变化是,我们只想移动自代码的最后一个 运行 以来我们移动手柄的距离。

因此解决方案如下所示:

onXChanged: {

    // HOW TO HANDLE THE SCROLL BASED ON x ?
    if(mouseAreaHorScroll.drag.active)
    {
        if(x > prevX)
        {
            chartview.scrollRight(x - prevX) // Only move the difference
        }
        else
        {
            chartview.scrollLeft(prevX - x) //Only move the difference
        }
        prevX = x // Update prevX
    }
}

除了手动处理这些东西并调用那些函数,您还可以 将轴的可见部分映射到 x - 删除您的句柄并相应地更改 axisX :

axisX: ValueAxis {
    min: rectHorScroll.x / (rectHorScrollBase.width - rectHorScroll.width) * 100
    max: rectHorScroll.x / (rectHorScrollBase.width - rectHorScroll.width) * 100 + 100
    tickCount: 12
    labelFormat: "%.0f"
}

在这里你需要找到正确的方法来应用映射,你得到正确的范围。

然后你也可以使用常规组件,比如Slider来模拟滚动条:

import QtQuick 2.6
import QtQuick.Window 2.2
import QtQuick.Controls 2.0
import QtCharts 2.0

ApplicationWindow {
    id: window
    width: 640
    height: 480
    visible: true

    ChartView {
        id: chartview
        width: parent.width
        height: 300

        LineSeries {
            name: "LineSeries"
            axisX: ValueAxis {
                property real minValue: 0
                property real maxValue: 200
                property real range: 100
                min: minValue + sb.position * (maxValue - minValue - range)
                max: minValue + sb.position * (maxValue - minValue - range) + range
                tickCount: 12
                labelFormat: "%.0f"
            }

            axisY: ValueAxis {
                min: 0
                max: 70
                tickCount: 5
                labelFormat: "%.0f"
            }
            XYPoint { x: 0; y: 0.0 }
            XYPoint { x: 1.1; y: 3.2 }
            XYPoint { x: 1.9; y: 2.4 }
            XYPoint { x: 2.1; y: 2.1 }
            XYPoint { x: 2.9; y: 2.6 }
            XYPoint { x: 3.4; y: 2.3 }
            XYPoint { x: 200.1; y: 3.1 }
        }


    }

    Slider {
        id: sb
        anchors {
            bottom: parent.bottom
            left: parent.left
            right: parent.right
        }
        height: 30
    }
}