【qml】ChartView LineSeries 曲线图 实现 游标功能(marker点)

【未完成待续】还有个小bug(移动光标是连续的,没有自动锁定到最近的点上,后边会改)

先上结果

1、十字光标形式

在这里插入图片描述

2、其他形式光标

请添加图片描述

环境

硬件:通用PC / 手机 / Jetson Xavier NX 套件
系统:Ubuntu 20.4 / Android / Windows (均测试有效)
软件 :QT6.2.4 + Qml
图标字体: adimecoin-Regular.ttf下载

解决

0、思路

使用QtCharts 的ChartView->LineSeries 实现曲线图,获取触摸位置,换算出曲线上对应的值,得到marker的位置(mymarker.xx,mymarker.yy),在marker的位置绘制游标。

1、实现

        XYPoint { x: 0; y: 0 }
        XYPoint { x: 1; y: 2.1 }
        XYPoint { x: 2; y: 3.3 }
        XYPoint { x: 3; y: 2.1 }
        XYPoint { x: 4; y: 4.9 }
        XYPoint { x: 5; y: 3.0 }
        XYPoint { x: 7; y: 3.3 }

2、封装 LineSeriesMarker.qml

import QtQuick 2.12
import QtQuick.Controls 2.12
import QtQuick.Layouts 1.12
import QtCharts 2.3

/******************************************************************************
 * Copyright 2022-Adiemcoin.
 * All right reserved. See COPYRIGHT for detailed Information.
 *
 * @file       LineSeriesMarker.qml
 * @brief      XXXX Function
 *
 * @author     Adimecoin(QQ:413819260)
 * @e-mail     adimecoin@foxmail.com
 * @date       2022/11/03
 * @history
 *1、实现LineSeries曲线 的游标功能  (十字游标)
 *****************************************************************************/

ChartView {

    property double zoomMultiple:1 //X轴缩放倍数

    property color markerColor: "#17a81a" //游标颜色
    property int markerDecimalDigits: 4 //游标数据小数位位数
    property double markerX: 0.0
    property double markerY: 0.0

    property int mylineWidth: 1 //线宽
    property color mylineColor: "white" //线颜色
    property bool axisXGridVisible: false
    property bool axisYGridVisible: false
    property int axisXLabelPointSize: 8 //轴标字体大小
    property int axisYLabelPointSize: 8
    property color axisXLabelColor: "white" //轴标签颜色
    property color axisYLabelColor: "white"


    property double axisXValueMax: 1
    property double axisXValueMin: -1 //X轴显示范围
    property double axisYValueMax: 1
    property double axisYValueMin: -1//Y轴显示范围

    id: adimecoin
    antialiasing: true   //抗锯齿
    legend.visible: false
    MouseArea{
                anchors.fill: parent
                hoverEnabled: true  //鼠标离开区域
                onPositionChanged: {//获取鼠标移动时的位置(Xmouse ,Ymouse)
                    //使用mapToValue转换该鼠标屏幕位置处LineSeries坐标系的坐标值
                    var chatviewPosition = adimecoin.mapToValue(Qt.point(mouse.x,mouse.y),myline);

                    //由该坐标值的横坐标获得LineSeries曲线上的对应点的值,注意,这里由于at方法 的参数是索引,所以x轴的值要转换一下
                    var value = myline.at(chatviewPosition.x / zoomMultiple);

                    //将坐标值对应的点还原成屏幕位置(Xscreen ,Yscreen)
                    var screenPosition = adimecoin.mapToPosition(value,myline)

                    //设置maker显示位置
                    mymarker.xx = mouse.x
                    mymarker.yy =  screenPosition.y
                    mymarker.requestPaint()
                }
                onExited:{//检测鼠标是否离开图表区域,注意hoverEnabled的区别
                    mymarker.xx = 0
                    mymarker.yy = 0
                    mymarker.requestPaint()
                }
            }

    Canvas{  //绘制游标
        id:mymarker
        anchors.fill: parent
        property double xx: 0
        property double yy: 0
        property int temp
        onPaint: {
            if(xx+yy>0){
                var ctx = getContext("2d")//绘制十字交叉的竖线
                ctx.clearRect(0,0,parent.width,parent.height)
                ctx.strokeStyle = markerColor
                ctx.fillStyle = markerColor
                ctx.lineWidth = 1
                ctx.font="8px adimecoin"
                var value = adimecoin.mapToValue(Qt.point(xx,yy),myline);
                temp = value.x *  Math.pow(10,markerDecimalDigits)
                markerX = temp
                markerX = markerX / Math.pow(10,markerDecimalDigits)
                temp = value.y *  Math.pow(10,markerDecimalDigits)
                markerY = temp
                markerY = markerY / Math.pow(10,markerDecimalDigits)
                ctx.fillText("("+markerX+","+markerY+")",xx+5,yy-10)//十字游标样式
//                ctx.fillText("\uF4E0",xx-4,yy-5) //箭头游标样式

                ctx.lineWidth = 3
                ctx.beginPath()
                ctx.moveTo(xx,adimecoin.plotArea.y)
                ctx.lineTo(xx,adimecoin.plotArea.height+adimecoin.plotArea.y)
                ctx.stroke()
                ctx.beginPath()//绘制十字交叉的横线
                ctx.moveTo(adimecoin.plotArea.x,yy)
                ctx.lineTo(adimecoin.plotArea.x+adimecoin.plotArea.width,yy)
                ctx.stroke()
            }else{//鼠标离开图表区域时,清除游标
                var ctx2 = getContext("2d")
                ctx2.clearRect(0,0,parent.width,parent.height)
            }
        }
    }

    LineSeries {  //曲线
        id:myline
//        useOpenGL:true
        width: mylineWidth
        color:mylineColor
        ValueAxis {//X轴值
            id: axisXValue
            gridVisible: axisXGridVisible
            labelsFont{
                pointSize:axisXLabelPointSize
            }
            labelsColor: axisXLabelColor
            min: axisXValueMin
            max: axisXValueMax
        }
        ValueAxis {//X轴值
            id: axisYValue
            gridVisible: axisYGridVisible
            labelsFont{
                pointSize:axisYLabelPointSize
            }
            labelsColor: axisYLabelColor
            min: axisYValueMin
            max: axisYValueMax
        }
        axisX: axisXValue
        axisY: axisYValue
    }


}


/*##^##
Designer {
    D{i:0;autoSize:true;formeditorZoom:0.9;height:480;width:640}
}
##^##*/

3、调用

	//在需要的地方调用 封装好的LineSeriesMarker 
    LineSeriesMarker {
        id: charX
        anchors.fill: parent
        antialiasing: true
        backgroundColor:"transparent"
        plotAreaColor: "transparent"
        legend.visible: false
        visible: true

        axisXValueMin: 0
        axisXValueMax: 10
        
        axisYValueMin: -1
        axisYValueMax: 5

    }

OK!
至此,问题解决。欢迎留言交流

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
### 回答1: qml chartviewQtQuick中用于绘制图表的组件,可以通过设置属性来实现曲线的显示和隐藏。 要隐藏曲线,可以通过设置chartview的visible属性为false。例如: ChartView { id: chart visible: false // 其他属性设置 } 要显示曲线,可以将visible属性设置为true。例如: chart.visible = true; 另外,如果希望在特定情况下进行曲线的显示和隐藏,可以使用其他的条件判断,并通过设置visible属性来达到目的。例如: Rectangle { width: 200 height: 200 MouseArea { anchors.fill: parent onClicked: { if(chart.visible){ chart.visible = false; }else{ chart.visible = true; } } } ChartView { id: chart anchors.fill: parent // 其他属性设置 } } 以上是使用qml chartview实现曲线的显示和隐藏的方法。通过设置visible属性,可以方便地控制曲线的可见性。 ### 回答2: QMLChartView组件可以通过设置lineSeries的visible属性来控制曲线的显示和隐藏。通过修改该属性,我们可以在需要的时候显示曲线并在不需要的时候隐藏曲线。 在QML中,我们可以通过以下代码隐藏或显示曲线: ```qml ChartView { // ... LineSeries { visible: false // 默认情况下曲线是隐藏的 // ... } } ``` 上述代码中,我们通过将LineSeries的visible属性设置为false,来隐藏曲线。如果要显示曲线,只需将该属性设置为true即可。 另外,我们还可以通过按钮或其他交互方式来控制曲线的显示和隐藏。代码示例如下: ```qml ChartView { id: chartView // ... LineSeries { id: lineSeries // ... } Button { text: lineSeries.visible ? "隐藏曲线" : "显示曲线" onClicked: lineSeries.visible = !lineSeries.visible } } ``` 上述代码中,我们创建了一个按钮,按钮的文本会根据曲线的可见性进行调整。当按钮被击时,会切换曲线的可见性。如果曲线是可见的,则按钮的文本将显示为"隐藏曲线",并隐藏曲线。反之,如果曲线是隐藏的,则按钮的文本将显示为"显示曲线",并显示曲线。 综上所述,在QML中,我们可以通过设置LineSeries的visible属性,或者利用交互控件(如按钮)来控制ChartView中曲线的显示和隐藏。 ### 回答3: 使用QML中的ChartView组件可以很容易地实现曲线的显示和隐藏。 要显示曲线,首先需要创建一个ChartView,并设置曲线的属性。可以通过设置series属性来指定要显示的曲线类型,如折线图、柱状图等。 以下是一个简单的例子: ``` import QtCharts 2.15 ChartView{ id: chartView ValueAxis{ id: valueAxis } LineSeries{ name: "曲线" axisX: chartView.axisX axisY: valueAxis // 曲线的数据 XYPoint{x: 0; y: 0} XYPoint{x: 1; y: 1} XYPoint{x: 2; y: 2} } // 更多曲线... } ``` 要隐藏曲线,可以通过设置曲线的visible属性为false来实现。 ``` LineSeries{ //... visible: false } ``` 另外,还可以使用QML中的状态(State)或者动画(Animation)来实现曲线的显示和隐藏效果。例如,可以创建一个按钮,通过击按钮来切换曲线的显示状态。 ``` Button{ text: "隐藏曲线" onClicked: { lineSeries.visible = !lineSeries.visible } } ``` 通过以上方法,我们可以方便地在QML实现曲线的显示和隐藏操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值