1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the Qt Charts module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:GPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU
19** General Public License version 3 or (at your option) any later version
20** approved by the KDE Free Qt Foundation. The licenses are as published by
21** the Free Software Foundation and appearing in the file LICENSE.GPL3
22** included in the packaging of this file. Please review the following
23** information to ensure the GNU General Public License requirements will
24** be met: https://www.gnu.org/licenses/gpl-3.0.html.
25**
26** $QT_END_LICENSE$
27**
28****************************************************************************/
29
30#include "chart.h"
31#include <QtCharts/QValueAxis>
32#include <QtCharts/QAbstractAxis>
33#include <QtCore/QtMath>
34
35Chart::Chart(QGraphicsItem *parent, Qt::WindowFlags wFlags, QLineSeries *series)
36 : QChart(QChart::ChartTypeCartesian, parent, wFlags), m_series(series)
37{
38 m_clicked = false;
39}
40
41Chart::~Chart()
42{
43}
44
45void Chart::clickPoint(const QPointF &point)
46{
47 // Find the closest data point
48 m_movingPoint = QPoint();
49 m_clicked = false;
50 const auto points = m_series->points();
51 for (QPointF p : points) {
52 if (distance(p1: p, p2: point) < distance(p1: m_movingPoint, p2: point)) {
53 m_movingPoint = p;
54 m_clicked = true;
55 }
56 }
57}
58
59qreal Chart::distance(const QPointF &p1, const QPointF &p2)
60{
61 return qSqrt(v: (p1.x() - p2.x()) * (p1.x() - p2.x())
62 + (p1.y() - p2.y()) * (p1.y() - p2.y()));
63}
64
65void Chart::setPointClicked(bool clicked)
66{
67 m_clicked = clicked;
68}
69
70void Chart::handlePointMove(const QPoint &point)
71{
72 if (m_clicked) {
73 //Map the point clicked from the ChartView
74 //to the area occupied by the chart.
75 QPoint mappedPoint = point;
76 mappedPoint.setX(point.x() - this->plotArea().x());
77 mappedPoint.setY(point.y() - this->plotArea().y());
78
79 //Get the x- and y axis to be able to convert the mapped
80 //coordinate point to the charts scale.
81 QAbstractAxis *axisx = axes(orientation: Qt::Horizontal).first();
82 QValueAxis *haxis = 0;
83 if (axisx->type() == QAbstractAxis::AxisTypeValue)
84 haxis = qobject_cast<QValueAxis *>(object: axisx);
85
86 QAbstractAxis *axisy = axes(orientation: Qt::Vertical).first();
87 QValueAxis *vaxis = 0;
88 if (axisy->type() == QAbstractAxis::AxisTypeValue)
89 vaxis = qobject_cast<QValueAxis *>(object: axisy);
90
91 if (haxis && vaxis) {
92 //Calculate the "unit" between points on the x
93 //y axis.
94 double xUnit = this->plotArea().width() / haxis->max();
95 double yUnit = this->plotArea().height() / vaxis->max();
96
97 //Convert the mappedPoint to the actual chart scale.
98 double x = mappedPoint.x() / xUnit;
99 double y = vaxis->max() - mappedPoint.y() / yUnit;
100
101 //Replace the old point with the new one.
102 m_series->replace(oldPoint: m_movingPoint, newPoint: QPointF(x, y));
103
104 //Update the m_movingPoint so we are able to
105 //do the replace also during mousemoveEvent.
106 m_movingPoint.setX(x);
107 m_movingPoint.setY(y);
108 }
109 }
110}
111
112

source code of qtcharts/examples/charts/chartinteractions/chart.cpp