##// END OF EJS Templates
Fix line series graphic arefacts
Michal Klocek -
r1819:a15deac8eef4
parent child
Show More
@@ -1,132 +1,130
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "linechartitem_p.h"
22 22 #include "qlineseries.h"
23 23 #include "qlineseries_p.h"
24 24 #include "chartpresenter_p.h"
25 25 #include <QPainter>
26 26 #include <QGraphicsSceneMouseEvent>
27 27
28 28 QTCOMMERCIALCHART_BEGIN_NAMESPACE
29 29
30 30 const qreal mouseEventMinWidth(12);
31 31
32 32 LineChartItem::LineChartItem(QLineSeries* series,ChartPresenter *presenter):
33 33 XYChart(series, presenter),
34 34 QGraphicsItem(presenter ? presenter->rootItem() : 0),
35 35 m_series(series),
36 36 m_pointsVisible(false)
37 37 {
38 38 setZValue(ChartPresenter::LineChartZValue);
39 39 QObject::connect(series->d_func(),SIGNAL(updated()),this,SLOT(handleUpdated()));
40 40 QObject::connect(series, SIGNAL(visibleChanged()), this, SLOT(handleUpdated()));
41 41 handleUpdated();
42 42 }
43 43
44 44 QRectF LineChartItem::boundingRect() const
45 45 {
46 46 return m_rect;
47 47 }
48 48
49 49 QPainterPath LineChartItem::shape() const
50 50 {
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);
51 return m_path;
58 52 }
59 53
60 54 void LineChartItem::updateGeometry()
61 55 {
62 const QVector<QPointF>& points = geometryPoints();
56 m_points = geometryPoints();
63 57
64 if(points.size()==0)
58 if(m_points.size()==0)
65 59 {
66 60 prepareGeometryChange();
67 61 m_path = QPainterPath();
68 62 m_rect = QRect();
69 63 return;
70 64 }
71 65
72 QPainterPath linePath(points.at(0));
66 QPainterPath linePath(m_points.at(0));
73 67
74 for(int i=1; i< points.size();i++) {
75 linePath.lineTo(points.at(i));
68 if(m_pointsVisible) {
69
70 int size = m_linePen.width();
71 linePath.addEllipse(m_points.at(0),size,size);
72 for(int i=1; i< m_points.size();i++) {
73 linePath.lineTo(m_points.at(i));
74 linePath.addEllipse(m_points.at(i),size,size);
75 }
76
77 } else {
78
79 for(int i=1; i< m_points.size();i++) {
80 linePath.lineTo(m_points.at(i));
81 }
76 82 }
77 83
78 prepareGeometryChange();
84 m_linePath=linePath;
85 QPainterPathStroker stroker;
86 stroker.setWidth(m_linePen.width());
79 87
80 m_path = linePath;
88 prepareGeometryChange();
81 89
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 m_path = stroker.createStroke(linePath);
91 m_rect = m_path.boundingRect();
90 92
91 93 setPos(origin());
92 94 }
93 95
94 96 void LineChartItem::handleUpdated()
95 97 {
96 98 setVisible(m_series->isVisible());
97 99 m_pointsVisible = m_series->pointsVisible();
98 100 m_linePen = m_series->pen();
99 m_pointPen = m_series->pen();
100 m_pointPen.setWidthF(2*m_pointPen.width());
101 101 update();
102 102 }
103 103
104 104 void LineChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
105 105 {
106 106 Q_UNUSED(widget)
107 107 Q_UNUSED(option)
108 108
109 painter->save();
110 109 painter->setPen(m_linePen);
110 painter->setBrush(m_linePen.color());
111 111 painter->setClipRect(clipRect());
112 // Draw lines
113 const QVector<QPointF> &points = geometryPoints();
114 for (int i(1); i < points.size();i++)
115 painter->drawLine(points.at(i-1), points.at(i));
116 // Draw points
117 if (m_pointsVisible){
118 painter->setPen(m_pointPen);
119 painter->drawPoints(geometryPoints());
112
113 if (m_pointsVisible) {
114 painter->drawPath(m_linePath);
115 }
116 else {
117 for (int i(1); i < m_points.size();i++)
118 painter->drawLine(m_points.at(i-1), m_points.at(i));
120 119 }
121 painter->restore();
122 120 }
123 121
124 122 void LineChartItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
125 123 {
126 124 emit XYChart::clicked(calculateDomainPoint(event->pos()));
127 125 QGraphicsItem::mousePressEvent(event);
128 126 }
129 127
130 128 #include "moc_linechartitem_p.cpp"
131 129
132 130 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,75 +1,76
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 // W A R N I N G
22 22 // -------------
23 23 //
24 24 // This file is not part of the QtCommercial Chart API. It exists purely as an
25 25 // implementation detail. This header file may change from version to
26 26 // version without notice, or even be removed.
27 27 //
28 28 // We mean it.
29 29
30 30 #ifndef LINECHARTITEM_H
31 31 #define LINECHARTITEM_H
32 32
33 33 #include "qchartglobal.h"
34 34 #include "xychart_p.h"
35 35 #include <QPen>
36 36
37 37 QTCOMMERCIALCHART_BEGIN_NAMESPACE
38 38
39 39 class QLineSeries;
40 40 class ChartPresenter;
41 41
42 42 class LineChartItem : public XYChart , public QGraphicsItem
43 43 {
44 44 Q_OBJECT
45 45 Q_INTERFACES(QGraphicsItem)
46 46 public:
47 47 explicit LineChartItem(QLineSeries *series,ChartPresenter *presenter);
48 48 ~LineChartItem() {}
49 49
50 50 //from QGraphicsItem
51 51 QRectF boundingRect() const;
52 52 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
53 53 QPainterPath shape() const;
54 54
55 55 QPainterPath path() const { return m_path; }
56 56
57 57 public Q_SLOTS:
58 58 void handleUpdated();
59 59
60 60 protected:
61 61 void updateGeometry();
62 62 void mousePressEvent(QGraphicsSceneMouseEvent *event);
63 63
64 64 private:
65 65 QLineSeries* m_series;
66 66 QPainterPath m_path;
67 QPainterPath m_linePath;
68 QVector<QPointF> m_points;
67 69 QRectF m_rect;
68 70 QPen m_linePen;
69 QPen m_pointPen;
70 71 bool m_pointsVisible;
71 72 };
72 73
73 74 QTCOMMERCIALCHART_END_NAMESPACE
74 75
75 76 #endif
General Comments 0
You need to be logged in to leave comments. Login now