##// END OF EJS Templates
Added hovered support to scatter series
Marek Rosa -
r2261:f149ef311d71
parent child
Show More
@@ -1,189 +1,194
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 "scatterchartitem_p.h"
21 #include "scatterchartitem_p.h"
22 #include "qscatterseries.h"
22 #include "qscatterseries.h"
23 #include "qscatterseries_p.h"
23 #include "qscatterseries_p.h"
24 #include "chartpresenter_p.h"
24 #include "chartpresenter_p.h"
25 #include <QPainter>
25 #include <QPainter>
26 #include <QGraphicsScene>
26 #include <QGraphicsScene>
27 #include <QDebug>
27 #include <QDebug>
28 #include <QGraphicsSceneMouseEvent>
28 #include <QGraphicsSceneMouseEvent>
29
29
30 QTCOMMERCIALCHART_BEGIN_NAMESPACE
30 QTCOMMERCIALCHART_BEGIN_NAMESPACE
31
31
32 ScatterChartItem::ScatterChartItem(QScatterSeries *series, ChartPresenter *presenter)
32 ScatterChartItem::ScatterChartItem(QScatterSeries *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_items(this),
36 m_items(this),
37 m_visible(true),
37 m_visible(true),
38 m_shape(QScatterSeries::MarkerShapeRectangle),
38 m_shape(QScatterSeries::MarkerShapeRectangle),
39 m_size(15)
39 m_size(15)
40 {
40 {
41 QObject::connect(m_series->d_func(), SIGNAL(updated()), this, SLOT(handleUpdated()));
41 QObject::connect(m_series->d_func(), SIGNAL(updated()), this, SLOT(handleUpdated()));
42 QObject::connect(m_series, SIGNAL(visibleChanged()), this, SLOT(handleUpdated()));
42 QObject::connect(m_series, SIGNAL(visibleChanged()), this, SLOT(handleUpdated()));
43 QObject::connect(m_series, SIGNAL(opacityChanged()), this, SLOT(handleUpdated()));
43 QObject::connect(m_series, SIGNAL(opacityChanged()), this, SLOT(handleUpdated()));
44
44
45 setZValue(ChartPresenter::ScatterSeriesZValue);
45 setZValue(ChartPresenter::ScatterSeriesZValue);
46 setFlags(QGraphicsItem::ItemClipsChildrenToShape);
46 setFlags(QGraphicsItem::ItemClipsChildrenToShape);
47
47
48 handleUpdated();
48 handleUpdated();
49
49
50 m_items.setHandlesChildEvents(false);
50 m_items.setHandlesChildEvents(false);
51 }
51 }
52
52
53 QRectF ScatterChartItem::boundingRect() const
53 QRectF ScatterChartItem::boundingRect() const
54 {
54 {
55 return m_rect;
55 return m_rect;
56 }
56 }
57
57
58 void ScatterChartItem::createPoints(int count)
58 void ScatterChartItem::createPoints(int count)
59 {
59 {
60 for (int i = 0; i < count; ++i) {
60 for (int i = 0; i < count; ++i) {
61
61
62 QGraphicsItem *item = 0;
62 QGraphicsItem *item = 0;
63
63
64 switch (m_shape) {
64 switch (m_shape) {
65 case QScatterSeries::MarkerShapeCircle: {
65 case QScatterSeries::MarkerShapeCircle: {
66 item = new CircleMarker(0, 0, m_size, m_size, this);
66 item = new CircleMarker(0, 0, m_size, m_size, this);
67 const QRectF &rect = item->boundingRect();
67 const QRectF &rect = item->boundingRect();
68 item->setPos(-rect.width() / 2, -rect.height() / 2);
68 item->setPos(-rect.width() / 2, -rect.height() / 2);
69 break;
69 break;
70 }
70 }
71 case QScatterSeries::MarkerShapeRectangle:
71 case QScatterSeries::MarkerShapeRectangle:
72 item = new RectangleMarker(0, 0, m_size, m_size, this);
72 item = new RectangleMarker(0, 0, m_size, m_size, this);
73 item->setPos(-m_size / 2, -m_size / 2);
73 item->setPos(-m_size / 2, -m_size / 2);
74 break;
74 break;
75 default:
75 default:
76 qWarning() << "Unsupported marker type";
76 qWarning() << "Unsupported marker type";
77 break;
77 break;
78 }
78 }
79 m_items.addToGroup(item);
79 m_items.addToGroup(item);
80 }
80 }
81 }
81 }
82
82
83 void ScatterChartItem::deletePoints(int count)
83 void ScatterChartItem::deletePoints(int count)
84 {
84 {
85 QList<QGraphicsItem *> items = m_items.childItems();
85 QList<QGraphicsItem *> items = m_items.childItems();
86
86
87 for (int i = 0; i < count; ++i) {
87 for (int i = 0; i < count; ++i) {
88 QGraphicsItem *item = items.takeLast();
88 QGraphicsItem *item = items.takeLast();
89 m_markerMap.remove(item);
89 m_markerMap.remove(item);
90 delete(item);
90 delete(item);
91 }
91 }
92 }
92 }
93
93
94 void ScatterChartItem::markerSelected(QGraphicsItem *marker)
94 void ScatterChartItem::markerSelected(QGraphicsItem *marker)
95 {
95 {
96 emit XYChart::clicked(calculateDomainPoint(m_markerMap[marker]));
96 emit XYChart::clicked(calculateDomainPoint(m_markerMap[marker]));
97 }
97 }
98
98
99 void ScatterChartItem::markerHovered(QGraphicsItem *marker, bool state)
100 {
101 emit XYChart::hovered(calculateDomainPoint(m_markerMap[marker]), state);
102 }
103
99 void ScatterChartItem::updateGeometry()
104 void ScatterChartItem::updateGeometry()
100 {
105 {
101
106
102 const QVector<QPointF>& points = geometryPoints();
107 const QVector<QPointF>& points = geometryPoints();
103
108
104 if (points.size() == 0) {
109 if (points.size() == 0) {
105 deletePoints(m_items.childItems().count());
110 deletePoints(m_items.childItems().count());
106 return;
111 return;
107 }
112 }
108
113
109 int diff = m_items.childItems().size() - points.size();
114 int diff = m_items.childItems().size() - points.size();
110
115
111 if (diff > 0)
116 if (diff > 0)
112 deletePoints(diff);
117 deletePoints(diff);
113 else if (diff < 0)
118 else if (diff < 0)
114 createPoints(-diff);
119 createPoints(-diff);
115
120
116 if (diff != 0)
121 if (diff != 0)
117 handleUpdated();
122 handleUpdated();
118
123
119 QList<QGraphicsItem *> items = m_items.childItems();
124 QList<QGraphicsItem *> items = m_items.childItems();
120
125
121 for (int i = 0; i < points.size(); i++) {
126 for (int i = 0; i < points.size(); i++) {
122 QGraphicsItem *item = items.at(i);
127 QGraphicsItem *item = items.at(i);
123 const QPointF &point = points.at(i);
128 const QPointF &point = points.at(i);
124 const QRectF &rect = item->boundingRect();
129 const QRectF &rect = item->boundingRect();
125 m_markerMap[item] = point;
130 m_markerMap[item] = point;
126 item->setPos(point.x() - rect.width() / 2, point.y() - rect.height() / 2);
131 item->setPos(point.x() - rect.width() / 2, point.y() - rect.height() / 2);
127 if (!m_visible || !clipRect().contains(point))
132 if (!m_visible || !clipRect().contains(point))
128 item->setVisible(false);
133 item->setVisible(false);
129 else
134 else
130 item->setVisible(true);
135 item->setVisible(true);
131 }
136 }
132
137
133 prepareGeometryChange();
138 prepareGeometryChange();
134 m_rect = clipRect();
139 m_rect = clipRect();
135 setPos(origin());
140 setPos(origin());
136 }
141 }
137
142
138 void ScatterChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
143 void ScatterChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
139 {
144 {
140 Q_UNUSED(painter)
145 Q_UNUSED(painter)
141 Q_UNUSED(option)
146 Q_UNUSED(option)
142 Q_UNUSED(widget)
147 Q_UNUSED(widget)
143 }
148 }
144
149
145 void ScatterChartItem::setPen(const QPen &pen)
150 void ScatterChartItem::setPen(const QPen &pen)
146 {
151 {
147 foreach (QGraphicsItem *item , m_items.childItems())
152 foreach (QGraphicsItem *item , m_items.childItems())
148 static_cast<QAbstractGraphicsShapeItem*>(item)->setPen(pen);
153 static_cast<QAbstractGraphicsShapeItem*>(item)->setPen(pen);
149 }
154 }
150
155
151 void ScatterChartItem::setBrush(const QBrush &brush)
156 void ScatterChartItem::setBrush(const QBrush &brush)
152 {
157 {
153 foreach (QGraphicsItem *item , m_items.childItems())
158 foreach (QGraphicsItem *item , m_items.childItems())
154 static_cast<QAbstractGraphicsShapeItem*>(item)->setBrush(brush);
159 static_cast<QAbstractGraphicsShapeItem*>(item)->setBrush(brush);
155 }
160 }
156
161
157 void ScatterChartItem::handleUpdated()
162 void ScatterChartItem::handleUpdated()
158 {
163 {
159 int count = m_items.childItems().count();
164 int count = m_items.childItems().count();
160
165
161 if (count == 0)
166 if (count == 0)
162 return;
167 return;
163
168
164 bool recreate = m_visible != m_series->isVisible()
169 bool recreate = m_visible != m_series->isVisible()
165 || m_size != m_series->markerSize()
170 || m_size != m_series->markerSize()
166 || m_shape != m_series->markerShape();
171 || m_shape != m_series->markerShape();
167
172
168 m_visible = m_series->isVisible();
173 m_visible = m_series->isVisible();
169 m_size = m_series->markerSize();
174 m_size = m_series->markerSize();
170 m_shape = m_series->markerShape();
175 m_shape = m_series->markerShape();
171 setOpacity(m_series->opacity());
176 setOpacity(m_series->opacity());
172
177
173 if (recreate) {
178 if (recreate) {
174 // TODO: optimize handleUpdate to recreate points only in case shape changed
179 // TODO: optimize handleUpdate to recreate points only in case shape changed
175 deletePoints(count);
180 deletePoints(count);
176 createPoints(count);
181 createPoints(count);
177
182
178 // Updating geometry is now safe, because it won't call handleUpdated unless it creates/deletes points
183 // Updating geometry is now safe, because it won't call handleUpdated unless it creates/deletes points
179 updateGeometry();
184 updateGeometry();
180 }
185 }
181
186
182 setPen(m_series->pen());
187 setPen(m_series->pen());
183 setBrush(m_series->brush());
188 setBrush(m_series->brush());
184 update();
189 update();
185 }
190 }
186
191
187 #include "moc_scatterchartitem_p.cpp"
192 #include "moc_scatterchartitem_p.cpp"
188
193
189 QTCOMMERCIALCHART_END_NAMESPACE
194 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,123 +1,146
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 SCATTERCHARTITEM_H
30 #ifndef SCATTERCHARTITEM_H
31 #define SCATTERCHARTITEM_H
31 #define SCATTERCHARTITEM_H
32
32
33 #include "qchartglobal.h"
33 #include "qchartglobal.h"
34 #include "xychart_p.h"
34 #include "xychart_p.h"
35 #include <QGraphicsEllipseItem>
35 #include <QGraphicsEllipseItem>
36 #include <QPen>
36 #include <QPen>
37
37
38 QTCOMMERCIALCHART_BEGIN_NAMESPACE
38 QTCOMMERCIALCHART_BEGIN_NAMESPACE
39
39
40 class QScatterSeries;
40 class QScatterSeries;
41
41
42 class ScatterChartItem : public XYChart, public QGraphicsItem
42 class ScatterChartItem : 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 ScatterChartItem(QScatterSeries *series, ChartPresenter *presenter);
47 explicit ScatterChartItem(QScatterSeries *series, ChartPresenter *presenter);
48
48
49 public:
49 public:
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
53
54 void setPen(const QPen &pen);
54 void setPen(const QPen &pen);
55 void setBrush(const QBrush &brush);
55 void setBrush(const QBrush &brush);
56
56
57 void markerSelected(QGraphicsItem *item);
57 void markerSelected(QGraphicsItem *item);
58 void markerHovered(QGraphicsItem *item, bool state);
58
59
59 public Q_SLOTS:
60 public Q_SLOTS:
60 void handleUpdated();
61 void handleUpdated();
61
62
62 private:
63 private:
63 void createPoints(int count);
64 void createPoints(int count);
64 void deletePoints(int count);
65 void deletePoints(int count);
65
66
66 protected:
67 protected:
67 void updateGeometry();
68 void updateGeometry();
68
69
69 private:
70 private:
70 QScatterSeries *m_series;
71 QScatterSeries *m_series;
71 QGraphicsItemGroup m_items;
72 QGraphicsItemGroup m_items;
72 bool m_visible;
73 bool m_visible;
73 int m_shape;
74 int m_shape;
74 int m_size;
75 int m_size;
75 QRectF m_rect;
76 QRectF m_rect;
76 QMap<QGraphicsItem *, QPointF> m_markerMap;
77 QMap<QGraphicsItem *, QPointF> m_markerMap;
77 };
78 };
78
79
79 class CircleMarker: public QGraphicsEllipseItem
80 class CircleMarker: public QGraphicsEllipseItem
80 {
81 {
81
82
82 public:
83 public:
83 CircleMarker(qreal x, qreal y, qreal w, qreal h, ScatterChartItem *parent)
84 CircleMarker(qreal x, qreal y, qreal w, qreal h, ScatterChartItem *parent)
84 : QGraphicsEllipseItem(x, y, w, h, parent),
85 : QGraphicsEllipseItem(x, y, w, h, parent),
85 m_parent(parent)
86 m_parent(parent)
86 {
87 {
88 setAcceptHoverEvents(true);
87 }
89 }
88
90
89 protected:
91 protected:
90 void mousePressEvent(QGraphicsSceneMouseEvent *event)
92 void mousePressEvent(QGraphicsSceneMouseEvent *event)
91 {
93 {
92 m_parent->markerSelected(this);
94 m_parent->markerSelected(this);
93 QGraphicsEllipseItem::mousePressEvent(event);
95 QGraphicsEllipseItem::mousePressEvent(event);
94 }
96 }
97 void hoverEnterEvent(QGraphicsSceneHoverEvent *event)
98 {
99 m_parent->markerHovered(this, true);
100 QGraphicsEllipseItem::hoverEnterEvent(event);
101 }
102 void hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
103 {
104 m_parent->markerHovered(this, false);
105 QGraphicsEllipseItem::hoverLeaveEvent(event);
106 }
95
107
96 private:
108 private:
97 ScatterChartItem *m_parent;
109 ScatterChartItem *m_parent;
98 };
110 };
99
111
100 class RectangleMarker: public QGraphicsRectItem
112 class RectangleMarker: public QGraphicsRectItem
101 {
113 {
102
114
103 public:
115 public:
104 RectangleMarker(qreal x, qreal y, qreal w, qreal h, ScatterChartItem *parent)
116 RectangleMarker(qreal x, qreal y, qreal w, qreal h, ScatterChartItem *parent)
105 : QGraphicsRectItem(x, y, w, h, parent),
117 : QGraphicsRectItem(x, y, w, h, parent),
106 m_parent(parent)
118 m_parent(parent)
107 {
119 {
120 setAcceptHoverEvents(true);
108 }
121 }
109
122
110 protected:
123 protected:
111 void mousePressEvent(QGraphicsSceneMouseEvent *event)
124 void mousePressEvent(QGraphicsSceneMouseEvent *event)
112 {
125 {
113 m_parent->markerSelected(this);
126 m_parent->markerSelected(this);
114 QGraphicsRectItem::mousePressEvent(event);
127 QGraphicsRectItem::mousePressEvent(event);
115 }
128 }
129 void hoverEnterEvent(QGraphicsSceneHoverEvent *event)
130 {
131 m_parent->markerHovered(this, true);
132 QGraphicsRectItem::hoverEnterEvent(event);
133 }
134 void hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
135 {
136 m_parent->markerHovered(this, false);
137 QGraphicsRectItem::hoverLeaveEvent(event);
138 }
116
139
117 private:
140 private:
118 ScatterChartItem *m_parent;
141 ScatterChartItem *m_parent;
119 };
142 };
120
143
121 QTCOMMERCIALCHART_END_NAMESPACE
144 QTCOMMERCIALCHART_END_NAMESPACE
122
145
123 #endif // SCATTERPRESENTER_H
146 #endif // SCATTERPRESENTER_H
General Comments 0
You need to be logged in to leave comments. Login now