##// END OF EJS Templates
Fixed area series paint bug caused by mouse event fix on line series
Tero Ahola -
r1792:ea0ec9902253
parent child
Show More
@@ -1,151 +1,151
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "areachartitem_p.h"
21 #include "areachartitem_p.h"
22 #include "qareaseries.h"
22 #include "qareaseries.h"
23 #include "qareaseries_p.h"
23 #include "qareaseries_p.h"
24 #include "qlineseries.h"
24 #include "qlineseries.h"
25 #include "chartpresenter_p.h"
25 #include "chartpresenter_p.h"
26 #include "domain_p.h"
26 #include "domain_p.h"
27 #include <QPainter>
27 #include <QPainter>
28 #include <QGraphicsSceneMouseEvent>
28 #include <QGraphicsSceneMouseEvent>
29 #include <QDebug>
29 #include <QDebug>
30
30
31
31
32 QTCOMMERCIALCHART_BEGIN_NAMESPACE
32 QTCOMMERCIALCHART_BEGIN_NAMESPACE
33
33
34 //TODO: optimize : remove points which are not visible
34 //TODO: optimize : remove points which are not visible
35
35
36 AreaChartItem::AreaChartItem(QAreaSeries *areaSeries, ChartPresenter *presenter)
36 AreaChartItem::AreaChartItem(QAreaSeries *areaSeries, ChartPresenter *presenter)
37 : ChartItem(presenter),
37 : ChartItem(presenter),
38 m_series(areaSeries),
38 m_series(areaSeries),
39 m_upper(0),
39 m_upper(0),
40 m_lower(0),
40 m_lower(0),
41 m_pointsVisible(false)
41 m_pointsVisible(false)
42 {
42 {
43 setZValue(ChartPresenter::LineChartZValue);
43 setZValue(ChartPresenter::LineChartZValue);
44 m_upper = new AreaBoundItem(this,m_series->upperSeries(),presenter);
44 m_upper = new AreaBoundItem(this,m_series->upperSeries(),presenter);
45 if (m_series->lowerSeries()){
45 if (m_series->lowerSeries()){
46 m_lower = new AreaBoundItem(this,m_series->lowerSeries(),presenter);
46 m_lower = new AreaBoundItem(this,m_series->lowerSeries(),presenter);
47 }
47 }
48
48
49 QObject::connect(m_series->d_func(),SIGNAL(updated()),this,SLOT(handleUpdated()));
49 QObject::connect(m_series->d_func(),SIGNAL(updated()),this,SLOT(handleUpdated()));
50 QObject::connect(m_series, SIGNAL(visibleChanged()), this, SLOT(handleUpdated()));
50 QObject::connect(m_series, SIGNAL(visibleChanged()), this, SLOT(handleUpdated()));
51 QObject::connect(this,SIGNAL(clicked(QPointF)),areaSeries,SIGNAL(clicked(QPointF)));
51 QObject::connect(this,SIGNAL(clicked(QPointF)),areaSeries,SIGNAL(clicked(QPointF)));
52
52
53 handleUpdated();
53 handleUpdated();
54 }
54 }
55
55
56 AreaChartItem::~AreaChartItem()
56 AreaChartItem::~AreaChartItem()
57 {
57 {
58 delete m_upper;
58 delete m_upper;
59 delete m_lower;
59 delete m_lower;
60 }
60 }
61
61
62 QRectF AreaChartItem::boundingRect() const
62 QRectF AreaChartItem::boundingRect() const
63 {
63 {
64 return m_rect;
64 return m_rect;
65 }
65 }
66
66
67 QPainterPath AreaChartItem::shape() const
67 QPainterPath AreaChartItem::shape() const
68 {
68 {
69 return m_path;
69 return m_path;
70 }
70 }
71
71
72 void AreaChartItem::updatePath()
72 void AreaChartItem::updatePath()
73 {
73 {
74 QPainterPath path;
74 QPainterPath path;
75
75
76 path = m_upper->shape();
76 path = m_upper->path();
77
77
78 if (m_lower) {
78 if (m_lower) {
79 path.connectPath(m_lower->shape().toReversed());
79 path.connectPath(m_lower->path().toReversed());
80 } else {
80 } else {
81 QPointF first = path.pointAtPercent(0);
81 QPointF first = path.pointAtPercent(0);
82 QPointF last = path.pointAtPercent(1);
82 QPointF last = path.pointAtPercent(1);
83 path.lineTo(last.x(),m_clipRect.bottom());
83 path.lineTo(last.x(),m_clipRect.bottom());
84 path.lineTo(first.x(),m_clipRect.bottom());
84 path.lineTo(first.x(),m_clipRect.bottom());
85 }
85 }
86 path.closeSubpath();
86 path.closeSubpath();
87 prepareGeometryChange();
87 prepareGeometryChange();
88 m_path = path;
88 m_path = path;
89 m_rect = path.boundingRect();
89 m_rect = path.boundingRect();
90 update();
90 update();
91 }
91 }
92
92
93 void AreaChartItem::handleUpdated()
93 void AreaChartItem::handleUpdated()
94 {
94 {
95 setVisible(m_series->isVisible());
95 setVisible(m_series->isVisible());
96 m_pointsVisible = m_series->pointsVisible();
96 m_pointsVisible = m_series->pointsVisible();
97 m_linePen = m_series->pen();
97 m_linePen = m_series->pen();
98 m_brush = m_series->brush();
98 m_brush = m_series->brush();
99 m_pointPen = m_series->pen();
99 m_pointPen = m_series->pen();
100 m_pointPen.setWidthF(2 * m_pointPen.width());
100 m_pointPen.setWidthF(2 * m_pointPen.width());
101
101
102 update();
102 update();
103 }
103 }
104
104
105 void AreaChartItem::handleDomainUpdated()
105 void AreaChartItem::handleDomainUpdated()
106 {
106 {
107 m_upper->setDomain(domain());
107 m_upper->setDomain(domain());
108 m_upper->handleDomainUpdated();
108 m_upper->handleDomainUpdated();
109 if (m_lower){
109 if (m_lower){
110 m_lower->setDomain(domain());
110 m_lower->setDomain(domain());
111 m_lower->handleDomainUpdated();
111 m_lower->handleDomainUpdated();
112 }
112 }
113 }
113 }
114
114
115 void AreaChartItem::handleGeometryChanged(const QRectF &rect)
115 void AreaChartItem::handleGeometryChanged(const QRectF &rect)
116 {
116 {
117 m_clipRect=rect.translated(-rect.topLeft());
117 m_clipRect=rect.translated(-rect.topLeft());
118 setPos(rect.topLeft());
118 setPos(rect.topLeft());
119 m_upper->handleGeometryChanged(rect);
119 m_upper->handleGeometryChanged(rect);
120 if (m_lower)
120 if (m_lower)
121 m_lower->handleGeometryChanged(rect);
121 m_lower->handleGeometryChanged(rect);
122 }
122 }
123
123
124 void AreaChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
124 void AreaChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
125 {
125 {
126 Q_UNUSED(widget)
126 Q_UNUSED(widget)
127 Q_UNUSED(option)
127 Q_UNUSED(option)
128
128
129 painter->save();
129 painter->save();
130 painter->setPen(m_linePen);
130 painter->setPen(m_linePen);
131 painter->setBrush(m_brush);
131 painter->setBrush(m_brush);
132 painter->setClipRect(m_clipRect);
132 painter->setClipRect(m_clipRect);
133 painter->drawPath(m_path);
133 painter->drawPath(m_path);
134 if (m_pointsVisible) {
134 if (m_pointsVisible) {
135 painter->setPen(m_pointPen);
135 painter->setPen(m_pointPen);
136 painter->drawPoints(m_upper->geometryPoints());
136 painter->drawPoints(m_upper->geometryPoints());
137 if (m_lower)
137 if (m_lower)
138 painter->drawPoints(m_lower->geometryPoints());
138 painter->drawPoints(m_lower->geometryPoints());
139 }
139 }
140 painter->restore();
140 painter->restore();
141 }
141 }
142
142
143 void AreaChartItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
143 void AreaChartItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
144 {
144 {
145 emit clicked(m_upper->calculateDomainPoint(event->pos()));
145 emit clicked(m_upper->calculateDomainPoint(event->pos()));
146 ChartItem::mousePressEvent(event);
146 ChartItem::mousePressEvent(event);
147 }
147 }
148
148
149 #include "moc_areachartitem_p.cpp"
149 #include "moc_areachartitem_p.cpp"
150
150
151 QTCOMMERCIALCHART_END_NAMESPACE
151 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,132 +1,132
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "linechartitem_p.h"
21 #include "linechartitem_p.h"
22 #include "qlineseries.h"
22 #include "qlineseries.h"
23 #include "qlineseries_p.h"
23 #include "qlineseries_p.h"
24 #include "chartpresenter_p.h"
24 #include "chartpresenter_p.h"
25 #include <QPainter>
25 #include <QPainter>
26 #include <QGraphicsSceneMouseEvent>
26 #include <QGraphicsSceneMouseEvent>
27
27
28 QTCOMMERCIALCHART_BEGIN_NAMESPACE
28 QTCOMMERCIALCHART_BEGIN_NAMESPACE
29
29
30 const qreal mouseEventMinWidth(14);
30 const qreal mouseEventMinWidth(12);
31
31
32 LineChartItem::LineChartItem(QLineSeries* series,ChartPresenter *presenter):
32 LineChartItem::LineChartItem(QLineSeries* series,ChartPresenter *presenter):
33 XYChart(series, presenter),
33 XYChart(series, presenter),
34 QGraphicsItem(presenter ? presenter->rootItem() : 0),
34 QGraphicsItem(presenter ? presenter->rootItem() : 0),
35 m_series(series),
35 m_series(series),
36 m_pointsVisible(false)
36 m_pointsVisible(false)
37 {
37 {
38 setZValue(ChartPresenter::LineChartZValue);
38 setZValue(ChartPresenter::LineChartZValue);
39 QObject::connect(series->d_func(),SIGNAL(updated()),this,SLOT(handleUpdated()));
39 QObject::connect(series->d_func(),SIGNAL(updated()),this,SLOT(handleUpdated()));
40 QObject::connect(series, SIGNAL(visibleChanged()), this, SLOT(handleUpdated()));
40 QObject::connect(series, SIGNAL(visibleChanged()), this, SLOT(handleUpdated()));
41 handleUpdated();
41 handleUpdated();
42 }
42 }
43
43
44 QRectF LineChartItem::boundingRect() const
44 QRectF LineChartItem::boundingRect() const
45 {
45 {
46 return m_rect;
46 return m_rect;
47 }
47 }
48
48
49 QPainterPath LineChartItem::shape() const
49 QPainterPath LineChartItem::shape() const
50 {
50 {
51 // Increase the size of the path slightly to make mouse interactions more natural
51 // Increase the size of the path slightly to make mouse interactions more natural
52 QPainterPathStroker s;
52 QPainterPathStroker s;
53 s.setCapStyle(Qt::RoundCap);
53 s.setCapStyle(Qt::RoundCap);
54 s.setJoinStyle(Qt::RoundJoin);
54 s.setJoinStyle(Qt::RoundJoin);
55 qreal spacing = qMax(mouseEventMinWidth, (qreal) m_linePen.width());
55 qreal spacing = qMax(mouseEventMinWidth, (qreal) m_linePen.width());
56 s.setWidth(spacing);
56 s.setWidth(spacing);
57 return s.createStroke(m_path);
57 return s.createStroke(m_path);
58 }
58 }
59
59
60 void LineChartItem::updateGeometry()
60 void LineChartItem::updateGeometry()
61 {
61 {
62 const QVector<QPointF>& points = geometryPoints();
62 const QVector<QPointF>& points = geometryPoints();
63
63
64 if(points.size()==0)
64 if(points.size()==0)
65 {
65 {
66 prepareGeometryChange();
66 prepareGeometryChange();
67 m_path = QPainterPath();
67 m_path = QPainterPath();
68 m_rect = QRect();
68 m_rect = QRect();
69 return;
69 return;
70 }
70 }
71
71
72 QPainterPath linePath(points.at(0));
72 QPainterPath linePath(points.at(0));
73
73
74 for(int i=1; i< points.size();i++) {
74 for(int i=1; i< points.size();i++) {
75 linePath.lineTo(points.at(i));
75 linePath.lineTo(points.at(i));
76 }
76 }
77
77
78 prepareGeometryChange();
78 prepareGeometryChange();
79
79
80 m_path = linePath;
80 m_path = linePath;
81
81
82 // When defining bounding rectangle,
82 // When defining bounding rectangle,
83 // 1. take the line width into account (otherwise you will get drawing artifacts) and
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
84 // 2. take the shape into account (otherwise you will not get mouse events through on border
85 // areas).
85 // areas).
86 const qreal sqrtOf2 = 1.414214;
86 const qreal sqrtOf2 = 1.414214;
87 const qreal spacing = qMax(mouseEventMinWidth / 2.0,
87 const qreal spacing = qMax(mouseEventMinWidth / 2.0,
88 sqrtOf2 * (qreal) m_linePen.width() / 2.0);
88 sqrtOf2 * (qreal) m_linePen.width() / 2.0);
89 m_rect = m_path.boundingRect().adjusted(-spacing, -spacing, spacing, spacing);
89 m_rect = m_path.boundingRect().adjusted(-spacing, -spacing, spacing, spacing);
90
90
91 setPos(origin());
91 setPos(origin());
92 }
92 }
93
93
94 void LineChartItem::handleUpdated()
94 void LineChartItem::handleUpdated()
95 {
95 {
96 setVisible(m_series->isVisible());
96 setVisible(m_series->isVisible());
97 m_pointsVisible = m_series->pointsVisible();
97 m_pointsVisible = m_series->pointsVisible();
98 m_linePen = m_series->pen();
98 m_linePen = m_series->pen();
99 m_pointPen = m_series->pen();
99 m_pointPen = m_series->pen();
100 m_pointPen.setWidthF(2*m_pointPen.width());
100 m_pointPen.setWidthF(2*m_pointPen.width());
101 update();
101 update();
102 }
102 }
103
103
104 void LineChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
104 void LineChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
105 {
105 {
106 Q_UNUSED(widget)
106 Q_UNUSED(widget)
107 Q_UNUSED(option)
107 Q_UNUSED(option)
108
108
109 painter->save();
109 painter->save();
110 painter->setPen(m_linePen);
110 painter->setPen(m_linePen);
111 painter->setClipRect(clipRect());
111 painter->setClipRect(clipRect());
112 // Draw lines
112 // Draw lines
113 const QVector<QPointF> &points = geometryPoints();
113 const QVector<QPointF> &points = geometryPoints();
114 for (int i(1); i < points.size();i++)
114 for (int i(1); i < points.size();i++)
115 painter->drawLine(points.at(i-1), points.at(i));
115 painter->drawLine(points.at(i-1), points.at(i));
116 // Draw points
116 // Draw points
117 if (m_pointsVisible){
117 if (m_pointsVisible){
118 painter->setPen(m_pointPen);
118 painter->setPen(m_pointPen);
119 painter->drawPoints(geometryPoints());
119 painter->drawPoints(geometryPoints());
120 }
120 }
121 painter->restore();
121 painter->restore();
122 }
122 }
123
123
124 void LineChartItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
124 void LineChartItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
125 {
125 {
126 emit XYChart::clicked(calculateDomainPoint(event->pos()));
126 emit XYChart::clicked(calculateDomainPoint(event->pos()));
127 QGraphicsItem::mousePressEvent(event);
127 QGraphicsItem::mousePressEvent(event);
128 }
128 }
129
129
130 #include "moc_linechartitem_p.cpp"
130 #include "moc_linechartitem_p.cpp"
131
131
132 QTCOMMERCIALCHART_END_NAMESPACE
132 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,73 +1,75
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 // W A R N I N G
21 // W A R N I N G
22 // -------------
22 // -------------
23 //
23 //
24 // This file is not part of the QtCommercial Chart API. It exists purely as an
24 // This file is not part of the QtCommercial Chart API. It exists purely as an
25 // implementation detail. This header file may change from version to
25 // implementation detail. This header file may change from version to
26 // version without notice, or even be removed.
26 // version without notice, or even be removed.
27 //
27 //
28 // We mean it.
28 // We mean it.
29
29
30 #ifndef LINECHARTITEM_H
30 #ifndef LINECHARTITEM_H
31 #define LINECHARTITEM_H
31 #define LINECHARTITEM_H
32
32
33 #include "qchartglobal.h"
33 #include "qchartglobal.h"
34 #include "xychart_p.h"
34 #include "xychart_p.h"
35 #include <QPen>
35 #include <QPen>
36
36
37 QTCOMMERCIALCHART_BEGIN_NAMESPACE
37 QTCOMMERCIALCHART_BEGIN_NAMESPACE
38
38
39 class QLineSeries;
39 class QLineSeries;
40 class ChartPresenter;
40 class ChartPresenter;
41
41
42 class LineChartItem : public XYChart , public QGraphicsItem
42 class LineChartItem : public XYChart , public QGraphicsItem
43 {
43 {
44 Q_OBJECT
44 Q_OBJECT
45 Q_INTERFACES(QGraphicsItem)
45 Q_INTERFACES(QGraphicsItem)
46 public:
46 public:
47 explicit LineChartItem(QLineSeries *series,ChartPresenter *presenter);
47 explicit LineChartItem(QLineSeries *series,ChartPresenter *presenter);
48 ~LineChartItem() {}
48 ~LineChartItem() {}
49
49
50 //from QGraphicsItem
50 //from QGraphicsItem
51 QRectF boundingRect() const;
51 QRectF boundingRect() const;
52 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
52 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
53 QPainterPath shape() const;
53 QPainterPath shape() const;
54
54
55 QPainterPath path() const { return m_path; }
56
55 public Q_SLOTS:
57 public Q_SLOTS:
56 void handleUpdated();
58 void handleUpdated();
59
57 protected:
60 protected:
58 void updateGeometry();
61 void updateGeometry();
59 void mousePressEvent(QGraphicsSceneMouseEvent *event);
62 void mousePressEvent(QGraphicsSceneMouseEvent *event);
60
63
61 private:
64 private:
62 QLineSeries* m_series;
65 QLineSeries* m_series;
63 QPainterPath m_path;
66 QPainterPath m_path;
64 QRectF m_rect;
67 QRectF m_rect;
65 QPen m_linePen;
68 QPen m_linePen;
66 QPen m_pointPen;
69 QPen m_pointPen;
67 bool m_pointsVisible;
70 bool m_pointsVisible;
68
69 };
71 };
70
72
71 QTCOMMERCIALCHART_END_NAMESPACE
73 QTCOMMERCIALCHART_END_NAMESPACE
72
74
73 #endif
75 #endif
General Comments 0
You need to be logged in to leave comments. Login now