##// END OF EJS Templates
rename PieSlice -> PieSliceItem
Jani Honkonen -
r673:e6252af95451
parent child
Show More
@@ -1,18 +1,18
1 INCLUDEPATH += $$PWD
1 INCLUDEPATH += $$PWD
2 DEPENDPATH += $$PWD
2 DEPENDPATH += $$PWD
3
3
4 SOURCES += \
4 SOURCES += \
5 $$PWD/qpieseries.cpp \
5 $$PWD/qpieseries.cpp \
6 $$PWD/pieslice.cpp \
6 $$PWD/piesliceitem.cpp \
7 $$PWD/piechartitem.cpp \
7 $$PWD/piechartitem.cpp \
8 $$PWD/qpieslice.cpp
8 $$PWD/qpieslice.cpp
9
9
10 PRIVATE_HEADERS += \
10 PRIVATE_HEADERS += \
11 $$PWD/piechartitem_p.h \
11 $$PWD/piechartitem_p.h \
12 $$PWD/pieslice_p.h \
12 $$PWD/piesliceitem_p.h \
13 $$PWD/qpiesliceprivate_p.h \
13 $$PWD/qpiesliceprivate_p.h \
14 $$PWD/qpieseriesprivate_p.h
14 $$PWD/qpieseriesprivate_p.h
15
15
16 PUBLIC_HEADERS += \
16 PUBLIC_HEADERS += \
17 $$PWD/qpieseries.h \
17 $$PWD/qpieseries.h \
18 $$PWD/qpieslice.h
18 $$PWD/qpieslice.h
@@ -1,193 +1,193
1 #include "piechartitem_p.h"
1 #include "piechartitem_p.h"
2 #include "pieslice_p.h"
2 #include "piesliceitem_p.h"
3 #include "qpieslice.h"
3 #include "qpieslice.h"
4 #include "qpiesliceprivate_p.h"
4 #include "qpiesliceprivate_p.h"
5 #include "qpieseries.h"
5 #include "qpieseries.h"
6 #include "chartpresenter_p.h"
6 #include "chartpresenter_p.h"
7 #include "chartdataset_p.h"
7 #include "chartdataset_p.h"
8 #include "chartanimator_p.h"
8 #include "chartanimator_p.h"
9 #include <QDebug>
9 #include <QDebug>
10 #include <QPainter>
10 #include <QPainter>
11 #include <QTimer>
11 #include <QTimer>
12
12
13 QTCOMMERCIALCHART_BEGIN_NAMESPACE
13 QTCOMMERCIALCHART_BEGIN_NAMESPACE
14
14
15 PieChartItem::PieChartItem(QPieSeries *series, ChartPresenter *presenter, QGraphicsItem *parent)
15 PieChartItem::PieChartItem(QPieSeries *series, ChartPresenter *presenter, QGraphicsItem *parent)
16 :ChartItem(parent),
16 :ChartItem(parent),
17 m_series(series),
17 m_series(series),
18 m_presenter(presenter)
18 m_presenter(presenter)
19 {
19 {
20 Q_ASSERT(series);
20 Q_ASSERT(series);
21 connect(series, SIGNAL(added(QList<QPieSlice*>)), this, SLOT(handleSlicesAdded(QList<QPieSlice*>)));
21 connect(series, SIGNAL(added(QList<QPieSlice*>)), this, SLOT(handleSlicesAdded(QList<QPieSlice*>)));
22 connect(series, SIGNAL(removed(QList<QPieSlice*>)), this, SLOT(handleSlicesRemoved(QList<QPieSlice*>)));
22 connect(series, SIGNAL(removed(QList<QPieSlice*>)), this, SLOT(handleSlicesRemoved(QList<QPieSlice*>)));
23 connect(series, SIGNAL(piePositionChanged()), this, SLOT(handlePieLayoutChanged()));
23 connect(series, SIGNAL(piePositionChanged()), this, SLOT(handlePieLayoutChanged()));
24 connect(series, SIGNAL(pieSizeChanged()), this, SLOT(handlePieLayoutChanged()));
24 connect(series, SIGNAL(pieSizeChanged()), this, SLOT(handlePieLayoutChanged()));
25
25
26 QTimer::singleShot(0, this, SLOT(initialize()));
26 QTimer::singleShot(0, this, SLOT(initialize()));
27
27
28 // Note: the following does not affect as long as the item does not have anything to paint
28 // Note: the following does not affect as long as the item does not have anything to paint
29 setZValue(ChartPresenter::PieSeriesZValue);
29 setZValue(ChartPresenter::PieSeriesZValue);
30 }
30 }
31
31
32 PieChartItem::~PieChartItem()
32 PieChartItem::~PieChartItem()
33 {
33 {
34 // slices deleted automatically through QGraphicsItem
34 // slices deleted automatically through QGraphicsItem
35 }
35 }
36
36
37 void PieChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
37 void PieChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
38 {
38 {
39 Q_UNUSED(painter)
39 Q_UNUSED(painter)
40 // TODO: paint shadows for all components
40 // TODO: paint shadows for all components
41 // - get paths from items & merge & offset and draw with shadow color?
41 // - get paths from items & merge & offset and draw with shadow color?
42 //painter->setBrush(QBrush(Qt::red));
42 //painter->setBrush(QBrush(Qt::red));
43 //painter->drawRect(m_debugRect);
43 //painter->drawRect(m_debugRect);
44 }
44 }
45
45
46 void PieChartItem::initialize()
46 void PieChartItem::initialize()
47 {
47 {
48 handleSlicesAdded(m_series->slices());
48 handleSlicesAdded(m_series->slices());
49 }
49 }
50
50
51 void PieChartItem::handleSlicesAdded(QList<QPieSlice*> slices)
51 void PieChartItem::handleSlicesAdded(QList<QPieSlice*> slices)
52 {
52 {
53 bool isEmpty = m_slices.isEmpty();
53 bool isEmpty = m_slices.isEmpty();
54
54
55 m_presenter->theme()->decorate(m_series, m_presenter->dataSet()->seriesIndex(m_series));
55 m_presenter->theme()->decorate(m_series, m_presenter->dataSet()->seriesIndex(m_series));
56
56
57 foreach (QPieSlice *s, slices) {
57 foreach (QPieSlice *s, slices) {
58 PieSlice* slice = new PieSlice(this);
58 PieSliceItem* item = new PieSliceItem(this);
59 m_slices.insert(s, slice);
59 m_slices.insert(s, item);
60 connect(s, SIGNAL(changed()), this, SLOT(handleSliceChanged()));
60 connect(s, SIGNAL(changed()), this, SLOT(handleSliceChanged()));
61 connect(slice, SIGNAL(clicked()), s, SIGNAL(clicked()));
61 connect(item, SIGNAL(clicked()), s, SIGNAL(clicked()));
62 connect(slice, SIGNAL(hoverEnter()), s, SIGNAL(hoverEnter()));
62 connect(item, SIGNAL(hoverEnter()), s, SIGNAL(hoverEnter()));
63 connect(slice, SIGNAL(hoverLeave()), s, SIGNAL(hoverLeave()));
63 connect(item, SIGNAL(hoverLeave()), s, SIGNAL(hoverLeave()));
64
64
65 PieSliceData data = sliceData(s);
65 PieSliceData data = sliceData(s);
66
66
67 if (m_animator)
67 if (m_animator)
68 m_animator->addAnimation(this, s, data, isEmpty);
68 m_animator->addAnimation(this, s, data, isEmpty);
69 else
69 else
70 setLayout(s, data);
70 setLayout(s, data);
71 }
71 }
72 }
72 }
73
73
74 void PieChartItem::handleSlicesRemoved(QList<QPieSlice*> slices)
74 void PieChartItem::handleSlicesRemoved(QList<QPieSlice*> slices)
75 {
75 {
76 m_presenter->theme()->decorate(m_series, m_presenter->dataSet()->seriesIndex(m_series));
76 m_presenter->theme()->decorate(m_series, m_presenter->dataSet()->seriesIndex(m_series));
77
77
78 foreach (QPieSlice *s, slices) {
78 foreach (QPieSlice *s, slices) {
79 if (m_animator)
79 if (m_animator)
80 m_animator->removeAnimation(this, s);
80 m_animator->removeAnimation(this, s);
81 else
81 else
82 destroySlice(s);
82 destroySlice(s);
83 }
83 }
84 }
84 }
85
85
86 void PieChartItem::handlePieLayoutChanged()
86 void PieChartItem::handlePieLayoutChanged()
87 {
87 {
88 PieLayout layout = calculateLayout();
88 PieLayout layout = calculateLayout();
89 applyLayout(layout);
89 applyLayout(layout);
90 update();
90 update();
91 }
91 }
92
92
93 void PieChartItem::handleSliceChanged()
93 void PieChartItem::handleSliceChanged()
94 {
94 {
95 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
95 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
96 Q_ASSERT(m_slices.contains(slice));
96 Q_ASSERT(m_slices.contains(slice));
97 PieSliceData data = sliceData(slice);
97 PieSliceData data = sliceData(slice);
98 updateLayout(slice, data);
98 updateLayout(slice, data);
99 update();
99 update();
100 }
100 }
101
101
102 void PieChartItem::handleDomainChanged(qreal, qreal, qreal, qreal)
102 void PieChartItem::handleDomainChanged(qreal, qreal, qreal, qreal)
103 {
103 {
104 // TODO
104 // TODO
105 }
105 }
106
106
107 void PieChartItem::handleGeometryChanged(const QRectF& rect)
107 void PieChartItem::handleGeometryChanged(const QRectF& rect)
108 {
108 {
109 prepareGeometryChange();
109 prepareGeometryChange();
110 m_rect = rect;
110 m_rect = rect;
111 handlePieLayoutChanged();
111 handlePieLayoutChanged();
112 }
112 }
113
113
114 void PieChartItem::calculatePieLayout()
114 void PieChartItem::calculatePieLayout()
115 {
115 {
116 // find pie center coordinates
116 // find pie center coordinates
117 m_pieCenter.setX(m_rect.left() + (m_rect.width() * m_series->pieHorizontalPosition()));
117 m_pieCenter.setX(m_rect.left() + (m_rect.width() * m_series->pieHorizontalPosition()));
118 m_pieCenter.setY(m_rect.top() + (m_rect.height() * m_series->pieVerticalPosition()));
118 m_pieCenter.setY(m_rect.top() + (m_rect.height() * m_series->pieVerticalPosition()));
119
119
120 // find maximum radius for pie
120 // find maximum radius for pie
121 m_pieRadius = m_rect.height() / 2;
121 m_pieRadius = m_rect.height() / 2;
122 if (m_rect.width() < m_rect.height())
122 if (m_rect.width() < m_rect.height())
123 m_pieRadius = m_rect.width() / 2;
123 m_pieRadius = m_rect.width() / 2;
124
124
125 // apply size factor
125 // apply size factor
126 m_pieRadius *= m_series->pieSize();
126 m_pieRadius *= m_series->pieSize();
127 }
127 }
128
128
129 PieSliceData PieChartItem::sliceData(QPieSlice *slice)
129 PieSliceData PieChartItem::sliceData(QPieSlice *slice)
130 {
130 {
131 PieSliceData sliceData = slice->d_ptr->m_data;
131 PieSliceData sliceData = slice->d_ptr->m_data;
132 sliceData.m_center = PieSlice::sliceCenter(m_pieCenter, m_pieRadius, slice);
132 sliceData.m_center = PieSliceItem::sliceCenter(m_pieCenter, m_pieRadius, slice);
133 sliceData.m_radius = m_pieRadius;
133 sliceData.m_radius = m_pieRadius;
134 sliceData.m_angleSpan = slice->endAngle() - slice->startAngle();
134 sliceData.m_angleSpan = slice->endAngle() - slice->startAngle();
135 return sliceData;
135 return sliceData;
136 }
136 }
137
137
138 PieLayout PieChartItem::calculateLayout()
138 PieLayout PieChartItem::calculateLayout()
139 {
139 {
140 calculatePieLayout();
140 calculatePieLayout();
141 PieLayout layout;
141 PieLayout layout;
142 foreach (QPieSlice* s, m_series->slices()) {
142 foreach (QPieSlice* s, m_series->slices()) {
143 if (m_slices.contains(s)) // calculate layout only for those slices that are already visible
143 if (m_slices.contains(s)) // calculate layout only for those slices that are already visible
144 layout.insert(s, sliceData(s));
144 layout.insert(s, sliceData(s));
145 }
145 }
146 return layout;
146 return layout;
147 }
147 }
148
148
149 void PieChartItem::applyLayout(const PieLayout &layout)
149 void PieChartItem::applyLayout(const PieLayout &layout)
150 {
150 {
151 if (m_animator)
151 if (m_animator)
152 m_animator->updateLayout(this, layout);
152 m_animator->updateLayout(this, layout);
153 else
153 else
154 setLayout(layout);
154 setLayout(layout);
155 }
155 }
156
156
157 void PieChartItem::updateLayout(QPieSlice *slice, const PieSliceData &sliceData)
157 void PieChartItem::updateLayout(QPieSlice *slice, const PieSliceData &sliceData)
158 {
158 {
159 if (m_animator)
159 if (m_animator)
160 m_animator->updateLayout(this, slice, sliceData);
160 m_animator->updateLayout(this, slice, sliceData);
161 else
161 else
162 setLayout(slice, sliceData);
162 setLayout(slice, sliceData);
163 }
163 }
164
164
165 void PieChartItem::setLayout(const PieLayout &layout)
165 void PieChartItem::setLayout(const PieLayout &layout)
166 {
166 {
167 foreach (QPieSlice *slice, layout.keys()) {
167 foreach (QPieSlice *slice, layout.keys()) {
168 PieSlice *s = m_slices.value(slice);
168 PieSliceItem *item = m_slices.value(slice);
169 Q_ASSERT(s);
169 Q_ASSERT(item);
170 s->setSliceData(layout.value(slice));
170 item->setSliceData(layout.value(slice));
171 s->updateGeometry();
171 item->updateGeometry();
172 s->update();
172 item->update();
173 }
173 }
174 }
174 }
175
175
176 void PieChartItem::setLayout(QPieSlice *slice, const PieSliceData &sliceData)
176 void PieChartItem::setLayout(QPieSlice *slice, const PieSliceData &sliceData)
177 {
177 {
178 // find slice
178 // find slice
179 PieSlice *s = m_slices.value(slice);
179 PieSliceItem *item = m_slices.value(slice);
180 Q_ASSERT(s);
180 Q_ASSERT(item);
181 s->setSliceData(sliceData);
181 item->setSliceData(sliceData);
182 s->updateGeometry();
182 item->updateGeometry();
183 s->update();
183 item->update();
184 }
184 }
185
185
186 void PieChartItem::destroySlice(QPieSlice *slice)
186 void PieChartItem::destroySlice(QPieSlice *slice)
187 {
187 {
188 delete m_slices.take(slice);
188 delete m_slices.take(slice);
189 }
189 }
190
190
191 #include "moc_piechartitem_p.cpp"
191 #include "moc_piechartitem_p.cpp"
192
192
193 QTCOMMERCIALCHART_END_NAMESPACE
193 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,59 +1,59
1 #ifndef PIECHARTITEM_H
1 #ifndef PIECHARTITEM_H
2 #define PIECHARTITEM_H
2 #define PIECHARTITEM_H
3
3
4 #include "qpieseries.h"
4 #include "qpieseries.h"
5 #include "chartitem_p.h"
5 #include "chartitem_p.h"
6 #include "pieslice_p.h"
6 #include "piesliceitem_p.h"
7
7
8 class QGraphicsItem;
8 class QGraphicsItem;
9 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9 QTCOMMERCIALCHART_BEGIN_NAMESPACE
10 class QPieSlice;
10 class QPieSlice;
11 class ChartPresenter;
11 class ChartPresenter;
12
12
13 typedef QHash<QPieSlice*, PieSliceData> PieLayout;
13 typedef QHash<QPieSlice*, PieSliceData> PieLayout;
14
14
15 class PieChartItem : public QObject, public ChartItem
15 class PieChartItem : public QObject, public ChartItem
16 {
16 {
17 Q_OBJECT
17 Q_OBJECT
18
18
19 public:
19 public:
20 // TODO: use a generic data class instead of x and y
20 // TODO: use a generic data class instead of x and y
21 PieChartItem(QPieSeries *series, ChartPresenter *presenter, QGraphicsItem *parent);
21 PieChartItem(QPieSeries *series, ChartPresenter *presenter, QGraphicsItem *parent);
22 ~PieChartItem();
22 ~PieChartItem();
23
23
24 public: // from QGraphicsItem
24 public: // from QGraphicsItem
25 QRectF boundingRect() const { return m_rect; }
25 QRectF boundingRect() const { return m_rect; }
26 void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *);
26 void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *);
27
27
28 public Q_SLOTS:
28 public Q_SLOTS:
29 void initialize();
29 void initialize();
30 void handleSlicesAdded(QList<QPieSlice*> slices);
30 void handleSlicesAdded(QList<QPieSlice*> slices);
31 void handleSlicesRemoved(QList<QPieSlice*> slices);
31 void handleSlicesRemoved(QList<QPieSlice*> slices);
32 void handlePieLayoutChanged();
32 void handlePieLayoutChanged();
33 void handleSliceChanged();
33 void handleSliceChanged();
34 void handleDomainChanged(qreal, qreal, qreal, qreal);
34 void handleDomainChanged(qreal, qreal, qreal, qreal);
35 void handleGeometryChanged(const QRectF& rect);
35 void handleGeometryChanged(const QRectF& rect);
36
36
37 public:
37 public:
38 void calculatePieLayout();
38 void calculatePieLayout();
39 PieSliceData sliceData(QPieSlice *slice);
39 PieSliceData sliceData(QPieSlice *slice);
40 PieLayout calculateLayout();
40 PieLayout calculateLayout();
41 void applyLayout(const PieLayout &layout);
41 void applyLayout(const PieLayout &layout);
42 void updateLayout(QPieSlice *slice, const PieSliceData &sliceData);
42 void updateLayout(QPieSlice *slice, const PieSliceData &sliceData);
43 void setLayout(const PieLayout &layout);
43 void setLayout(const PieLayout &layout);
44 void setLayout(QPieSlice *slice, const PieSliceData &sliceData);
44 void setLayout(QPieSlice *slice, const PieSliceData &sliceData);
45 void destroySlice(QPieSlice *slice);
45 void destroySlice(QPieSlice *slice);
46
46
47 private:
47 private:
48 friend class PieSlice;
48 friend class PieSliceItem;
49 QHash<QPieSlice*, PieSlice*> m_slices;
49 QHash<QPieSlice*, PieSliceItem*> m_slices;
50 QPieSeries *m_series;
50 QPieSeries *m_series;
51 QRectF m_rect;
51 QRectF m_rect;
52 QPointF m_pieCenter;
52 QPointF m_pieCenter;
53 qreal m_pieRadius;
53 qreal m_pieRadius;
54 ChartPresenter *m_presenter;
54 ChartPresenter *m_presenter;
55 };
55 };
56
56
57 QTCOMMERCIALCHART_END_NAMESPACE
57 QTCOMMERCIALCHART_END_NAMESPACE
58
58
59 #endif // PIECHARTITEM_H
59 #endif // PIECHARTITEM_H
@@ -1,184 +1,184
1 #include "pieslice_p.h"
1 #include "piesliceitem_p.h"
2 #include "piechartitem_p.h"
2 #include "piechartitem_p.h"
3 #include "qpieseries.h"
3 #include "qpieseries.h"
4 #include "qpieslice.h"
4 #include "qpieslice.h"
5 #include "chartpresenter_p.h"
5 #include "chartpresenter_p.h"
6 #include <QPainter>
6 #include <QPainter>
7 #include <QDebug>
7 #include <QDebug>
8 #include <qmath.h>
8 #include <qmath.h>
9 #include <QGraphicsSceneEvent>
9 #include <QGraphicsSceneEvent>
10 #include <QTime>
10 #include <QTime>
11
11
12 QTCOMMERCIALCHART_BEGIN_NAMESPACE
12 QTCOMMERCIALCHART_BEGIN_NAMESPACE
13
13
14 #define PI 3.14159265 // TODO: is this defined in some header?
14 #define PI 3.14159265 // TODO: is this defined in some header?
15
15
16 QPointF offset(qreal angle, qreal length)
16 QPointF offset(qreal angle, qreal length)
17 {
17 {
18 qreal dx = qSin(angle*(PI/180)) * length;
18 qreal dx = qSin(angle*(PI/180)) * length;
19 qreal dy = qCos(angle*(PI/180)) * length;
19 qreal dy = qCos(angle*(PI/180)) * length;
20 return QPointF(dx, -dy);
20 return QPointF(dx, -dy);
21 }
21 }
22
22
23 PieSlice::PieSlice(QGraphicsItem* parent)
23 PieSliceItem::PieSliceItem(QGraphicsItem* parent)
24 :QGraphicsObject(parent)
24 :QGraphicsObject(parent)
25 {
25 {
26 setAcceptHoverEvents(true);
26 setAcceptHoverEvents(true);
27 setAcceptedMouseButtons(Qt::LeftButton);
27 setAcceptedMouseButtons(Qt::LeftButton);
28 setZValue(ChartPresenter::PieSeriesZValue);
28 setZValue(ChartPresenter::PieSeriesZValue);
29 }
29 }
30
30
31 PieSlice::~PieSlice()
31 PieSliceItem::~PieSliceItem()
32 {
32 {
33
33
34 }
34 }
35
35
36 QRectF PieSlice::boundingRect() const
36 QRectF PieSliceItem::boundingRect() const
37 {
37 {
38 return m_boundingRect;
38 return m_boundingRect;
39 }
39 }
40
40
41 QPainterPath PieSlice::shape() const
41 QPainterPath PieSliceItem::shape() const
42 {
42 {
43 // Don't include the label and label arm.
43 // Don't include the label and label arm.
44 // This is used to detect a mouse clicks. We do not want clicks from label.
44 // This is used to detect a mouse clicks. We do not want clicks from label.
45 return m_slicePath;
45 return m_slicePath;
46 }
46 }
47
47
48 void PieSlice::paint(QPainter* painter, const QStyleOptionGraphicsItem* /*option*/, QWidget* /*widget*/)
48 void PieSliceItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* /*option*/, QWidget* /*widget*/)
49 {
49 {
50 painter->setClipRect(parentItem()->boundingRect());
50 painter->setClipRect(parentItem()->boundingRect());
51
51
52 painter->save();
52 painter->save();
53 painter->setPen(m_data.m_slicePen);
53 painter->setPen(m_data.m_slicePen);
54 painter->setBrush(m_data.m_sliceBrush);
54 painter->setBrush(m_data.m_sliceBrush);
55 painter->drawPath(m_slicePath);
55 painter->drawPath(m_slicePath);
56 painter->restore();
56 painter->restore();
57
57
58 if (m_data.m_labelVisible) {
58 if (m_data.m_labelVisible) {
59 painter->save();
59 painter->save();
60 painter->setPen(m_data.m_labelArmPen);
60 painter->setPen(m_data.m_labelArmPen);
61 painter->drawPath(m_labelArmPath);
61 painter->drawPath(m_labelArmPath);
62 painter->restore();
62 painter->restore();
63
63
64 painter->setFont(m_data.m_labelFont);
64 painter->setFont(m_data.m_labelFont);
65 painter->drawText(m_labelTextRect.bottomLeft(), m_data.m_labelText);
65 painter->drawText(m_labelTextRect.bottomLeft(), m_data.m_labelText);
66 }
66 }
67 }
67 }
68
68
69 void PieSlice::hoverEnterEvent(QGraphicsSceneHoverEvent* /*event*/)
69 void PieSliceItem::hoverEnterEvent(QGraphicsSceneHoverEvent* /*event*/)
70 {
70 {
71 emit hoverEnter();
71 emit hoverEnter();
72 }
72 }
73
73
74 void PieSlice::hoverLeaveEvent(QGraphicsSceneHoverEvent* /*event*/)
74 void PieSliceItem::hoverLeaveEvent(QGraphicsSceneHoverEvent* /*event*/)
75 {
75 {
76 emit hoverLeave();
76 emit hoverLeave();
77 }
77 }
78
78
79 void PieSlice::mousePressEvent(QGraphicsSceneMouseEvent* /*event*/)
79 void PieSliceItem::mousePressEvent(QGraphicsSceneMouseEvent* /*event*/)
80 {
80 {
81 emit clicked();
81 emit clicked();
82 }
82 }
83
83
84 void PieSlice::setSliceData(PieSliceData sliceData)
84 void PieSliceItem::setSliceData(PieSliceData sliceData)
85 {
85 {
86 m_data = sliceData;
86 m_data = sliceData;
87 }
87 }
88
88
89 void PieSlice::updateGeometry()
89 void PieSliceItem::updateGeometry()
90 {
90 {
91 if (m_data.m_radius <= 0)
91 if (m_data.m_radius <= 0)
92 return;
92 return;
93
93
94 prepareGeometryChange();
94 prepareGeometryChange();
95
95
96 // update slice path
96 // update slice path
97 qreal centerAngle;
97 qreal centerAngle;
98 QPointF armStart;
98 QPointF armStart;
99 m_slicePath = slicePath(m_data.m_center, m_data.m_radius, m_data.m_startAngle, m_data.m_angleSpan, &centerAngle, &armStart);
99 m_slicePath = slicePath(m_data.m_center, m_data.m_radius, m_data.m_startAngle, m_data.m_angleSpan, &centerAngle, &armStart);
100
100
101 // update text rect
101 // update text rect
102 m_labelTextRect = labelTextRect(m_data.m_labelFont, m_data.m_labelText);
102 m_labelTextRect = labelTextRect(m_data.m_labelFont, m_data.m_labelText);
103
103
104 // update label arm path
104 // update label arm path
105 QPointF labelTextStart;
105 QPointF labelTextStart;
106 m_labelArmPath = labelArmPath(armStart, centerAngle, m_data.m_radius * m_data.m_labelArmLengthFactor, m_labelTextRect.width(), &labelTextStart);
106 m_labelArmPath = labelArmPath(armStart, centerAngle, m_data.m_radius * m_data.m_labelArmLengthFactor, m_labelTextRect.width(), &labelTextStart);
107
107
108 // update text position
108 // update text position
109 m_labelTextRect.moveBottomLeft(labelTextStart);
109 m_labelTextRect.moveBottomLeft(labelTextStart);
110
110
111 // update bounding rect
111 // update bounding rect
112 m_boundingRect = m_slicePath.boundingRect().united(m_labelArmPath.boundingRect()).united(m_labelTextRect);
112 m_boundingRect = m_slicePath.boundingRect().united(m_labelArmPath.boundingRect()).united(m_labelTextRect);
113 }
113 }
114
114
115 QPointF PieSlice::sliceCenter(QPointF point, qreal radius, QPieSlice *slice)
115 QPointF PieSliceItem::sliceCenter(QPointF point, qreal radius, QPieSlice *slice)
116 {
116 {
117 if (slice->isExploded()) {
117 if (slice->isExploded()) {
118 qreal centerAngle = slice->startAngle() + ((slice->endAngle() - slice->startAngle())/2);
118 qreal centerAngle = slice->startAngle() + ((slice->endAngle() - slice->startAngle())/2);
119 qreal len = radius * slice->explodeDistanceFactor();
119 qreal len = radius * slice->explodeDistanceFactor();
120 qreal dx = qSin(centerAngle*(PI/180)) * len;
120 qreal dx = qSin(centerAngle*(PI/180)) * len;
121 qreal dy = -qCos(centerAngle*(PI/180)) * len;
121 qreal dy = -qCos(centerAngle*(PI/180)) * len;
122 point += QPointF(dx, dy);
122 point += QPointF(dx, dy);
123 }
123 }
124 return point;
124 return point;
125 }
125 }
126
126
127 QPainterPath PieSlice::slicePath(QPointF center, qreal radius, qreal startAngle, qreal angleSpan, qreal* centerAngle, QPointF* armStart)
127 QPainterPath PieSliceItem::slicePath(QPointF center, qreal radius, qreal startAngle, qreal angleSpan, qreal* centerAngle, QPointF* armStart)
128 {
128 {
129 // calculate center angle
129 // calculate center angle
130 *centerAngle = startAngle + (angleSpan/2);
130 *centerAngle = startAngle + (angleSpan/2);
131
131
132 // calculate slice rectangle
132 // calculate slice rectangle
133 QRectF rect(center.x()-radius, center.y()-radius, radius*2, radius*2);
133 QRectF rect(center.x()-radius, center.y()-radius, radius*2, radius*2);
134
134
135 // slice path
135 // slice path
136 // TODO: draw the shape so that it might have a hole in the center
136 // TODO: draw the shape so that it might have a hole in the center
137 QPainterPath path;
137 QPainterPath path;
138 path.moveTo(rect.center());
138 path.moveTo(rect.center());
139 path.arcTo(rect, -startAngle + 90, -angleSpan);
139 path.arcTo(rect, -startAngle + 90, -angleSpan);
140 path.closeSubpath();
140 path.closeSubpath();
141
141
142 // calculate label arm start point
142 // calculate label arm start point
143 *armStart = center;
143 *armStart = center;
144 *armStart += offset(*centerAngle, radius + PIESLICE_LABEL_GAP);
144 *armStart += offset(*centerAngle, radius + PIESLICE_LABEL_GAP);
145
145
146 return path;
146 return path;
147 }
147 }
148
148
149 QPainterPath PieSlice::labelArmPath(QPointF start, qreal angle, qreal length, qreal textWidth, QPointF* textStart)
149 QPainterPath PieSliceItem::labelArmPath(QPointF start, qreal angle, qreal length, qreal textWidth, QPointF* textStart)
150 {
150 {
151 qreal dx = qSin(angle*(PI/180)) * length;
151 qreal dx = qSin(angle*(PI/180)) * length;
152 qreal dy = -qCos(angle*(PI/180)) * length;
152 qreal dy = -qCos(angle*(PI/180)) * length;
153 QPointF parm1 = start + QPointF(dx, dy);
153 QPointF parm1 = start + QPointF(dx, dy);
154
154
155 QPointF parm2 = parm1;
155 QPointF parm2 = parm1;
156 if (angle < 180) { // arm swings the other way on the left side
156 if (angle < 180) { // arm swings the other way on the left side
157 parm2 += QPointF(textWidth, 0);
157 parm2 += QPointF(textWidth, 0);
158 *textStart = parm1;
158 *textStart = parm1;
159 }
159 }
160 else {
160 else {
161 parm2 += QPointF(-textWidth,0);
161 parm2 += QPointF(-textWidth,0);
162 *textStart = parm2;
162 *textStart = parm2;
163 }
163 }
164
164
165 // elevate the text position a bit so that it does not hit the line
165 // elevate the text position a bit so that it does not hit the line
166 *textStart += QPointF(0, -5);
166 *textStart += QPointF(0, -5);
167
167
168 QPainterPath path;
168 QPainterPath path;
169 path.moveTo(start);
169 path.moveTo(start);
170 path.lineTo(parm1);
170 path.lineTo(parm1);
171 path.lineTo(parm2);
171 path.lineTo(parm2);
172
172
173 return path;
173 return path;
174 }
174 }
175
175
176 QRectF PieSlice::labelTextRect(QFont font, QString text)
176 QRectF PieSliceItem::labelTextRect(QFont font, QString text)
177 {
177 {
178 QFontMetricsF fm(font);
178 QFontMetricsF fm(font);
179 return fm.boundingRect(text);
179 return fm.boundingRect(text);
180 }
180 }
181
181
182 #include "moc_pieslice_p.cpp"
182 #include "moc_piesliceitem_p.cpp"
183
183
184 QTCOMMERCIALCHART_END_NAMESPACE
184 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,59 +1,59
1 #ifndef PIESLICE_H
1 #ifndef PIESLICEITEM_H
2 #define PIESLICE_H
2 #define PIESLICEITEM_H
3
3
4 #include "qchartglobal.h"
4 #include "qchartglobal.h"
5 #include "charttheme_p.h"
5 #include "charttheme_p.h"
6 #include "qpieseries.h"
6 #include "qpieseries.h"
7 #include "qpiesliceprivate_p.h"
7 #include "qpiesliceprivate_p.h"
8 #include <QGraphicsItem>
8 #include <QGraphicsItem>
9 #include <QRectF>
9 #include <QRectF>
10 #include <QColor>
10 #include <QColor>
11 #include <QPen>
11 #include <QPen>
12
12
13 #define PIESLICE_LABEL_GAP 5
13 #define PIESLICE_LABEL_GAP 5
14
14
15 QTCOMMERCIALCHART_BEGIN_NAMESPACE
15 QTCOMMERCIALCHART_BEGIN_NAMESPACE
16 class PieChartItem;
16 class PieChartItem;
17 class PieSliceLabel;
17 class PieSliceLabel;
18 class QPieSlice;
18 class QPieSlice;
19
19
20 class PieSlice : public QGraphicsObject
20 class PieSliceItem : public QGraphicsObject
21 {
21 {
22 Q_OBJECT
22 Q_OBJECT
23
23
24 public:
24 public:
25 PieSlice(QGraphicsItem* parent = 0);
25 PieSliceItem(QGraphicsItem* parent = 0);
26 ~PieSlice();
26 ~PieSliceItem();
27
27
28 public: // from QGraphicsItem
28 public: // from QGraphicsItem
29 QRectF boundingRect() const;
29 QRectF boundingRect() const;
30 QPainterPath shape() const;
30 QPainterPath shape() const;
31 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
31 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
32 void hoverEnterEvent(QGraphicsSceneHoverEvent *event);
32 void hoverEnterEvent(QGraphicsSceneHoverEvent *event);
33 void hoverLeaveEvent(QGraphicsSceneHoverEvent *event);
33 void hoverLeaveEvent(QGraphicsSceneHoverEvent *event);
34 void mousePressEvent(QGraphicsSceneMouseEvent *event);
34 void mousePressEvent(QGraphicsSceneMouseEvent *event);
35
35
36 Q_SIGNALS:
36 Q_SIGNALS:
37 void clicked();
37 void clicked();
38 void hoverEnter();
38 void hoverEnter();
39 void hoverLeave();
39 void hoverLeave();
40
40
41 public:
41 public:
42 void setSliceData(PieSliceData sliceData);
42 void setSliceData(PieSliceData sliceData);
43 void updateGeometry();
43 void updateGeometry();
44 static QPointF sliceCenter(QPointF point, qreal radius, QPieSlice *slice);
44 static QPointF sliceCenter(QPointF point, qreal radius, QPieSlice *slice);
45 static QPainterPath slicePath(QPointF center, qreal radius, qreal startAngle, qreal angleSpan, qreal* centerAngle, QPointF* armStart);
45 static QPainterPath slicePath(QPointF center, qreal radius, qreal startAngle, qreal angleSpan, qreal* centerAngle, QPointF* armStart);
46 static QPainterPath labelArmPath(QPointF start, qreal angle, qreal length, qreal textWidth, QPointF* textStart);
46 static QPainterPath labelArmPath(QPointF start, qreal angle, qreal length, qreal textWidth, QPointF* textStart);
47 static QRectF labelTextRect(QFont font, QString text);
47 static QRectF labelTextRect(QFont font, QString text);
48
48
49 private:
49 private:
50 PieSliceData m_data;
50 PieSliceData m_data;
51 QRectF m_boundingRect;
51 QRectF m_boundingRect;
52 QPainterPath m_slicePath;
52 QPainterPath m_slicePath;
53 QPainterPath m_labelArmPath;
53 QPainterPath m_labelArmPath;
54 QRectF m_labelTextRect;
54 QRectF m_labelTextRect;
55 };
55 };
56
56
57 QTCOMMERCIALCHART_END_NAMESPACE
57 QTCOMMERCIALCHART_END_NAMESPACE
58
58
59 #endif // PIESLICE_H
59 #endif // PIESLICEITEM_H
General Comments 0
You need to be logged in to leave comments. Login now