英文:
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
}
}
}
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
}
}
答案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
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论