QML 极坐标图上的悬停点标签

huangapple go评论54阅读模式
英文:

QML PolarChart point label on hover

问题

以下是翻译好的部分:

有一个 QML 极坐标图示例。 (https://doc.qt.io/qt-6/images/examples_qmlpolarchart1.png)

正如您所见,这些点是没有名称的。我想要的是通过悬停或单击来查看确切的点的值。
有一个选项可以显示所有点的标签,但由于在我的项目中有太多点,我需要只显示一个特定点的标签。或者在其上显示工具提示。

是否有内置选项可以为系列或点执行此操作?
也许有一种方法可以通过使用 "onHovered" 信号来确定悬停在点上的点,该信号适用于系列组件?
对我来说可用的是 Qt5.15,没有 Qt6。

英文:

There is that QML PolarChart example. (https://doc.qt.io/qt-6/images/examples_qmlpolarchart1.png)

As you see, those points are nameless. What I want is to see what exact point's values are by hovering over or clicking it.
There is an option to show labels for all points, but since in my project there are too much of them, I need to show only one particular point label. Or tooltip over it.

Are there any built-in options to do it for series or points?
Maybe there is a way to determine point by hovering over it using "onHovered" signal for series component?
Qt5.15 is available for me. No Qt6.

答案1

得分: 1

这是如何解决你的问题的方法(基本上是你的解决方案)。我只想确认这不是一种变通方法,是什么让你有这种感觉?你使用了由ChartView类型提供的功能来解决你的任务。

通过使用hovered(point point, bool state)信号,你可以处理当鼠标悬停在点上时(state = true)和再次失去悬停时(state = false)的情况。使用ChartView提供的mapToPosition函数,你可以将数据点转换为位置,并将其分配给ToolTip

import QtQuick 2.15
import QtQuick.Controls 2.15
import QtCharts 2.15

ChartView {
    id: chart
    width: 640
    height: 480
    antialiasing: true

    ToolTip {
        id: toolTip
        visible: false
    }

    ScatterSeries {
        id: scatter
        name: "Scatter"
        axisX: ValueAxis { min: 1; max: 3 }
        axisY: ValueAxis { min: 1; max: 2.5 }

        XYPoint { x: 1.5; y: 1.5 }
        XYPoint { x: 1.5; y: 1.6 }
        XYPoint { x: 1.57; y: 1.55 }
        XYPoint { x: 1.8; y: 1.8 }
        XYPoint { x: 1.9; y: 1.6 }
        XYPoint { x: 2.1; y: 1.3 }
        XYPoint { x: 2.5; y: 2.1 }

        onHovered: function(point, state) {
            toolTip.text = point.x + ", " + point.y
            toolTip.visible = state
            let p = chart.mapToPosition(point, scatter)
            toolTip.x = p.x
            toolTip.y = p.y - toolTip.height
        }
    }
}

更新:

要仅获取AreaSeries的上部系列的工具提示,你需要监听此确切LineSeries的信号,如下所示。不幸的是,LineSeries悬停信号的参数point取决于你将鼠标光标放在哪里,而不仅限于提供的点,就像ScatterSeries一样。因此,通常会得到带有许多小数位的插值点。你可以通过在AreaSeries的上方绘制一个ScatterSeries并使用该系列的hovered信号来解决这个问题。如果你想这样做,你可以舍入较小工具提示的值。

PolarChartView {
    id: chart
    title: "Some Polar Area Series"
    width: 640
    height: 480
    legend.visible: false
    antialiasing: true

    ToolTip {
        id: toolTip
        visible: false
    }

    ValueAxis { id: axis1 }
    ValueAxis { id: axis2 }

    LineSeries {
        id: lowerLine
        axisAngular: axis1
        axisRadial: axis2

        XYPoint { x: 0; y: 15 }
        XYPoint { x: 2; y: 35 }
        XYPoint { x: 3; y: 50 }
        XYPoint { x: 5; y: 75 }
        XYPoint { x: 6; y: 102 }
        XYPoint { x: 9; y: 132 }
        XYPoint { x: 10; y: 100 }
        XYPoint { x: 12; y: 120 }
        XYPoint { x: 16; y: 140 }
        XYPoint { x: 20; y: 150 }

        onHovered: function(point, state) {
            toolTip.text = point.x + ", " + point.y
            toolTip.visible = state
            let p = chart.mapToPosition(point, lowerLine)
            toolTip.x = p.x
            toolTip.y = p.y - toolTip.height
        }
    }

    LineSeries {
        id: upperLine
        axisAngular: axis1
        axisRadial: axis2

        XYPoint { x: 0; y: 30 }
        XYPoint { x: 2; y: 55 }
        XYPoint { x: 3; y: 80 }
        XYPoint { x: 5; y: 105 }
        XYPoint { x: 6; y: 125 }
        XYPoint { x: 9; y: 160 }
        XYPoint { x: 10; y: 140 }
        XYPoint { x: 12; y: 140 }
        XYPoint { x: 16; y: 170 }
        XYPoint { x: 20; y: 200 }

        onHovered: function(point, state) {
            toolTip.text = point.x + ", " + point.y
            toolTip.visible = state
            let p = chart.mapToPosition(point, upperLine)
            toolTip.x = p.x
            toolTip.y = p.y - toolTip.height
        }
    }

    AreaSeries {
        axisAngular: axis1
        axisRadial: axis2
        lowerSeries: lowerLine
        upperSeries: upperLine
    }
}
英文:

This is how you would solve your question (basically your solution). I just want to confirm that it is not a workaround, what makes you feel this way? You use the functionality that is provided by the ChartView types to solve your task.

By using the hovered(point point, bool state) signal you can handle when a point is hovered (state = true) and loses hover again (state = false). Using the mapToPosition function given by the ChartView you can convert the data point into a position to assign that to the ToolTip.

import QtQuick 2.15
import QtQuick.Controls 2.15
import QtCharts 2.15
ChartView {
id: chart
width: 640
height: 480
antialiasing: true
ToolTip {
id: toolTip
visible: false
}
ScatterSeries {
id: scatter
name: "Scatter"
axisX: ValueAxis { min: 1; max: 3 }
axisY: ValueAxis { min: 1; max: 2.5 }
XYPoint { x: 1.5; y: 1.5 }
XYPoint { x: 1.5; y: 1.6 }
XYPoint { x: 1.57; y: 1.55 }
XYPoint { x: 1.8; y: 1.8 }
XYPoint { x: 1.9; y: 1.6 }
XYPoint { x: 2.1; y: 1.3 }
XYPoint { x: 2.5; y: 2.1 }
onHovered: function(point, state) {
toolTip.text = point.x + ", " + point.y
toolTip.visible = state
let p = chart.mapToPosition(point, scatter)
toolTip.x = p.x
toolTip.y = p.y - toolTip.height
}
}
}

QML 极坐标图上的悬停点标签


UPDATE

To get the ToolTips for the upper series of an AreaSeries only you would need to listen to the signal of this exact LineSeries as shown below. Unfortunately the point that is given as the parameter of the LineSeries hovered signal depends on where you put the mouse cursor at and isn't restricted to the provided points only as with a ScatterSeries. So you usually get interpolated points with a lot of decimal places. You could work around that by drawing a ScatterSeries on top of the AreaSeries and use the hovered signal from that series instead. If you want that though you could round the values for smaller tool tips.

PolarChartView {
id: chart
title: "Some Polar Area Series"
width: 640
height: 480
legend.visible: false
antialiasing: true
ToolTip {
id: toolTip
visible: false
}
ValueAxis { id: axis1 }
ValueAxis { id: axis2 }
LineSeries {
id: lowerLine
axisAngular: axis1
axisRadial: axis2
// Please note that month in JavaScript months are zero based, so 2 means March
XYPoint { x: 0;  y: 15 }
XYPoint { x: 2;  y: 35 }
XYPoint { x: 3;  y: 50 }
XYPoint { x: 5;  y: 75 }
XYPoint { x: 6;  y: 102 }
XYPoint { x: 9;  y: 132 }
XYPoint { x: 10;  y: 100 }
XYPoint { x: 12;  y: 120 }
XYPoint { x: 16;  y: 140 }
XYPoint { x: 20;  y: 150 }
}
LineSeries {
id: upperLine
axisAngular: axis1
axisRadial: axis2
// Please note that month in JavaScript months are zero based, so 2 means March
XYPoint { x: 0; y: 30 }
XYPoint { x: 2; y: 55 }
XYPoint { x: 3; y: 80 }
XYPoint { x: 5; y: 105 }
XYPoint { x: 6; y: 125 }
XYPoint { x: 9; y: 160 }
XYPoint { x: 10; y: 140 }
XYPoint { x: 12; y: 140 }
XYPoint { x: 16; y: 170 }
XYPoint { x: 20; y: 200 }
onHovered: function(point, state) {
toolTip.text = point.x + ", " + point.y
toolTip.visible = state
let p = chart.mapToPosition(point, upperLine)
toolTip.x = p.x
toolTip.y = p.y - toolTip.height
}
}
AreaSeries {
axisAngular: axis1
axisRadial: axis2
lowerSeries: lowerLine
upperSeries: upperLine
}
}

QML 极坐标图上的悬停点标签

答案2

得分: 0

我使用单独的ToolTip组件和mapToPosition方法来实现了我想要的。但我想知道是否有更准确和聪明的方法可以做到这一点。我的方法看起来更像是一种解决方法。

这是PolarChartView AreaSeries的onHovered处理程序的一部分代码:

onHovered: (point) =>
{
toolTipID.show(Math.round(point.x)+" "+Math.round(point.y));
var pp = chartID.mapToPosition(point);
toolTipID.x = pp.x;
toolTipID.y = pp.y;
}

这是一个单独的ToolTip组件:

ToolTip
{
id: toolTipID
timeout: 2000
}
英文:

I implemented what I wanted using separate ToolTip component and mapToPosition method for AreaSeries's onHovered handler to position it. But I wonder if there is more accurate and smart way to do it. My way looks more like a workaround.

Here is a piece of code for PolarChartView AreaSeries's onHovered handler:

onHovered: (point) =>
{
toolTipID.show(Math.round(point.x)+" "+Math.round(point.y));
var pp = chartID.mapToPosition(point);
toolTipID.x = pp.x;
toolTipID.y = pp.y;
}

And this is a separate ToolTip component:

ToolTip
{
id: toolTipID
timeout: 2000
}

huangapple
  • 本文由 发表于 2023年5月15日 01:03:53
  • 转载请务必保留本文链接:https://go.coder-hub.com/76248716.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定