##// END OF EJS Templates
Fixed paint and mouse event issues with QLineSeries...
Tero Ahola -
r1791:877b494897a0
parent child
Show More
@@ -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