From 05d38aebe0edc5fd6bd0382d4a005008cb1acbce Mon Sep 17 00:00:00 2001 From: Sami Varanka Date: Mon, 24 Mar 2025 19:39:30 +0200 Subject: [PATCH] Add easy way to get plot area point from point User cannot just click the screen and get the correct position on the graph's coordinates. That require's calculating plot area position from the mousearea click position. This patch adds method to lineseries for calculating the graph coordinates from plot area click. Task-number: QTBUG-134499 Change-Id: Id020d040f87c5c8cfe6661aee941b1dd783f0e49 Reviewed-by: Sami Varanka --- src/graphs2d/linechart/qlineseries.cpp | 19 +++++++++++ src/graphs2d/linechart/qlineseries.h | 2 ++ src/graphs2d/qgraphsview.cpp | 9 +++++ src/graphs2d/qgraphsview_p.h | 2 ++ src/graphs2d/qsgrenderer/pointrenderer.cpp | 34 +++++++++++++++++++ src/graphs2d/qsgrenderer/pointrenderer_p.h | 2 ++ .../qml2dtest/graphsview/tst_graphsview.qml | 12 +++++++ 7 files changed, 80 insertions(+) diff --git a/src/graphs2d/linechart/qlineseries.cpp b/src/graphs2d/linechart/qlineseries.cpp index 73304935..345526db 100644 --- a/src/graphs2d/linechart/qlineseries.cpp +++ b/src/graphs2d/linechart/qlineseries.cpp @@ -146,4 +146,23 @@ void QLineSeries::setCapStyle(Qt::PenCapStyle newCapStyle) emit update(); } + +/*! + \qmlmethod LineSeries::getDataPointCoordinates(real x, real y) + Returns \a x and \a y rendercoordinates converted into data point + coordinates. +*/ +/*! + Returns \a x and \a y rendercoordinates converted into data point + coordinates. + +*/ +QPointF QLineSeries::getDataPointCoordinates(qreal x, qreal y) +{ + Q_D(QLineSeries); + + auto oPoint = d->m_graph->getDataPointCoordinates(x, y); + return oPoint; +} + QT_END_NAMESPACE diff --git a/src/graphs2d/linechart/qlineseries.h b/src/graphs2d/linechart/qlineseries.h index fb73d745..34ff55c2 100644 --- a/src/graphs2d/linechart/qlineseries.h +++ b/src/graphs2d/linechart/qlineseries.h @@ -30,6 +30,8 @@ public: Qt::PenCapStyle capStyle() const; void setCapStyle(Qt::PenCapStyle newCapStyle); + Q_REVISION(6, 10) Q_INVOKABLE QPointF getDataPointCoordinates(qreal x, qreal y); + Q_SIGNALS: void widthChanged(); void capStyleChanged(); diff --git a/src/graphs2d/qgraphsview.cpp b/src/graphs2d/qgraphsview.cpp index 097b6833..c10fc63e 100644 --- a/src/graphs2d/qgraphsview.cpp +++ b/src/graphs2d/qgraphsview.cpp @@ -207,6 +207,15 @@ bool QGraphsView::hasSeries(QObject *series) return m_seriesList.contains(series); } +QPointF QGraphsView::getDataPointCoordinates(qreal x, qreal y) +{ + if (m_pointRenderer) + return m_pointRenderer->reverseRenderCoordinates(x, y); + + return QPointF(); +} + + void QGraphsView::addAxis(QAbstractAxis *axis) { if (axis) { diff --git a/src/graphs2d/qgraphsview_p.h b/src/graphs2d/qgraphsview_p.h index db3976c2..800d4b0c 100644 --- a/src/graphs2d/qgraphsview_p.h +++ b/src/graphs2d/qgraphsview_p.h @@ -86,6 +86,8 @@ public: return m_seriesList; } + QPointF getDataPointCoordinates(qreal x, qreal y); + QQmlListProperty seriesList(); static void appendSeriesFunc(QQmlListProperty *list, QObject *series); static qsizetype countSeriesFunc(QQmlListProperty *list); diff --git a/src/graphs2d/qsgrenderer/pointrenderer.cpp b/src/graphs2d/qsgrenderer/pointrenderer.cpp index 6e290d22..570d0baa 100644 --- a/src/graphs2d/qsgrenderer/pointrenderer.cpp +++ b/src/graphs2d/qsgrenderer/pointrenderer.cpp @@ -839,4 +839,38 @@ bool PointRenderer::handleHoverMove(QHoverEvent *event) return handled; } + +QPointF PointRenderer::reverseRenderCoordinates(qreal x, qreal y) +{ + m_areaWidth = width(); + m_areaHeight = height(); + + m_maxVertical = m_graph->m_axisRenderer->m_axisVerticalValueRange > 0 + ? 1.0 / m_graph->m_axisRenderer->m_axisVerticalValueRange + : 100.0; + m_maxHorizontal = m_graph->m_axisRenderer->m_axisHorizontalValueRange > 0 + ? 1.0 / m_graph->m_axisRenderer->m_axisHorizontalValueRange + : 100.0; + + auto vmin = m_graph->m_axisRenderer->m_axisVerticalMinValue + > m_graph->m_axisRenderer->m_axisVerticalMaxValue + ? std::abs(m_graph->m_axisRenderer->m_axisVerticalMinValue) + : m_graph->m_axisRenderer->m_axisVerticalMinValue; + + m_verticalOffset = (vmin / m_graph->m_axisRenderer->m_axisVerticalValueRange) * m_areaHeight; + + auto hmin = m_graph->m_axisRenderer->m_axisHorizontalMinValue + > m_graph->m_axisRenderer->m_axisHorizontalMaxValue + ? std::abs(m_graph->m_axisRenderer->m_axisHorizontalMinValue) + : m_graph->m_axisRenderer->m_axisHorizontalMinValue; + + m_horizontalOffset = (hmin / m_graph->m_axisRenderer->m_axisHorizontalValueRange) * m_areaWidth; + qreal x0; + qreal y0; + + reverseRenderCoordinates(m_graph->m_axisRenderer, x, y, &x0, &y0); + + return QPointF(x0, y0); +} + QT_END_NAMESPACE diff --git a/src/graphs2d/qsgrenderer/pointrenderer_p.h b/src/graphs2d/qsgrenderer/pointrenderer_p.h index 0a4f9176..78b0daf8 100644 --- a/src/graphs2d/qsgrenderer/pointrenderer_p.h +++ b/src/graphs2d/qsgrenderer/pointrenderer_p.h @@ -45,6 +45,8 @@ public: void afterUpdate(QList &cleanupSeries); bool handleHoverMove(QHoverEvent *event); + QPointF reverseRenderCoordinates(qreal x, qreal y); + private: struct PointGroup { diff --git a/tests/auto/qml2dtest/graphsview/tst_graphsview.qml b/tests/auto/qml2dtest/graphsview/tst_graphsview.qml index ac19c6c4..858e057f 100644 --- a/tests/auto/qml2dtest/graphsview/tst_graphsview.qml +++ b/tests/auto/qml2dtest/graphsview/tst_graphsview.qml @@ -135,6 +135,18 @@ Item { compare(initial.theme.colorScheme, Qt.Dark) compare(initial.theme.seriesColors.length, 5) } + + function test_2_getDataPointCoordinate() { + var point = lineInitial.getDataPointCoordinates(0, 0) + compare(point.x, 0) + compare(point.y, 8) + var point = lineInitial.getDataPointCoordinates(1, 1) + compare(point.x, 0.2) + compare(point.y, 7.794871794871795) + var point = lineInitial.getDataPointCoordinates(4, 4) + compare(point.x, 0.8) + compare(point.y, 7.17948717948718) + } } TestCase {