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