@@ -20,6 +20,7 | |||
|
20 | 20 | |
|
21 | 21 | #include <QValuesAxis> |
|
22 | 22 | #include <QAbstractAxis> |
|
23 | #include <cmath> | |
|
23 | 24 | #include <QDebug> |
|
24 | 25 | |
|
25 | 26 | #include "chart.h" |
@@ -36,22 +37,23 Chart::~Chart() | |||
|
36 | 37 | |
|
37 | 38 | void Chart::clickPoint(const QPointF &point) |
|
38 | 39 | { |
|
39 | //Get all points from the series. | |
|
40 | QList<QPointF> points = m_series->points(); | |
|
41 | //Construct a small rectangle around the clicked point | |
|
42 | //to identify the real point clicked from the series. | |
|
43 | QRectF clickRect(point.x() - 0.5, point.y() - 0.5, 1.0, 1.0); | |
|
44 | ||
|
45 | //Find the clicked point to be moved. | |
|
46 | foreach (QPointF p, points) { | |
|
47 | if (clickRect.contains(p)) { | |
|
40 | // Find the closes data point | |
|
41 | m_movingPoint = QPoint(); | |
|
42 | m_clicked = false; | |
|
43 | foreach (QPointF p, m_series->points()) { | |
|
44 | if (distance(p, point) < distance(m_movingPoint, point)) { | |
|
48 | 45 | m_movingPoint = p; |
|
49 | 46 | m_clicked = true; |
|
50 | return; | |
|
51 | 47 | } |
|
52 | 48 | } |
|
53 | 49 | } |
|
54 | 50 | |
|
51 | qreal Chart::distance(const QPointF &p1, const QPointF &p2) | |
|
52 | { | |
|
53 | return sqrt((p1.x() - p2.x()) * (p1.x() - p2.x()) | |
|
54 | + (p1.y() - p2.y()) * (p1.y() - p2.y())); | |
|
55 | } | |
|
56 | ||
|
55 | 57 | void Chart::setPointClicked(bool clicked) |
|
56 | 58 | { |
|
57 | 59 | m_clicked = clicked; |
@@ -41,6 +41,7 public: | |||
|
41 | 41 | void setPointClicked(bool clicked); |
|
42 | 42 | |
|
43 | 43 | private: |
|
44 | qreal distance(const QPointF &p1, const QPointF &p2); | |
|
44 | 45 | QLineSeries *m_series; |
|
45 | 46 | QPointF m_movingPoint; |
|
46 | 47 |
@@ -46,6 +46,9 int main(int argc, char *argv[]) | |||
|
46 | 46 | Chart* chart = new Chart(0, 0, series); |
|
47 | 47 | chart->legend()->hide(); |
|
48 | 48 | chart->addSeries(series); |
|
49 | QPen p = series->pen(); | |
|
50 | p.setWidth(5); | |
|
51 | series->setPen(p); | |
|
49 | 52 | chart->createDefaultAxes(); |
|
50 | 53 | chart->setTitle("Drag'n drop to move data points"); |
|
51 | 54 |
@@ -25,10 +25,9 | |||
|
25 | 25 | #include <QPainter> |
|
26 | 26 | #include <QGraphicsSceneMouseEvent> |
|
27 | 27 | |
|
28 | ||
|
29 | 28 | QTCOMMERCIALCHART_BEGIN_NAMESPACE |
|
30 | 29 | |
|
31 | //TODO: optimize : remove points which are not visible | |
|
30 | const qreal mouseEventMinWidth(14); | |
|
32 | 31 | |
|
33 | 32 | LineChartItem::LineChartItem(QLineSeries* series,ChartPresenter *presenter): |
|
34 | 33 | XYChart(series, presenter), |
@@ -49,7 +48,13 QRectF LineChartItem::boundingRect() const | |||
|
49 | 48 | |
|
50 | 49 | QPainterPath LineChartItem::shape() const |
|
51 | 50 | { |
|
52 | return m_path; | |
|
51 | // Increase the size of the path slightly to make mouse interactions more natural | |
|
52 | QPainterPathStroker s; | |
|
53 | s.setCapStyle(Qt::RoundCap); | |
|
54 | s.setJoinStyle(Qt::RoundJoin); | |
|
55 | qreal spacing = qMax(mouseEventMinWidth, (qreal) m_linePen.width()); | |
|
56 | s.setWidth(spacing); | |
|
57 | return s.createStroke(m_path); | |
|
53 | 58 | } |
|
54 | 59 | |
|
55 | 60 | void LineChartItem::updateGeometry() |
@@ -71,8 +76,18 void LineChartItem::updateGeometry() | |||
|
71 | 76 | } |
|
72 | 77 | |
|
73 | 78 | prepareGeometryChange(); |
|
79 | ||
|
74 | 80 | m_path = linePath; |
|
75 | m_rect = linePath.boundingRect(); | |
|
81 | ||
|
82 | // When defining bounding rectangle, | |
|
83 | // 1. take the line width into account (otherwise you will get drawing artifacts) and | |
|
84 | // 2. take the shape into account (otherwise you will not get mouse events through on border | |
|
85 | // areas). | |
|
86 | const qreal sqrtOf2 = 1.414214; | |
|
87 | const qreal spacing = qMax(mouseEventMinWidth / 2.0, | |
|
88 | sqrtOf2 * (qreal) m_linePen.width() / 2.0); | |
|
89 | m_rect = m_path.boundingRect().adjusted(-spacing, -spacing, spacing, spacing); | |
|
90 | ||
|
76 | 91 | setPos(origin()); |
|
77 | 92 | } |
|
78 | 93 | |
@@ -86,8 +101,6 void LineChartItem::handleUpdated() | |||
|
86 | 101 | update(); |
|
87 | 102 | } |
|
88 | 103 | |
|
89 | //painter | |
|
90 | ||
|
91 | 104 | void LineChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) |
|
92 | 105 | { |
|
93 | 106 | Q_UNUSED(widget) |
@@ -45,7 +45,7 class LineChartItem : public XYChart , public QGraphicsItem | |||
|
45 | 45 | Q_INTERFACES(QGraphicsItem) |
|
46 | 46 | public: |
|
47 | 47 | explicit LineChartItem(QLineSeries *series,ChartPresenter *presenter); |
|
48 |
~LineChartItem() {} |
|
|
48 | ~LineChartItem() {} | |
|
49 | 49 | |
|
50 | 50 | //from QGraphicsItem |
|
51 | 51 | QRectF boundingRect() const; |
General Comments 0
You need to be logged in to leave comments.
Login now