##// END OF EJS Templates
Introducing vertical and horizontal factors to control the position of the pie.
Jani Honkonen -
r454:06980850b7dd
parent child
Show More
@@ -14,8 +14,6
14 14
15 15 QTCOMMERCIALCHART_USE_NAMESPACE
16 16
17 Q_DECLARE_METATYPE(QPieSeries::PiePosition)
18
19 17 class CustomSlice : public QPieSlice
20 18 {
21 19 Q_OBJECT
@@ -52,11 +50,13 class MainWidget : public QWidget
52 50
53 51 public:
54 52 explicit MainWidget(QWidget* parent = 0)
55 :QWidget(parent)
53 :QWidget(parent),
54 m_slice(0)
56 55 {
57 56 m_chartView = new QChartView();
58 57 m_chartView->setChartTitle("Piechart customization");
59 //m_chartView->setRenderHint(QPainter::Antialiasing);
58 m_chartView->setRenderHint(QPainter::Antialiasing);
59 m_chartView->setChartTheme(QChart::ChartThemeIcy);
60 60
61 61 m_series = new QPieSeries();
62 62 *m_series << new CustomSlice(10.0, "Slice 1");
@@ -66,27 +66,23 public:
66 66 *m_series << new CustomSlice(50.0, "Slice 5");
67 67 m_chartView->addSeries(m_series);
68 68
69 m_vPosition = new QComboBox();
70 m_vPosition->addItem("Top", QPieSeries::PiePositionTop);
71 m_vPosition->addItem("Bottom", QPieSeries::PiePositionBottom);
72 m_vPosition->addItem("Center", QPieSeries::PiePositionVCenter);
73
74 m_hPosition = new QComboBox();
75 m_hPosition->addItem("Left", QPieSeries::PiePositionLeft);
76 m_hPosition->addItem("Right", QPieSeries::PiePositionRight);
77 m_hPosition->addItem("Center", QPieSeries::PiePositionHCenter);
69 m_hPosition = new QDoubleSpinBox();
70 m_hPosition->setMinimum(0.0);
71 m_hPosition->setMaximum(1.0);
72 m_hPosition->setSingleStep(0.1);
73 m_hPosition->setValue(m_series->horizontalPositionFactor());
78 74
79 m_sizePolicy = new QComboBox();
80 m_sizePolicy->addItem("Maximized", QPieSeries::PieSizePolicyMaximized);
81 m_sizePolicy->addItem("Space for labels", QPieSeries::PieSizePolicyReserveSpaceForLabels);
82 m_sizePolicy->addItem("Space for exploding", QPieSeries::PieSizePolicyReserveSpaceForExploding);
83 m_sizePolicy->addItem("Space for all", QPieSeries::PieSizePolicyReserveSpaceForAll);
75 m_vPosition = new QDoubleSpinBox();
76 m_vPosition->setMinimum(0.0);
77 m_vPosition->setMaximum(1.0);
78 m_vPosition->setSingleStep(0.1);
79 m_vPosition->setValue(m_series->verticalPositionFactor());
84 80
85 81 m_sizeFactor = new QDoubleSpinBox();
86 82 m_sizeFactor->setMinimum(0.0);
87 83 m_sizeFactor->setMaximum(1.0);
88 m_sizeFactor->setValue(m_series->sizeFactor());
89 84 m_sizeFactor->setSingleStep(0.1);
85 m_sizeFactor->setValue(m_series->sizeFactor());
90 86
91 87 m_startAngle = new QDoubleSpinBox();
92 88 m_startAngle->setMinimum(0.0);
@@ -101,9 +97,8 public:
101 97 m_endAngle->setSingleStep(1);
102 98
103 99 QFormLayout* seriesSettingsLayout = new QFormLayout();
104 seriesSettingsLayout->addRow("Vertical position", m_vPosition);
105 100 seriesSettingsLayout->addRow("Horizontal position", m_hPosition);
106 seriesSettingsLayout->addRow("Size policy", m_sizePolicy);
101 seriesSettingsLayout->addRow("Vertical position", m_vPosition);
107 102 seriesSettingsLayout->addRow("Size factor", m_sizeFactor);
108 103 seriesSettingsLayout->addRow("Start angle", m_startAngle);
109 104 seriesSettingsLayout->addRow("End angle", m_endAngle);
@@ -114,13 +109,20 public:
114 109 m_sliceValue = new QDoubleSpinBox();
115 110 m_sliceValue->setMaximum(1000);
116 111 m_sliceLabelVisible = new QCheckBox();
112 m_sliceLabelArmFactor = new QDoubleSpinBox();
113 m_sliceLabelArmFactor->setSingleStep(0.01);
117 114 m_sliceExploded = new QCheckBox();
115 m_sliceExplodedFactor = new QDoubleSpinBox();
116 m_sliceExplodedFactor->setSingleStep(0.01);
118 117
119 118 QFormLayout* sliceSettingsLayout = new QFormLayout();
120 119 sliceSettingsLayout->addRow("Selected", m_sliceName);
121 120 sliceSettingsLayout->addRow("Value", m_sliceValue);
122 121 sliceSettingsLayout->addRow("Label visible", m_sliceLabelVisible);
122 sliceSettingsLayout->addRow("Label arm length", m_sliceLabelArmFactor);
123 123 sliceSettingsLayout->addRow("Exploded", m_sliceExploded);
124 sliceSettingsLayout->addRow("Explode distance", m_sliceExplodedFactor);
125
124 126 QGroupBox* sliceSettings = new QGroupBox("Slice");
125 127 sliceSettings->setLayout(sliceSettingsLayout);
126 128
@@ -130,16 +132,17 public:
130 132 baseLayout->addWidget(m_chartView, 0, 1, 2, 1);
131 133 setLayout(baseLayout);
132 134
133 connect(m_vPosition, SIGNAL(currentIndexChanged(int)), this, SLOT(updateSerieSettings()));
134 connect(m_hPosition, SIGNAL(currentIndexChanged(int)), this, SLOT(updateSerieSettings()));
135 connect(m_sizePolicy, SIGNAL(currentIndexChanged(int)), this, SLOT(updateSerieSettings()));
135 connect(m_vPosition, SIGNAL(valueChanged(double)), this, SLOT(updateSerieSettings()));
136 connect(m_hPosition, SIGNAL(valueChanged(double)), this, SLOT(updateSerieSettings()));
136 137 connect(m_sizeFactor, SIGNAL(valueChanged(double)), this, SLOT(updateSerieSettings()));
137 138 connect(m_startAngle, SIGNAL(valueChanged(double)), this, SLOT(updateSerieSettings()));
138 139 connect(m_endAngle, SIGNAL(valueChanged(double)), this, SLOT(updateSerieSettings()));
139 140
140 141 connect(m_sliceValue, SIGNAL(valueChanged(double)), this, SLOT(updateSliceSettings()));
141 142 connect(m_sliceLabelVisible, SIGNAL(toggled(bool)), this, SLOT(updateSliceSettings()));
143 connect(m_sliceLabelArmFactor, SIGNAL(valueChanged(double)), this, SLOT(updateSliceSettings()));
142 144 connect(m_sliceExploded, SIGNAL(toggled(bool)), this, SLOT(updateSliceSettings()));
145 connect(m_sliceExplodedFactor, SIGNAL(valueChanged(double)), this, SLOT(updateSliceSettings()));
143 146
144 147 connect(m_series, SIGNAL(clicked(QPieSlice*)), this, SLOT(handleSliceClicked(QPieSlice*)));
145 148
@@ -150,12 +153,7 public Q_SLOTS:
150 153
151 154 void updateSerieSettings()
152 155 {
153 QPieSeries::PiePosition vPos(m_vPosition->itemData(m_vPosition->currentIndex()).toInt());
154 QPieSeries::PiePosition hPos(m_hPosition->itemData(m_hPosition->currentIndex()).toInt());
155 m_series->setPosition(vPos | hPos);
156
157 QPieSeries::PieSizePolicy policy(m_sizePolicy->itemData(m_sizePolicy->currentIndex()).toInt());
158 m_series->setSizePolicy(policy);
156 m_series->setPositionFactors(m_vPosition->value(), m_hPosition->value());
159 157
160 158 m_series->setSizeFactor(m_sizeFactor->value());
161 159
@@ -165,9 +163,14 public Q_SLOTS:
165 163
166 164 void updateSliceSettings()
167 165 {
166 if (!m_slice)
167 return;
168
168 169 m_slice->setValue(m_sliceValue->value());
169 170 m_slice->setLabelVisible(m_sliceLabelVisible->isChecked());
171 m_slice->setLabelArmLengthFactor(m_sliceLabelArmFactor->value());
170 172 m_slice->setExploded(m_sliceExploded->isChecked());
173 m_slice->setExplodeDistanceFactor(m_sliceExplodedFactor->value());
171 174 }
172 175
173 176 void handleSliceClicked(QPieSlice* slice)
@@ -183,9 +186,17 public Q_SLOTS:
183 186 m_sliceLabelVisible->setChecked(slice->isLabelVisible());
184 187 m_sliceLabelVisible->blockSignals(false);
185 188
189 m_sliceLabelArmFactor->blockSignals(true);
190 m_sliceLabelArmFactor->setValue(slice->labelArmLengthFactor());
191 m_sliceLabelArmFactor->blockSignals(false);
192
186 193 m_sliceExploded->blockSignals(true);
187 194 m_sliceExploded->setChecked(slice->isExploded());
188 195 m_sliceExploded->blockSignals(false);
196
197 m_sliceExplodedFactor->blockSignals(true);
198 m_sliceExplodedFactor->setValue(slice->explodeDistanceFactor());
199 m_sliceExplodedFactor->blockSignals(false);
189 200 }
190 201
191 202 private:
@@ -193,9 +204,8 private:
193 204 QPieSeries* m_series;
194 205 QPieSlice* m_slice;
195 206
196 QComboBox* m_vPosition;
197 QComboBox* m_hPosition;
198 QComboBox* m_sizePolicy;
207 QDoubleSpinBox* m_hPosition;
208 QDoubleSpinBox* m_vPosition;
199 209 QDoubleSpinBox* m_sizeFactor;
200 210 QDoubleSpinBox* m_startAngle;
201 211 QDoubleSpinBox* m_endAngle;
@@ -203,7 +213,9 private:
203 213 QLabel* m_sliceName;
204 214 QDoubleSpinBox* m_sliceValue;
205 215 QCheckBox* m_sliceLabelVisible;
216 QDoubleSpinBox* m_sliceLabelArmFactor;
206 217 QCheckBox* m_sliceExploded;
218 QDoubleSpinBox* m_sliceExplodedFactor;
207 219 };
208 220
209 221 int main(int argc, char *argv[])
@@ -16,7 +16,6 PiePresenter::PiePresenter(QGraphicsItem *parent, QPieSeries *series)
16 16 connect(series, SIGNAL(changed(const QPieSeries::ChangeSet&)), this, SLOT(handleSeriesChanged(const QPieSeries::ChangeSet&)));
17 17 connect(series, SIGNAL(sizeFactorChanged()), this, SLOT(updateGeometry()));
18 18 connect(series, SIGNAL(positionChanged()), this, SLOT(updateGeometry()));
19 connect(series, SIGNAL(sizePolicyChanged()), this, SLOT(updateGeometry()));
20 19
21 20 if (m_series->count()) {
22 21 QPieSeries::ChangeSet changeSet;
@@ -75,113 +74,26 void PiePresenter::updateGeometry()
75 74 if (!m_rect.isValid() || m_rect.isEmpty())
76 75 return;
77 76
78 // calculate maximum rectangle for pie
79 QRectF pieRect = m_rect;
80 if (pieRect.width() < pieRect.height()) {
81 pieRect.setHeight(pieRect.width());
82 } else {
83 pieRect.setWidth(pieRect.height());
84 }
85
86 // position the pie rectangle
87 QPointF center = m_rect.center(); // default position is center
88 qreal dx = pieRect.width() / 2;
89 qreal dy = pieRect.height() / 2;
90 if (m_series->position() & QPieSeries::PiePositionLeft)
91 center.setX(m_rect.left() + dx);
92 if (m_series->position() & QPieSeries::PiePositionRight)
93 center.setX(m_rect.right() - dx);
94 if (m_series->position() & QPieSeries::PiePositionHCenter)
95 center.setX(m_rect.center().x());
96 if (m_series->position() & QPieSeries::PiePositionTop)
97 center.setY(m_rect.top() + dy);
98 if (m_series->position() & QPieSeries::PiePositionBottom)
99 center.setY(m_rect.bottom() - dy);
100 if (m_series->position() & QPieSeries::PiePositionVCenter)
101 center.setY(m_rect.center().y());
102 pieRect.moveCenter(center);
103
104 // calculate how much space we need around the pie rectangle (labels & exploding)
105 qreal delta = 0;
106 qreal pieRadius = pieRect.height() / 2;
107 foreach (QPieSlice* s, m_series->m_slices) {
108
109 bool exploded = s->isExploded();
110 if (m_series->sizePolicy() & QPieSeries::PieSizePolicyReserveSpaceForExploding)
111 exploded = true;
112
113 bool labelVisible = s->isLabelVisible();
114 if (m_series->sizePolicy() & QPieSeries::PieSizePolicyReserveSpaceForLabels)
115 labelVisible = true;
116
117 qreal centerAngle;
118 QPointF armStart;
119 QRectF sliceRect = PieSlice::slicePath(center, pieRadius, s->m_startAngle, s->m_angleSpan, exploded, s->explodeDistance(), &centerAngle, &armStart).boundingRect();
120
121 if (labelVisible) {
122 QRectF textRect = PieSlice::labelTextRect(s->labelFont(), s->label());
123 QPointF textStart;
124 QRectF armRect = PieSlice::labelArmPath(armStart, centerAngle, s->labelArmLength(), textRect.width(), &textStart).boundingRect();
125 textRect.moveBottomLeft(textStart);
126 sliceRect = sliceRect.united(armRect);
127 sliceRect = sliceRect.united(textRect);
128 }
129
130
131 qreal dt = m_rect.top() - sliceRect.top();
132 if (dt > delta)
133 delta = dt;
134 qreal dl = m_rect.left() - sliceRect.left();
135 if (dl > delta)
136 delta = dl;
137 qreal dr = sliceRect.right() - m_rect.right();
138 if (dr > delta)
139 delta = dr;
140 qreal db = sliceRect.bottom() - m_rect.bottom();
141 if (db > delta)
142 delta = db;
143
144 /*
145 if (s->label() == "Slice 5") {
146 m_debugRect = sliceRect;
147 qDebug() << "dt:" << dt << ", dl:" << dl << ", dr:" << dr << ", db:" << db << ", delta:" << delta;
148 }
149 */
150 }
151
152 // shrink the pie rectangle so that everything outside it fits the base rectangle
153 pieRect.adjust(delta, delta, -delta, -delta);
154
155 /*
156 // apply size factor (range 0.0 ... 1.0)
157 pieRect.setWidth(pieRect.width() * m_series->sizeFactor());
158 pieRect.setHeight(pieRect.height() * m_series->sizeFactor());
159
160 // position the pie rectangle (again)
161 center = m_rect.center(); // default position is center
162 dx = pieRect.width() / 2;
163 dy = pieRect.height() / 2;
164 if (m_series->position() & QPieSeries::PiePositionLeft)
165 center.setX(m_rect.left() + dx);
166 if (m_series->position() & QPieSeries::PiePositionRight)
167 center.setX(m_rect.right() - dx);
168 if (m_series->position() & QPieSeries::PiePositionHCenter)
169 center.setX(m_rect.center().x());
170 if (m_series->position() & QPieSeries::PiePositionTop)
171 center.setY(m_rect.top() + dy);
172 if (m_series->position() & QPieSeries::PiePositionBottom)
173 center.setY(m_rect.bottom() - dy);
174 if (m_series->position() & QPieSeries::PiePositionVCenter)
175 center.setY(m_rect.center().y());
176 pieRect.moveCenter(center);
177 */
77 // find pie center coordinates
78 QPointF center;
79 center.setX(m_rect.left() + (m_rect.width() * m_series->m_hPositionFactor));
80 center.setY(m_rect.top() + (m_rect.height() * m_series->m_vPositionFactor));
81
82 // find maximum radius for pie
83 qreal radius = m_rect.height() / 2;
84 if (m_rect.width() < m_rect.height())
85 radius = m_rect.width() / 2;
86
87 // apply size factor
88 radius *= m_series->m_pieSizeFactor;
178 89
179 90 // update slices
180 if (m_pieRect != pieRect) {
181 m_pieRect = pieRect;
182 //qDebug() << "PiePresenter::updateGeometry()" << m_rect << m_pieRect;
91 if (m_pieCenter != center || m_pieRadius != radius) {
92 m_pieCenter = center;
93 m_pieRadius = radius;
94 //qDebug() << "PiePresenter::updateGeometry()" << m_rect << m_pieCenter << m_pieRadius;
183 95 foreach (PieSlice* s, m_slices.values()) {
184 s->setPieRect(m_pieRect);
96 s->setPieCenterAndRadius(center, radius);
185 97 s->updateGeometry();
186 98 s->update();
187 99 }
@@ -201,7 +113,7 void PiePresenter::addSlice(QPieSlice* sliceData)
201 113
202 114 // create slice
203 115 PieSlice *slice = new PieSlice(this);
204 slice->setPieRect(m_pieRect);
116 slice->setPieCenterAndRadius(m_pieCenter, m_pieRadius);
205 117 slice->updateData(sliceData);
206 118 slice->updateGeometry();
207 119 slice->update();
@@ -9,8 +9,6 class QGraphicsItem;
9 9 QTCOMMERCIALCHART_BEGIN_NAMESPACE
10 10 class PieSlice;
11 11
12 #define PI 3.14159265 // TODO: is this defined in some header?
13
14 12 class PiePresenter : public QObject, public ChartItem
15 13 {
16 14 Q_OBJECT
@@ -24,9 +22,6 public: // from QGraphicsItem
24 22 QRectF boundingRect() const { return m_rect; }
25 23 void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *);
26 24
27 public:
28 QRectF pieRect() const { return m_pieRect; }
29
30 25 public Q_SLOTS:
31 26 void handleSeriesChanged(const QPieSeries::ChangeSet& changeSet);
32 27 void handleDomainChanged(const Domain& domain);
@@ -43,7 +38,8 private:
43 38 QHash<QPieSlice*, PieSlice*> m_slices;
44 39 QPieSeries *m_series;
45 40 QRectF m_rect;
46 QRectF m_pieRect;
41 QPointF m_pieCenter;
42 qreal m_pieRadius;
47 43 QRectF m_debugRect;
48 44 };
49 45
@@ -10,6 +10,8
10 10
11 11 QTCOMMERCIALCHART_BEGIN_NAMESPACE
12 12
13 #define PI 3.14159265 // TODO: is this defined in some header?
14
13 15 QPointF offset(qreal angle, qreal length)
14 16 {
15 17 qreal dx = qSin(angle*(PI/180)) * length;
@@ -19,11 +21,13 QPointF offset(qreal angle, qreal length)
19 21
20 22 PieSlice::PieSlice(QGraphicsItem* parent)
21 23 :QGraphicsObject(parent),
24 m_pieRadius(0),
22 25 m_startAngle(0),
23 26 m_angleSpan(0),
24 27 m_isExploded(false),
25 m_explodeDistance(0),
26 m_labelVisible(false)
28 m_explodeDistanceFactor(0),
29 m_labelVisible(false),
30 m_labelArmLengthFactor(0)
27 31 {
28 32 setAcceptHoverEvents(true);
29 33 setAcceptedMouseButtons(Qt::LeftButton);
@@ -41,11 +45,15 QRectF PieSlice::boundingRect() const
41 45
42 46 QPainterPath PieSlice::shape() const
43 47 {
48 // Don't include the label and label arm.
49 // This is used to detect a mouse clicks. We do not want clicks from label.
44 50 return m_slicePath;
45 51 }
46 52
47 53 void PieSlice::paint(QPainter* painter, const QStyleOptionGraphicsItem* /*option*/, QWidget* /*widget*/)
48 54 {
55 painter->setClipRect(parentItem()->boundingRect());
56
49 57 painter->save();
50 58 painter->setPen(m_pen);
51 59 painter->setBrush(m_brush);
@@ -78,36 +86,35 void PieSlice::mousePressEvent(QGraphicsSceneMouseEvent* /*event*/)
78 86 emit clicked();
79 87 }
80 88
81 void PieSlice::setPieRect(QRectF rect)
89 void PieSlice::setPieCenterAndRadius(QPointF center, qreal radius)
82 90 {
83 m_pieRect = rect;
91 m_pieCenter = center;
92 m_pieRadius = radius;
84 93 }
85 94
86 95 void PieSlice::updateGeometry()
87 96 {
88 if (!m_pieRect.isValid() || m_pieRect.isEmpty())
97 if (m_pieRadius <= 0)
89 98 return;
90 99
91 100 prepareGeometryChange();
92 101
93 102 // update slice path
94 QPointF center = m_pieRect.center();
95 qreal radius = m_pieRect.height() / 2;
96 103 qreal centerAngle;
97 104 QPointF armStart;
98 m_slicePath = slicePath(center, radius, m_startAngle, m_angleSpan, m_isExploded, m_explodeDistance, &centerAngle, &armStart);
105 m_slicePath = slicePath(m_pieCenter, m_pieRadius, m_startAngle, m_angleSpan, m_isExploded, m_pieRadius * m_explodeDistanceFactor, &centerAngle, &armStart);
99 106
100 107 // update text rect
101 108 m_labelTextRect = labelTextRect(m_labelFont, m_labelText);
102 109
103 110 // update label arm path
104 111 QPointF labelTextStart;
105 m_labelArmPath = labelArmPath(armStart, centerAngle, m_labelArmLength, m_labelTextRect.width(), &labelTextStart);
112 m_labelArmPath = labelArmPath(armStart, centerAngle, m_pieRadius * m_labelArmLengthFactor, m_labelTextRect.width(), &labelTextStart);
106 113
107 114 // update text position
108 115 m_labelTextRect.moveBottomLeft(labelTextStart);
109 116
110 //qDebug() << "PieSlice::updateGeometry" << m_slicelabel->text() << boundingRect() << m_angle << m_span;
117 //qDebug() << "PieSlice::updateGeometry" << m_labelText << boundingRect() << m_startAngle << m_startAngle + m_angleSpan;
111 118 }
112 119
113 120 void PieSlice::updateData(const QPieSlice* sliceData)
@@ -117,14 +124,14 void PieSlice::updateData(const QPieSlice* sliceData)
117 124 m_startAngle = sliceData->startAngle();
118 125 m_angleSpan = sliceData->m_angleSpan;
119 126 m_isExploded = sliceData->isExploded();
120 m_explodeDistance = sliceData->explodeDistance();
127 m_explodeDistanceFactor = sliceData->explodeDistanceFactor();
121 128 m_pen = sliceData->pen();
122 129 m_brush = sliceData->brush();
123 130
124 131 m_labelVisible = sliceData->isLabelVisible();
125 132 m_labelText = sliceData->label();
126 133 m_labelFont = sliceData->labelFont();
127 m_labelArmLength = sliceData->labelArmLength();
134 m_labelArmLengthFactor = sliceData->labelArmLengthFactor();
128 135 m_labelArmPen = sliceData->labelPen();
129 136
130 137 updateGeometry();
@@ -38,7 +38,7 Q_SIGNALS:
38 38 void hoverLeave();
39 39
40 40 public Q_SLOTS:
41 void setPieRect(QRectF rect);
41 void setPieCenterAndRadius(QPointF center, qreal radius);
42 42 void updateGeometry();
43 43 void updateData(const QPieSlice *sliceData);
44 44
@@ -48,19 +48,20 public:
48 48 static QRectF labelTextRect(QFont font, QString text);
49 49
50 50 private:
51 QRectF m_pieRect;
51 QPointF m_pieCenter;
52 qreal m_pieRadius;
52 53
53 54 QPainterPath m_slicePath;
54 55 qreal m_startAngle;
55 56 qreal m_angleSpan;
56 57 bool m_isExploded;
57 qreal m_explodeDistance;
58 qreal m_explodeDistanceFactor;
58 59 bool m_labelVisible;
59 60 QPen m_pen;
60 61 QBrush m_brush;
61 62
62 63 QPainterPath m_labelArmPath;
63 qreal m_labelArmLength;
64 qreal m_labelArmLengthFactor;
64 65 QPen m_labelArmPen;
65 66
66 67 QRectF m_labelTextRect;
@@ -89,18 +89,6 bool QPieSeries::ChangeSet::isEmpty() const
89 89 }
90 90
91 91 /*!
92 \enum QPieSeries::PiePosition
93
94 This enum describes pie position within its bounding rectangle
95
96 \value PiePositionMaximized
97 \value PiePositionTopLeft
98 \value PiePositionTopRight
99 \value PiePositionBottomLeft
100 \value PiePositionBottomRight
101 */
102
103 /*!
104 92 \class QPieSeries
105 93 \brief Pie series API for QtCommercial Charts
106 94
@@ -117,11 +105,12 bool QPieSeries::ChangeSet::isEmpty() const
117 105 */
118 106 QPieSeries::QPieSeries(QObject *parent) :
119 107 QSeries(parent),
120 m_sizeFactor(1.0),
121 m_position(PiePositionCenter),
122 m_sizePolicy(PieSizePolicyMaximized),
108 m_hPositionFactor(0.5),
109 m_vPositionFactor(0.5),
110 m_pieSizeFactor(0.7),
123 111 m_pieStartAngle(0),
124 m_pieEndAngle(360)
112 m_pieEndAngle(360),
113 m_total(0)
125 114 {
126 115
127 116 }
@@ -265,76 +254,109 QList<QPieSlice*> QPieSeries::slices() const
265 254 }
266 255
267 256 /*!
268 Sets the size \a factor of the pie. 1.0 is the default value.
269 Note that the pie will not grow beyond its absolute maximum size.
270 In practice its use is to make the pie appear smaller.
271 \sa sizeFactor()
257 Sets the center position of the pie by \a horizontalFactor and \a verticalFactor.
258
259 The factors are relative to the chart rectangle where:
260
261 \a horizontalFactor 0.0 means the absolute left.
262 \a horizontalFactor 1.0 means the absolute right.
263 \a verticalFactor 0.0 means the absolute top.
264 \a verticalFactor 1.0 means the absolute bottom.
265
266 By default \a horizontalFactor and \a verticalFactor are 0.5 which puts the pie in the middle of the chart rectangle.
267
268 \sa horizontalPositionFactor(), verticalPositionFactor(), setSizeFactor()
272 269 */
273 void QPieSeries::setSizeFactor(qreal factor)
270 void QPieSeries::setPositionFactors(qreal horizontalFactor, qreal verticalFactor)
274 271 {
275 if (factor < 0.0)
272 if (horizontalFactor < 0.0 || horizontalFactor > 1.0 || verticalFactor < 0.0 || verticalFactor > 1.0)
276 273 return;
277 274
278 if (m_sizeFactor != factor) {
279 m_sizeFactor = factor;
280 emit sizeFactorChanged();
275 if (m_hPositionFactor != horizontalFactor || m_vPositionFactor != verticalFactor) {
276 m_hPositionFactor = horizontalFactor;
277 m_vPositionFactor = verticalFactor;
278 emit positionChanged();
281 279 }
282 280 }
283 281
284 282 /*!
285 Gets the size factor of the pie.
286 \sa setSizeFactor()
287 */
288 qreal QPieSeries::sizeFactor() const
289 {
290 return m_sizeFactor;
291 }
283 Gets the horizontal position factor of the pie.
292 284
293 /*!
294 Sets the \a position of the pie within its bounding rectangle.
295 \sa PiePosition, position()
285 The factors are relative to the chart rectangle where:
286
287 Horizontal factor 0.0 means the absolute left.
288 Horizontal factor 1.0 means the absolute right.
289
290 By default horizontal factor is 0.5 which puts the pie in the horizontal middle of the chart rectangle.
291
292 \sa setPositionFactors(), verticalPositionFactor(), setSizeFactor()
296 293 */
297 void QPieSeries::setPosition(PiePosition position)
294 qreal QPieSeries::horizontalPositionFactor() const
298 295 {
299 // TODO: sanity check
300 if (m_position != position) {
301 m_position = position;
302 emit positionChanged();
303 }
296 return m_hPositionFactor;
304 297 }
305 298
306 299 /*!
307 Gets the position of the pie within its bounding rectangle.
308 \sa PiePosition, setPosition()
300 Gets the vertical position factor of the pie.
301
302 The factors are relative to the chart rectangle where:
303
304 Vertical factor 0.0 means the absolute top.
305 Vertical factor 1.0 means the absolute bottom.
306
307 By default vertical factor is 0.5 which puts the pie in the vertical middle of the chart rectangle.
308
309 \sa setPositionFactors(), horizontalPositionFactor(), setSizeFactor()
309 310 */
310 QPieSeries::PiePosition QPieSeries::position() const
311 qreal QPieSeries::verticalPositionFactor() const
311 312 {
312 return m_position;
313 return m_vPositionFactor;
313 314 }
314 315
315 316 /*!
316 Sets the \a sizePolicy of the pie.
317 \sa PieSizePolicy, sizePolicy()
317 Sets the size \a sizeFactor of the pie.
318
319 The size factor is defined so that the 1.0 is the maximum that can fit the given chart rectangle.
320
321 Default value is 0.7.
322
323 \sa sizeFactor(), setPositionFactors(), verticalPositionFactor(), horizontalPositionFactor()
318 324 */
319 void QPieSeries::setSizePolicy(PieSizePolicy sizePolicy)
325 void QPieSeries::setSizeFactor(qreal sizeFactor)
320 326 {
321 // TODO: sanity check
322 if (m_sizePolicy != sizePolicy) {
323 m_sizePolicy = sizePolicy;
324 emit sizePolicyChanged();
327 if (sizeFactor < 0.0)
328 return;
329
330 if (m_pieSizeFactor != sizeFactor) {
331 m_pieSizeFactor = sizeFactor;
332 emit sizeFactorChanged();
325 333 }
326 334 }
327 335
328 336 /*!
329 Gets the size policy of the pie.
330 \sa PieSizePolicy, setSizePolicy()
337 Gets the size factor of the pie.
338
339 The size factor is defined so that the 1.0 is the maximum that can fit the given chart rectangle.
340
341 Default value is 0.7.
342
343 \sa setSizeFactor(), setPositionFactors(), verticalPositionFactor(), horizontalPositionFactor()
331 344 */
332 QPieSeries::PieSizePolicy QPieSeries::sizePolicy() const
345 qreal QPieSeries::sizeFactor() const
333 346 {
334 return m_sizePolicy;
347 return m_pieSizeFactor;
335 348 }
336 349
337 350
351 /*!
352 Sets the end angle of the pie.
353
354 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
355
356 \a startAngle must be less than end angle. Default value is 0.
357
358 \sa startAngle(), endAngle(), setEndAngle()
359 */
338 360 void QPieSeries::setStartAngle(qreal startAngle)
339 361 {
340 362 if (startAngle >= 0 && startAngle <= 360 && startAngle != m_pieStartAngle && startAngle <= m_pieEndAngle) {
@@ -343,11 +365,27 void QPieSeries::setStartAngle(qreal startAngle)
343 365 }
344 366 }
345 367
368 /*!
369 Gets the start angle of the pie.
370
371 Full pie is 360 degrees where 0 degrees is at 12 a'clock. Default value is 360.
372
373 \sa setStartAngle(), endAngle(), setEndAngle()
374 */
346 375 qreal QPieSeries::startAngle() const
347 376 {
348 377 return m_pieStartAngle;
349 378 }
350 379
380 /*!
381 Sets the end angle of the pie.
382
383 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
384
385 \a endAngle must be greater than start angle.
386
387 \sa endAngle(), startAngle(), setStartAngle()
388 */
351 389 void QPieSeries::setEndAngle(qreal endAngle)
352 390 {
353 391 if (endAngle >= 0 && endAngle <= 360 && endAngle != m_pieEndAngle && endAngle >= m_pieStartAngle) {
@@ -356,6 +394,13 void QPieSeries::setEndAngle(qreal endAngle)
356 394 }
357 395 }
358 396
397 /*!
398 Returns the end angle of the pie.
399
400 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
401
402 \sa setEndAngle(), startAngle(), setStartAngle()
403 */
359 404 qreal QPieSeries::endAngle() const
360 405 {
361 406 return m_pieEndAngle;
@@ -428,7 +473,7 qreal QPieSeries::total() const
428 473
429 474 This signal is emitted when position of the pie has been changed.
430 475
431 \sa position(), setPosition()
476 \sa horizontalPositionFactor(), verticalPositionFactor(), setPositionFactors()
432 477 */
433 478
434 479 void QPieSeries::sliceChanged()
@@ -21,27 +21,6 class QTCOMMERCIALCHART_EXPORT QPieSeries : public QSeries
21 21
22 22 public:
23 23
24 enum PiePositionFlag {
25 PiePositionLeft = 0x1,
26 PiePositionRight = 0x2,
27 PiePositionHCenter = 0x4,
28 PiePositionTop = 0x10,
29 PiePositionBottom = 0x20,
30 PiePositionVCenter = 0x40,
31 PiePositionCenter = PiePositionHCenter | PiePositionVCenter
32 };
33
34 Q_DECLARE_FLAGS(PiePosition, PiePositionFlag)
35
36 enum PieSizePolicyFlag {
37 PieSizePolicyMaximized = 0,
38 PieSizePolicyReserveSpaceForLabels = 0x1,
39 PieSizePolicyReserveSpaceForExploding = 0x2,
40 PieSizePolicyReserveSpaceForAll = PieSizePolicyReserveSpaceForLabels | PieSizePolicyReserveSpaceForExploding
41 };
42
43 Q_DECLARE_FLAGS(PieSizePolicy, PieSizePolicyFlag)
44
45 24 class ChangeSet
46 25 {
47 26 public:
@@ -88,10 +67,9 public:
88 67 qreal total() const;
89 68
90 69 // pie customization
91 void setPosition(PiePosition position);
92 PiePosition position() const;
93 void setSizePolicy(PieSizePolicy policy);
94 PieSizePolicy sizePolicy() const;
70 void setPositionFactors(qreal horizontalFactor, qreal verticalFactor);
71 qreal horizontalPositionFactor() const;
72 qreal verticalPositionFactor() const;
95 73 void setSizeFactor(qreal sizeFactor);
96 74 qreal sizeFactor() const;
97 75 void setStartAngle(qreal startAngle);
@@ -125,7 +103,6 Q_SIGNALS:
125 103
126 104 void sizeFactorChanged();
127 105 void positionChanged();
128 void sizePolicyChanged();
129 106
130 107 private Q_SLOTS: // TODO: should be private and not visible in the interface at all
131 108 void sliceChanged();
@@ -144,12 +121,12 private:
144 121 friend class PieSlice;
145 122
146 123 QList<QPieSlice*> m_slices;
147 qreal m_sizeFactor;
148 PiePosition m_position;
149 PieSizePolicy m_sizePolicy;
150 qreal m_total;
124 qreal m_hPositionFactor;
125 qreal m_vPositionFactor;
126 qreal m_pieSizeFactor;
151 127 qreal m_pieStartAngle;
152 128 qreal m_pieEndAngle;
129 qreal m_total;
153 130 };
154 131
155 132 QTCOMMERCIALCHART_END_NAMESPACE
@@ -4,8 +4,8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
4 4
5 5 #define DEFAULT_PEN_COLOR Qt::black
6 6 #define DEFAULT_BRUSH_COLOR Qt::white
7 #define DEFAULT_LABEL_ARM_LENGTH 40
8 #define DEFAULT_EXPOLODE_DISTANCE 20
7 #define DEFAULT_LABEL_ARM_LENGTH_FACTOR 0.15
8 #define DEFAULT_EXPOLODE_DISTANCE_FACTOR 0.15
9 9
10 10 /*!
11 11 \class QPieSlice
@@ -42,14 +42,14 QPieSlice::QPieSlice(QObject *parent)
42 42 m_value(0),
43 43 m_isLabelVisible(false),
44 44 m_isExploded(false),
45 m_explodeDistance(DEFAULT_EXPOLODE_DISTANCE),
45 m_explodeDistanceFactor(DEFAULT_EXPOLODE_DISTANCE_FACTOR),
46 46 m_percentage(0),
47 47 m_startAngle(0),
48 48 m_angleSpan(0),
49 49 m_pen(DEFAULT_PEN_COLOR),
50 50 m_brush(DEFAULT_BRUSH_COLOR),
51 51 m_labelPen(DEFAULT_PEN_COLOR),
52 m_labelArmLength(DEFAULT_LABEL_ARM_LENGTH)
52 m_labelArmLengthFactor(DEFAULT_LABEL_ARM_LENGTH_FACTOR)
53 53 {
54 54
55 55 }
@@ -65,14 +65,14 QPieSlice::QPieSlice(qreal value, QString label, QObject *parent)
65 65 m_label(label),
66 66 m_isLabelVisible(false),
67 67 m_isExploded(false),
68 m_explodeDistance(DEFAULT_EXPOLODE_DISTANCE),
68 m_explodeDistanceFactor(DEFAULT_EXPOLODE_DISTANCE_FACTOR),
69 69 m_percentage(0),
70 70 m_startAngle(0),
71 71 m_angleSpan(0),
72 72 m_pen(DEFAULT_PEN_COLOR),
73 73 m_brush(DEFAULT_BRUSH_COLOR),
74 74 m_labelPen(DEFAULT_PEN_COLOR),
75 m_labelArmLength(DEFAULT_LABEL_ARM_LENGTH)
75 m_labelArmLengthFactor(DEFAULT_LABEL_ARM_LENGTH_FACTOR)
76 76 {
77 77
78 78 }
@@ -116,7 +116,7 bool QPieSlice::isLabelVisible() const
116 116
117 117 /*!
118 118 Returns true if slice is exloded from the pie.
119 \sa setExploded()
119 \sa setExploded(), setExplodeDistanceFactor()
120 120 */
121 121 bool QPieSlice::isExploded() const
122 122 {
@@ -124,13 +124,19 bool QPieSlice::isExploded() const
124 124 }
125 125
126 126 /*!
127 Returns the explosion distance of the slice.
128 Default value is 20.
129 \sa setExplodeDistance()
127 Returns the explode distance factor.
128
129 The factor is relative to pie radius. For example:
130 1.0 means the distance is the same as the radius.
131 0.5 means the distance is half of the radius.
132
133 Default value is 0.15.
134
135 \sa setExplodeDistanceFactor()
130 136 */
131 qreal QPieSlice::explodeDistance() const
137 qreal QPieSlice::explodeDistanceFactor() const
132 138 {
133 return m_explodeDistance;
139 return m_explodeDistanceFactor;
134 140 }
135 141
136 142 /*!
@@ -205,13 +211,19 QFont QPieSlice::labelFont() const
205 211 }
206 212
207 213 /*!
208 Returns the label arm lenght used in this slice.
209 Default value is 40 pixels.
210 \sa setLabelArmLength()
214 Gets the label arm lenght factor.
215
216 The factor is relative to pie radius. For example:
217 1.0 means the length is the same as the radius.
218 0.5 means the length is half of the radius.
219
220 Default value is 0.15
221
222 \sa setLabelArmLengthFactor()
211 223 */
212 qreal QPieSlice::labelArmLength() const
224 qreal QPieSlice::labelArmLengthFactor() const
213 225 {
214 return m_labelArmLength;
226 return m_labelArmLengthFactor;
215 227 }
216 228
217 229 /*!
@@ -247,7 +259,7 qreal QPieSlice::labelArmLength() const
247 259 */
248 260
249 261 /*!
250 Sets the value of this slice.
262 Sets the \a value of this slice.
251 263 \sa value()
252 264 */
253 265 void QPieSlice::setValue(qreal value)
@@ -284,7 +296,7 void QPieSlice::setLabelVisible(bool visible)
284 296
285 297 /*!
286 298 Sets this slice \a exploded.
287 \sa isExploded(), setExplodeDistance()
299 \sa isExploded(), explodeDistanceFactor()
288 300 */
289 301 void QPieSlice::setExploded(bool exploded)
290 302 {
@@ -295,14 +307,20 void QPieSlice::setExploded(bool exploded)
295 307 }
296 308
297 309 /*!
298 Sets the explosion \a distance of this slice.
299 It is the distance the slice is moved away from the pie center.
300 \sa explodeDistance(), isExploded()
310 Sets the explode distance \a factor.
311
312 The factor is relative to pie radius. For example:
313 1.0 means the distance is the same as the radius.
314 0.5 means the distance is half of the radius.
315
316 Default value is 0.15
317
318 \sa explodeDistanceFactor()
301 319 */
302 void QPieSlice::setExplodeDistance(qreal distance)
320 void QPieSlice::setExplodeDistanceFactor(qreal factor)
303 321 {
304 if (m_explodeDistance != distance) {
305 m_explodeDistance = distance;
322 if (m_explodeDistanceFactor != factor) {
323 m_explodeDistanceFactor = factor;
306 324 emit changed();
307 325 }
308 326 }
@@ -360,13 +378,20 void QPieSlice::setLabelFont(QFont font)
360 378 }
361 379
362 380 /*!
363 Sets the label arm \a length used to draw the label in this slice.
364 \sa labelArmLength()
381 Sets the label arm lenght \a factor.
382
383 The factor is relative to pie radius. For example:
384 1.0 means the length is the same as the radius.
385 0.5 means the length is half of the radius.
386
387 Default value is 0.15
388
389 \sa labelArmLengthFactor()
365 390 */
366 void QPieSlice::setLabelArmLength(qreal length)
391 void QPieSlice::setLabelArmLengthFactor(qreal factor)
367 392 {
368 if (m_labelArmLength != length) {
369 m_labelArmLength = length;
393 if (m_labelArmLengthFactor != factor) {
394 m_labelArmLengthFactor = factor;
370 395 emit changed();
371 396 }
372 397 }
@@ -29,8 +29,8 public:
29 29 bool isLabelVisible() const;
30 30 void setExploded(bool exploded);
31 31 bool isExploded() const;
32 void setExplodeDistance(qreal distance);
33 qreal explodeDistance() const;
32 void setExplodeDistanceFactor(qreal factor);
33 qreal explodeDistanceFactor() const;
34 34
35 35 // generated data
36 36 qreal percentage() const;
@@ -46,8 +46,8 public:
46 46 QPen labelPen() const;
47 47 void setLabelFont(QFont font);
48 48 QFont labelFont() const;
49 void setLabelArmLength(qreal len);
50 qreal labelArmLength() const;
49 void setLabelArmLengthFactor(qreal factor);
50 qreal labelArmLengthFactor() const;
51 51
52 52 // TODO: label position in general
53 53 // setLabelFlags(inside|outside|labelArmOn|labelArmOff|???)
@@ -71,7 +71,7 private:
71 71 QString m_label;
72 72 bool m_isLabelVisible;
73 73 bool m_isExploded;
74 qreal m_explodeDistance;
74 qreal m_explodeDistanceFactor;
75 75
76 76 // generated data
77 77 qreal m_percentage;
@@ -83,7 +83,7 private:
83 83 QBrush m_brush;
84 84 QPen m_labelPen;
85 85 QFont m_labelFont;
86 qreal m_labelArmLength;
86 qreal m_labelArmLengthFactor;
87 87 };
88 88
89 89 QTCOMMERCIALCHART_END_NAMESPACE
General Comments 0
You need to be logged in to leave comments. Login now