##// END OF EJS Templates
Fix mingw build errors...
Miikka Heikkinen -
r2552:f2e3b33e0938
parent child
Show More
@@ -1,422 +1,423
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2013 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "polarchartaxisangular_p.h"
22 22 #include "chartpresenter_p.h"
23 23 #include "abstractchartlayout_p.h"
24 24 #include "qabstractaxis.h"
25 25 #include "qabstractaxis_p.h"
26 26 #include <QDebug>
27 27 #include <qmath.h>
28 28
29 29 QTCOMMERCIALCHART_BEGIN_NAMESPACE
30 30
31 31 PolarChartAxisAngular::PolarChartAxisAngular(QAbstractAxis *axis, QGraphicsItem *item, bool intervalAxis)
32 32 : PolarChartAxis(axis, item, intervalAxis)
33 33 {
34 34 }
35 35
36 36 PolarChartAxisAngular::~PolarChartAxisAngular()
37 37 {
38 38 }
39 39
40 40 void PolarChartAxisAngular::updateGeometry()
41 41 {
42 42 QGraphicsLayoutItem::updateGeometry();
43 43
44 44 const QVector<qreal> &layout = this->layout();
45 45 if (layout.isEmpty())
46 46 return;
47 47
48 48 createAxisLabels(layout);
49 49 QStringList labelList = labels();
50 50 QPointF center = axisGeometry().center();
51 51 QList<QGraphicsItem *> arrowItemList = arrowItems();
52 52 QList<QGraphicsItem *> gridItemList = gridItems();
53 53 QList<QGraphicsItem *> labelItemList = labelItems();
54 54 QList<QGraphicsItem *> shadeItemList = shadeItems();
55 55 QGraphicsTextItem *title = titleItem();
56 56
57 57 QGraphicsEllipseItem *axisLine = static_cast<QGraphicsEllipseItem *>(arrowItemList.at(0));
58 58 axisLine->setRect(axisGeometry());
59 59
60 60 qreal radius = axisGeometry().height() / 2.0;
61 61
62 62 QRectF previousLabelRect;
63 63 QRectF firstLabelRect;
64 64
65 65 qreal labelHeight = 0;
66 66
67 67 bool firstShade = true;
68 68 bool nextTickVisible = false;
69 69 if (layout.size())
70 70 nextTickVisible = !(layout.at(0) < 0.0 || layout.at(0) > 360.0);
71 71
72 72 for (int i = 0; i < layout.size(); ++i) {
73 73 qreal angularCoordinate = layout.at(i);
74 74
75 75 QGraphicsLineItem *gridLineItem = static_cast<QGraphicsLineItem *>(gridItemList.at(i));
76 76 QGraphicsLineItem *tickItem = static_cast<QGraphicsLineItem *>(arrowItemList.at(i + 1));
77 77 QGraphicsTextItem *labelItem = static_cast<QGraphicsTextItem *>(labelItemList.at(i));
78 78 QGraphicsPathItem *shadeItem = 0;
79 79 if (i == 0)
80 80 shadeItem = static_cast<QGraphicsPathItem *>(shadeItemList.at(0));
81 81 else if (i % 2)
82 82 shadeItem = static_cast<QGraphicsPathItem *>(shadeItemList.at((i / 2) + 1));
83 83
84 84 // Ignore ticks outside valid range
85 85 bool currentTickVisible = nextTickVisible;
86 86 if ((i == layout.size() - 1)
87 87 || layout.at(i + 1) < 0.0
88 88 || layout.at(i + 1) > 360.0) {
89 89 nextTickVisible = false;
90 90 } else {
91 91 nextTickVisible = true;
92 92 }
93 93
94 94 qreal labelCoordinate = angularCoordinate;
95 95 qreal labelVisible = currentTickVisible;
96 96 if (intervalAxis()) {
97 97 qreal farEdge;
98 98 if (i == (layout.size() - 1))
99 99 farEdge = 360.0;
100 100 else
101 101 farEdge = qMin(qreal(360.0), layout.at(i + 1));
102 102
103 103 // Adjust the labelCoordinate to show it if next tick is visible
104 104 if (nextTickVisible)
105 105 labelCoordinate = qMax(qreal(0.0), labelCoordinate);
106 106
107 107 labelCoordinate = (labelCoordinate + farEdge) / 2.0;
108 108 // Don't display label once the category gets too small near the axis
109 109 if (labelCoordinate < 5.0 || labelCoordinate > 355.0)
110 110 labelVisible = false;
111 111 else
112 112 labelVisible = true;
113 113 }
114 114
115 115 // Need this also in label calculations, so determine it first
116 116 QLineF tickLine(QLineF::fromPolar(radius - tickWidth(), 90.0 - angularCoordinate).p2(),
117 117 QLineF::fromPolar(radius + tickWidth(), 90.0 - angularCoordinate).p2());
118 118 tickLine.translate(center);
119 119
120 120 // Angular axis label
121 121 if (axis()->labelsVisible() && labelVisible) {
122 122 labelItem->setHtml(labelList.at(i));
123 123 const QRectF &rect = labelItem->boundingRect();
124 124 QPointF labelCenter = rect.center();
125 125 labelItem->setTransformOriginPoint(labelCenter.x(), labelCenter.y());
126 126 QRectF boundingRect = ChartPresenter::textBoundingRect(axis()->labelsFont(), labelList.at(i), axis()->labelsAngle());
127 127 boundingRect.moveCenter(labelCenter);
128 128 QPointF positionDiff(rect.topLeft() - boundingRect.topLeft());
129 129
130 130 QPointF labelPoint;
131 131 if (intervalAxis()) {
132 132 QLineF labelLine = QLineF::fromPolar(radius + tickWidth(), 90.0 - labelCoordinate);
133 133 labelLine.translate(center);
134 134 labelPoint = labelLine.p2();
135 135 } else {
136 136 labelPoint = tickLine.p2();
137 137 }
138 138
139 139 QRectF labelRect = moveLabelToPosition(labelCoordinate, labelPoint, boundingRect);
140 140 labelItem->setPos(labelRect.topLeft() + positionDiff);
141 141
142 142 // Store height for title calculations
143 143 qreal labelClearance = axisGeometry().top() - labelRect.top();
144 144 labelHeight = qMax(labelHeight, labelClearance);
145 145
146 146 // Label overlap detection
147 147 if (i && (previousLabelRect.intersects(labelRect) || firstLabelRect.intersects(labelRect))) {
148 148 labelVisible = false;
149 149 } else {
150 150 // Store labelRect for future comparison. Some area is deducted to make things look
151 151 // little nicer, as usually intersection happens at label corner with angular labels.
152 152 labelRect.adjust(-2.0, -4.0, -2.0, -4.0);
153 153 if (firstLabelRect.isEmpty())
154 154 firstLabelRect = labelRect;
155 155
156 156 previousLabelRect = labelRect;
157 157 labelVisible = true;
158 158 }
159 159 }
160 160
161 161 labelItem->setVisible(labelVisible);
162 162 if (!currentTickVisible) {
163 163 gridLineItem->setVisible(false);
164 164 tickItem->setVisible(false);
165 165 if (shadeItem)
166 166 shadeItem->setVisible(false);
167 167 continue;
168 168 }
169 169
170 170 // Angular grid line
171 171 QLineF gridLine = QLineF::fromPolar(radius, 90.0 - angularCoordinate);
172 172 gridLine.translate(center);
173 173 gridLineItem->setLine(gridLine);
174 174 gridLineItem->setVisible(true);
175 175
176 176 // Tick
177 177 tickItem->setLine(tickLine);
178 178 tickItem->setVisible(true);
179 179
180 180 // Shades
181 181 if (i % 2 || (i == 0 && !nextTickVisible)) {
182 182 QPainterPath path;
183 183 path.moveTo(center);
184 184 if (i == 0) {
185 185 // If first tick is also the last, we need to custom fill the first partial arc
186 186 // or it won't get filled.
187 187 path.arcTo(axisGeometry(), 90.0 - layout.at(0), layout.at(0));
188 188 path.closeSubpath();
189 189 } else {
190 190 qreal nextCoordinate;
191 191 if (!nextTickVisible) // Last visible tick
192 192 nextCoordinate = 360.0;
193 193 else
194 194 nextCoordinate = layout.at(i + 1);
195 195 qreal arcSpan = angularCoordinate - nextCoordinate;
196 196 path.arcTo(axisGeometry(), 90.0 - angularCoordinate, arcSpan);
197 197 path.closeSubpath();
198 198
199 199 // Add additional arc for first shade item if there is a partial arc to be filled
200 200 if (firstShade) {
201 201 QGraphicsPathItem *specialShadeItem = static_cast<QGraphicsPathItem *>(shadeItemList.at(0));
202 202 if (layout.at(i - 1) > 0.0) {
203 203 QPainterPath specialPath;
204 204 specialPath.moveTo(center);
205 205 specialPath.arcTo(axisGeometry(), 90.0 - layout.at(i - 1), layout.at(i - 1));
206 206 specialPath.closeSubpath();
207 207 specialShadeItem->setPath(specialPath);
208 208 specialShadeItem->setVisible(true);
209 209 } else {
210 210 specialShadeItem->setVisible(false);
211 211 }
212 212 }
213 213 }
214 214 shadeItem->setPath(path);
215 215 shadeItem->setVisible(true);
216 216 firstShade = false;
217 217 }
218 218 }
219 219
220 220 // Title, centered above the chart
221 221 QString titleText = axis()->titleText();
222 222 if (!titleText.isEmpty() && axis()->isTitleVisible()) {
223 title->setHtml(ChartPresenter::truncatedText(axis()->titleFont(), titleText, qreal(0.0), axisGeometry().width(), Qt::Horizontal, QRectF()));
223 QRectF dummyRect;
224 title->setHtml(ChartPresenter::truncatedText(axis()->titleFont(), titleText, qreal(0.0), axisGeometry().width(), Qt::Horizontal, dummyRect));
224 225
225 226 QRectF titleBoundingRect = title->boundingRect();
226 227 QPointF titleCenter = center - titleBoundingRect.center();
227 228 title->setPos(titleCenter.x(), axisGeometry().top() - titlePadding() * 2.0 - titleBoundingRect.height() - labelHeight);
228 229 }
229 230 }
230 231
231 232 Qt::Orientation PolarChartAxisAngular::orientation() const
232 233 {
233 234 return Qt::Horizontal;
234 235 }
235 236
236 237 void PolarChartAxisAngular::createItems(int count)
237 238 {
238 239 if (arrowItems().count() == 0) {
239 240 // angular axis line
240 241 // TODO: need class similar to LineArrowItem for click handling?
241 242 QGraphicsEllipseItem *arrow = new QGraphicsEllipseItem(presenter()->rootItem());
242 243 arrow->setPen(axis()->linePen());
243 244 arrowGroup()->addToGroup(arrow);
244 245 }
245 246
246 247 for (int i = 0; i < count; ++i) {
247 248 QGraphicsLineItem *arrow = new QGraphicsLineItem(presenter()->rootItem());
248 249 QGraphicsLineItem *grid = new QGraphicsLineItem(presenter()->rootItem());
249 250 QGraphicsTextItem *label = new QGraphicsTextItem(presenter()->rootItem());
250 251 QGraphicsTextItem *title = titleItem();
251 252 arrow->setPen(axis()->linePen());
252 253 grid->setPen(axis()->gridLinePen());
253 254 label->setFont(axis()->labelsFont());
254 255 label->setDefaultTextColor(axis()->labelsBrush().color());
255 256 label->setRotation(axis()->labelsAngle());
256 257 title->setFont(axis()->titleFont());
257 258 title->setDefaultTextColor(axis()->titleBrush().color());
258 259 title->setHtml(axis()->titleText());
259 260 arrowGroup()->addToGroup(arrow);
260 261 gridGroup()->addToGroup(grid);
261 262 labelGroup()->addToGroup(label);
262 263 if (gridItems().size() == 1 || (((gridItems().size() + 1) % 2) && gridItems().size() > 0)) {
263 264 QGraphicsPathItem *shade = new QGraphicsPathItem(presenter()->rootItem());
264 265 shade->setPen(axis()->shadesPen());
265 266 shade->setBrush(axis()->shadesBrush());
266 267 shadeGroup()->addToGroup(shade);
267 268 }
268 269 }
269 270 }
270 271
271 272 void PolarChartAxisAngular::handleArrowPenChanged(const QPen &pen)
272 273 {
273 274 bool first = true;
274 275 foreach (QGraphicsItem *item, arrowItems()) {
275 276 if (first) {
276 277 first = false;
277 278 // First arrow item is the outer circle of axis
278 279 static_cast<QGraphicsEllipseItem *>(item)->setPen(pen);
279 280 } else {
280 281 static_cast<QGraphicsLineItem *>(item)->setPen(pen);
281 282 }
282 283 }
283 284 }
284 285
285 286 void PolarChartAxisAngular::handleGridPenChanged(const QPen &pen)
286 287 {
287 288 foreach (QGraphicsItem *item, gridItems())
288 289 static_cast<QGraphicsLineItem *>(item)->setPen(pen);
289 290 }
290 291
291 292 QSizeF PolarChartAxisAngular::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
292 293 {
293 294 Q_UNUSED(which);
294 295 Q_UNUSED(constraint);
295 296 return QSizeF(-1, -1);
296 297 }
297 298
298 299 qreal PolarChartAxisAngular::preferredAxisRadius(const QSizeF &maxSize)
299 300 {
300 301 qreal radius = maxSize.height() / 2.0;
301 302 if (maxSize.width() < maxSize.height())
302 303 radius = maxSize.width() / 2.0;
303 304
304 305 if (axis()->labelsVisible()) {
305 306 QVector<qreal> layout = calculateLayout();
306 307 if (layout.isEmpty())
307 308 return radius;
308 309
309 310 createAxisLabels(layout);
310 311 QStringList labelList = labels();
311 312 QFont font = axis()->labelsFont();
312 313
313 314 QRectF maxRect;
314 315 maxRect.setSize(maxSize);
315 316 maxRect.moveCenter(QPointF(0.0, 0.0));
316 317
317 318 // This is a horrible way to find out the maximum radius for angular axis and its labels.
318 319 // It just increments the radius down until everyhing fits the constraint size.
319 320 // Proper way would be to actually calculate it but this seems to work reasonably fast as it is.
320 321 bool nextTickVisible = false;
321 322 for (int i = 0; i < layout.size(); ) {
322 323 if ((i == layout.size() - 1)
323 324 || layout.at(i + 1) < 0.0
324 325 || layout.at(i + 1) > 360.0) {
325 326 nextTickVisible = false;
326 327 } else {
327 328 nextTickVisible = true;
328 329 }
329 330
330 331 qreal labelCoordinate = layout.at(i);
331 332 qreal labelVisible;
332 333
333 334 if (intervalAxis()) {
334 335 qreal farEdge;
335 336 if (i == (layout.size() - 1))
336 337 farEdge = 360.0;
337 338 else
338 339 farEdge = qMin(qreal(360.0), layout.at(i + 1));
339 340
340 341 // Adjust the labelCoordinate to show it if next tick is visible
341 342 if (nextTickVisible)
342 343 labelCoordinate = qMax(qreal(0.0), labelCoordinate);
343 344
344 345 labelCoordinate = (labelCoordinate + farEdge) / 2.0;
345 346 }
346 347
347 348 if (labelCoordinate < 0.0 || labelCoordinate > 360.0)
348 349 labelVisible = false;
349 350 else
350 351 labelVisible = true;
351 352
352 353 if (!labelVisible) {
353 354 i++;
354 355 continue;
355 356 }
356 357
357 358 QRectF boundingRect = ChartPresenter::textBoundingRect(axis()->labelsFont(), labelList.at(i), axis()->labelsAngle());
358 359 QPointF labelPoint = QLineF::fromPolar(radius + tickWidth(), 90.0 - labelCoordinate).p2();
359 360
360 361 boundingRect = moveLabelToPosition(labelCoordinate, labelPoint, boundingRect);
361 362 QRectF intersectRect = maxRect.intersected(boundingRect);
362 363 if (boundingRect.isEmpty() || intersectRect == boundingRect) {
363 364 i++;
364 365 } else {
365 366 qreal reduction(0.0);
366 367 // If there is no intersection, reduce by smallest dimension of label rect to be on the safe side
367 368 if (intersectRect.isEmpty()) {
368 369 reduction = qMin(boundingRect.height(), boundingRect.width());
369 370 } else {
370 371 // Approximate needed radius reduction is the amount label rect exceeds max rect in either dimension.
371 372 // Could be further optimized by figuring out the proper math how to calculate exact needed reduction.
372 373 reduction = qMax(boundingRect.height() - intersectRect.height(),
373 374 boundingRect.width() - intersectRect.width());
374 375 }
375 376 // Typically the approximated reduction is little low, so add one
376 377 radius -= (reduction + 1.0);
377 378
378 379 if (radius < 1.0) // safeguard
379 380 return 1.0;
380 381 }
381 382 }
382 383 }
383 384
384 385 if (!axis()->titleText().isEmpty() && axis()->isTitleVisible()) {
385 386 QRectF titleRect = ChartPresenter::textBoundingRect(axis()->titleFont(), axis()->titleText());
386 387
387 388 radius -= titlePadding() + (titleRect.height() / 2.0);
388 389 if (radius < 1.0) // safeguard
389 390 return 1.0;
390 391 }
391 392
392 393 return radius;
393 394 }
394 395
395 396 QRectF PolarChartAxisAngular::moveLabelToPosition(qreal angularCoordinate, QPointF labelPoint, QRectF labelRect) const
396 397 {
397 398 // TODO use fuzzy compare for "==" cases?
398 399 // TODO Adjust the rect position near 0, 90, 180, and 270 angles for smoother animation?
399 400 if (angularCoordinate == 0.0)
400 401 labelRect.moveCenter(labelPoint + QPointF(0, -labelRect.height() / 2.0));
401 402 else if (angularCoordinate < 90.0)
402 403 labelRect.moveBottomLeft(labelPoint);
403 404 else if (angularCoordinate == 90.0)
404 405 labelRect.moveCenter(labelPoint + QPointF(labelRect.width() / 2.0 + 2.0, 0)); // +2 so that it does not hit the radial axis
405 406 else if (angularCoordinate < 180.0)
406 407 labelRect.moveTopLeft(labelPoint);
407 408 else if (angularCoordinate == 180.0)
408 409 labelRect.moveCenter(labelPoint + QPointF(0, labelRect.height() / 2.0));
409 410 else if (angularCoordinate < 270.0)
410 411 labelRect.moveTopRight(labelPoint);
411 412 else if (angularCoordinate == 270.0)
412 413 labelRect.moveCenter(labelPoint + QPointF(-labelRect.width() / 2.0 - 2.0, 0)); // -2 so that it does not hit the radial axis
413 414 else if (angularCoordinate < 360.0)
414 415 labelRect.moveBottomRight(labelPoint);
415 416 else
416 417 labelRect.moveCenter(labelPoint + QPointF(0, -labelRect.height() / 2.0));
417 418 return labelRect;
418 419 }
419 420
420 421 #include "moc_polarchartaxisangular_p.cpp"
421 422
422 423 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,288 +1,289
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2013 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "polarchartaxisradial_p.h"
22 22 #include "chartpresenter_p.h"
23 23 #include "abstractchartlayout_p.h"
24 24 #include "qabstractaxis_p.h"
25 25 #include "linearrowitem_p.h"
26 26
27 27 QTCOMMERCIALCHART_BEGIN_NAMESPACE
28 28
29 29 PolarChartAxisRadial::PolarChartAxisRadial(QAbstractAxis *axis, QGraphicsItem *item, bool intervalAxis)
30 30 : PolarChartAxis(axis, item, intervalAxis)
31 31 {
32 32 }
33 33
34 34 PolarChartAxisRadial::~PolarChartAxisRadial()
35 35 {
36 36 }
37 37
38 38 void PolarChartAxisRadial::updateGeometry()
39 39 {
40 40 const QVector<qreal> &layout = this->layout();
41 41 if (layout.isEmpty())
42 42 return;
43 43
44 44 createAxisLabels(layout);
45 45 QStringList labelList = labels();
46 46 QPointF center = axisGeometry().center();
47 47 QList<QGraphicsItem *> arrowItemList = arrowItems();
48 48 QList<QGraphicsItem *> gridItemList = gridItems();
49 49 QList<QGraphicsItem *> labelItemList = labelItems();
50 50 QList<QGraphicsItem *> shadeItemList = shadeItems();
51 51 QGraphicsTextItem* title = titleItem();
52 52 qreal radius = axisGeometry().height() / 2.0;
53 53
54 54 QLineF line(center, center + QPointF(0, -radius));
55 55 QGraphicsLineItem *axisLine = static_cast<QGraphicsLineItem *>(arrowItemList.at(0));
56 56 axisLine->setLine(line);
57 57
58 58 QRectF previousLabelRect;
59 59 bool firstShade = true;
60 60 bool nextTickVisible = false;
61 61 if (layout.size())
62 62 nextTickVisible = !(layout.at(0) < 0.0 || layout.at(0) > radius);
63 63
64 64 for (int i = 0; i < layout.size(); ++i) {
65 65 qreal radialCoordinate = layout.at(i);
66 66
67 67 QGraphicsEllipseItem *gridItem = static_cast<QGraphicsEllipseItem *>(gridItemList.at(i));
68 68 QGraphicsLineItem *tickItem = static_cast<QGraphicsLineItem *>(arrowItemList.at(i + 1));
69 69 QGraphicsTextItem *labelItem = static_cast<QGraphicsTextItem *>(labelItemList.at(i));
70 70 QGraphicsPathItem *shadeItem = 0;
71 71 if (i == 0)
72 72 shadeItem = static_cast<QGraphicsPathItem *>(shadeItemList.at(0));
73 73 else if (i % 2)
74 74 shadeItem = static_cast<QGraphicsPathItem *>(shadeItemList.at((i / 2) + 1));
75 75
76 76 // Ignore ticks outside valid range
77 77 bool currentTickVisible = nextTickVisible;
78 78 if ((i == layout.size() - 1)
79 79 || layout.at(i + 1) < 0.0
80 80 || layout.at(i + 1) > radius) {
81 81 nextTickVisible = false;
82 82 } else {
83 83 nextTickVisible = true;
84 84 }
85 85
86 86 qreal labelCoordinate = radialCoordinate;
87 87 qreal labelVisible = currentTickVisible;
88 88 qreal labelPad = labelPadding() / 2.0;
89 89 if (intervalAxis()) {
90 90 qreal farEdge;
91 91 if (i == (layout.size() - 1))
92 92 farEdge = radius;
93 93 else
94 94 farEdge = qMin(radius, layout.at(i + 1));
95 95
96 96 // Adjust the labelCoordinate to show it if next tick is visible
97 97 if (nextTickVisible)
98 98 labelCoordinate = qMax(qreal(0.0), labelCoordinate);
99 99
100 100 labelCoordinate = (labelCoordinate + farEdge) / 2.0;
101 101 if (labelCoordinate > 0.0 && labelCoordinate < radius)
102 102 labelVisible = true;
103 103 else
104 104 labelVisible = false;
105 105 }
106 106
107 107 // Radial axis label
108 108 if (axis()->labelsVisible() && labelVisible) {
109 109 labelItem->setHtml(labelList.at(i));
110 110 QRectF labelRect = labelItem->boundingRect();
111 111 QPointF labelCenter = labelRect.center();
112 112 labelItem->setTransformOriginPoint(labelCenter.x(), labelCenter.y());
113 113 QRectF boundingRect = ChartPresenter::textBoundingRect(axis()->labelsFont(), labelList.at(i), axis()->labelsAngle());
114 114 boundingRect.moveCenter(labelCenter);
115 115 QPointF positionDiff(labelRect.topLeft() - boundingRect.topLeft());
116 116 QPointF labelPoint = center;
117 117 if (intervalAxis())
118 118 labelPoint += QPointF(labelPad, -labelCoordinate - (boundingRect.height() / 2.0));
119 119 else
120 120 labelPoint += QPointF(labelPad, labelPad - labelCoordinate);
121 121 labelRect.moveTopLeft(labelPoint);
122 122 labelItem->setPos(labelRect.topLeft() + positionDiff);
123 123
124 124 // Label overlap detection
125 125 labelRect.setSize(boundingRect.size());
126 126 if ((i && previousLabelRect.intersects(labelRect))
127 127 || !axisGeometry().contains(labelRect)) {
128 128 labelVisible = false;
129 129 } else {
130 130 previousLabelRect = labelRect;
131 131 labelVisible = true;
132 132 }
133 133 }
134 134
135 135 labelItem->setVisible(labelVisible);
136 136 if (!currentTickVisible) {
137 137 gridItem->setVisible(false);
138 138 tickItem->setVisible(false);
139 139 if (shadeItem)
140 140 shadeItem->setVisible(false);
141 141 continue;
142 142 }
143 143
144 144 // Radial grid line
145 145 QRectF gridRect;
146 146 gridRect.setWidth(radialCoordinate * 2.0);
147 147 gridRect.setHeight(radialCoordinate * 2.0);
148 148 gridRect.moveCenter(center);
149 149
150 150 gridItem->setRect(gridRect);
151 151 gridItem->setVisible(true);
152 152
153 153 // Tick
154 154 QLineF tickLine(-tickWidth(), 0.0, tickWidth(), 0.0);
155 155 tickLine.translate(center.rx(), gridRect.top());
156 156 tickItem->setLine(tickLine);
157 157 tickItem->setVisible(true);
158 158
159 159 // Shades
160 160 if (i % 2 || (i == 0 && !nextTickVisible)) {
161 161 QPainterPath path;
162 162 if (i == 0) {
163 163 // If first tick is also the last, we need to custom fill the inner circle
164 164 // or it won't get filled.
165 165 QRectF innerCircle(0.0, 0.0, layout.at(0) * 2.0, layout.at(0) * 2.0);
166 166 innerCircle.moveCenter(center);
167 167 path.addEllipse(innerCircle);
168 168 } else {
169 169 QRectF otherGridRect;
170 170 if (!nextTickVisible) { // Last visible tick
171 171 otherGridRect = axisGeometry();
172 172 } else {
173 173 qreal otherGridRectDimension = layout.at(i + 1) * 2.0;
174 174 otherGridRect.setWidth(otherGridRectDimension);
175 175 otherGridRect.setHeight(otherGridRectDimension);
176 176 otherGridRect.moveCenter(center);
177 177 }
178 178 path.addEllipse(gridRect);
179 179 path.addEllipse(otherGridRect);
180 180
181 181 // Add additional shading in first visible shade item if there is a partial tick
182 182 // to be filled at the center (log & category axes)
183 183 if (firstShade) {
184 184 QGraphicsPathItem *specialShadeItem = static_cast<QGraphicsPathItem *>(shadeItemList.at(0));
185 185 if (layout.at(i - 1) > 0.0) {
186 186 QRectF innerCircle(0.0, 0.0, layout.at(i - 1) * 2.0, layout.at(i - 1) * 2.0);
187 187 innerCircle.moveCenter(center);
188 188 QPainterPath specialPath;
189 189 specialPath.addEllipse(innerCircle);
190 190 specialShadeItem->setPath(specialPath);
191 191 specialShadeItem->setVisible(true);
192 192 } else {
193 193 specialShadeItem->setVisible(false);
194 194 }
195 195 }
196 196 }
197 197 shadeItem->setPath(path);
198 198 shadeItem->setVisible(true);
199 199 firstShade = false;
200 200 }
201 201 }
202 202
203 203 // Title, along the 0 axis
204 204 QString titleText = axis()->titleText();
205 205 if (!titleText.isEmpty() && axis()->isTitleVisible()) {
206 title->setHtml(ChartPresenter::truncatedText(axis()->titleFont(), titleText, qreal(0.0), radius, Qt::Horizontal, QRectF()));
206 QRectF dummyRect;
207 title->setHtml(ChartPresenter::truncatedText(axis()->titleFont(), titleText, qreal(0.0), radius, Qt::Horizontal, dummyRect));
207 208
208 209 QRectF titleBoundingRect = title->boundingRect();
209 210 QPointF titleCenter = titleBoundingRect.center();
210 211 QPointF arrowCenter = axisLine->boundingRect().center();
211 212 QPointF titleCenterDiff = arrowCenter - titleCenter;
212 213 title->setPos(titleCenterDiff.x() - titlePadding() - (titleBoundingRect.height() / 2.0), titleCenterDiff.y());
213 214 title->setTransformOriginPoint(titleCenter);
214 215 title->setRotation(270.0);
215 216 }
216 217
217 218 QGraphicsLayoutItem::updateGeometry();
218 219 }
219 220
220 221 Qt::Orientation PolarChartAxisRadial::orientation() const
221 222 {
222 223 return Qt::Vertical;
223 224 }
224 225
225 226 void PolarChartAxisRadial::createItems(int count)
226 227 {
227 228 if (arrowItems().count() == 0) {
228 229 // radial axis center line
229 230 QGraphicsLineItem *arrow = new LineArrowItem(this, presenter()->rootItem());
230 231 arrow->setPen(axis()->linePen());
231 232 arrowGroup()->addToGroup(arrow);
232 233 }
233 234
234 235 for (int i = 0; i < count; ++i) {
235 236 QGraphicsLineItem *arrow = new QGraphicsLineItem(presenter()->rootItem());
236 237 QGraphicsEllipseItem *grid = new QGraphicsEllipseItem(presenter()->rootItem());
237 238 QGraphicsTextItem *label = new QGraphicsTextItem(presenter()->rootItem());
238 239 QGraphicsTextItem *title = titleItem();
239 240 arrow->setPen(axis()->linePen());
240 241 grid->setPen(axis()->gridLinePen());
241 242 label->setFont(axis()->labelsFont());
242 243 label->setDefaultTextColor(axis()->labelsBrush().color());
243 244 label->setRotation(axis()->labelsAngle());
244 245 title->setFont(axis()->titleFont());
245 246 title->setDefaultTextColor(axis()->titleBrush().color());
246 247 title->setHtml(axis()->titleText());
247 248 arrowGroup()->addToGroup(arrow);
248 249 gridGroup()->addToGroup(grid);
249 250 labelGroup()->addToGroup(label);
250 251 if (gridItems().size() == 1 || (((gridItems().size() + 1) % 2) && gridItems().size() > 0)) {
251 252 QGraphicsPathItem *shade = new QGraphicsPathItem(presenter()->rootItem());
252 253 shade->setPen(axis()->shadesPen());
253 254 shade->setBrush(axis()->shadesBrush());
254 255 shadeGroup()->addToGroup(shade);
255 256 }
256 257 }
257 258 }
258 259
259 260 void PolarChartAxisRadial::handleArrowPenChanged(const QPen &pen)
260 261 {
261 262 foreach (QGraphicsItem *item, arrowItems())
262 263 static_cast<QGraphicsLineItem *>(item)->setPen(pen);
263 264 }
264 265
265 266 void PolarChartAxisRadial::handleGridPenChanged(const QPen &pen)
266 267 {
267 268 foreach (QGraphicsItem *item, gridItems())
268 269 static_cast<QGraphicsEllipseItem *>(item)->setPen(pen);
269 270 }
270 271
271 272 QSizeF PolarChartAxisRadial::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
272 273 {
273 274 Q_UNUSED(which);
274 275 Q_UNUSED(constraint);
275 276 return QSizeF(-1.0, -1.0);
276 277 }
277 278
278 279 qreal PolarChartAxisRadial::preferredAxisRadius(const QSizeF &maxSize)
279 280 {
280 281 qreal radius = maxSize.height() / 2.0;
281 282 if (maxSize.width() < maxSize.height())
282 283 radius = maxSize.width() / 2.0;
283 284 return radius;
284 285 }
285 286
286 287 #include "moc_polarchartaxisradial_p.cpp"
287 288
288 289 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,86 +1,87
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2013 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "charttitle_p.h"
22 22 #include "chartpresenter_p.h"
23 23 #include <QFont>
24 24 #include <QFontMetrics>
25 25 #include <QDebug>
26 26
27 27 QTCOMMERCIALCHART_BEGIN_NAMESPACE
28 28
29 29 ChartTitle::ChartTitle(QGraphicsItem *parent)
30 30 : QGraphicsTextItem(parent)
31 31 {
32 32
33 33 }
34 34
35 35 ChartTitle::~ChartTitle()
36 36 {
37 37
38 38 }
39 39
40 40 void ChartTitle::setText(const QString &text)
41 41 {
42 42 m_text = text;
43 43 }
44 44
45 45 QString ChartTitle::text() const
46 46 {
47 47 return m_text;
48 48 }
49 49
50 50 void ChartTitle::setGeometry(const QRectF &rect)
51 51 {
52 QGraphicsTextItem::setHtml(ChartPresenter::truncatedText(font(), m_text, qreal(0.0), rect.width(), Qt::Horizontal, QRectF()));
52 QRectF dummyRect;
53 QGraphicsTextItem::setHtml(ChartPresenter::truncatedText(font(), m_text, qreal(0.0), rect.width(), Qt::Horizontal, dummyRect));
53 54 setPos(rect.topLeft());
54 55 }
55 56
56 57
57 58 QSizeF ChartTitle::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
58 59 {
59 60 Q_UNUSED(constraint);
60 61 QSizeF sh;
61 62
62 63 switch (which) {
63 64 case Qt::MinimumSize: {
64 65 QRectF titleRect = ChartPresenter::textBoundingRect(font(), "...");
65 66 sh = QSizeF(titleRect.width(), titleRect.height());
66 67 break;
67 68 }
68 69 case Qt::PreferredSize:
69 70 case Qt::MaximumSize: {
70 71 QRectF titleRect = ChartPresenter::textBoundingRect(font(), m_text);
71 72 sh = QSizeF(titleRect.width(), titleRect.height());
72 73 break;
73 74 }
74 75 case Qt::MinimumDescent: {
75 76 QFontMetrics fn(font());
76 77 sh = QSizeF(0, fn.descent());
77 78 break;
78 79 }
79 80 default:
80 81 break;
81 82 }
82 83
83 84 return sh;
84 85 }
85 86
86 87 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,20 +1,21
1 1 !include( ../tests.pri ) {
2 2 error( "Couldn't find the test.pri file!" )
3 3 }
4 4
5 5 QT += core gui
6 6
7 7 greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
8 8
9 9 TARGET = polarcharttest
10 10 TEMPLATE = app
11 INCLUDEPATH += .
11 12
12 13
13 14 SOURCES += main.cpp \
14 15 mainwindow.cpp \
15 16 chartview.cpp
16 17
17 18 HEADERS += mainwindow.h \
18 19 chartview.h
19 20
20 21 FORMS += mainwindow.ui
General Comments 0
You need to be logged in to leave comments. Login now