@@ -0,0 +1,76 | |||||
|
1 | #include "pieslicelabel.h" | |||
|
2 | #include <QPainter> | |||
|
3 | #include <qmath.h> | |||
|
4 | ||||
|
5 | QTCOMMERCIALCHART_BEGIN_NAMESPACE | |||
|
6 | ||||
|
7 | #define PI 3.14159265 | |||
|
8 | ||||
|
9 | PieSliceLabel::PieSliceLabel(QGraphicsItem* parent) | |||
|
10 | :QGraphicsItem(parent) | |||
|
11 | { | |||
|
12 | m_pen = QPen(Qt::black); | |||
|
13 | } | |||
|
14 | ||||
|
15 | PieSliceLabel::~PieSliceLabel() | |||
|
16 | { | |||
|
17 | ||||
|
18 | } | |||
|
19 | ||||
|
20 | QRectF PieSliceLabel::boundingRect() const | |||
|
21 | { | |||
|
22 | return m_rect; | |||
|
23 | } | |||
|
24 | ||||
|
25 | QPainterPath PieSliceLabel::shape() const | |||
|
26 | { | |||
|
27 | return m_path; | |||
|
28 | } | |||
|
29 | ||||
|
30 | void PieSliceLabel::paint(QPainter *painter, const QStyleOptionGraphicsItem* /*option*/, QWidget* /*widget*/) | |||
|
31 | { | |||
|
32 | painter->setRenderHint(QPainter::Antialiasing); | |||
|
33 | painter->setPen(m_pen); | |||
|
34 | painter->drawPath(m_path); | |||
|
35 | } | |||
|
36 | ||||
|
37 | void PieSliceLabel::updateGeometry(const QPointF& startPoint, qreal armAngle, qreal armLength) | |||
|
38 | { | |||
|
39 | prepareGeometryChange(); | |||
|
40 | ||||
|
41 | QPainterPath path; | |||
|
42 | path.moveTo(startPoint); | |||
|
43 | ||||
|
44 | // draw arm | |||
|
45 | qreal dx = qSin(armAngle*(PI/180)) * armLength; | |||
|
46 | qreal dy = -qCos(armAngle*(PI/180)) * armLength; | |||
|
47 | QPointF p1 = startPoint + QPointF(dx, dy); | |||
|
48 | path.lineTo(p1); | |||
|
49 | ||||
|
50 | QPointF p2 = p1; | |||
|
51 | QPointF pt = p1; | |||
|
52 | if (armAngle < 180) { | |||
|
53 | p2 += QPointF(50, 0); | |||
|
54 | } else { | |||
|
55 | p2 += QPointF(-50,0); | |||
|
56 | pt = p2; | |||
|
57 | } | |||
|
58 | path.lineTo(p2); | |||
|
59 | ||||
|
60 | QFont font; | |||
|
61 | pt += QPointF(0,-2); | |||
|
62 | path.addText(pt, font, m_label); | |||
|
63 | ||||
|
64 | m_path = path; | |||
|
65 | m_rect = path.boundingRect(); | |||
|
66 | } | |||
|
67 | ||||
|
68 | void PieSliceLabel::setLabel(QString label) | |||
|
69 | { | |||
|
70 | m_label = label; | |||
|
71 | // TODO: animation? | |||
|
72 | } | |||
|
73 | ||||
|
74 | ||||
|
75 | ||||
|
76 | QTCOMMERCIALCHART_END_NAMESPACE |
@@ -0,0 +1,36 | |||||
|
1 | #ifndef PIELABEL_H | |||
|
2 | #define PIELABEL_H | |||
|
3 | ||||
|
4 | #include "qchartglobal.h" | |||
|
5 | #include <QGraphicsItem> | |||
|
6 | #include <QPen> | |||
|
7 | ||||
|
8 | QTCOMMERCIALCHART_BEGIN_NAMESPACE | |||
|
9 | ||||
|
10 | class PieSliceLabel : public QGraphicsItem | |||
|
11 | { | |||
|
12 | public: | |||
|
13 | PieSliceLabel(QGraphicsItem* parent = 0); | |||
|
14 | ~PieSliceLabel(); | |||
|
15 | ||||
|
16 | public: // from QGraphicsItem | |||
|
17 | QRectF boundingRect() const; | |||
|
18 | QPainterPath shape() const; | |||
|
19 | void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); | |||
|
20 | ||||
|
21 | public: | |||
|
22 | void updateGeometry(const QPointF& startPoint, qreal armAngle, qreal armLength); | |||
|
23 | void setLabel(QString label); | |||
|
24 | QString label() const {return m_label;} | |||
|
25 | void setPen(QPen pen); | |||
|
26 | ||||
|
27 | private: | |||
|
28 | QString m_label; | |||
|
29 | QPainterPath m_path; | |||
|
30 | QRectF m_rect; | |||
|
31 | QPen m_pen; | |||
|
32 | }; | |||
|
33 | ||||
|
34 | QTCOMMERCIALCHART_END_NAMESPACE | |||
|
35 | ||||
|
36 | #endif // PIELABEL_H |
@@ -17,11 +17,11 int main(int argc, char *argv[]) | |||||
17 | Q_ASSERT(series); |
|
17 | Q_ASSERT(series); | |
18 |
|
18 | |||
19 | // Add test data to the series |
|
19 | // Add test data to the series | |
20 |
series->add(QPieSlice(1, "test1", Qt::red, tr |
|
20 | series->add(QPieSlice(1, "test1", true, true, QPen(Qt::red, 2), QBrush(Qt::red))); | |
21 |
series->add(QPieSlice(2, "test2" |
|
21 | series->add(QPieSlice(2, "test2")); | |
22 |
series->add(QPieSlice(3, "test3" |
|
22 | series->add(QPieSlice(3, "test3")); | |
23 |
series->add(QPieSlice(4, "test4" |
|
23 | series->add(QPieSlice(4, "test4")); | |
24 |
series->add(QPieSlice(5, "test5" |
|
24 | series->add(QPieSlice(5, "test5")); | |
25 |
|
25 | |||
26 | // Use the chart widget as the central widget |
|
26 | // Use the chart widget as the central widget | |
27 | QMainWindow w; |
|
27 | QMainWindow w; |
@@ -198,14 +198,12 void ChartTheme::decorate(PiePresenter* item, QPieSeries* series, int /*count*/) | |||||
198 | } |
|
198 | } | |
199 |
|
199 | |||
200 | // finally update colors |
|
200 | // finally update colors | |
201 | QList<QPieSlice> slices; |
|
201 | foreach (QPieSliceId id, series->ids()) { | |
202 | for (int i=0; i<series->count(); i++) { |
|
202 | QPieSlice s = series->slice(id); | |
203 | QPieSlice slice = series->slice(i); |
|
203 | s.setPen(QPen(Qt::black)); // TODO: get from theme | |
204 |
s |
|
204 | s.setBrush(colors.takeFirst()); | |
205 | slices << slice; |
|
205 | series->update(s); | |
206 | } |
|
206 | } | |
207 |
|
||||
208 | series->set(slices); |
|
|||
209 | } |
|
207 | } | |
210 |
|
208 | |||
211 |
|
209 |
@@ -4,11 +4,13 DEPENDPATH += $$PWD | |||||
4 | SOURCES += \ |
|
4 | SOURCES += \ | |
5 | $$PWD/qpieseries.cpp \ |
|
5 | $$PWD/qpieseries.cpp \ | |
6 | $$PWD/pieslice.cpp \ |
|
6 | $$PWD/pieslice.cpp \ | |
7 | $$PWD/piepresenter.cpp |
|
7 | $$PWD/piepresenter.cpp \ | |
|
8 | $$PWD/pieslicelabel.cpp | |||
8 |
|
9 | |||
9 | PRIVATE_HEADERS += \ |
|
10 | PRIVATE_HEADERS += \ | |
10 | $$PWD/piepresenter.h \ |
|
11 | $$PWD/piepresenter.h \ | |
11 | $$PWD/pieslice.h |
|
12 | $$PWD/pieslice.h \ | |
|
13 | $$PWD/pieslicelabel.h | |||
12 |
|
14 | |||
13 | PUBLIC_HEADERS += \ |
|
15 | PUBLIC_HEADERS += \ | |
14 | $$PWD/qpieseries.h |
|
16 | $$PWD/qpieseries.h |
@@ -6,57 +6,50 | |||||
6 |
|
6 | |||
7 | QTCOMMERCIALCHART_BEGIN_NAMESPACE |
|
7 | QTCOMMERCIALCHART_BEGIN_NAMESPACE | |
8 |
|
8 | |||
9 |
PiePresenter::PiePresenter(QGraphicsItem *parent, QPieSeries *series) |
|
9 | PiePresenter::PiePresenter(QGraphicsItem *parent, QPieSeries *series) | |
10 | ChartItem(parent), |
|
10 | :ChartItem(parent), | |
11 |
m_ |
|
11 | m_series(series) | |
12 | { |
|
12 | { | |
13 | Q_ASSERT(parent); |
|
|||
14 | Q_ASSERT(series); |
|
13 | Q_ASSERT(series); | |
15 |
|
14 | connect(series, SIGNAL(changed(const QPieSeries::ChangeSet&)), this, SLOT(handleSeriesChanged(const QPieSeries::ChangeSet&))); | ||
16 | m_rect = parentItem()->boundingRect(); |
|
|||
17 | setAcceptHoverEvents(true); |
|
|||
18 | qsrand(QTime::currentTime().msec()); // for random color generation |
|
|||
19 |
|
||||
20 | connect(series, SIGNAL(changed(const PieChangeSet&)), this, SLOT(handleSeriesChanged(const PieChangeSet&))); |
|
|||
21 | connect(series, SIGNAL(sizeFactorChanged()), this, SLOT(updateGeometry())); |
|
15 | connect(series, SIGNAL(sizeFactorChanged()), this, SLOT(updateGeometry())); | |
22 | connect(series, SIGNAL(positionChanged()), this, SLOT(updateGeometry())); |
|
16 | connect(series, SIGNAL(positionChanged()), this, SLOT(updateGeometry())); | |
23 | } |
|
17 | } | |
24 |
|
18 | |||
25 | PiePresenter::~PiePresenter() |
|
19 | PiePresenter::~PiePresenter() | |
26 | { |
|
20 | { | |
27 | while (m_slices.count()) |
|
21 | // slices deleted automatically through QGraphicsItem | |
28 | delete m_slices.takeLast(); |
|
|||
29 | } |
|
22 | } | |
30 |
|
23 | |||
31 | void PiePresenter::handleSeriesChanged(const PieChangeSet& /*changeSet*/) |
|
24 | void PiePresenter::paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *) | |
32 | { |
|
25 | { | |
33 | const qreal fullPie = 360; |
|
26 | // TODO: paint shadows for all components | |
34 | qreal total = 0; |
|
27 | // - get paths from items & merge & offset and draw with shadow color? | |
35 |
|
28 | } | ||
36 | // calculate total and set random color if there is no color |
|
29 | ||
37 | for (int i=0; i<m_pieSeries->count(); i++) { |
|
30 | void PiePresenter::handleSeriesChanged(const QPieSeries::ChangeSet& changeSet) | |
38 | QPieSlice& slice = m_pieSeries->m_slices[i]; |
|
31 | { | |
39 | total += slice.m_value; |
|
32 | qDebug() << "PiePresenter::handleSeriesChanged()"; | |
40 | if (slice.m_color == QColor::Invalid) { |
|
33 | qDebug() << " added : " << changeSet.m_added; | |
41 | slice.m_color.setRed(qrand() % 255); |
|
34 | qDebug() << " changed: " << changeSet.m_changed; | |
42 | slice.m_color.setGreen(qrand() % 255); |
|
35 | qDebug() << " removed: " << changeSet.m_removed; | |
43 | slice.m_color.setBlue(qrand() % 255); |
|
36 | ||
44 | } |
|
37 | // ignore changeset when there are no visual slices | |
|
38 | // changeset might not be valid about the added slices | |||
|
39 | if (m_slices.count() == 0) { | |||
|
40 | foreach (QPieSliceId id, m_series->m_slices.keys()) | |||
|
41 | addSlice(id); | |||
|
42 | return; | |||
45 | } |
|
43 | } | |
46 |
|
44 | |||
47 | // TODO: no need to create new slices in case size changed; we should re-use the existing ones |
|
45 | foreach (QPieSliceId id, changeSet.m_removed) | |
48 | while (m_slices.count()) |
|
46 | deleteSlice(id); | |
49 | delete m_slices.takeLast(); |
|
|||
50 |
|
47 | |||
51 | // create slices |
|
48 | foreach (QPieSliceId id, changeSet.m_changed) | |
52 | qreal angle = 0; |
|
49 | updateSlice(id); | |
53 | for (int i=0; i<m_pieSeries->count(); i++) { |
|
50 | ||
54 | QPieSlice sliceData = m_pieSeries->slice(i); |
|
51 | foreach (QPieSliceId id, changeSet.m_added) | |
55 | qreal span = sliceData.m_value / total * fullPie; |
|
52 | addSlice(id); | |
56 | PieSlice *slice = new PieSlice(this, i, angle, span); |
|
|||
57 | m_slices.append(slice); |
|
|||
58 | angle += span; |
|
|||
59 | } |
|
|||
60 | } |
|
53 | } | |
61 |
|
54 | |||
62 | void PiePresenter::updateGeometry() |
|
55 | void PiePresenter::updateGeometry() | |
@@ -66,16 +59,16 void PiePresenter::updateGeometry() | |||||
66 | m_pieRect = m_rect; |
|
59 | m_pieRect = m_rect; | |
67 |
|
60 | |||
68 | if (m_pieRect.width() < m_pieRect.height()) { |
|
61 | if (m_pieRect.width() < m_pieRect.height()) { | |
69 |
m_pieRect.setWidth(m_pieRect.width() * m_ |
|
62 | m_pieRect.setWidth(m_pieRect.width() * m_series->sizeFactor()); | |
70 | m_pieRect.setHeight(m_pieRect.width()); |
|
63 | m_pieRect.setHeight(m_pieRect.width()); | |
71 | m_pieRect.moveCenter(m_rect.center()); |
|
64 | m_pieRect.moveCenter(m_rect.center()); | |
72 | } else { |
|
65 | } else { | |
73 |
m_pieRect.setHeight(m_pieRect.height() * m_ |
|
66 | m_pieRect.setHeight(m_pieRect.height() * m_series->sizeFactor()); | |
74 | m_pieRect.setWidth(m_pieRect.height()); |
|
67 | m_pieRect.setWidth(m_pieRect.height()); | |
75 | m_pieRect.moveCenter(m_rect.center()); |
|
68 | m_pieRect.moveCenter(m_rect.center()); | |
76 | } |
|
69 | } | |
77 |
|
70 | |||
78 |
switch (m_ |
|
71 | switch (m_series->position()) { | |
79 | case QPieSeries::PiePositionTopLeft: { |
|
72 | case QPieSeries::PiePositionTopLeft: { | |
80 | m_pieRect.setHeight(m_pieRect.height() / 2); |
|
73 | m_pieRect.setHeight(m_pieRect.height() / 2); | |
81 | m_pieRect.setWidth(m_pieRect.height()); |
|
74 | m_pieRect.setWidth(m_pieRect.height()); | |
@@ -104,10 +97,16 void PiePresenter::updateGeometry() | |||||
104 | break; |
|
97 | break; | |
105 | } |
|
98 | } | |
106 |
|
99 | |||
107 | qDebug() << "presentation rect:" << m_rect; |
|
100 | // update slice geometry | |
108 | qDebug() << "pie rect:" << m_pieRect; |
|
101 | const qreal fullPie = 360; | |
109 | foreach (PieSlice *slice, m_slices) |
|
102 | qreal angle = 0; | |
110 | slice->updateGeometry(); |
|
103 | foreach (QPieSliceId id, m_slices.keys()) { | |
|
104 | qreal span = fullPie * m_series->slice(id).percentage(); | |||
|
105 | m_slices[id]->updateGeometry(m_pieRect, angle, span); | |||
|
106 | angle += span; | |||
|
107 | } | |||
|
108 | ||||
|
109 | //qDebug() << "PiePresenter::updateGeometry" << m_rect << m_pieRect; | |||
111 | } |
|
110 | } | |
112 |
|
111 | |||
113 | void PiePresenter::handleDomainChanged(const Domain& domain) |
|
112 | void PiePresenter::handleDomainChanged(const Domain& domain) | |
@@ -119,7 +118,51 void PiePresenter::handleGeometryChanged(const QRectF& rect) | |||||
119 | { |
|
118 | { | |
120 | m_rect = rect; |
|
119 | m_rect = rect; | |
121 | updateGeometry(); |
|
120 | updateGeometry(); | |
|
121 | } | |||
122 |
|
122 | |||
|
123 | void PiePresenter::addSlice(QPieSliceId id) | |||
|
124 | { | |||
|
125 | qDebug() << "PiePresenter::addSlice()" << id; | |||
|
126 | ||||
|
127 | if (m_slices.contains(id)) { | |||
|
128 | qWarning() << "PiePresenter::addSlice(): slice already exists!" << id; | |||
|
129 | updateSlice(id); | |||
|
130 | return; | |||
|
131 | } | |||
|
132 | ||||
|
133 | // create slice | |||
|
134 | PieSlice *slice = new PieSlice(id, m_series, this); | |||
|
135 | m_slices.insert(id, slice); | |||
|
136 | ||||
|
137 | updateGeometry(); | |||
|
138 | } | |||
|
139 | ||||
|
140 | void PiePresenter::updateSlice(QPieSliceId id) | |||
|
141 | { | |||
|
142 | qDebug() << "PiePresenter::updateSlice()" << id; | |||
|
143 | ||||
|
144 | // TODO: animation | |||
|
145 | if (m_slices.contains(id)) | |||
|
146 | m_slices.value(id)->updateData(); | |||
|
147 | else { | |||
|
148 | qWarning() << "PiePresenter::updateSlice(): slice does not exist!" << id; | |||
|
149 | addSlice(id); | |||
|
150 | } | |||
|
151 | ||||
|
152 | updateGeometry(); | |||
|
153 | } | |||
|
154 | ||||
|
155 | void PiePresenter::deleteSlice(QPieSliceId id) | |||
|
156 | { | |||
|
157 | qDebug() << "PiePresenter::deleteSlice()" << id; | |||
|
158 | ||||
|
159 | // TODO: animation | |||
|
160 | if (m_slices.contains(id)) | |||
|
161 | delete m_slices.take(id); | |||
|
162 | else | |||
|
163 | qWarning() << "PiePresenter::deleteSlice(): slice does not exist!" << id; | |||
|
164 | ||||
|
165 | updateGeometry(); | |||
123 | } |
|
166 | } | |
124 |
|
167 | |||
125 | #include "moc_piepresenter.cpp" |
|
168 | #include "moc_piepresenter.cpp" |
@@ -3,6 +3,7 | |||||
3 |
|
3 | |||
4 | #include "chartitem_p.h" |
|
4 | #include "chartitem_p.h" | |
5 | #include "qpieseries.h" |
|
5 | #include "qpieseries.h" | |
|
6 | #include <QSignalMapper> | |||
6 |
|
7 | |||
7 | class QGraphicsItem; |
|
8 | class QGraphicsItem; | |
8 | QTCOMMERCIALCHART_BEGIN_NAMESPACE |
|
9 | QTCOMMERCIALCHART_BEGIN_NAMESPACE | |
@@ -19,21 +20,26 public: | |||||
19 |
|
20 | |||
20 | public: // from QGraphicsItem |
|
21 | public: // from QGraphicsItem | |
21 | QRectF boundingRect() const { return m_rect; } |
|
22 | QRectF boundingRect() const { return m_rect; } | |
22 |
void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *) |
|
23 | void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *); | |
23 |
|
24 | |||
24 | public: |
|
25 | public: | |
25 | QRectF pieRect() const { return m_pieRect; } |
|
26 | QRectF pieRect() const { return m_pieRect; } | |
26 |
|
27 | |||
27 | public Q_SLOTS: |
|
28 | public Q_SLOTS: | |
28 | void handleSeriesChanged(const PieChangeSet& changeSet); |
|
29 | void handleSeriesChanged(const QPieSeries::ChangeSet& changeSet); | |
29 | void handleDomainChanged(const Domain& domain); |
|
30 | void handleDomainChanged(const Domain& domain); | |
30 | void handleGeometryChanged(const QRectF& rect); |
|
31 | void handleGeometryChanged(const QRectF& rect); | |
31 | void updateGeometry(); |
|
32 | void updateGeometry(); | |
32 |
|
33 | |||
33 | private: |
|
34 | private: | |
|
35 | void addSlice(QPieSliceId id); | |||
|
36 | void updateSlice(QPieSliceId id); | |||
|
37 | void deleteSlice(QPieSliceId id); | |||
|
38 | ||||
|
39 | private: | |||
34 | friend class PieSlice; |
|
40 | friend class PieSlice; | |
35 |
Q |
|
41 | QHash<QPieSliceId, PieSlice*> m_slices; | |
36 |
QPieSeries *m_ |
|
42 | QPieSeries *m_series; | |
37 | QRectF m_rect; |
|
43 | QRectF m_rect; | |
38 | QRectF m_pieRect; |
|
44 | QRectF m_pieRect; | |
39 | }; |
|
45 | }; |
@@ -1,10 +1,12 | |||||
1 | #include "pieslice.h" |
|
1 | #include "pieslice.h" | |
|
2 | #include "pieslicelabel.h" | |||
2 | #include "piepresenter.h" |
|
3 | #include "piepresenter.h" | |
3 | #include "qpieseries.h" |
|
4 | #include "qpieseries.h" | |
4 | #include <QPainter> |
|
5 | #include <QPainter> | |
5 | #include <QDebug> |
|
6 | #include <QDebug> | |
6 | #include <qmath.h> |
|
7 | #include <qmath.h> | |
7 | #include <QGraphicsSceneEvent> |
|
8 | #include <QGraphicsSceneEvent> | |
|
9 | #include <QTime> | |||
8 |
|
10 | |||
9 | QTCOMMERCIALCHART_BEGIN_NAMESPACE |
|
11 | QTCOMMERCIALCHART_BEGIN_NAMESPACE | |
10 |
|
12 | |||
@@ -18,25 +20,22 QPointF offset(qreal angle, qreal length) | |||||
18 | return QPointF(dx, -dy); |
|
20 | return QPointF(dx, -dy); | |
19 | } |
|
21 | } | |
20 |
|
22 | |||
21 | PieSlice::PieSlice(PiePresenter *presenter, int seriesIndex, qreal startAngle, qreal span) |
|
23 | PieSlice::PieSlice(QPieSliceId id, QPieSeries *series, QGraphicsItem* parent) | |
22 |
:QGraphics |
|
24 | :QGraphicsObject(parent), | |
23 | m_label(new QGraphicsTextItem(this)), |
|
25 | m_id(id), | |
24 |
m_series |
|
26 | m_series(series), | |
25 | m_startAngle(startAngle), |
|
27 | m_slicelabel(new PieSliceLabel(this)), | |
26 | m_span(span) |
|
28 | m_isHovering(false) | |
27 | { |
|
29 | { | |
28 |
Q_ASSERT( |
|
30 | Q_ASSERT(series); | |
29 | setAcceptHoverEvents(true); |
|
31 | setAcceptHoverEvents(true); | |
30 | setAcceptedMouseButtons(Qt::LeftButton); |
|
32 | setAcceptedMouseButtons(Qt::LeftButton); | |
31 |
update |
|
33 | updateData(); | |
32 |
|
||||
33 | // TODO: use themes |
|
|||
34 | m_pen = QPen(Qt::black); |
|
|||
35 | m_brush = QBrush(sliceData().m_color); |
|
|||
36 | } |
|
34 | } | |
37 |
|
35 | |||
38 | PieSlice::~PieSlice() |
|
36 | PieSlice::~PieSlice() | |
39 | { |
|
37 | { | |
|
38 | qDebug() << "~PieSlice()" << m_id; | |||
40 | } |
|
39 | } | |
41 |
|
40 | |||
42 | QRectF PieSlice::boundingRect() const |
|
41 | QRectF PieSlice::boundingRect() const | |
@@ -51,72 +50,86 QPainterPath PieSlice::shape() const | |||||
51 |
|
50 | |||
52 | void PieSlice::paint(QPainter* painter, const QStyleOptionGraphicsItem* /*option*/, QWidget* /*widget*/) |
|
51 | void PieSlice::paint(QPainter* painter, const QStyleOptionGraphicsItem* /*option*/, QWidget* /*widget*/) | |
53 | { |
|
52 | { | |
54 | painter->setRenderHint(QPainter::Antialiasing); |
|
53 | // set hover brush | |
|
54 | // TODO: what if we are using gradients... | |||
|
55 | QBrush brush = m_data.brush(); | |||
|
56 | if (m_isHovering) | |||
|
57 | brush.setColor(brush.color().lighter()); | |||
55 |
|
58 | |||
56 | // TODO: themes |
|
59 | painter->setRenderHint(QPainter::Antialiasing); | |
57 | painter->setPen(m_pen); |
|
60 | painter->setPen(m_data.pen()); | |
58 |
painter->setBrush( |
|
61 | painter->setBrush(brush); | |
59 | painter->drawPath(m_path); |
|
62 | painter->drawPath(m_path); | |
60 |
|
||||
61 | // Draw the label |
|
|||
62 | // TODO: do this better |
|
|||
63 | //QTextItem text; |
|
|||
64 | painter->drawText(m_center, sliceData().m_label); |
|
|||
65 | } |
|
63 | } | |
66 |
|
64 | |||
67 | void PieSlice::hoverEnterEvent(QGraphicsSceneHoverEvent* event) |
|
65 | void PieSlice::hoverEnterEvent(QGraphicsSceneHoverEvent* /*event*/) | |
68 | { |
|
66 | { | |
69 | m_brush = QBrush(sliceData().m_color.lighter()); |
|
67 | m_isHovering = true; | |
70 | update(); |
|
68 | update(); | |
|
69 | // TODO: emit hoverEnter() | |||
71 | } |
|
70 | } | |
72 |
|
71 | |||
73 | void PieSlice::hoverLeaveEvent(QGraphicsSceneHoverEvent* /*event*/) |
|
72 | void PieSlice::hoverLeaveEvent(QGraphicsSceneHoverEvent* /*event*/) | |
74 | { |
|
73 | { | |
75 | m_brush = QBrush(sliceData().m_color); |
|
74 | m_isHovering = false; | |
76 | update(); |
|
75 | update(); | |
|
76 | // TODO: emit hoverLeave() | |||
77 | } |
|
77 | } | |
78 |
|
78 | |||
79 | void PieSlice::mousePressEvent(QGraphicsSceneMouseEvent* /*event*/) |
|
79 | void PieSlice::mousePressEvent(QGraphicsSceneMouseEvent* /*event*/) | |
80 | { |
|
80 | { | |
81 | QPieSlice data = sliceData(); |
|
81 | // TODO: emit clicked | |
82 | data.m_isExploded = !data.m_isExploded; |
|
82 | // TODO: should we let the user decide if this can be exploded? | |
83 | (static_cast<PiePresenter*>(parentItem()))->m_pieSeries->update(m_seriesIndex, data); |
|
83 | m_data.setExploded(!m_data.isExploded()); | |
|
84 | m_series->update(m_data); | |||
84 | } |
|
85 | } | |
85 |
|
86 | |||
86 | void PieSlice::updateGeometry() |
|
87 | void PieSlice::updateGeometry(QRectF rect, qreal startAngle, qreal span) | |
87 | { |
|
88 | { | |
88 | prepareGeometryChange(); |
|
89 | prepareGeometryChange(); | |
89 |
|
90 | |||
90 | PiePresenter *presenter = static_cast<PiePresenter*>(parentItem()); |
|
91 | // calculate center angle | |
91 | QRectF rect = presenter->pieRect(); |
|
92 | qreal centerAngle = startAngle + (span/2); | |
92 | rect.adjust(EXPLODE_OFFSET, EXPLODE_OFFSET, -EXPLODE_OFFSET ,-EXPLODE_OFFSET); |
|
|||
93 |
|
93 | |||
94 | qreal centerAngle = m_startAngle + (m_span/2); |
|
94 | // adjust rect for exploding | |
95 |
|
95 | rect.adjust(EXPLODE_OFFSET, EXPLODE_OFFSET, -EXPLODE_OFFSET ,-EXPLODE_OFFSET); | ||
96 | if (presenter->m_pieSeries->slice(m_seriesIndex).m_isExploded) { |
|
96 | if (m_data.isExploded()) { | |
97 | QPointF d = offset((centerAngle), EXPLODE_OFFSET); |
|
97 | QPointF d = offset((centerAngle), EXPLODE_OFFSET); | |
98 | rect.translate(d.x(), d.y()); |
|
98 | rect.translate(d.x(), d.y()); | |
99 | } |
|
99 | } | |
100 |
|
100 | |||
101 | qreal angle = (-m_startAngle) + (90); |
|
101 | // update slice path | |
102 | qreal span = -m_span; |
|
102 | // TODO: draw the shape so that it might have a hole in the center | |
103 |
|
||||
104 | QPainterPath path; |
|
103 | QPainterPath path; | |
105 | path.moveTo(rect.center()); |
|
104 | path.moveTo(rect.center()); | |
106 | path.arcTo(rect, angle, span); |
|
105 | path.arcTo(rect, -startAngle + 90, -span); | |
107 |
|
||||
108 | // TODO: draw the shape so that it might have a hole in the center |
|
|||
109 |
|
||||
110 | m_path = path; |
|
106 | m_path = path; | |
111 | m_rect = path.boundingRect(); |
|
107 | m_rect = path.boundingRect(); | |
112 |
|
108 | |||
|
109 | // update label position | |||
113 | qreal radius = rect.height() / 2; |
|
110 | qreal radius = rect.height() / 2; | |
114 |
|
|
111 | QPointF edgeCenter = rect.center() + offset(centerAngle, radius + 5); | |
|
112 | m_slicelabel->updateGeometry(edgeCenter, centerAngle, 50); | |||
|
113 | ||||
|
114 | //qDebug() << "PieSlice::updateGeometry" << m_rect; | |||
115 | } |
|
115 | } | |
116 |
|
116 | |||
117 |
|
|
117 | void PieSlice::updateData() | |
118 | { |
|
118 | { | |
119 | return (static_cast<PiePresenter*>(parentItem()))->m_pieSeries->slice(m_seriesIndex); |
|
119 | if (!m_series->m_slices.contains(m_id)) | |
|
120 | qWarning() << "PieSlice::updateData(): cannot find slice data!" << m_id; | |||
|
121 | ||||
|
122 | QPieSlice data = m_series->slice(m_id); | |||
|
123 | // TODO: find out what has changed and trigger some animation | |||
|
124 | m_data = data; | |||
|
125 | ||||
|
126 | update(); | |||
|
127 | ||||
|
128 | m_slicelabel->setLabel(m_data.label()); | |||
|
129 | m_slicelabel->setVisible(m_data.isLabelVisible()); | |||
|
130 | m_slicelabel->update(); | |||
120 | } |
|
131 | } | |
121 |
|
132 | |||
|
133 | #include "moc_pieslice.cpp" | |||
|
134 | ||||
122 | QTCOMMERCIALCHART_END_NAMESPACE |
|
135 | QTCOMMERCIALCHART_END_NAMESPACE |
@@ -11,11 +11,14 | |||||
11 |
|
11 | |||
12 | QTCOMMERCIALCHART_BEGIN_NAMESPACE |
|
12 | QTCOMMERCIALCHART_BEGIN_NAMESPACE | |
13 | class PiePresenter; |
|
13 | class PiePresenter; | |
|
14 | class PieSliceLabel; | |||
14 |
|
15 | |||
15 |
class PieSlice : public QGraphics |
|
16 | class PieSlice : public QGraphicsObject | |
16 | { |
|
17 | { | |
|
18 | Q_OBJECT | |||
|
19 | ||||
17 | public: |
|
20 | public: | |
18 | PieSlice(PiePresenter *piePresenter, int seriesIndex, qreal startAngle, qreal span); |
|
21 | PieSlice(QPieSliceId id, QPieSeries *series, QGraphicsItem* parent = 0); | |
19 | ~PieSlice(); |
|
22 | ~PieSlice(); | |
20 |
|
23 | |||
21 | public: // from QGraphicsItem |
|
24 | public: // from QGraphicsItem | |
@@ -26,22 +29,21 public: // from QGraphicsItem | |||||
26 | void hoverLeaveEvent(QGraphicsSceneHoverEvent *event); |
|
29 | void hoverLeaveEvent(QGraphicsSceneHoverEvent *event); | |
27 | void mousePressEvent(QGraphicsSceneMouseEvent *event); |
|
30 | void mousePressEvent(QGraphicsSceneMouseEvent *event); | |
28 |
|
31 | |||
29 | public: |
|
32 | Q_SIGNALS: | |
30 | void updateGeometry(); |
|
33 | void clicked(); | |
31 |
|
34 | |||
32 | private: |
|
35 | public: | |
33 | QPieSlice sliceData(); |
|
36 | void updateGeometry(QRectF rect, qreal startAngle, qreal span); | |
|
37 | void updateData(); | |||
34 |
|
38 | |||
35 | private: |
|
39 | private: | |
36 | QGraphicsTextItem* m_label; |
|
40 | QPieSliceId m_id; | |
37 |
|
|
41 | QPieSeries* m_series; | |
38 | qreal m_startAngle; |
|
42 | QPieSlice m_data; | |
39 | qreal m_span; |
|
43 | PieSliceLabel* m_slicelabel; | |
40 | QPainterPath m_path; |
|
44 | QPainterPath m_path; | |
41 | QRectF m_rect; |
|
45 | QRectF m_rect; | |
42 | QPointF m_center; |
|
46 | bool m_isHovering; | |
43 | QPen m_pen; |
|
|||
44 | QBrush m_brush; |
|
|||
45 | }; |
|
47 | }; | |
46 |
|
48 | |||
47 | QTCOMMERCIALCHART_END_NAMESPACE |
|
49 | QTCOMMERCIALCHART_END_NAMESPACE |
@@ -8,7 +8,8 QTCOMMERCIALCHART_BEGIN_NAMESPACE | |||||
8 | QPieSeries::QPieSeries(QObject *parent) : |
|
8 | QPieSeries::QPieSeries(QObject *parent) : | |
9 | QChartSeries(parent), |
|
9 | QChartSeries(parent), | |
10 | m_sizeFactor(1.0), |
|
10 | m_sizeFactor(1.0), | |
11 | m_position(PiePositionMaximized) |
|
11 | m_position(PiePositionMaximized), | |
|
12 | m_sliceIdSeed(0) | |||
12 | { |
|
13 | { | |
13 | } |
|
14 | } | |
14 |
|
15 | |||
@@ -19,70 +20,93 QPieSeries::~QPieSeries() | |||||
19 |
|
20 | |||
20 | bool QPieSeries::setData(QList<qreal> data) |
|
21 | bool QPieSeries::setData(QList<qreal> data) | |
21 | { |
|
22 | { | |
|
23 | // TODO: remove this function | |||
22 | QList<QPieSlice> slices; |
|
24 | QList<QPieSlice> slices; | |
23 | foreach (int value, data) |
|
25 | foreach (int value, data) | |
24 | slices << QPieSlice(value, QString::number(value)); |
|
26 | slices << QPieSlice(value, QString::number(value)); | |
25 | return set(slices); |
|
27 | return set(slices); | |
26 | } |
|
28 | } | |
27 |
|
29 | |||
28 | bool QPieSeries::set(QList<QPieSlice> slices) |
|
30 | bool QPieSeries::set(const QList<QPieSlice>& slices) | |
29 | { |
|
31 | { | |
30 | if (!slices.count()) |
|
32 | if (!slices.count()) | |
31 | return false; |
|
33 | return false; | |
32 |
|
34 | |||
33 |
|
|
35 | ChangeSet changeSet; | |
34 |
|
36 | |||
35 | for (int i=slices.count(); i<m_slices.count(); i++) |
|
37 | foreach (QPieSlice s, m_slices.values()) | |
36 | changeSet.m_removed << i; |
|
38 | changeSet.m_removed << s.id(); | |
37 |
|
39 | |||
38 | for (int i=0; i<slices.count(); i++) { |
|
40 | m_slices.clear(); | |
39 | if (i < m_slices.count()) |
|
41 | ||
40 | changeSet.m_changed << i; |
|
42 | foreach (QPieSlice s, slices) { | |
41 | else |
|
43 | s.m_id = generateSliceId(); | |
42 | changeSet.m_added << i; |
|
44 | m_slices.insert(s.id(), s); | |
|
45 | changeSet.m_added << s.id(); | |||
43 | } |
|
46 | } | |
44 |
|
47 | |||
45 | m_slices = slices; |
|
48 | updateDerivativeData(); | |
46 | emit changed(changeSet); |
|
49 | emit changed(changeSet); | |
|
50 | ||||
47 | return true; |
|
51 | return true; | |
48 | } |
|
52 | } | |
49 |
|
53 | |||
50 | bool QPieSeries::add(QList<QPieSlice> slices) |
|
54 | bool QPieSeries::add(const QList<QPieSlice>& slices) | |
51 | { |
|
55 | { | |
52 | if (!slices.count()) |
|
56 | if (!slices.count()) | |
53 | return false; |
|
57 | return false; | |
54 |
|
58 | |||
55 |
|
|
59 | ChangeSet changeSet; | |
56 | for (int i=0; i<slices.count(); i++) |
|
60 | foreach (QPieSlice s, slices) { | |
57 | changeSet.m_added << m_slices.count() + i; |
|
61 | s.m_id = generateSliceId(); | |
|
62 | m_slices.insert(s.id(), s); | |||
|
63 | changeSet.m_added << s.id(); | |||
|
64 | } | |||
58 |
|
65 | |||
59 | m_slices += slices; |
|
66 | updateDerivativeData(); | |
60 | emit changed(changeSet); |
|
67 | emit changed(changeSet); | |
|
68 | ||||
61 | return true; |
|
69 | return true; | |
62 | } |
|
70 | } | |
63 |
|
71 | |||
64 | bool QPieSeries::add(QPieSlice slice) |
|
72 | bool QPieSeries::add(const QPieSlice& slice) | |
65 | { |
|
73 | { | |
66 | return add(QList<QPieSlice>() << slice); |
|
74 | return add(QList<QPieSlice>() << slice); | |
67 | } |
|
75 | } | |
68 |
|
76 | |||
69 | QPieSlice QPieSeries::slice(int index) const |
|
77 | bool QPieSeries::update(const QPieSlice& slice) | |
70 | { |
|
78 | { | |
71 | if ((index >= 0) && (index < m_slices.count())) |
|
79 | if (!m_slices.contains(slice.id())) | |
72 | return m_slices.at(index); |
|
80 | return false; // series does not contain this slice | |
73 | return QPieSlice(); |
|
81 | ||
|
82 | m_slices[slice.id()] = slice; | |||
|
83 | ||||
|
84 | ChangeSet changeSet; | |||
|
85 | changeSet.m_changed << slice.id(); | |||
|
86 | updateDerivativeData(); | |||
|
87 | emit changed(changeSet); | |||
|
88 | ||||
|
89 | return true; | |||
74 | } |
|
90 | } | |
75 |
|
91 | |||
76 |
bool QPieSeries:: |
|
92 | bool QPieSeries::remove(QPieSliceId id) | |
77 | { |
|
93 | { | |
78 | if ((index >= 0) && (index < m_slices.count())) { |
|
94 | if (!m_slices.contains(id)) | |
79 | m_slices[index] = slice; |
|
95 | return false; // series does not contain this slice | |
80 | PieChangeSet changeSet; |
|
96 | ||
81 | changeSet.m_changed << index; |
|
97 | m_slices.remove(id); | |
82 | emit changed(changeSet); |
|
98 | ||
83 | return true; |
|
99 | ChangeSet changeSet; | |
84 | } |
|
100 | changeSet.m_removed << id; | |
85 | return false; |
|
101 | updateDerivativeData(); | |
|
102 | emit changed(changeSet); | |||
|
103 | ||||
|
104 | return true; | |||
|
105 | } | |||
|
106 | ||||
|
107 | QPieSlice QPieSeries::slice(QPieSliceId id) const | |||
|
108 | { | |||
|
109 | return m_slices.value(id); | |||
86 | } |
|
110 | } | |
87 |
|
111 | |||
88 | void QPieSeries::setSizeFactor(qreal factor) |
|
112 | void QPieSeries::setSizeFactor(qreal factor) | |
@@ -104,6 +128,25 void QPieSeries::setPosition(PiePosition position) | |||||
104 | } |
|
128 | } | |
105 | } |
|
129 | } | |
106 |
|
130 | |||
|
131 | QPieSliceId QPieSeries::generateSliceId() | |||
|
132 | { | |||
|
133 | // Id is quint64 so it should be enough for us. | |||
|
134 | // Note that id is not unique between pie series. | |||
|
135 | return m_sliceIdSeed++; | |||
|
136 | } | |||
|
137 | ||||
|
138 | void QPieSeries::updateDerivativeData() | |||
|
139 | { | |||
|
140 | m_total = 0; | |||
|
141 | foreach (const QPieSlice& s, m_slices.values()) | |||
|
142 | m_total += s.value(); | |||
|
143 | ||||
|
144 | Q_ASSERT(m_total > 0); // TODO: remove this before release | |||
|
145 | ||||
|
146 | foreach (QPieSliceId id, m_slices.keys()) | |||
|
147 | m_slices[id].m_percentage = m_slices.value(id).value() / m_total; | |||
|
148 | } | |||
|
149 | ||||
107 | #include "moc_qpieseries.cpp" |
|
150 | #include "moc_qpieseries.cpp" | |
108 |
|
151 | |||
109 | QTCOMMERCIALCHART_END_NAMESPACE |
|
152 | QTCOMMERCIALCHART_END_NAMESPACE |
@@ -5,33 +5,62 | |||||
5 | #include <QObject> |
|
5 | #include <QObject> | |
6 | #include <QRectF> |
|
6 | #include <QRectF> | |
7 | #include <QColor> |
|
7 | #include <QColor> | |
|
8 | #include <QPen> | |||
|
9 | #include <QBrush> | |||
8 |
|
10 | |||
9 | class QGraphicsObject; |
|
11 | class QGraphicsObject; | |
10 | QTCOMMERCIALCHART_BEGIN_NAMESPACE |
|
12 | QTCOMMERCIALCHART_BEGIN_NAMESPACE | |
11 | class PiePresenter; |
|
13 | class PiePresenter; | |
12 | class PieSlice; |
|
14 | class PieSlice; | |
13 |
|
15 | |||
|
16 | typedef quint64 QPieSliceId; | |||
|
17 | ||||
14 | class QPieSlice |
|
18 | class QPieSlice | |
15 | { |
|
19 | { | |
16 | public: |
|
20 | public: | |
17 | QPieSlice() |
|
21 | QPieSlice() | |
18 | :m_value(0), m_label("<empty>"), m_color(QColor::Invalid), m_isExploded(false) {} |
|
22 | :m_id(-1), m_value(0), m_isLabelVisible(true), m_isExploded(false), m_percentage(0) {} | |
19 |
|
23 | |||
20 |
QPieSlice(qreal value, QString label = |
|
24 | QPieSlice(qreal value, QString label = QString(), bool labelVisible = true, bool exploded = false, QPen pen = QPen(), QBrush brush = QBrush()) | |
21 |
:m_value(value), m_label(label), m_ |
|
25 | :m_id(-1), m_value(value), m_label(label), m_isLabelVisible(labelVisible), m_isExploded(exploded), m_pen(pen), m_brush(brush), m_percentage(0) {} | |
22 | public: |
|
26 | ||
|
27 | QPieSliceId id() const { return m_id; } | |||
|
28 | ||||
|
29 | void setValue(qreal value) { m_value = value; } | |||
|
30 | qreal value() const { return m_value; } | |||
|
31 | ||||
|
32 | void setLabel(QString label) { m_label = label; } | |||
|
33 | QString label() const { return m_label; } | |||
|
34 | ||||
|
35 | void setLabelVisible(bool visible) { m_isLabelVisible = visible; } | |||
|
36 | bool isLabelVisible() const { return m_isLabelVisible; } | |||
|
37 | ||||
|
38 | void setExploded(bool exploded) { m_isExploded = exploded; } | |||
|
39 | bool isExploded() const { return m_isExploded; } | |||
|
40 | ||||
|
41 | void setPen(QPen pen) { m_pen = pen; } | |||
|
42 | QPen pen() const { return m_pen; } | |||
|
43 | ||||
|
44 | void setBrush(QBrush brush) { m_brush = brush; } | |||
|
45 | QBrush brush() const { return m_brush; } | |||
|
46 | ||||
|
47 | qreal percentage() const { return m_percentage; } | |||
|
48 | ||||
|
49 | private: | |||
|
50 | ||||
|
51 | // TODO: use private class | |||
|
52 | friend class QPieSeries; | |||
|
53 | ||||
|
54 | QPieSliceId m_id; | |||
23 | qreal m_value; |
|
55 | qreal m_value; | |
24 | QString m_label; |
|
56 | QString m_label; | |
25 | QColor m_color; // TODO: should we even define color here? |
|
57 | bool m_isLabelVisible; | |
26 | bool m_isExploded; |
|
58 | bool m_isExploded; | |
27 | }; |
|
|||
28 |
|
59 | |||
29 | class PieChangeSet |
|
60 | QPen m_pen; | |
30 | { |
|
61 | QBrush m_brush; | |
31 | public: |
|
62 | ||
32 | QList<int> m_added; |
|
63 | qreal m_percentage; // generated content | |
33 | QList<int> m_removed; |
|
|||
34 | QList<int> m_changed; |
|
|||
35 | }; |
|
64 | }; | |
36 |
|
65 | |||
37 | class QTCOMMERCIALCHART_EXPORT QPieSeries : public QChartSeries |
|
66 | class QTCOMMERCIALCHART_EXPORT QPieSeries : public QChartSeries | |
@@ -47,24 +76,38 public: | |||||
47 | PiePositionBottomRight |
|
76 | PiePositionBottomRight | |
48 | }; |
|
77 | }; | |
49 |
|
78 | |||
|
79 | class ChangeSet | |||
|
80 | { | |||
|
81 | public: | |||
|
82 | QList<QPieSliceId> m_added; | |||
|
83 | QList<QPieSliceId> m_removed; | |||
|
84 | QList<QPieSliceId> m_changed; | |||
|
85 | }; | |||
|
86 | ||||
50 | public: |
|
87 | public: | |
51 | QPieSeries(QObject *parent = 0); |
|
88 | QPieSeries(QObject *parent = 0); | |
52 | ~QPieSeries(); |
|
89 | ~QPieSeries(); | |
53 |
|
90 | |||
54 | public: // from QChartSeries |
|
91 | public: // from QChartSeries | |
55 | QChartSeriesType type() const { return QChartSeries::SeriesTypePie; } |
|
92 | QChartSeriesType type() const { return QChartSeries::SeriesTypePie; } | |
56 | virtual bool setData(QList<qreal> data); |
|
93 | virtual bool setData(QList<qreal> data); // TODO: remove this | |
57 |
|
94 | |||
58 | public: |
|
95 | public: | |
59 | bool set(QList<QPieSlice> slices); |
|
96 | // TODO: should we return id/bool or what? | |
60 | bool add(QList<QPieSlice> slices); |
|
97 | // TODO: should we prefer passing a modifiable reference? | |
61 |
bool |
|
98 | bool set(const QList<QPieSlice>& slices); | |
|
99 | bool add(const QList<QPieSlice>& slices); | |||
|
100 | bool add(const QPieSlice& slice); | |||
|
101 | bool update(const QPieSlice& slice); | |||
|
102 | bool remove(QPieSliceId id); | |||
62 |
|
103 | |||
63 | int count() const { return m_slices.count(); } |
|
104 | int count() const { return m_slices.count(); } | |
64 |
|
105 | |||
65 | QList<QPieSlice> slices() const { return m_slices; } |
|
106 | QList<QPieSlice> slices() const { return m_slices.values(); } | |
66 | QPieSlice slice(int index) const; |
|
107 | QList<QPieSliceId> ids() const { return m_slices.keys(); } | |
67 | bool update(int index, QPieSlice slice); |
|
108 | QPieSlice slice(QPieSliceId id) const; | |
|
109 | ||||
|
110 | // TODO: sorting? | |||
68 |
|
111 | |||
69 | // TODO: convenience functions |
|
112 | // TODO: convenience functions | |
70 | //void updateValue(int sliceIndex, qreal value); |
|
113 | //void updateValue(int sliceIndex, qreal value); | |
@@ -72,6 +115,11 public: | |||||
72 | //void updateColor(int sliceIndex, QColor color); |
|
115 | //void updateColor(int sliceIndex, QColor color); | |
73 | //void updateExploded(int slizeIndex, bool exploded); |
|
116 | //void updateExploded(int slizeIndex, bool exploded); | |
74 |
|
117 | |||
|
118 | // TODO: customization | |||
|
119 | // set/get pen/brush | |||
|
120 | // - for label | |||
|
121 | // - for whole pie/slice | |||
|
122 | ||||
75 | void setSizeFactor(qreal sizeFactor); |
|
123 | void setSizeFactor(qreal sizeFactor); | |
76 | qreal sizeFactor() const { return m_sizeFactor; } |
|
124 | qreal sizeFactor() const { return m_sizeFactor; } | |
77 |
|
125 | |||
@@ -79,17 +127,29 public: | |||||
79 | PiePosition position() const { return m_position; } |
|
127 | PiePosition position() const { return m_position; } | |
80 |
|
128 | |||
81 | Q_SIGNALS: |
|
129 | Q_SIGNALS: | |
82 | void changed(const PieChangeSet& changeSet); |
|
130 | void changed(const QPieSeries::ChangeSet& changeSet); | |
83 | void sizeFactorChanged(); |
|
131 | void sizeFactorChanged(); | |
84 | void positionChanged(); |
|
132 | void positionChanged(); | |
|
133 | //void sliceClicked(QPieSliceId id); | |||
|
134 | //void sliceHoverEnter(QPieSliceId id); | |||
|
135 | //void sliceHoverLeave(QPieSliceId id); | |||
|
136 | ||||
|
137 | private: | |||
|
138 | QPieSliceId generateSliceId(); | |||
|
139 | void updateDerivativeData(); | |||
85 |
|
140 | |||
86 | private: |
|
141 | private: | |
87 | Q_DISABLE_COPY(QPieSeries) |
|
142 | Q_DISABLE_COPY(QPieSeries) | |
88 | friend class PiePresenter; |
|
143 | ||
89 | // TODO: use PIML |
|
144 | // TODO: use PIML | |
90 | QList<QPieSlice> m_slices; |
|
145 | friend class PiePresenter; | |
|
146 | friend class PieSlice; | |||
|
147 | ||||
|
148 | QHash<QPieSliceId, QPieSlice> m_slices; | |||
91 | qreal m_sizeFactor; |
|
149 | qreal m_sizeFactor; | |
92 | PiePosition m_position; |
|
150 | PiePosition m_position; | |
|
151 | qreal m_total; | |||
|
152 | QPieSliceId m_sliceIdSeed; | |||
93 | }; |
|
153 | }; | |
94 |
|
154 | |||
95 | QTCOMMERCIALCHART_END_NAMESPACE |
|
155 | QTCOMMERCIALCHART_END_NAMESPACE |
General Comments 0
You need to be logged in to leave comments.
Login now