##// END OF EJS Templates
Fix some warnings for android build....
Miikka Heikkinen -
r2504:54fd83ddb7ed
parent child
Show More
@@ -1,120 +1,126
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 "polarchartaxis_p.h"
21 #include "polarchartaxis_p.h"
22 #include "qabstractaxis_p.h"
22 #include "qabstractaxis_p.h"
23 #include "chartpresenter_p.h"
23 #include "chartpresenter_p.h"
24
24
25 QTCOMMERCIALCHART_BEGIN_NAMESPACE
25 QTCOMMERCIALCHART_BEGIN_NAMESPACE
26
26
27 PolarChartAxis::PolarChartAxis(QAbstractAxis *axis, QGraphicsItem *item, bool intervalAxis)
27 PolarChartAxis::PolarChartAxis(QAbstractAxis *axis, QGraphicsItem *item, bool intervalAxis)
28 : ChartAxisElement(axis, item, intervalAxis)
28 : ChartAxisElement(axis, item, intervalAxis)
29 {
29 {
30 }
30 }
31
31
32 PolarChartAxis::~PolarChartAxis()
32 PolarChartAxis::~PolarChartAxis()
33 {
33 {
34
34
35 }
35 }
36
36
37 void PolarChartAxis::setGeometry(const QRectF &axis, const QRectF &grid)
37 void PolarChartAxis::setGeometry(const QRectF &axis, const QRectF &grid)
38 {
38 {
39 Q_UNUSED(grid);
39 Q_UNUSED(grid);
40 setAxisGeometry(axis);
40 setAxisGeometry(axis);
41
41
42 if (isEmpty())
42 if (isEmpty())
43 return;
43 return;
44
44
45 QVector<qreal> layout = calculateLayout();
45 QVector<qreal> layout = calculateLayout();
46 updateLayout(layout);
46 updateLayout(layout);
47 }
47 }
48
48
49 QRectF PolarChartAxis::gridGeometry() const
49 QRectF PolarChartAxis::gridGeometry() const
50 {
50 {
51 return QRectF();
51 return QRectF();
52 }
52 }
53
53
54 void PolarChartAxis::updateLayout(QVector<qreal> &layout)
54 void PolarChartAxis::updateLayout(QVector<qreal> &layout)
55 {
55 {
56 int diff = ChartAxisElement::layout().size() - layout.size();
56 int diff = ChartAxisElement::layout().size() - layout.size();
57
57
58 if (animation()) {
58 if (animation()) {
59 switch (presenter()->state()) {
59 switch (presenter()->state()) {
60 case ChartPresenter::ZoomInState:
61 case ChartPresenter::ZoomOutState:
62 case ChartPresenter::ScrollUpState:
63 case ChartPresenter::ScrollLeftState:
64 case ChartPresenter::ScrollDownState:
65 case ChartPresenter::ScrollRightState:
60 case ChartPresenter::ShowState:
66 case ChartPresenter::ShowState:
61 animation()->setAnimationType(AxisAnimation::DefaultAnimation);
67 animation()->setAnimationType(AxisAnimation::DefaultAnimation);
62 break;
68 break;
63 }
69 }
64 // Update to "old" geometry before starting animation to avoid incorrectly sized
70 // Update to "old" geometry before starting animation to avoid incorrectly sized
65 // axes lingering in wrong position compared to series plot before animation can kick in.
71 // axes lingering in wrong position compared to series plot before animation can kick in.
66 // Note that the position mismatch still exists even with this update, but it will be
72 // Note that the position mismatch still exists even with this update, but it will be
67 // far less ugly.
73 // far less ugly.
68 updateGeometry();
74 updateGeometry();
69 }
75 }
70
76
71 if (diff > 0)
77 if (diff > 0)
72 deleteItems(diff);
78 deleteItems(diff);
73 else if (diff < 0)
79 else if (diff < 0)
74 createItems(-diff);
80 createItems(-diff);
75
81
76 if (animation()) {
82 if (animation()) {
77 animation()->setValues(ChartAxisElement::layout(), layout);
83 animation()->setValues(ChartAxisElement::layout(), layout);
78 presenter()->startAnimation(animation());
84 presenter()->startAnimation(animation());
79 } else {
85 } else {
80 setLayout(layout);
86 setLayout(layout);
81 updateGeometry();
87 updateGeometry();
82 }
88 }
83 }
89 }
84
90
85 bool PolarChartAxis::isEmpty()
91 bool PolarChartAxis::isEmpty()
86 {
92 {
87 return !axisGeometry().isValid() || qFuzzyIsNull(min() - max());
93 return !axisGeometry().isValid() || qFuzzyIsNull(min() - max());
88 }
94 }
89
95
90 void PolarChartAxis::deleteItems(int count)
96 void PolarChartAxis::deleteItems(int count)
91 {
97 {
92 QList<QGraphicsItem *> gridLines = gridItems();
98 QList<QGraphicsItem *> gridLines = gridItems();
93 QList<QGraphicsItem *> labels = labelItems();
99 QList<QGraphicsItem *> labels = labelItems();
94 QList<QGraphicsItem *> shades = shadeItems();
100 QList<QGraphicsItem *> shades = shadeItems();
95 QList<QGraphicsItem *> axis = arrowItems();
101 QList<QGraphicsItem *> axis = arrowItems();
96
102
97 for (int i = 0; i < count; ++i) {
103 for (int i = 0; i < count; ++i) {
98 if (gridItems().size() == 1 || (((gridLines.size() + 1) % 2) && gridLines.size() > 0))
104 if (gridItems().size() == 1 || (((gridLines.size() + 1) % 2) && gridLines.size() > 0))
99 delete(shades.takeLast());
105 delete(shades.takeLast());
100 delete(gridLines.takeLast());
106 delete(gridLines.takeLast());
101 delete(labels.takeLast());
107 delete(labels.takeLast());
102 delete(axis.takeLast());
108 delete(axis.takeLast());
103 }
109 }
104 }
110 }
105
111
106 void PolarChartAxis::handleShadesBrushChanged(const QBrush &brush)
112 void PolarChartAxis::handleShadesBrushChanged(const QBrush &brush)
107 {
113 {
108 foreach (QGraphicsItem *item, shadeItems())
114 foreach (QGraphicsItem *item, shadeItems())
109 static_cast<QGraphicsPathItem *>(item)->setBrush(brush);
115 static_cast<QGraphicsPathItem *>(item)->setBrush(brush);
110 }
116 }
111
117
112 void PolarChartAxis::handleShadesPenChanged(const QPen &pen)
118 void PolarChartAxis::handleShadesPenChanged(const QPen &pen)
113 {
119 {
114 foreach (QGraphicsItem *item, shadeItems())
120 foreach (QGraphicsItem *item, shadeItems())
115 static_cast<QGraphicsPathItem *>(item)->setPen(pen);
121 static_cast<QGraphicsPathItem *>(item)->setPen(pen);
116 }
122 }
117
123
118 #include "moc_polarchartaxis_p.cpp"
124 #include "moc_polarchartaxis_p.cpp"
119
125
120 QTCOMMERCIALCHART_END_NAMESPACE
126 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,428 +1,425
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 <QFontMetrics>
26 #include <QFontMetrics>
27 #include <QDebug>
27 #include <QDebug>
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 QGraphicsSimpleTextItem *title = titleItem();
55 QGraphicsSimpleTextItem *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 QFontMetrics fn(axis()->labelsFont());
62 QFontMetrics fn(axis()->labelsFont());
63 QRectF previousLabelRect;
63 QRectF previousLabelRect;
64 QRectF firstLabelRect;
64 QRectF firstLabelRect;
65
65
66 qreal labelHeight = 0;
66 qreal labelHeight = 0;
67
67
68 bool firstShade = true;
68 bool firstShade = true;
69 bool nextTickVisible = false;
69 bool nextTickVisible = false;
70 if (layout.size())
70 if (layout.size())
71 nextTickVisible = !(layout.at(0) < 0.0 || layout.at(0) > 360.0);
71 nextTickVisible = !(layout.at(0) < 0.0 || layout.at(0) > 360.0);
72
72
73 for (int i = 0; i < layout.size(); ++i) {
73 for (int i = 0; i < layout.size(); ++i) {
74 qreal angularCoordinate = layout.at(i);
74 qreal angularCoordinate = layout.at(i);
75
75
76 QGraphicsLineItem *gridLineItem = static_cast<QGraphicsLineItem *>(gridItemList.at(i));
76 QGraphicsLineItem *gridLineItem = static_cast<QGraphicsLineItem *>(gridItemList.at(i));
77 QGraphicsLineItem *tickItem = static_cast<QGraphicsLineItem *>(arrowItemList.at(i + 1));
77 QGraphicsLineItem *tickItem = static_cast<QGraphicsLineItem *>(arrowItemList.at(i + 1));
78 QGraphicsSimpleTextItem *labelItem = static_cast<QGraphicsSimpleTextItem *>(labelItemList.at(i));
78 QGraphicsSimpleTextItem *labelItem = static_cast<QGraphicsSimpleTextItem *>(labelItemList.at(i));
79 QGraphicsPathItem *shadeItem = 0;
79 QGraphicsPathItem *shadeItem = 0;
80 if (i == 0)
80 if (i == 0)
81 shadeItem = static_cast<QGraphicsPathItem *>(shadeItemList.at(0));
81 shadeItem = static_cast<QGraphicsPathItem *>(shadeItemList.at(0));
82 else if (i % 2)
82 else if (i % 2)
83 shadeItem = static_cast<QGraphicsPathItem *>(shadeItemList.at((i / 2) + 1));
83 shadeItem = static_cast<QGraphicsPathItem *>(shadeItemList.at((i / 2) + 1));
84
84
85 // Ignore ticks outside valid range
85 // Ignore ticks outside valid range
86 bool currentTickVisible = nextTickVisible;
86 bool currentTickVisible = nextTickVisible;
87 if ((i == layout.size() - 1)
87 if ((i == layout.size() - 1)
88 || layout.at(i + 1) < 0.0
88 || layout.at(i + 1) < 0.0
89 || layout.at(i + 1) > 360.0) {
89 || layout.at(i + 1) > 360.0) {
90 nextTickVisible = false;
90 nextTickVisible = false;
91 } else {
91 } else {
92 nextTickVisible = true;
92 nextTickVisible = true;
93 }
93 }
94
94
95 qreal labelCoordinate = angularCoordinate;
95 qreal labelCoordinate = angularCoordinate;
96 qreal labelVisible = currentTickVisible;
96 qreal labelVisible = currentTickVisible;
97 if (intervalAxis()) {
97 if (intervalAxis()) {
98 qreal farEdge;
98 qreal farEdge;
99 if (i == (layout.size() - 1))
99 if (i == (layout.size() - 1))
100 farEdge = 360.0;
100 farEdge = 360.0;
101 else
101 else
102 farEdge = qMin(360.0, layout.at(i + 1));
102 farEdge = qMin(qreal(360.0), layout.at(i + 1));
103
103
104 // Adjust the labelCoordinate to show it if next tick is visible
104 // Adjust the labelCoordinate to show it if next tick is visible
105 if (nextTickVisible)
105 if (nextTickVisible)
106 labelCoordinate = qMax(0.0, labelCoordinate);
106 labelCoordinate = qMax(qreal(0.0), labelCoordinate);
107
107
108 labelCoordinate = (labelCoordinate + farEdge) / 2.0;
108 labelCoordinate = (labelCoordinate + farEdge) / 2.0;
109 // Don't display label once the category gets too small near the axis
109 // Don't display label once the category gets too small near the axis
110 if (labelCoordinate < 5.0 || labelCoordinate > 355.0)
110 if (labelCoordinate < 5.0 || labelCoordinate > 355.0)
111 labelVisible = false;
111 labelVisible = false;
112 else
112 else
113 labelVisible = true;
113 labelVisible = true;
114 }
114 }
115
115
116 // Need this also in label calculations, so determine it first
116 // Need this also in label calculations, so determine it first
117 QLineF tickLine(QLineF::fromPolar(radius - tickWidth(), 90.0 - angularCoordinate).p2(),
117 QLineF tickLine(QLineF::fromPolar(radius - tickWidth(), 90.0 - angularCoordinate).p2(),
118 QLineF::fromPolar(radius + tickWidth(), 90.0 - angularCoordinate).p2());
118 QLineF::fromPolar(radius + tickWidth(), 90.0 - angularCoordinate).p2());
119 tickLine.translate(center);
119 tickLine.translate(center);
120
120
121 // Angular axis label
121 // Angular axis label
122 if (axis()->labelsVisible() && labelVisible) {
122 if (axis()->labelsVisible() && labelVisible) {
123 labelItem->setText(labelList.at(i));
123 labelItem->setText(labelList.at(i));
124 const QRectF &rect = labelItem->boundingRect();
124 const QRectF &rect = labelItem->boundingRect();
125 QPointF labelCenter = rect.center();
125 QPointF labelCenter = rect.center();
126 labelItem->setTransformOriginPoint(labelCenter.x(), labelCenter.y());
126 labelItem->setTransformOriginPoint(labelCenter.x(), labelCenter.y());
127 QRectF boundingRect = labelBoundingRect(fn, labelList.at(i));
127 QRectF boundingRect = labelBoundingRect(fn, labelList.at(i));
128 boundingRect.moveCenter(labelCenter);
128 boundingRect.moveCenter(labelCenter);
129 QPointF positionDiff(rect.topLeft() - boundingRect.topLeft());
129 QPointF positionDiff(rect.topLeft() - boundingRect.topLeft());
130
130
131 QPointF labelPoint;
131 QPointF labelPoint;
132 if (intervalAxis()) {
132 if (intervalAxis()) {
133 QLineF labelLine = QLineF::fromPolar(radius + tickWidth(), 90.0 - labelCoordinate);
133 QLineF labelLine = QLineF::fromPolar(radius + tickWidth(), 90.0 - labelCoordinate);
134 labelLine.translate(center);
134 labelLine.translate(center);
135 labelPoint = labelLine.p2();
135 labelPoint = labelLine.p2();
136 } else {
136 } else {
137 labelPoint = tickLine.p2();
137 labelPoint = tickLine.p2();
138 }
138 }
139
139
140 QRectF labelRect = moveLabelToPosition(labelCoordinate, labelPoint, boundingRect);
140 QRectF labelRect = moveLabelToPosition(labelCoordinate, labelPoint, boundingRect);
141 labelItem->setPos(labelRect.topLeft() + positionDiff);
141 labelItem->setPos(labelRect.topLeft() + positionDiff);
142
142
143 // Store height for title calculations
143 // Store height for title calculations
144 qreal labelClearance = axisGeometry().top() - labelRect.top();
144 qreal labelClearance = axisGeometry().top() - labelRect.top();
145 labelHeight = qMax(labelHeight, labelClearance);
145 labelHeight = qMax(labelHeight, labelClearance);
146
146
147 // Label overlap detection
147 // Label overlap detection
148 if (i && (previousLabelRect.intersects(labelRect) || firstLabelRect.intersects(labelRect))) {
148 if (i && (previousLabelRect.intersects(labelRect) || firstLabelRect.intersects(labelRect))) {
149 labelVisible = false;
149 labelVisible = false;
150 } else {
150 } else {
151 // Store labelRect for future comparison. Some area is deducted to make things look
151 // Store labelRect for future comparison. Some area is deducted to make things look
152 // little nicer, as usually intersection happens at label corner with angular labels.
152 // little nicer, as usually intersection happens at label corner with angular labels.
153 labelRect.adjust(-2.0, -4.0, -2.0, -4.0);
153 labelRect.adjust(-2.0, -4.0, -2.0, -4.0);
154 if (firstLabelRect.isEmpty())
154 if (firstLabelRect.isEmpty())
155 firstLabelRect = labelRect;
155 firstLabelRect = labelRect;
156
156
157 previousLabelRect = labelRect;
157 previousLabelRect = labelRect;
158 labelVisible = true;
158 labelVisible = true;
159 }
159 }
160 }
160 }
161
161
162 labelItem->setVisible(labelVisible);
162 labelItem->setVisible(labelVisible);
163 if (!currentTickVisible) {
163 if (!currentTickVisible) {
164 gridLineItem->setVisible(false);
164 gridLineItem->setVisible(false);
165 tickItem->setVisible(false);
165 tickItem->setVisible(false);
166 if (shadeItem)
166 if (shadeItem)
167 shadeItem->setVisible(false);
167 shadeItem->setVisible(false);
168 continue;
168 continue;
169 }
169 }
170
170
171 // Angular grid line
171 // Angular grid line
172 QLineF gridLine = QLineF::fromPolar(radius, 90.0 - angularCoordinate);
172 QLineF gridLine = QLineF::fromPolar(radius, 90.0 - angularCoordinate);
173 gridLine.translate(center);
173 gridLine.translate(center);
174 gridLineItem->setLine(gridLine);
174 gridLineItem->setLine(gridLine);
175 gridLineItem->setVisible(true);
175 gridLineItem->setVisible(true);
176
176
177 // Tick
177 // Tick
178 tickItem->setLine(tickLine);
178 tickItem->setLine(tickLine);
179 tickItem->setVisible(true);
179 tickItem->setVisible(true);
180
180
181 // Shades
181 // Shades
182 if (i % 2 || (i == 0 && !nextTickVisible)) {
182 if (i % 2 || (i == 0 && !nextTickVisible)) {
183 QPainterPath path;
183 QPainterPath path;
184 path.moveTo(center);
184 path.moveTo(center);
185 if (i == 0) {
185 if (i == 0) {
186 // If first tick is also the last, we need to custom fill the first partial arc
186 // If first tick is also the last, we need to custom fill the first partial arc
187 // or it won't get filled.
187 // or it won't get filled.
188 path.arcTo(axisGeometry(), 90.0 - layout.at(0), layout.at(0));
188 path.arcTo(axisGeometry(), 90.0 - layout.at(0), layout.at(0));
189 path.closeSubpath();
189 path.closeSubpath();
190 } else {
190 } else {
191 qreal nextCoordinate;
191 qreal nextCoordinate;
192 if (!nextTickVisible) // Last visible tick
192 if (!nextTickVisible) // Last visible tick
193 nextCoordinate = 360.0;
193 nextCoordinate = 360.0;
194 else
194 else
195 nextCoordinate = layout.at(i + 1);
195 nextCoordinate = layout.at(i + 1);
196 qreal arcSpan = angularCoordinate - nextCoordinate;
196 qreal arcSpan = angularCoordinate - nextCoordinate;
197 path.arcTo(axisGeometry(), 90.0 - angularCoordinate, arcSpan);
197 path.arcTo(axisGeometry(), 90.0 - angularCoordinate, arcSpan);
198 path.closeSubpath();
198 path.closeSubpath();
199
199
200 // Add additional arc for first shade item if there is a partial arc to be filled
200 // Add additional arc for first shade item if there is a partial arc to be filled
201 if (firstShade) {
201 if (firstShade) {
202 QGraphicsPathItem *specialShadeItem = static_cast<QGraphicsPathItem *>(shadeItemList.at(0));
202 QGraphicsPathItem *specialShadeItem = static_cast<QGraphicsPathItem *>(shadeItemList.at(0));
203 if (layout.at(i - 1) > 0.0) {
203 if (layout.at(i - 1) > 0.0) {
204 QPainterPath specialPath;
204 QPainterPath specialPath;
205 specialPath.moveTo(center);
205 specialPath.moveTo(center);
206 specialPath.arcTo(axisGeometry(), 90.0 - layout.at(i - 1), layout.at(i - 1));
206 specialPath.arcTo(axisGeometry(), 90.0 - layout.at(i - 1), layout.at(i - 1));
207 specialPath.closeSubpath();
207 specialPath.closeSubpath();
208 specialShadeItem->setPath(specialPath);
208 specialShadeItem->setPath(specialPath);
209 specialShadeItem->setVisible(true);
209 specialShadeItem->setVisible(true);
210 } else {
210 } else {
211 specialShadeItem->setVisible(false);
211 specialShadeItem->setVisible(false);
212 }
212 }
213 }
213 }
214 }
214 }
215 shadeItem->setPath(path);
215 shadeItem->setPath(path);
216 shadeItem->setVisible(true);
216 shadeItem->setVisible(true);
217 firstShade = false;
217 firstShade = false;
218 }
218 }
219 }
219 }
220
220
221 // Title, centered above the chart
221 // Title, centered above the chart
222 QString titleText = axis()->titleText();
222 QString titleText = axis()->titleText();
223 if (!titleText.isEmpty() && axis()->isTitleVisible()) {
223 if (!titleText.isEmpty() && axis()->isTitleVisible()) {
224 int size(0);
224 int size(0);
225 size = axisGeometry().width();
225 size = axisGeometry().width();
226
226
227 QFontMetrics titleMetrics(axis()->titleFont());
227 QFontMetrics titleMetrics(axis()->titleFont());
228 if (titleMetrics.boundingRect(titleText).width() > size) {
228 if (titleMetrics.boundingRect(titleText).width() > size) {
229 QString string = titleText + "...";
229 QString string = titleText + "...";
230 while (titleMetrics.boundingRect(string).width() > size && string.length() > 3)
230 while (titleMetrics.boundingRect(string).width() > size && string.length() > 3)
231 string.remove(string.length() - 4, 1);
231 string.remove(string.length() - 4, 1);
232 title->setText(string);
232 title->setText(string);
233 } else {
233 } else {
234 title->setText(titleText);
234 title->setText(titleText);
235 }
235 }
236
236
237 QRectF titleBoundingRect;
237 QRectF titleBoundingRect;
238 titleBoundingRect = title->boundingRect();
238 titleBoundingRect = title->boundingRect();
239 QPointF titleCenter = center - titleBoundingRect.center();
239 QPointF titleCenter = center - titleBoundingRect.center();
240 title->setPos(titleCenter.x(), axisGeometry().top() - qreal(titlePadding()) * 2.0 - titleBoundingRect.height() - labelHeight);
240 title->setPos(titleCenter.x(), axisGeometry().top() - qreal(titlePadding()) * 2.0 - titleBoundingRect.height() - labelHeight);
241 }
241 }
242 }
242 }
243
243
244 Qt::Orientation PolarChartAxisAngular::orientation() const
244 Qt::Orientation PolarChartAxisAngular::orientation() const
245 {
245 {
246 return Qt::Horizontal;
246 return Qt::Horizontal;
247 }
247 }
248
248
249 void PolarChartAxisAngular::createItems(int count)
249 void PolarChartAxisAngular::createItems(int count)
250 {
250 {
251 if (arrowItems().count() == 0) {
251 if (arrowItems().count() == 0) {
252 // angular axis line
252 // angular axis line
253 // TODO: need class similar to LineArrowItem for click handling?
253 // TODO: need class similar to LineArrowItem for click handling?
254 QGraphicsEllipseItem *arrow = new QGraphicsEllipseItem(presenter()->rootItem());
254 QGraphicsEllipseItem *arrow = new QGraphicsEllipseItem(presenter()->rootItem());
255 arrow->setPen(axis()->linePen());
255 arrow->setPen(axis()->linePen());
256 arrowGroup()->addToGroup(arrow);
256 arrowGroup()->addToGroup(arrow);
257 }
257 }
258
258
259 for (int i = 0; i < count; ++i) {
259 for (int i = 0; i < count; ++i) {
260 QGraphicsLineItem *arrow = new QGraphicsLineItem(presenter()->rootItem());
260 QGraphicsLineItem *arrow = new QGraphicsLineItem(presenter()->rootItem());
261 QGraphicsLineItem *grid = new QGraphicsLineItem(presenter()->rootItem());
261 QGraphicsLineItem *grid = new QGraphicsLineItem(presenter()->rootItem());
262 QGraphicsSimpleTextItem *label = new QGraphicsSimpleTextItem(presenter()->rootItem());
262 QGraphicsSimpleTextItem *label = new QGraphicsSimpleTextItem(presenter()->rootItem());
263 QGraphicsSimpleTextItem *title = titleItem();
263 QGraphicsSimpleTextItem *title = titleItem();
264 arrow->setPen(axis()->linePen());
264 arrow->setPen(axis()->linePen());
265 grid->setPen(axis()->gridLinePen());
265 grid->setPen(axis()->gridLinePen());
266 label->setFont(axis()->labelsFont());
266 label->setFont(axis()->labelsFont());
267 label->setPen(axis()->labelsPen());
267 label->setPen(axis()->labelsPen());
268 label->setBrush(axis()->labelsBrush());
268 label->setBrush(axis()->labelsBrush());
269 label->setRotation(axis()->labelsAngle());
269 label->setRotation(axis()->labelsAngle());
270 title->setFont(axis()->titleFont());
270 title->setFont(axis()->titleFont());
271 title->setPen(axis()->titlePen());
271 title->setPen(axis()->titlePen());
272 title->setBrush(axis()->titleBrush());
272 title->setBrush(axis()->titleBrush());
273 title->setText(axis()->titleText());
273 title->setText(axis()->titleText());
274 arrowGroup()->addToGroup(arrow);
274 arrowGroup()->addToGroup(arrow);
275 gridGroup()->addToGroup(grid);
275 gridGroup()->addToGroup(grid);
276 labelGroup()->addToGroup(label);
276 labelGroup()->addToGroup(label);
277 if (gridItems().size() == 1 || (((gridItems().size() + 1) % 2) && gridItems().size() > 0)) {
277 if (gridItems().size() == 1 || (((gridItems().size() + 1) % 2) && gridItems().size() > 0)) {
278 QGraphicsPathItem *shade = new QGraphicsPathItem(presenter()->rootItem());
278 QGraphicsPathItem *shade = new QGraphicsPathItem(presenter()->rootItem());
279 shade->setPen(axis()->shadesPen());
279 shade->setPen(axis()->shadesPen());
280 shade->setBrush(axis()->shadesBrush());
280 shade->setBrush(axis()->shadesBrush());
281 shadeGroup()->addToGroup(shade);
281 shadeGroup()->addToGroup(shade);
282 }
282 }
283 }
283 }
284 }
284 }
285
285
286 void PolarChartAxisAngular::handleArrowPenChanged(const QPen &pen)
286 void PolarChartAxisAngular::handleArrowPenChanged(const QPen &pen)
287 {
287 {
288 bool first = true;
288 bool first = true;
289 foreach (QGraphicsItem *item, arrowItems()) {
289 foreach (QGraphicsItem *item, arrowItems()) {
290 if (first) {
290 if (first) {
291 first = false;
291 first = false;
292 // First arrow item is the outer circle of axis
292 // First arrow item is the outer circle of axis
293 static_cast<QGraphicsEllipseItem *>(item)->setPen(pen);
293 static_cast<QGraphicsEllipseItem *>(item)->setPen(pen);
294 } else {
294 } else {
295 static_cast<QGraphicsLineItem *>(item)->setPen(pen);
295 static_cast<QGraphicsLineItem *>(item)->setPen(pen);
296 }
296 }
297 }
297 }
298 }
298 }
299
299
300 void PolarChartAxisAngular::handleGridPenChanged(const QPen &pen)
300 void PolarChartAxisAngular::handleGridPenChanged(const QPen &pen)
301 {
301 {
302 foreach (QGraphicsItem *item, gridItems())
302 foreach (QGraphicsItem *item, gridItems())
303 static_cast<QGraphicsLineItem *>(item)->setPen(pen);
303 static_cast<QGraphicsLineItem *>(item)->setPen(pen);
304 }
304 }
305
305
306 QSizeF PolarChartAxisAngular::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
306 QSizeF PolarChartAxisAngular::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
307 {
307 {
308 Q_UNUSED(which);
308 Q_UNUSED(which);
309 Q_UNUSED(constraint);
309 Q_UNUSED(constraint);
310 return QSizeF(-1, -1);
310 return QSizeF(-1, -1);
311 }
311 }
312
312
313 qreal PolarChartAxisAngular::preferredAxisRadius(const QSizeF &maxSize)
313 qreal PolarChartAxisAngular::preferredAxisRadius(const QSizeF &maxSize)
314 {
314 {
315 qreal radius = maxSize.height() / 2.0;
315 qreal radius = maxSize.height() / 2.0;
316 if (maxSize.width() < maxSize.height())
316 if (maxSize.width() < maxSize.height())
317 radius = maxSize.width() / 2.0;
317 radius = maxSize.width() / 2.0;
318
318
319 int labelHeight = 0;
320
321 if (axis()->labelsVisible()) {
319 if (axis()->labelsVisible()) {
322 QVector<qreal> layout = calculateLayout();
320 QVector<qreal> layout = calculateLayout();
323 if (layout.isEmpty())
321 if (layout.isEmpty())
324 return radius;
322 return radius;
325
323
326 createAxisLabels(layout);
324 createAxisLabels(layout);
327 QStringList labelList = labels();
325 QStringList labelList = labels();
328 QFont font = axis()->labelsFont();
326 QFont font = axis()->labelsFont();
329
327
330 QRectF maxRect;
328 QRectF maxRect;
331 maxRect.setSize(maxSize);
329 maxRect.setSize(maxSize);
332 maxRect.moveCenter(QPointF(0.0, 0.0));
330 maxRect.moveCenter(QPointF(0.0, 0.0));
333
331
334 // This is a horrible way to find out the maximum radius for angular axis and its labels.
332 // This is a horrible way to find out the maximum radius for angular axis and its labels.
335 // It just increments the radius down until everyhing fits the constraint size.
333 // It just increments the radius down until everyhing fits the constraint size.
336 // Proper way would be to actually calculate it but this seems to work reasonably fast as it is.
334 // Proper way would be to actually calculate it but this seems to work reasonably fast as it is.
337 QFontMetrics fm(font);
335 QFontMetrics fm(font);
338 bool nextTickVisible = false;
336 bool nextTickVisible = false;
339 for (int i = 0; i < layout.size(); ) {
337 for (int i = 0; i < layout.size(); ) {
340 if ((i == layout.size() - 1)
338 if ((i == layout.size() - 1)
341 || layout.at(i + 1) < 0.0
339 || layout.at(i + 1) < 0.0
342 || layout.at(i + 1) > 360.0) {
340 || layout.at(i + 1) > 360.0) {
343 nextTickVisible = false;
341 nextTickVisible = false;
344 } else {
342 } else {
345 nextTickVisible = true;
343 nextTickVisible = true;
346 }
344 }
347
345
348 qreal labelCoordinate = layout.at(i);
346 qreal labelCoordinate = layout.at(i);
349 qreal labelVisible;
347 qreal labelVisible;
350
348
351 if (intervalAxis()) {
349 if (intervalAxis()) {
352 qreal farEdge;
350 qreal farEdge;
353 if (i == (layout.size() - 1))
351 if (i == (layout.size() - 1))
354 farEdge = 360.0;
352 farEdge = 360.0;
355 else
353 else
356 farEdge = qMin(360.0, layout.at(i + 1));
354 farEdge = qMin(qreal(360.0), layout.at(i + 1));
357
355
358 // Adjust the labelCoordinate to show it if next tick is visible
356 // Adjust the labelCoordinate to show it if next tick is visible
359 if (nextTickVisible)
357 if (nextTickVisible)
360 labelCoordinate = qMax(0.0, labelCoordinate);
358 labelCoordinate = qMax(qreal(0.0), labelCoordinate);
361
359
362 labelCoordinate = (labelCoordinate + farEdge) / 2.0;
360 labelCoordinate = (labelCoordinate + farEdge) / 2.0;
363 }
361 }
364
362
365 if (labelCoordinate < 0.0 || labelCoordinate > 360.0)
363 if (labelCoordinate < 0.0 || labelCoordinate > 360.0)
366 labelVisible = false;
364 labelVisible = false;
367 else
365 else
368 labelVisible = true;
366 labelVisible = true;
369
367
370 if (!labelVisible) {
368 if (!labelVisible) {
371 i++;
369 i++;
372 continue;
370 continue;
373 }
371 }
374
372
375 QRectF boundingRect = labelBoundingRect(fm, labelList.at(i));
373 QRectF boundingRect = labelBoundingRect(fm, labelList.at(i));
376 labelHeight = boundingRect.height();
377 QPointF labelPoint = QLineF::fromPolar(radius + tickWidth(), 90.0 - labelCoordinate).p2();
374 QPointF labelPoint = QLineF::fromPolar(radius + tickWidth(), 90.0 - labelCoordinate).p2();
378
375
379 boundingRect = moveLabelToPosition(labelCoordinate, labelPoint, boundingRect);
376 boundingRect = moveLabelToPosition(labelCoordinate, labelPoint, boundingRect);
380 if (boundingRect.isEmpty() || maxRect.intersected(boundingRect) == boundingRect) {
377 if (boundingRect.isEmpty() || maxRect.intersected(boundingRect) == boundingRect) {
381 i++;
378 i++;
382 } else {
379 } else {
383 radius -= 1.0;
380 radius -= 1.0;
384 if (radius < 1.0) // safeguard
381 if (radius < 1.0) // safeguard
385 return 1.0;
382 return 1.0;
386 }
383 }
387 }
384 }
388 }
385 }
389
386
390 if (!axis()->titleText().isEmpty() && axis()->isTitleVisible()) {
387 if (!axis()->titleText().isEmpty() && axis()->isTitleVisible()) {
391 QFontMetrics titleMetrics(axis()->titleFont());
388 QFontMetrics titleMetrics(axis()->titleFont());
392 int titleHeight = titleMetrics.boundingRect(axis()->titleText()).height();
389 int titleHeight = titleMetrics.boundingRect(axis()->titleText()).height();
393 radius -= titlePadding() + (titleHeight / 2);
390 radius -= titlePadding() + (titleHeight / 2);
394 if (radius < 1.0) // safeguard
391 if (radius < 1.0) // safeguard
395 return 1.0;
392 return 1.0;
396 }
393 }
397
394
398 return radius;
395 return radius;
399 }
396 }
400
397
401 QRectF PolarChartAxisAngular::moveLabelToPosition(qreal angularCoordinate, QPointF labelPoint, QRectF labelRect) const
398 QRectF PolarChartAxisAngular::moveLabelToPosition(qreal angularCoordinate, QPointF labelPoint, QRectF labelRect) const
402 {
399 {
403 // TODO use fuzzy compare for "==" cases?
400 // TODO use fuzzy compare for "==" cases?
404 // TODO Adjust the rect position near 0, 90, 180, and 270 angles for smoother animation?
401 // TODO Adjust the rect position near 0, 90, 180, and 270 angles for smoother animation?
405 if (angularCoordinate == 0.0)
402 if (angularCoordinate == 0.0)
406 labelRect.moveCenter(labelPoint + QPointF(0, -labelRect.height() / 2.0));
403 labelRect.moveCenter(labelPoint + QPointF(0, -labelRect.height() / 2.0));
407 else if (angularCoordinate < 90.0)
404 else if (angularCoordinate < 90.0)
408 labelRect.moveBottomLeft(labelPoint);
405 labelRect.moveBottomLeft(labelPoint);
409 else if (angularCoordinate == 90.0)
406 else if (angularCoordinate == 90.0)
410 labelRect.moveCenter(labelPoint + QPointF(labelRect.width() / 2.0 + 2.0, 0)); // +2 so that it does not hit the radial axis
407 labelRect.moveCenter(labelPoint + QPointF(labelRect.width() / 2.0 + 2.0, 0)); // +2 so that it does not hit the radial axis
411 else if (angularCoordinate < 180.0)
408 else if (angularCoordinate < 180.0)
412 labelRect.moveTopLeft(labelPoint);
409 labelRect.moveTopLeft(labelPoint);
413 else if (angularCoordinate == 180.0)
410 else if (angularCoordinate == 180.0)
414 labelRect.moveCenter(labelPoint + QPointF(0, labelRect.height() / 2.0));
411 labelRect.moveCenter(labelPoint + QPointF(0, labelRect.height() / 2.0));
415 else if (angularCoordinate < 270.0)
412 else if (angularCoordinate < 270.0)
416 labelRect.moveTopRight(labelPoint);
413 labelRect.moveTopRight(labelPoint);
417 else if (angularCoordinate == 270.0)
414 else if (angularCoordinate == 270.0)
418 labelRect.moveCenter(labelPoint + QPointF(-labelRect.width() / 2.0 - 2.0, 0)); // -2 so that it does not hit the radial axis
415 labelRect.moveCenter(labelPoint + QPointF(-labelRect.width() / 2.0 - 2.0, 0)); // -2 so that it does not hit the radial axis
419 else if (angularCoordinate < 360.0)
416 else if (angularCoordinate < 360.0)
420 labelRect.moveBottomRight(labelPoint);
417 labelRect.moveBottomRight(labelPoint);
421 else
418 else
422 labelRect.moveCenter(labelPoint + QPointF(0, -labelRect.height() / 2.0));
419 labelRect.moveCenter(labelPoint + QPointF(0, -labelRect.height() / 2.0));
423 return labelRect;
420 return labelRect;
424 }
421 }
425
422
426 #include "moc_polarchartaxisangular_p.cpp"
423 #include "moc_polarchartaxisangular_p.cpp"
427
424
428 QTCOMMERCIALCHART_END_NAMESPACE
425 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,301 +1,301
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 #include <QFontMetrics>
26 #include <QFontMetrics>
27
27
28 QTCOMMERCIALCHART_BEGIN_NAMESPACE
28 QTCOMMERCIALCHART_BEGIN_NAMESPACE
29
29
30 PolarChartAxisRadial::PolarChartAxisRadial(QAbstractAxis *axis, QGraphicsItem *item, bool intervalAxis)
30 PolarChartAxisRadial::PolarChartAxisRadial(QAbstractAxis *axis, QGraphicsItem *item, bool intervalAxis)
31 : PolarChartAxis(axis, item, intervalAxis)
31 : PolarChartAxis(axis, item, intervalAxis)
32 {
32 {
33 }
33 }
34
34
35 PolarChartAxisRadial::~PolarChartAxisRadial()
35 PolarChartAxisRadial::~PolarChartAxisRadial()
36 {
36 {
37 }
37 }
38
38
39 void PolarChartAxisRadial::updateGeometry()
39 void PolarChartAxisRadial::updateGeometry()
40 {
40 {
41 const QVector<qreal> &layout = this->layout();
41 const QVector<qreal> &layout = this->layout();
42 if (layout.isEmpty())
42 if (layout.isEmpty())
43 return;
43 return;
44
44
45 createAxisLabels(layout);
45 createAxisLabels(layout);
46 QStringList labelList = labels();
46 QStringList labelList = labels();
47 QPointF center = axisGeometry().center();
47 QPointF center = axisGeometry().center();
48 QList<QGraphicsItem *> arrowItemList = arrowItems();
48 QList<QGraphicsItem *> arrowItemList = arrowItems();
49 QList<QGraphicsItem *> gridItemList = gridItems();
49 QList<QGraphicsItem *> gridItemList = gridItems();
50 QList<QGraphicsItem *> labelItemList = labelItems();
50 QList<QGraphicsItem *> labelItemList = labelItems();
51 QList<QGraphicsItem *> shadeItemList = shadeItems();
51 QList<QGraphicsItem *> shadeItemList = shadeItems();
52 QGraphicsSimpleTextItem* title = titleItem();
52 QGraphicsSimpleTextItem* title = titleItem();
53 qreal radius = axisGeometry().height() / 2.0;
53 qreal radius = axisGeometry().height() / 2.0;
54
54
55 QLineF line(center, center + QPointF(0, -radius));
55 QLineF line(center, center + QPointF(0, -radius));
56 QGraphicsLineItem *axisLine = static_cast<QGraphicsLineItem *>(arrowItemList.at(0));
56 QGraphicsLineItem *axisLine = static_cast<QGraphicsLineItem *>(arrowItemList.at(0));
57 axisLine->setLine(line);
57 axisLine->setLine(line);
58
58
59 QFontMetrics fn(axis()->labelsFont());
59 QFontMetrics fn(axis()->labelsFont());
60 QRectF previousLabelRect;
60 QRectF previousLabelRect;
61 bool firstShade = true;
61 bool firstShade = true;
62 bool nextTickVisible = false;
62 bool nextTickVisible = false;
63 if (layout.size())
63 if (layout.size())
64 nextTickVisible = !(layout.at(0) < 0.0 || layout.at(0) > radius);
64 nextTickVisible = !(layout.at(0) < 0.0 || layout.at(0) > radius);
65
65
66 for (int i = 0; i < layout.size(); ++i) {
66 for (int i = 0; i < layout.size(); ++i) {
67 qreal radialCoordinate = layout.at(i);
67 qreal radialCoordinate = layout.at(i);
68
68
69 QGraphicsEllipseItem *gridItem = static_cast<QGraphicsEllipseItem *>(gridItemList.at(i));
69 QGraphicsEllipseItem *gridItem = static_cast<QGraphicsEllipseItem *>(gridItemList.at(i));
70 QGraphicsLineItem *tickItem = static_cast<QGraphicsLineItem *>(arrowItemList.at(i + 1));
70 QGraphicsLineItem *tickItem = static_cast<QGraphicsLineItem *>(arrowItemList.at(i + 1));
71 QGraphicsSimpleTextItem *labelItem = static_cast<QGraphicsSimpleTextItem *>(labelItemList.at(i));
71 QGraphicsSimpleTextItem *labelItem = static_cast<QGraphicsSimpleTextItem *>(labelItemList.at(i));
72 QGraphicsPathItem *shadeItem = 0;
72 QGraphicsPathItem *shadeItem = 0;
73 if (i == 0)
73 if (i == 0)
74 shadeItem = static_cast<QGraphicsPathItem *>(shadeItemList.at(0));
74 shadeItem = static_cast<QGraphicsPathItem *>(shadeItemList.at(0));
75 else if (i % 2)
75 else if (i % 2)
76 shadeItem = static_cast<QGraphicsPathItem *>(shadeItemList.at((i / 2) + 1));
76 shadeItem = static_cast<QGraphicsPathItem *>(shadeItemList.at((i / 2) + 1));
77
77
78 // Ignore ticks outside valid range
78 // Ignore ticks outside valid range
79 bool currentTickVisible = nextTickVisible;
79 bool currentTickVisible = nextTickVisible;
80 if ((i == layout.size() - 1)
80 if ((i == layout.size() - 1)
81 || layout.at(i + 1) < 0.0
81 || layout.at(i + 1) < 0.0
82 || layout.at(i + 1) > radius) {
82 || layout.at(i + 1) > radius) {
83 nextTickVisible = false;
83 nextTickVisible = false;
84 } else {
84 } else {
85 nextTickVisible = true;
85 nextTickVisible = true;
86 }
86 }
87
87
88 qreal labelCoordinate = radialCoordinate;
88 qreal labelCoordinate = radialCoordinate;
89 qreal labelVisible = currentTickVisible;
89 qreal labelVisible = currentTickVisible;
90 qreal labelPad = labelPadding() / 2.0;
90 qreal labelPad = labelPadding() / 2.0;
91 if (intervalAxis()) {
91 if (intervalAxis()) {
92 qreal farEdge;
92 qreal farEdge;
93 if (i == (layout.size() - 1))
93 if (i == (layout.size() - 1))
94 farEdge = radius;
94 farEdge = radius;
95 else
95 else
96 farEdge = qMin(radius, layout.at(i + 1));
96 farEdge = qMin(radius, layout.at(i + 1));
97
97
98 // Adjust the labelCoordinate to show it if next tick is visible
98 // Adjust the labelCoordinate to show it if next tick is visible
99 if (nextTickVisible)
99 if (nextTickVisible)
100 labelCoordinate = qMax(0.0, labelCoordinate);
100 labelCoordinate = qMax(qreal(0.0), labelCoordinate);
101
101
102 labelCoordinate = (labelCoordinate + farEdge) / 2.0;
102 labelCoordinate = (labelCoordinate + farEdge) / 2.0;
103 if (labelCoordinate > 0.0 && labelCoordinate < radius)
103 if (labelCoordinate > 0.0 && labelCoordinate < radius)
104 labelVisible = true;
104 labelVisible = true;
105 else
105 else
106 labelVisible = false;
106 labelVisible = false;
107 }
107 }
108
108
109 // Radial axis label
109 // Radial axis label
110 if (axis()->labelsVisible() && labelVisible) {
110 if (axis()->labelsVisible() && labelVisible) {
111 labelItem->setText(labelList.at(i));
111 labelItem->setText(labelList.at(i));
112 QRectF labelRect = labelItem->boundingRect();
112 QRectF labelRect = labelItem->boundingRect();
113 QPointF labelCenter = labelRect.center();
113 QPointF labelCenter = labelRect.center();
114 labelItem->setTransformOriginPoint(labelCenter.x(), labelCenter.y());
114 labelItem->setTransformOriginPoint(labelCenter.x(), labelCenter.y());
115 QRectF boundingRect = labelBoundingRect(fn, labelList.at(i));
115 QRectF boundingRect = labelBoundingRect(fn, labelList.at(i));
116 boundingRect.moveCenter(labelCenter);
116 boundingRect.moveCenter(labelCenter);
117 QPointF positionDiff(labelRect.topLeft() - boundingRect.topLeft());
117 QPointF positionDiff(labelRect.topLeft() - boundingRect.topLeft());
118 QPointF labelPoint = center;
118 QPointF labelPoint = center;
119 if (intervalAxis())
119 if (intervalAxis())
120 labelPoint += QPointF(labelPad, -labelCoordinate - (boundingRect.height() / 2.0));
120 labelPoint += QPointF(labelPad, -labelCoordinate - (boundingRect.height() / 2.0));
121 else
121 else
122 labelPoint += QPointF(labelPad, labelPad - labelCoordinate);
122 labelPoint += QPointF(labelPad, labelPad - labelCoordinate);
123 labelRect.moveTopLeft(labelPoint);
123 labelRect.moveTopLeft(labelPoint);
124 labelItem->setPos(labelRect.topLeft() + positionDiff);
124 labelItem->setPos(labelRect.topLeft() + positionDiff);
125
125
126 // Label overlap detection
126 // Label overlap detection
127 labelRect.setSize(boundingRect.size());
127 labelRect.setSize(boundingRect.size());
128 if ((i && previousLabelRect.intersects(labelRect))
128 if ((i && previousLabelRect.intersects(labelRect))
129 || !axisGeometry().contains(labelRect)) {
129 || !axisGeometry().contains(labelRect)) {
130 labelVisible = false;
130 labelVisible = false;
131 } else {
131 } else {
132 previousLabelRect = labelRect;
132 previousLabelRect = labelRect;
133 labelVisible = true;
133 labelVisible = true;
134 }
134 }
135 }
135 }
136
136
137 labelItem->setVisible(labelVisible);
137 labelItem->setVisible(labelVisible);
138 if (!currentTickVisible) {
138 if (!currentTickVisible) {
139 gridItem->setVisible(false);
139 gridItem->setVisible(false);
140 tickItem->setVisible(false);
140 tickItem->setVisible(false);
141 if (shadeItem)
141 if (shadeItem)
142 shadeItem->setVisible(false);
142 shadeItem->setVisible(false);
143 continue;
143 continue;
144 }
144 }
145
145
146 // Radial grid line
146 // Radial grid line
147 QRectF gridRect;
147 QRectF gridRect;
148 gridRect.setWidth(radialCoordinate * 2.0);
148 gridRect.setWidth(radialCoordinate * 2.0);
149 gridRect.setHeight(radialCoordinate * 2.0);
149 gridRect.setHeight(radialCoordinate * 2.0);
150 gridRect.moveCenter(center);
150 gridRect.moveCenter(center);
151
151
152 gridItem->setRect(gridRect);
152 gridItem->setRect(gridRect);
153 gridItem->setVisible(true);
153 gridItem->setVisible(true);
154
154
155 // Tick
155 // Tick
156 QLineF tickLine(-tickWidth(), 0.0, tickWidth(), 0.0);
156 QLineF tickLine(-tickWidth(), 0.0, tickWidth(), 0.0);
157 tickLine.translate(center.rx(), gridRect.top());
157 tickLine.translate(center.rx(), gridRect.top());
158 tickItem->setLine(tickLine);
158 tickItem->setLine(tickLine);
159 tickItem->setVisible(true);
159 tickItem->setVisible(true);
160
160
161 // Shades
161 // Shades
162 if (i % 2 || (i == 0 && !nextTickVisible)) {
162 if (i % 2 || (i == 0 && !nextTickVisible)) {
163 QPainterPath path;
163 QPainterPath path;
164 if (i == 0) {
164 if (i == 0) {
165 // If first tick is also the last, we need to custom fill the inner circle
165 // If first tick is also the last, we need to custom fill the inner circle
166 // or it won't get filled.
166 // or it won't get filled.
167 QRectF innerCircle(0.0, 0.0, layout.at(0) * 2.0, layout.at(0) * 2.0);
167 QRectF innerCircle(0.0, 0.0, layout.at(0) * 2.0, layout.at(0) * 2.0);
168 innerCircle.moveCenter(center);
168 innerCircle.moveCenter(center);
169 path.addEllipse(innerCircle);
169 path.addEllipse(innerCircle);
170 } else {
170 } else {
171 QRectF otherGridRect;
171 QRectF otherGridRect;
172 if (!nextTickVisible) { // Last visible tick
172 if (!nextTickVisible) { // Last visible tick
173 otherGridRect = axisGeometry();
173 otherGridRect = axisGeometry();
174 } else {
174 } else {
175 qreal otherGridRectDimension = layout.at(i + 1) * 2.0;
175 qreal otherGridRectDimension = layout.at(i + 1) * 2.0;
176 otherGridRect.setWidth(otherGridRectDimension);
176 otherGridRect.setWidth(otherGridRectDimension);
177 otherGridRect.setHeight(otherGridRectDimension);
177 otherGridRect.setHeight(otherGridRectDimension);
178 otherGridRect.moveCenter(center);
178 otherGridRect.moveCenter(center);
179 }
179 }
180 path.addEllipse(gridRect);
180 path.addEllipse(gridRect);
181 path.addEllipse(otherGridRect);
181 path.addEllipse(otherGridRect);
182
182
183 // Add additional shading in first visible shade item if there is a partial tick
183 // Add additional shading in first visible shade item if there is a partial tick
184 // to be filled at the center (log & category axes)
184 // to be filled at the center (log & category axes)
185 if (firstShade) {
185 if (firstShade) {
186 QGraphicsPathItem *specialShadeItem = static_cast<QGraphicsPathItem *>(shadeItemList.at(0));
186 QGraphicsPathItem *specialShadeItem = static_cast<QGraphicsPathItem *>(shadeItemList.at(0));
187 if (layout.at(i - 1) > 0.0) {
187 if (layout.at(i - 1) > 0.0) {
188 QRectF innerCircle(0.0, 0.0, layout.at(i - 1) * 2.0, layout.at(i - 1) * 2.0);
188 QRectF innerCircle(0.0, 0.0, layout.at(i - 1) * 2.0, layout.at(i - 1) * 2.0);
189 innerCircle.moveCenter(center);
189 innerCircle.moveCenter(center);
190 QPainterPath specialPath;
190 QPainterPath specialPath;
191 specialPath.addEllipse(innerCircle);
191 specialPath.addEllipse(innerCircle);
192 specialShadeItem->setPath(specialPath);
192 specialShadeItem->setPath(specialPath);
193 specialShadeItem->setVisible(true);
193 specialShadeItem->setVisible(true);
194 } else {
194 } else {
195 specialShadeItem->setVisible(false);
195 specialShadeItem->setVisible(false);
196 }
196 }
197 }
197 }
198 }
198 }
199 shadeItem->setPath(path);
199 shadeItem->setPath(path);
200 shadeItem->setVisible(true);
200 shadeItem->setVisible(true);
201 firstShade = false;
201 firstShade = false;
202 }
202 }
203 }
203 }
204
204
205 // Title, along the 0 axis
205 // Title, along the 0 axis
206 QString titleText = axis()->titleText();
206 QString titleText = axis()->titleText();
207 if (!titleText.isEmpty() && axis()->isTitleVisible()) {
207 if (!titleText.isEmpty() && axis()->isTitleVisible()) {
208 QFontMetrics titleMetrics(axis()->titleFont());
208 QFontMetrics titleMetrics(axis()->titleFont());
209 if (titleMetrics.boundingRect(titleText).width() > radius) {
209 if (titleMetrics.boundingRect(titleText).width() > radius) {
210 QString string = titleText + "...";
210 QString string = titleText + "...";
211 while (titleMetrics.boundingRect(string).width() > radius && string.length() > 3)
211 while (titleMetrics.boundingRect(string).width() > radius && string.length() > 3)
212 string.remove(string.length() - 4, 1);
212 string.remove(string.length() - 4, 1);
213 title->setText(string);
213 title->setText(string);
214 } else {
214 } else {
215 title->setText(titleText);
215 title->setText(titleText);
216 }
216 }
217
217
218 QRectF titleBoundingRect;
218 QRectF titleBoundingRect;
219 titleBoundingRect = title->boundingRect();
219 titleBoundingRect = title->boundingRect();
220 QPointF titleCenter = titleBoundingRect.center();
220 QPointF titleCenter = titleBoundingRect.center();
221 QPointF arrowCenter = axisLine->boundingRect().center();
221 QPointF arrowCenter = axisLine->boundingRect().center();
222 QPointF titleCenterDiff = arrowCenter - titleCenter;
222 QPointF titleCenterDiff = arrowCenter - titleCenter;
223 title->setPos(titleCenterDiff.x() - qreal(titlePadding()) - (titleBoundingRect.height() / 2.0), titleCenterDiff.y());
223 title->setPos(titleCenterDiff.x() - qreal(titlePadding()) - (titleBoundingRect.height() / 2.0), titleCenterDiff.y());
224 title->setTransformOriginPoint(titleCenter);
224 title->setTransformOriginPoint(titleCenter);
225 title->setRotation(270.0);
225 title->setRotation(270.0);
226 }
226 }
227
227
228 QGraphicsLayoutItem::updateGeometry();
228 QGraphicsLayoutItem::updateGeometry();
229 }
229 }
230
230
231 Qt::Orientation PolarChartAxisRadial::orientation() const
231 Qt::Orientation PolarChartAxisRadial::orientation() const
232 {
232 {
233 return Qt::Vertical;
233 return Qt::Vertical;
234 }
234 }
235
235
236 void PolarChartAxisRadial::createItems(int count)
236 void PolarChartAxisRadial::createItems(int count)
237 {
237 {
238 if (arrowItems().count() == 0) {
238 if (arrowItems().count() == 0) {
239 // radial axis center line
239 // radial axis center line
240 QGraphicsLineItem *arrow = new LineArrowItem(this, presenter()->rootItem());
240 QGraphicsLineItem *arrow = new LineArrowItem(this, presenter()->rootItem());
241 arrow->setPen(axis()->linePen());
241 arrow->setPen(axis()->linePen());
242 arrowGroup()->addToGroup(arrow);
242 arrowGroup()->addToGroup(arrow);
243 }
243 }
244
244
245 for (int i = 0; i < count; ++i) {
245 for (int i = 0; i < count; ++i) {
246 QGraphicsLineItem *arrow = new QGraphicsLineItem(presenter()->rootItem());
246 QGraphicsLineItem *arrow = new QGraphicsLineItem(presenter()->rootItem());
247 QGraphicsEllipseItem *grid = new QGraphicsEllipseItem(presenter()->rootItem());
247 QGraphicsEllipseItem *grid = new QGraphicsEllipseItem(presenter()->rootItem());
248 QGraphicsSimpleTextItem *label = new QGraphicsSimpleTextItem(presenter()->rootItem());
248 QGraphicsSimpleTextItem *label = new QGraphicsSimpleTextItem(presenter()->rootItem());
249 QGraphicsSimpleTextItem *title = titleItem();
249 QGraphicsSimpleTextItem *title = titleItem();
250 arrow->setPen(axis()->linePen());
250 arrow->setPen(axis()->linePen());
251 grid->setPen(axis()->gridLinePen());
251 grid->setPen(axis()->gridLinePen());
252 label->setFont(axis()->labelsFont());
252 label->setFont(axis()->labelsFont());
253 label->setPen(axis()->labelsPen());
253 label->setPen(axis()->labelsPen());
254 label->setBrush(axis()->labelsBrush());
254 label->setBrush(axis()->labelsBrush());
255 label->setRotation(axis()->labelsAngle());
255 label->setRotation(axis()->labelsAngle());
256 title->setFont(axis()->titleFont());
256 title->setFont(axis()->titleFont());
257 title->setPen(axis()->titlePen());
257 title->setPen(axis()->titlePen());
258 title->setBrush(axis()->titleBrush());
258 title->setBrush(axis()->titleBrush());
259 title->setText(axis()->titleText());
259 title->setText(axis()->titleText());
260 arrowGroup()->addToGroup(arrow);
260 arrowGroup()->addToGroup(arrow);
261 gridGroup()->addToGroup(grid);
261 gridGroup()->addToGroup(grid);
262 labelGroup()->addToGroup(label);
262 labelGroup()->addToGroup(label);
263 if (gridItems().size() == 1 || (((gridItems().size() + 1) % 2) && gridItems().size() > 0)) {
263 if (gridItems().size() == 1 || (((gridItems().size() + 1) % 2) && gridItems().size() > 0)) {
264 QGraphicsPathItem *shade = new QGraphicsPathItem(presenter()->rootItem());
264 QGraphicsPathItem *shade = new QGraphicsPathItem(presenter()->rootItem());
265 shade->setPen(axis()->shadesPen());
265 shade->setPen(axis()->shadesPen());
266 shade->setBrush(axis()->shadesBrush());
266 shade->setBrush(axis()->shadesBrush());
267 shadeGroup()->addToGroup(shade);
267 shadeGroup()->addToGroup(shade);
268 }
268 }
269 }
269 }
270 }
270 }
271
271
272 void PolarChartAxisRadial::handleArrowPenChanged(const QPen &pen)
272 void PolarChartAxisRadial::handleArrowPenChanged(const QPen &pen)
273 {
273 {
274 foreach (QGraphicsItem *item, arrowItems())
274 foreach (QGraphicsItem *item, arrowItems())
275 static_cast<QGraphicsLineItem *>(item)->setPen(pen);
275 static_cast<QGraphicsLineItem *>(item)->setPen(pen);
276 }
276 }
277
277
278 void PolarChartAxisRadial::handleGridPenChanged(const QPen &pen)
278 void PolarChartAxisRadial::handleGridPenChanged(const QPen &pen)
279 {
279 {
280 foreach (QGraphicsItem *item, gridItems())
280 foreach (QGraphicsItem *item, gridItems())
281 static_cast<QGraphicsEllipseItem *>(item)->setPen(pen);
281 static_cast<QGraphicsEllipseItem *>(item)->setPen(pen);
282 }
282 }
283
283
284 QSizeF PolarChartAxisRadial::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
284 QSizeF PolarChartAxisRadial::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
285 {
285 {
286 Q_UNUSED(which);
286 Q_UNUSED(which);
287 Q_UNUSED(constraint);
287 Q_UNUSED(constraint);
288 return QSizeF(-1.0, -1.0);
288 return QSizeF(-1.0, -1.0);
289 }
289 }
290
290
291 qreal PolarChartAxisRadial::preferredAxisRadius(const QSizeF &maxSize)
291 qreal PolarChartAxisRadial::preferredAxisRadius(const QSizeF &maxSize)
292 {
292 {
293 qreal radius = maxSize.height() / 2.0;
293 qreal radius = maxSize.height() / 2.0;
294 if (maxSize.width() < maxSize.height())
294 if (maxSize.width() < maxSize.height())
295 radius = maxSize.width() / 2.0;
295 radius = maxSize.width() / 2.0;
296 return radius;
296 return radius;
297 }
297 }
298
298
299 #include "moc_polarchartaxisradial_p.cpp"
299 #include "moc_polarchartaxisradial_p.cpp"
300
300
301 QTCOMMERCIALCHART_END_NAMESPACE
301 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,86 +1,86
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 // W A R N I N G
21 // W A R N I N G
22 // -------------
22 // -------------
23 //
23 //
24 // This file is not part of the QtCommercial Chart API. It exists purely as an
24 // This file is not part of the QtCommercial Chart API. It exists purely as an
25 // implementation detail. This header file may change from version to
25 // implementation detail. This header file may change from version to
26 // version without notice, or even be removed.
26 // version without notice, or even be removed.
27 //
27 //
28 // We mean it.
28 // We mean it.
29
29
30 #ifndef CHARTCONFIG_H
30 #ifndef CHARTCONFIG_H
31 #define CHARTCONFIG_H
31 #define CHARTCONFIG_H
32
32
33 #include "qchartglobal.h"
33 #include "qchartglobal.h"
34
34
35 #ifdef Q_CC_MSVC
35 #ifdef Q_CC_MSVC
36 // There is a problem with jom.exe currently. It does not seem to understand QMAKE_EXTRA_TARGETS properly.
36 // There is a problem with jom.exe currently. It does not seem to understand QMAKE_EXTRA_TARGETS properly.
37 // This is the case at least with shadow builds.
37 // This is the case at least with shadow builds.
38 // http://qt-project.org/wiki/jom
38 // http://qt-project.org/wiki/jom
39 #undef DEVELOPMENT_BUILD
39 #undef DEVELOPMENT_BUILD
40 #endif
40 #endif
41
41
42 #ifndef DEVELOPMENT_BUILD
42 #ifndef DEVELOPMENT_BUILD
43 const char *buildTime = __TIME__" "__DATE__;
43 const char *buildTime = __TIME__" "__DATE__;
44 const char *gitHead = "unknown";
44 const char *gitHead = "unknown";
45 #else
45 #else
46 #include "qchartversion_p.h"
46 #include "qchartversion_p.h"
47 #endif
47 #endif
48
48
49 QTCOMMERCIALCHART_BEGIN_NAMESPACE
49 QTCOMMERCIALCHART_BEGIN_NAMESPACE
50
50
51 class ChartConfig
51 class ChartConfig
52 {
52 {
53 private:
53 private:
54 ChartConfig() {
54 ChartConfig() {
55 #if defined(DEVELOPMENT_BUILD) && !defined(QT_NO_DEBUG)
55 #if defined(DEVELOPMENT_BUILD) && !defined(QT_NO_DEBUG)
56 qDebug() << "buildTime" << buildTime;
56 qDebug() << "buildTime" << buildTime;
57 qDebug() << "gitHead" << gitHead;
57 qDebug() << "gitHead" << gitHead;
58 #endif
58 #endif
59 m_instance = this;
59 m_instance = this;
60 }
60 }
61 public:
61 public:
62 static ChartConfig *instance() {
62 static ChartConfig *instance() {
63 if (!m_instance) {
63 if (!m_instance) {
64 m_instance = new ChartConfig();
64 m_instance = new ChartConfig();
65 }
65 }
66 return m_instance;
66 return m_instance;
67 }
67 }
68
68
69 QString compilationTime() {
69 QString compilationTime() {
70 return buildTime;
70 return QString(buildTime);
71 }
71 }
72
72
73 QString compilationHead() {
73 QString compilationHead() {
74 return gitHead;
74 return QString(gitHead);
75 }
75 }
76
76
77 private:
77 private:
78 static ChartConfig *m_instance;
78 static ChartConfig *m_instance;
79 };
79 };
80
80
81
81
82 ChartConfig *ChartConfig::m_instance = 0;
82 ChartConfig *ChartConfig::m_instance = 0;
83
83
84 QTCOMMERCIALCHART_END_NAMESPACE
84 QTCOMMERCIALCHART_END_NAMESPACE
85
85
86 #endif
86 #endif
@@ -1,754 +1,754
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 "qchart.h"
21 #include "qchart.h"
22 #include "qchart_p.h"
22 #include "qchart_p.h"
23 #include "legendscroller_p.h"
23 #include "legendscroller_p.h"
24 #include "qlegend_p.h"
24 #include "qlegend_p.h"
25 #include "chartbackground_p.h"
25 #include "chartbackground_p.h"
26 #include "qabstractaxis.h"
26 #include "qabstractaxis.h"
27 #include "abstractchartlayout_p.h"
27 #include "abstractchartlayout_p.h"
28 #include "charttheme_p.h"
28 #include "charttheme_p.h"
29 #include "chartpresenter_p.h"
29 #include "chartpresenter_p.h"
30 #include "chartdataset_p.h"
30 #include "chartdataset_p.h"
31 #include <QGraphicsScene>
31 #include <QGraphicsScene>
32 #include <QGraphicsSceneResizeEvent>
32 #include <QGraphicsSceneResizeEvent>
33
33
34 QTCOMMERCIALCHART_BEGIN_NAMESPACE
34 QTCOMMERCIALCHART_BEGIN_NAMESPACE
35
35
36 /*!
36 /*!
37 \enum QChart::ChartTheme
37 \enum QChart::ChartTheme
38
38
39 This enum describes the theme used by the chart.
39 This enum describes the theme used by the chart.
40
40
41 \value ChartThemeLight The default theme
41 \value ChartThemeLight The default theme
42 \value ChartThemeBlueCerulean
42 \value ChartThemeBlueCerulean
43 \value ChartThemeDark
43 \value ChartThemeDark
44 \value ChartThemeBrownSand
44 \value ChartThemeBrownSand
45 \value ChartThemeBlueNcs
45 \value ChartThemeBlueNcs
46 \value ChartThemeHighContrast
46 \value ChartThemeHighContrast
47 \value ChartThemeBlueIcy
47 \value ChartThemeBlueIcy
48 */
48 */
49
49
50 /*!
50 /*!
51 \enum QChart::AnimationOption
51 \enum QChart::AnimationOption
52
52
53 For enabling/disabling animations. Defaults to NoAnimation.
53 For enabling/disabling animations. Defaults to NoAnimation.
54
54
55 \value NoAnimation
55 \value NoAnimation
56 \value GridAxisAnimations
56 \value GridAxisAnimations
57 \value SeriesAnimations
57 \value SeriesAnimations
58 \value AllAnimations
58 \value AllAnimations
59 */
59 */
60
60
61 /*!
61 /*!
62 \enum QChart::ChartType
62 \enum QChart::ChartType
63
63
64 This enum describes the chart type.
64 This enum describes the chart type.
65
65
66 \value ChartTypeUndefined
66 \value ChartTypeUndefined
67 \value ChartTypeCartesian
67 \value ChartTypeCartesian
68 \value ChartTypePolar
68 \value ChartTypePolar
69 */
69 */
70
70
71 /*!
71 /*!
72 \class QChart
72 \class QChart
73 \brief QtCommercial chart API.
73 \brief QtCommercial chart API.
74
74
75 QChart is a QGraphicsWidget that you can show in a QGraphicsScene. It manages the graphical
75 QChart is a QGraphicsWidget that you can show in a QGraphicsScene. It manages the graphical
76 representation of different types of series and other chart related objects like legend and
76 representation of different types of series and other chart related objects like legend and
77 axes. If you simply want to show a chart in a layout, you can use the
77 axes. If you simply want to show a chart in a layout, you can use the
78 convenience class QChartView instead of QChart.
78 convenience class QChartView instead of QChart.
79 \sa QChartView, QPolarChart
79 \sa QChartView, QPolarChart
80 */
80 */
81
81
82 /*!
82 /*!
83 \property QChart::animationOptions
83 \property QChart::animationOptions
84 The animation \a options for the chart. Animations are enabled/disabled based on this setting.
84 The animation \a options for the chart. Animations are enabled/disabled based on this setting.
85 */
85 */
86
86
87 /*!
87 /*!
88 \property QChart::backgroundVisible
88 \property QChart::backgroundVisible
89 Specifies whether the chart background is visible or not.
89 Specifies whether the chart background is visible or not.
90 \sa setBackgroundBrush(), setBackgroundPen(), plotAreaBackgroundVisible
90 \sa setBackgroundBrush(), setBackgroundPen(), plotAreaBackgroundVisible
91 */
91 */
92
92
93 /*!
93 /*!
94 \property QChart::dropShadowEnabled
94 \property QChart::dropShadowEnabled
95 If set to true, the background drop shadow effect is enabled. If set to false, it is disabled. Note that the drop
95 If set to true, the background drop shadow effect is enabled. If set to false, it is disabled. Note that the drop
96 shadow effect depends on theme, which means the setting may be changed if you switch to another theme.
96 shadow effect depends on theme, which means the setting may be changed if you switch to another theme.
97 */
97 */
98
98
99 /*!
99 /*!
100 \property QChart::minimumMargins
100 \property QChart::minimumMargins
101 Minimum margins between the plot area (axes) and the edge of the chart widget.
101 Minimum margins between the plot area (axes) and the edge of the chart widget.
102 This property is deprecated; use margins property instead.
102 This property is deprecated; use margins property instead.
103
103
104 \sa margins
104 \sa margins
105 */
105 */
106
106
107 /*!
107 /*!
108 \property QChart::margins
108 \property QChart::margins
109 Margins between the plot area (axes) and the edge of the chart widget.
109 Margins between the plot area (axes) and the edge of the chart widget.
110 */
110 */
111
111
112 /*!
112 /*!
113 \property QChart::theme
113 \property QChart::theme
114 Theme is a built-in collection of UI style related settings applied for all visual elements of a chart, like colors,
114 Theme is a built-in collection of UI style related settings applied for all visual elements of a chart, like colors,
115 pens, brushes, and fonts of series, axes, title, and legend. \l {Chart themes demo} shows an example with a few
115 pens, brushes, and fonts of series, axes, title, and legend. \l {Chart themes demo} shows an example with a few
116 different themes.
116 different themes.
117 \note Changing the theme will overwrite all customizations previously applied to the series.
117 \note Changing the theme will overwrite all customizations previously applied to the series.
118 */
118 */
119
119
120 /*!
120 /*!
121 \property QChart::title
121 \property QChart::title
122 Title is the name (label) of a chart. It is shown as a headline on top of the chart.
122 Title is the name (label) of a chart. It is shown as a headline on top of the chart.
123 */
123 */
124
124
125 /*!
125 /*!
126 \property QChart::chartType
126 \property QChart::chartType
127 Chart type indicates if the chart is a cartesian chart or a polar chart.
127 Chart type indicates if the chart is a cartesian chart or a polar chart.
128 This property is set internally and it is read only.
128 This property is set internally and it is read only.
129 \sa QPolarChart
129 \sa QPolarChart
130 */
130 */
131
131
132 /*!
132 /*!
133 \property QChart::plotAreaBackgroundVisible
133 \property QChart::plotAreaBackgroundVisible
134 Specifies whether the chart plot area background is visible or not.
134 Specifies whether the chart plot area background is visible or not.
135 \note By default the plot area background is not visible and the plot area uses
135 \note By default the plot area background is not visible and the plot area uses
136 the general chart background.
136 the general chart background.
137 \sa setPlotAreaBackgroundBrush(), setPlotAreaBackgroundPen(), backgroundVisible
137 \sa setPlotAreaBackgroundBrush(), setPlotAreaBackgroundPen(), backgroundVisible
138 */
138 */
139
139
140 /*!
140 /*!
141 \internal
141 \internal
142 Constructs a chart object of \a type which is a child of a \a parent.
142 Constructs a chart object of \a type which is a child of a \a parent.
143 Parameter \a wFlags is passed to the QGraphicsWidget constructor.
143 Parameter \a wFlags is passed to the QGraphicsWidget constructor.
144 This constructor is called only by subclasses.
144 This constructor is called only by subclasses.
145 */
145 */
146 QChart::QChart(QChart::ChartType type, QGraphicsItem *parent, Qt::WindowFlags wFlags)
146 QChart::QChart(QChart::ChartType type, QGraphicsItem *parent, Qt::WindowFlags wFlags)
147 : QGraphicsWidget(parent, wFlags),
147 : QGraphicsWidget(parent, wFlags),
148 d_ptr(new QChartPrivate(this, type))
148 d_ptr(new QChartPrivate(this, type))
149 {
149 {
150 d_ptr->init();
150 d_ptr->init();
151 }
151 }
152
152
153 /*!
153 /*!
154 Constructs a chart object which is a child of a \a parent.
154 Constructs a chart object which is a child of a \a parent.
155 Parameter \a wFlags is passed to the QGraphicsWidget constructor.
155 Parameter \a wFlags is passed to the QGraphicsWidget constructor.
156 */
156 */
157 QChart::QChart(QGraphicsItem *parent, Qt::WindowFlags wFlags)
157 QChart::QChart(QGraphicsItem *parent, Qt::WindowFlags wFlags)
158 : QGraphicsWidget(parent, wFlags),
158 : QGraphicsWidget(parent, wFlags),
159 d_ptr(new QChartPrivate(this, ChartTypeCartesian))
159 d_ptr(new QChartPrivate(this, ChartTypeCartesian))
160 {
160 {
161 d_ptr->init();
161 d_ptr->init();
162 }
162 }
163
163
164 /*!
164 /*!
165 Destroys the chart object and its children, like series and axis objects added to it.
165 Destroys the chart object and its children, like series and axis objects added to it.
166 */
166 */
167 QChart::~QChart()
167 QChart::~QChart()
168 {
168 {
169 //start by deleting dataset, it will remove all series and axes
169 //start by deleting dataset, it will remove all series and axes
170 delete d_ptr->m_dataset;
170 delete d_ptr->m_dataset;
171 d_ptr->m_dataset = 0;
171 d_ptr->m_dataset = 0;
172 }
172 }
173
173
174 /*!
174 /*!
175 Adds the \a series onto the chart and takes the ownership of it.
175 Adds the \a series onto the chart and takes the ownership of it.
176
176
177 \note A newly added series is attached to no axes by default, including any axes that were created for the chart
177 \note A newly added series is attached to no axes by default, including any axes that were created for the chart
178 using createDefaultAxes() before the series was added to the chart. If no axes are attached to
178 using createDefaultAxes() before the series was added to the chart. If no axes are attached to
179 the newly added series before the chart is shown, the series will get drawn as if it had axes with ranges
179 the newly added series before the chart is shown, the series will get drawn as if it had axes with ranges
180 that exactly fit the series to the plot area of the chart. This can be confusing if the same chart also displays other
180 that exactly fit the series to the plot area of the chart. This can be confusing if the same chart also displays other
181 series that have properly attached axes, so always make sure you either call createDefaultAxes() after
181 series that have properly attached axes, so always make sure you either call createDefaultAxes() after
182 a series has been added or explicitly attach axes for the series.
182 a series has been added or explicitly attach axes for the series.
183
183
184 \sa removeSeries(), removeAllSeries(), createDefaultAxes(), QAbstractSeries::attachAxis()
184 \sa removeSeries(), removeAllSeries(), createDefaultAxes(), QAbstractSeries::attachAxis()
185 */
185 */
186 void QChart::addSeries(QAbstractSeries *series)
186 void QChart::addSeries(QAbstractSeries *series)
187 {
187 {
188 Q_ASSERT(series);
188 Q_ASSERT(series);
189 d_ptr->m_dataset->addSeries(series);
189 d_ptr->m_dataset->addSeries(series);
190 }
190 }
191
191
192 /*!
192 /*!
193 Removes the \a series from the chart.
193 Removes the \a series from the chart.
194 The chart releases its ownership of the specified \a series object.
194 The chart releases its ownership of the specified \a series object.
195
195
196 \sa addSeries(), removeAllSeries()
196 \sa addSeries(), removeAllSeries()
197 */
197 */
198 void QChart::removeSeries(QAbstractSeries *series)
198 void QChart::removeSeries(QAbstractSeries *series)
199 {
199 {
200 Q_ASSERT(series);
200 Q_ASSERT(series);
201 d_ptr->m_dataset->removeSeries(series);
201 d_ptr->m_dataset->removeSeries(series);
202 }
202 }
203
203
204 /*!
204 /*!
205 Removes and deletes all series objects that have been added to the chart.
205 Removes and deletes all series objects that have been added to the chart.
206
206
207 \sa addSeries(), removeSeries()
207 \sa addSeries(), removeSeries()
208 */
208 */
209 void QChart::removeAllSeries()
209 void QChart::removeAllSeries()
210 {
210 {
211 foreach (QAbstractSeries *s , d_ptr->m_dataset->series()){
211 foreach (QAbstractSeries *s , d_ptr->m_dataset->series()){
212 removeSeries(s);
212 removeSeries(s);
213 delete s;
213 delete s;
214 }
214 }
215 }
215 }
216
216
217 /*!
217 /*!
218 Sets the \a brush that is used for painting the background of the chart area.
218 Sets the \a brush that is used for painting the background of the chart area.
219 */
219 */
220 void QChart::setBackgroundBrush(const QBrush &brush)
220 void QChart::setBackgroundBrush(const QBrush &brush)
221 {
221 {
222 d_ptr->m_presenter->setBackgroundBrush(brush);
222 d_ptr->m_presenter->setBackgroundBrush(brush);
223 }
223 }
224
224
225 /*!
225 /*!
226 Gets the brush that is used for painting the background of the chart area.
226 Gets the brush that is used for painting the background of the chart area.
227 */
227 */
228 QBrush QChart::backgroundBrush() const
228 QBrush QChart::backgroundBrush() const
229 {
229 {
230 return d_ptr->m_presenter->backgroundBrush();
230 return d_ptr->m_presenter->backgroundBrush();
231 }
231 }
232
232
233 /*!
233 /*!
234 Sets the \a pen that is used for painting the background of the chart area.
234 Sets the \a pen that is used for painting the background of the chart area.
235 */
235 */
236 void QChart::setBackgroundPen(const QPen &pen)
236 void QChart::setBackgroundPen(const QPen &pen)
237 {
237 {
238 d_ptr->m_presenter->setBackgroundPen(pen);
238 d_ptr->m_presenter->setBackgroundPen(pen);
239 }
239 }
240
240
241 /*!
241 /*!
242 Gets the pen that is used for painting the background of the chart area.
242 Gets the pen that is used for painting the background of the chart area.
243 */
243 */
244 QPen QChart::backgroundPen() const
244 QPen QChart::backgroundPen() const
245 {
245 {
246 return d_ptr->m_presenter->backgroundPen();
246 return d_ptr->m_presenter->backgroundPen();
247 }
247 }
248
248
249 void QChart::setTitle(const QString &title)
249 void QChart::setTitle(const QString &title)
250 {
250 {
251 d_ptr->m_presenter->setTitle(title);
251 d_ptr->m_presenter->setTitle(title);
252 }
252 }
253
253
254 QString QChart::title() const
254 QString QChart::title() const
255 {
255 {
256 return d_ptr->m_presenter->title();
256 return d_ptr->m_presenter->title();
257 }
257 }
258
258
259 /*!
259 /*!
260 Sets the \a font that is used for drawing the chart title.
260 Sets the \a font that is used for drawing the chart title.
261 */
261 */
262 void QChart::setTitleFont(const QFont &font)
262 void QChart::setTitleFont(const QFont &font)
263 {
263 {
264 d_ptr->m_presenter->setTitleFont(font);
264 d_ptr->m_presenter->setTitleFont(font);
265 }
265 }
266
266
267 /*!
267 /*!
268 Gets the font that is used for drawing the chart title.
268 Gets the font that is used for drawing the chart title.
269 */
269 */
270 QFont QChart::titleFont() const
270 QFont QChart::titleFont() const
271 {
271 {
272 return d_ptr->m_presenter->titleFont();
272 return d_ptr->m_presenter->titleFont();
273 }
273 }
274
274
275 /*!
275 /*!
276 Sets the \a brush used for drawing the title text.
276 Sets the \a brush used for drawing the title text.
277 */
277 */
278 void QChart::setTitleBrush(const QBrush &brush)
278 void QChart::setTitleBrush(const QBrush &brush)
279 {
279 {
280 d_ptr->m_presenter->setTitleBrush(brush);
280 d_ptr->m_presenter->setTitleBrush(brush);
281 }
281 }
282
282
283 /*!
283 /*!
284 Returns the brush used for drawing the title text.
284 Returns the brush used for drawing the title text.
285 */
285 */
286 QBrush QChart::titleBrush() const
286 QBrush QChart::titleBrush() const
287 {
287 {
288 return d_ptr->m_presenter->titleBrush();
288 return d_ptr->m_presenter->titleBrush();
289 }
289 }
290
290
291 void QChart::setTheme(QChart::ChartTheme theme)
291 void QChart::setTheme(QChart::ChartTheme theme)
292 {
292 {
293 d_ptr->m_themeManager->setTheme(theme);
293 d_ptr->m_themeManager->setTheme(theme);
294 }
294 }
295
295
296 QChart::ChartTheme QChart::theme() const
296 QChart::ChartTheme QChart::theme() const
297 {
297 {
298 return d_ptr->m_themeManager->theme()->id();
298 return d_ptr->m_themeManager->theme()->id();
299 }
299 }
300
300
301 /*!
301 /*!
302 Zooms in the view by a factor of two.
302 Zooms in the view by a factor of two.
303 */
303 */
304 void QChart::zoomIn()
304 void QChart::zoomIn()
305 {
305 {
306 d_ptr->zoomIn(2.0);
306 d_ptr->zoomIn(2.0);
307 }
307 }
308
308
309 /*!
309 /*!
310 Zooms in the view to a maximum level at which \a rect is still fully visible.
310 Zooms in the view to a maximum level at which \a rect is still fully visible.
311 \note This is not supported for polar charts.
311 \note This is not supported for polar charts.
312 */
312 */
313 void QChart::zoomIn(const QRectF &rect)
313 void QChart::zoomIn(const QRectF &rect)
314 {
314 {
315 if (d_ptr->m_type == QChart::ChartTypePolar)
315 if (d_ptr->m_type == QChart::ChartTypePolar)
316 return;
316 return;
317 d_ptr->zoomIn(rect);
317 d_ptr->zoomIn(rect);
318 }
318 }
319
319
320 /*!
320 /*!
321 Zooms out the view by a factor of two.
321 Zooms out the view by a factor of two.
322 */
322 */
323 void QChart::zoomOut()
323 void QChart::zoomOut()
324 {
324 {
325 d_ptr->zoomOut(2.0);
325 d_ptr->zoomOut(2.0);
326 }
326 }
327
327
328 /*!
328 /*!
329 Zooms in the view by a custom \a factor.
329 Zooms in the view by a custom \a factor.
330
330
331 A factor over 1.0 zooms the view in and factor between 0.0 and 1.0 zooms out.
331 A factor over 1.0 zooms the view in and factor between 0.0 and 1.0 zooms out.
332 */
332 */
333 void QChart::zoom(qreal factor)
333 void QChart::zoom(qreal factor)
334 {
334 {
335 if (qFuzzyCompare(factor, 0))
335 if (qFuzzyCompare(factor, 0))
336 return;
336 return;
337
337
338 if (qFuzzyCompare(factor, (qreal)1.0))
338 if (qFuzzyCompare(factor, (qreal)1.0))
339 return;
339 return;
340
340
341 if (factor < 0)
341 if (factor < 0)
342 return;
342 return;
343
343
344 if (factor > 1.0)
344 if (factor > 1.0)
345 d_ptr->zoomIn(factor);
345 d_ptr->zoomIn(factor);
346 else
346 else
347 d_ptr->zoomOut(1.0 / factor);
347 d_ptr->zoomOut(1.0 / factor);
348 }
348 }
349
349
350 /*!
350 /*!
351 Returns a pointer to the horizontal axis attached to the specified \a series.
351 Returns a pointer to the horizontal axis attached to the specified \a series.
352 If no \a series is specified, the first horizontal axis added to the chart is returned.
352 If no \a series is specified, the first horizontal axis added to the chart is returned.
353
353
354 \sa addAxis(), QAbstractSeries::attachAxis()
354 \sa addAxis(), QAbstractSeries::attachAxis()
355 */
355 */
356 QAbstractAxis *QChart::axisX(QAbstractSeries *series) const
356 QAbstractAxis *QChart::axisX(QAbstractSeries *series) const
357 {
357 {
358 QList<QAbstractAxis *> axisList = axes(Qt::Horizontal, series);
358 QList<QAbstractAxis *> axisList = axes(Qt::Horizontal, series);
359 if (axisList.count())
359 if (axisList.count())
360 return axisList[0];
360 return axisList[0];
361 return 0;
361 return 0;
362 }
362 }
363
363
364 /*!
364 /*!
365 Returns a pointer to the vertical axis attached to the specified \a series.
365 Returns a pointer to the vertical axis attached to the specified \a series.
366 If no \a series is specified, the first vertical axis added to the chart is returned.
366 If no \a series is specified, the first vertical axis added to the chart is returned.
367
367
368 \sa addAxis(), QAbstractSeries::attachAxis()
368 \sa addAxis(), QAbstractSeries::attachAxis()
369 */
369 */
370 QAbstractAxis *QChart::axisY(QAbstractSeries *series) const
370 QAbstractAxis *QChart::axisY(QAbstractSeries *series) const
371 {
371 {
372 QList<QAbstractAxis *> axisList = axes(Qt::Vertical, series);
372 QList<QAbstractAxis *> axisList = axes(Qt::Vertical, series);
373 if (axisList.count())
373 if (axisList.count())
374 return axisList[0];
374 return axisList[0];
375 return 0;
375 return 0;
376 }
376 }
377
377
378 /*!
378 /*!
379 Returns the axes attached to the \a series with \a orientation. If no \a series is provided,
379 Returns the axes attached to the \a series with \a orientation. If no \a series is provided,
380 then all axes added to the chart with the specified orientation are returned.
380 then all axes added to the chart with the specified orientation are returned.
381 \sa addAxis(), createDefaultAxes()
381 \sa addAxis(), createDefaultAxes()
382 */
382 */
383 QList<QAbstractAxis *> QChart::axes(Qt::Orientations orientation, QAbstractSeries *series) const
383 QList<QAbstractAxis *> QChart::axes(Qt::Orientations orientation, QAbstractSeries *series) const
384 {
384 {
385 QList<QAbstractAxis *> result ;
385 QList<QAbstractAxis *> result ;
386
386
387 if (series) {
387 if (series) {
388 foreach (QAbstractAxis *axis, series->attachedAxes()){
388 foreach (QAbstractAxis *axis, series->attachedAxes()){
389 if (orientation.testFlag(axis->orientation()))
389 if (orientation.testFlag(axis->orientation()))
390 result << axis;
390 result << axis;
391 }
391 }
392 } else {
392 } else {
393 foreach (QAbstractAxis *axis, d_ptr->m_dataset->axes()){
393 foreach (QAbstractAxis *axis, d_ptr->m_dataset->axes()){
394 if (orientation.testFlag(axis->orientation()) && !result.contains(axis))
394 if (orientation.testFlag(axis->orientation()) && !result.contains(axis))
395 result << axis;
395 result << axis;
396 }
396 }
397 }
397 }
398
398
399 return result;
399 return result;
400 }
400 }
401
401
402 /*!
402 /*!
403 Creates axes for the chart based on the series that have already been added to the chart. Any axes previously added to
403 Creates axes for the chart based on the series that have already been added to the chart. Any axes previously added to
404 the chart will be deleted.
404 the chart will be deleted.
405
405
406 \note This function has to be called after all series have been added to the chart. The axes created by this function
406 \note This function has to be called after all series have been added to the chart. The axes created by this function
407 will NOT get automatically attached to any series added to the chart after this function has been called.
407 will NOT get automatically attached to any series added to the chart after this function has been called.
408 A series with no axes attached will by default scale to utilize the entire plot area of the chart, which can be confusing
408 A series with no axes attached will by default scale to utilize the entire plot area of the chart, which can be confusing
409 if there are other series with properly attached axes also present.
409 if there are other series with properly attached axes also present.
410
410
411 \table
411 \table
412 \header
412 \header
413 \o Series type
413 \o Series type
414 \o X-axis
414 \o X-axis
415 \o Y-axis
415 \o Y-axis
416 \row
416 \row
417 \o QXYSeries
417 \o QXYSeries
418 \o QValueAxis
418 \o QValueAxis
419 \o QValueAxis
419 \o QValueAxis
420 \row
420 \row
421 \o QBarSeries
421 \o QBarSeries
422 \o QBarCategoryAxis
422 \o QBarCategoryAxis
423 \o QValueAxis
423 \o QValueAxis
424 \row
424 \row
425 \o QPieSeries
425 \o QPieSeries
426 \o None
426 \o None
427 \o None
427 \o None
428 \endtable
428 \endtable
429
429
430 If there are several QXYSeries derived series added to the chart and no series of other types have been added, then only one pair of axes is created.
430 If there are several QXYSeries derived series added to the chart and no series of other types have been added, then only one pair of axes is created.
431 If there are several series of different types added to the chart, then each series gets its own axes pair.
431 If there are several series of different types added to the chart, then each series gets its own axes pair.
432
432
433 The axes specific to the series can be later obtained from the chart by providing the series as the parameter for axes() function call.
433 The axes specific to the series can be later obtained from the chart by providing the series as the parameter for axes() function call.
434 QPieSeries does not create any axes.
434 QPieSeries does not create any axes.
435
435
436 \sa axisX(), axisY(), axes(), setAxisX(), setAxisY(), QAbstractSeries::attachAxis()
436 \sa axisX(), axisY(), axes(), setAxisX(), setAxisY(), QAbstractSeries::attachAxis()
437 */
437 */
438 void QChart::createDefaultAxes()
438 void QChart::createDefaultAxes()
439 {
439 {
440 d_ptr->m_dataset->createDefaultAxes();
440 d_ptr->m_dataset->createDefaultAxes();
441 }
441 }
442
442
443 /*!
443 /*!
444 Returns the legend object of the chart. Ownership stays with the chart.
444 Returns the legend object of the chart. Ownership stays with the chart.
445 */
445 */
446 QLegend *QChart::legend() const
446 QLegend *QChart::legend() const
447 {
447 {
448 return d_ptr->m_legend;
448 return d_ptr->m_legend;
449 }
449 }
450
450
451 void QChart::setMinimumMargins(const QMargins &margins)
451 void QChart::setMinimumMargins(const QMargins &margins)
452 {
452 {
453 qWarning() << "QChart::setMinimumMargins is deprecated. Use QChart::setMargins instead.";
453 qWarning() << "QChart::setMinimumMargins is deprecated. Use QChart::setMargins instead.";
454 d_ptr->m_presenter->layout()->setMargins(margins);
454 d_ptr->m_presenter->layout()->setMargins(margins);
455 }
455 }
456
456
457 QMargins QChart::minimumMargins() const
457 QMargins QChart::minimumMargins() const
458 {
458 {
459 qWarning() << "QChart::minimumMargins is deprecated. Use QChart::margins instead.";
459 qWarning() << "QChart::minimumMargins is deprecated. Use QChart::margins instead.";
460 return d_ptr->m_presenter->layout()->margins();
460 return d_ptr->m_presenter->layout()->margins();
461 }
461 }
462
462
463 void QChart::setMargins(const QMargins &margins)
463 void QChart::setMargins(const QMargins &margins)
464 {
464 {
465 d_ptr->m_presenter->layout()->setMargins(margins);
465 d_ptr->m_presenter->layout()->setMargins(margins);
466 }
466 }
467
467
468 QMargins QChart::margins() const
468 QMargins QChart::margins() const
469 {
469 {
470 return d_ptr->m_presenter->layout()->margins();
470 return d_ptr->m_presenter->layout()->margins();
471 }
471 }
472
472
473 QChart::ChartType QChart::chartType() const
473 QChart::ChartType QChart::chartType() const
474 {
474 {
475 return d_ptr->m_type;
475 return d_ptr->m_type;
476 }
476 }
477
477
478 /*!
478 /*!
479 Returns the the rectangle within which the drawing of the chart is done.
479 Returns the the rectangle within which the drawing of the chart is done.
480 It does not include the area defined by margins.
480 It does not include the area defined by margins.
481 */
481 */
482 QRectF QChart::plotArea() const
482 QRectF QChart::plotArea() const
483 {
483 {
484 return d_ptr->m_presenter->geometry();
484 return d_ptr->m_presenter->geometry();
485 }
485 }
486
486
487 /*!
487 /*!
488 Sets the \a brush for the background of the plot area of the chart.
488 Sets the \a brush for the background of the plot area of the chart.
489
489
490 \sa plotArea(), plotAreaBackgroundVisible, setPlotAreaBackgroundPen(), plotAreaBackgroundBrush()
490 \sa plotArea(), plotAreaBackgroundVisible, setPlotAreaBackgroundPen(), plotAreaBackgroundBrush()
491 */
491 */
492 void QChart::setPlotAreaBackgroundBrush(const QBrush &brush)
492 void QChart::setPlotAreaBackgroundBrush(const QBrush &brush)
493 {
493 {
494 d_ptr->m_presenter->setPlotAreaBackgroundBrush(brush);
494 d_ptr->m_presenter->setPlotAreaBackgroundBrush(brush);
495 }
495 }
496
496
497 /*!
497 /*!
498 Returns the brush for the background of the plot area of the chart.
498 Returns the brush for the background of the plot area of the chart.
499
499
500 \sa plotArea(), plotAreaBackgroundVisible, plotAreaBackgroundPen(), setPlotAreaBackgroundBrush()
500 \sa plotArea(), plotAreaBackgroundVisible, plotAreaBackgroundPen(), setPlotAreaBackgroundBrush()
501 */
501 */
502 QBrush QChart::plotAreaBackgroundBrush() const
502 QBrush QChart::plotAreaBackgroundBrush() const
503 {
503 {
504 return d_ptr->m_presenter->plotAreaBackgroundBrush();
504 return d_ptr->m_presenter->plotAreaBackgroundBrush();
505 }
505 }
506
506
507 /*!
507 /*!
508 Sets the \a pen for the background of the plot area of the chart.
508 Sets the \a pen for the background of the plot area of the chart.
509
509
510 \sa plotArea(), plotAreaBackgroundVisible, setPlotAreaBackgroundBrush(), plotAreaBackgroundPen()
510 \sa plotArea(), plotAreaBackgroundVisible, setPlotAreaBackgroundBrush(), plotAreaBackgroundPen()
511 */
511 */
512 void QChart::setPlotAreaBackgroundPen(const QPen &pen)
512 void QChart::setPlotAreaBackgroundPen(const QPen &pen)
513 {
513 {
514 d_ptr->m_presenter->setPlotAreaBackgroundPen(pen);
514 d_ptr->m_presenter->setPlotAreaBackgroundPen(pen);
515 }
515 }
516
516
517 /*!
517 /*!
518 Returns the pen for the background of the plot area of the chart.
518 Returns the pen for the background of the plot area of the chart.
519
519
520 \sa plotArea(), plotAreaBackgroundVisible, plotAreaBackgroundBrush(), setPlotAreaBackgroundPen()
520 \sa plotArea(), plotAreaBackgroundVisible, plotAreaBackgroundBrush(), setPlotAreaBackgroundPen()
521 */
521 */
522 QPen QChart::plotAreaBackgroundPen() const
522 QPen QChart::plotAreaBackgroundPen() const
523 {
523 {
524 return d_ptr->m_presenter->plotAreaBackgroundPen();
524 return d_ptr->m_presenter->plotAreaBackgroundPen();
525 }
525 }
526
526
527 void QChart::setPlotAreaBackgroundVisible(bool visible)
527 void QChart::setPlotAreaBackgroundVisible(bool visible)
528 {
528 {
529 d_ptr->m_presenter->setPlotAreaBackgroundVisible(visible);
529 d_ptr->m_presenter->setPlotAreaBackgroundVisible(visible);
530 }
530 }
531
531
532 bool QChart::isPlotAreaBackgroundVisible() const
532 bool QChart::isPlotAreaBackgroundVisible() const
533 {
533 {
534 return d_ptr->m_presenter->isPlotAreaBackgroundVisible();
534 return d_ptr->m_presenter->isPlotAreaBackgroundVisible();
535 }
535 }
536
536
537 void QChart::setAnimationOptions(AnimationOptions options)
537 void QChart::setAnimationOptions(AnimationOptions options)
538 {
538 {
539 d_ptr->m_presenter->setAnimationOptions(options);
539 d_ptr->m_presenter->setAnimationOptions(options);
540 }
540 }
541
541
542 QChart::AnimationOptions QChart::animationOptions() const
542 QChart::AnimationOptions QChart::animationOptions() const
543 {
543 {
544 return d_ptr->m_presenter->animationOptions();
544 return d_ptr->m_presenter->animationOptions();
545 }
545 }
546
546
547 /*!
547 /*!
548 Scrolls the visible area of the chart by the distance defined in the \a dx and \a dy.
548 Scrolls the visible area of the chart by the distance defined in the \a dx and \a dy.
549
549
550 For polar charts, \a dx indicates the angle along angular axis instead of distance.
550 For polar charts, \a dx indicates the angle along angular axis instead of distance.
551 */
551 */
552 void QChart::scroll(qreal dx, qreal dy)
552 void QChart::scroll(qreal dx, qreal dy)
553 {
553 {
554 d_ptr->scroll(dx,dy);
554 d_ptr->scroll(dx,dy);
555 }
555 }
556
556
557 void QChart::setBackgroundVisible(bool visible)
557 void QChart::setBackgroundVisible(bool visible)
558 {
558 {
559 d_ptr->m_presenter->setBackgroundVisible(visible);
559 d_ptr->m_presenter->setBackgroundVisible(visible);
560 }
560 }
561
561
562 bool QChart::isBackgroundVisible() const
562 bool QChart::isBackgroundVisible() const
563 {
563 {
564 return d_ptr->m_presenter->isBackgroundVisible();
564 return d_ptr->m_presenter->isBackgroundVisible();
565 }
565 }
566
566
567 void QChart::setDropShadowEnabled(bool enabled)
567 void QChart::setDropShadowEnabled(bool enabled)
568 {
568 {
569 d_ptr->m_presenter->setBackgroundDropShadowEnabled(enabled);
569 d_ptr->m_presenter->setBackgroundDropShadowEnabled(enabled);
570 }
570 }
571
571
572 bool QChart::isDropShadowEnabled() const
572 bool QChart::isDropShadowEnabled() const
573 {
573 {
574 return d_ptr->m_presenter->isBackgroundDropShadowEnabled();
574 return d_ptr->m_presenter->isBackgroundDropShadowEnabled();
575 }
575 }
576
576
577 /*!
577 /*!
578 Returns all series that are added to the chart.
578 Returns all series that are added to the chart.
579
579
580 \sa addSeries(), removeSeries(), removeAllSeries()
580 \sa addSeries(), removeSeries(), removeAllSeries()
581 */
581 */
582 QList<QAbstractSeries *> QChart::series() const
582 QList<QAbstractSeries *> QChart::series() const
583 {
583 {
584 return d_ptr->m_dataset->series();
584 return d_ptr->m_dataset->series();
585 }
585 }
586
586
587 /*!
587 /*!
588 Adds the \a axis to the chart and attaches it to the \a series as a bottom-aligned horizontal axis.
588 Adds the \a axis to the chart and attaches it to the \a series as a bottom-aligned horizontal axis.
589 The chart takes ownership of both the \a axis and the \a series.
589 The chart takes ownership of both the \a axis and the \a series.
590 Any horizontal axes previously attached to the \a series are deleted.
590 Any horizontal axes previously attached to the \a series are deleted.
591
591
592 \sa axisX(), axisY(), setAxisY(), createDefaultAxes(), QAbstractSeries::attachAxis()
592 \sa axisX(), axisY(), setAxisY(), createDefaultAxes(), QAbstractSeries::attachAxis()
593 */
593 */
594 void QChart::setAxisX(QAbstractAxis *axis ,QAbstractSeries *series)
594 void QChart::setAxisX(QAbstractAxis *axis ,QAbstractSeries *series)
595 {
595 {
596 QList<QAbstractAxis*> list = axes(Qt::Horizontal, series);
596 QList<QAbstractAxis*> list = axes(Qt::Horizontal, series);
597
597
598 foreach (QAbstractAxis* a, list) {
598 foreach (QAbstractAxis* a, list) {
599 d_ptr->m_dataset->removeAxis(a);
599 d_ptr->m_dataset->removeAxis(a);
600 delete a;
600 delete a;
601 }
601 }
602
602
603 if (!d_ptr->m_dataset->axes().contains(axis))
603 if (!d_ptr->m_dataset->axes().contains(axis))
604 d_ptr->m_dataset->addAxis(axis, Qt::AlignBottom);
604 d_ptr->m_dataset->addAxis(axis, Qt::AlignBottom);
605 d_ptr->m_dataset->attachAxis(series, axis);
605 d_ptr->m_dataset->attachAxis(series, axis);
606 }
606 }
607
607
608 /*!
608 /*!
609 Adds the \a axis to the chart and attaches it to the \a series as a left-aligned vertical axis.
609 Adds the \a axis to the chart and attaches it to the \a series as a left-aligned vertical axis.
610 The chart takes ownership of both the \a axis and the \a series.
610 The chart takes ownership of both the \a axis and the \a series.
611 Any vertical axes previously attached to the \a series are deleted.
611 Any vertical axes previously attached to the \a series are deleted.
612
612
613 \sa axisX(), axisY(), setAxisX(), createDefaultAxes(), QAbstractSeries::attachAxis()
613 \sa axisX(), axisY(), setAxisX(), createDefaultAxes(), QAbstractSeries::attachAxis()
614 */
614 */
615 void QChart::setAxisY(QAbstractAxis *axis ,QAbstractSeries *series)
615 void QChart::setAxisY(QAbstractAxis *axis ,QAbstractSeries *series)
616 {
616 {
617 QList<QAbstractAxis*> list = axes(Qt::Vertical, series);
617 QList<QAbstractAxis*> list = axes(Qt::Vertical, series);
618
618
619 foreach (QAbstractAxis* a, list) {
619 foreach (QAbstractAxis* a, list) {
620 d_ptr->m_dataset->removeAxis(a);
620 d_ptr->m_dataset->removeAxis(a);
621 delete a;
621 delete a;
622 }
622 }
623
623
624 if (!d_ptr->m_dataset->axes().contains(axis))
624 if (!d_ptr->m_dataset->axes().contains(axis))
625 d_ptr->m_dataset->addAxis(axis, Qt::AlignLeft);
625 d_ptr->m_dataset->addAxis(axis, Qt::AlignLeft);
626 d_ptr->m_dataset->attachAxis(series, axis);
626 d_ptr->m_dataset->attachAxis(series, axis);
627 }
627 }
628
628
629 /*!
629 /*!
630 Adds the \a axis to the chart with \a alignment. The chart takes the ownership of the axis.
630 Adds the \a axis to the chart with \a alignment. The chart takes the ownership of the axis.
631
631
632 \sa removeAxis(), createDefaultAxes(), QAbstractSeries::attachAxis()
632 \sa removeAxis(), createDefaultAxes(), QAbstractSeries::attachAxis()
633 */
633 */
634 void QChart::addAxis(QAbstractAxis *axis, Qt::Alignment alignment)
634 void QChart::addAxis(QAbstractAxis *axis, Qt::Alignment alignment)
635 {
635 {
636 d_ptr->m_dataset->addAxis(axis, alignment);
636 d_ptr->m_dataset->addAxis(axis, alignment);
637 }
637 }
638
638
639 /*!
639 /*!
640 Removes the \a axis from the chart.
640 Removes the \a axis from the chart.
641 The chart releases its ownership of the specified \a axis object.
641 The chart releases its ownership of the specified \a axis object.
642
642
643 \sa addAxis(), createDefaultAxes(), QAbstractSeries::detachAxis()
643 \sa addAxis(), createDefaultAxes(), QAbstractSeries::detachAxis()
644 */
644 */
645 void QChart::removeAxis(QAbstractAxis *axis)
645 void QChart::removeAxis(QAbstractAxis *axis)
646 {
646 {
647 d_ptr->m_dataset->removeAxis(axis);
647 d_ptr->m_dataset->removeAxis(axis);
648 }
648 }
649
649
650 /*!
650 /*!
651 Returns the value in the \a series domain that corresponds to the \a position relative to chart widget.
651 Returns the value in the \a series domain that corresponds to the \a position relative to chart widget.
652 */
652 */
653 QPointF QChart::mapToValue(const QPointF &position, QAbstractSeries *series)
653 QPointF QChart::mapToValue(const QPointF &position, QAbstractSeries *series)
654 {
654 {
655 return d_ptr->m_dataset->mapToValue(position, series);
655 return d_ptr->m_dataset->mapToValue(position, series);
656 }
656 }
657
657
658 /*!
658 /*!
659 Returns the position on the chart widget that corresponds to the \a value in the \a series domain.
659 Returns the position on the chart widget that corresponds to the \a value in the \a series domain.
660 */
660 */
661 QPointF QChart::mapToPosition(const QPointF &value, QAbstractSeries *series)
661 QPointF QChart::mapToPosition(const QPointF &value, QAbstractSeries *series)
662 {
662 {
663 return d_ptr->m_dataset->mapToPosition(value, series);
663 return d_ptr->m_dataset->mapToPosition(value, series);
664 }
664 }
665
665
666 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
666 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
667
667
668 QChartPrivate::QChartPrivate(QChart *q, QChart::ChartType type):
668 QChartPrivate::QChartPrivate(QChart *q, QChart::ChartType type):
669 q_ptr(q),
669 q_ptr(q),
670 m_type(type),
671 m_legend(0),
670 m_legend(0),
672 m_dataset(new ChartDataSet(q)),
671 m_dataset(new ChartDataSet(q)),
673 m_presenter(new ChartPresenter(q, type)),
672 m_presenter(new ChartPresenter(q, type)),
674 m_themeManager(new ChartThemeManager(q))
673 m_themeManager(new ChartThemeManager(q)),
674 m_type(type)
675 {
675 {
676 QObject::connect(m_dataset, SIGNAL(seriesAdded(QAbstractSeries*)), m_presenter, SLOT(handleSeriesAdded(QAbstractSeries*)));
676 QObject::connect(m_dataset, SIGNAL(seriesAdded(QAbstractSeries*)), m_presenter, SLOT(handleSeriesAdded(QAbstractSeries*)));
677 QObject::connect(m_dataset, SIGNAL(seriesRemoved(QAbstractSeries*)), m_presenter, SLOT(handleSeriesRemoved(QAbstractSeries*)));
677 QObject::connect(m_dataset, SIGNAL(seriesRemoved(QAbstractSeries*)), m_presenter, SLOT(handleSeriesRemoved(QAbstractSeries*)));
678 QObject::connect(m_dataset, SIGNAL(axisAdded(QAbstractAxis*)), m_presenter, SLOT(handleAxisAdded(QAbstractAxis*)));
678 QObject::connect(m_dataset, SIGNAL(axisAdded(QAbstractAxis*)), m_presenter, SLOT(handleAxisAdded(QAbstractAxis*)));
679 QObject::connect(m_dataset, SIGNAL(axisRemoved(QAbstractAxis*)), m_presenter, SLOT(handleAxisRemoved(QAbstractAxis*)));
679 QObject::connect(m_dataset, SIGNAL(axisRemoved(QAbstractAxis*)), m_presenter, SLOT(handleAxisRemoved(QAbstractAxis*)));
680 QObject::connect(m_dataset, SIGNAL(seriesAdded(QAbstractSeries*)), m_themeManager, SLOT(handleSeriesAdded(QAbstractSeries*)));
680 QObject::connect(m_dataset, SIGNAL(seriesAdded(QAbstractSeries*)), m_themeManager, SLOT(handleSeriesAdded(QAbstractSeries*)));
681 QObject::connect(m_dataset, SIGNAL(seriesRemoved(QAbstractSeries*)), m_themeManager, SLOT(handleSeriesRemoved(QAbstractSeries*)));
681 QObject::connect(m_dataset, SIGNAL(seriesRemoved(QAbstractSeries*)), m_themeManager, SLOT(handleSeriesRemoved(QAbstractSeries*)));
682 QObject::connect(m_dataset, SIGNAL(axisAdded(QAbstractAxis*)), m_themeManager, SLOT(handleAxisAdded(QAbstractAxis*)));
682 QObject::connect(m_dataset, SIGNAL(axisAdded(QAbstractAxis*)), m_themeManager, SLOT(handleAxisAdded(QAbstractAxis*)));
683 QObject::connect(m_dataset, SIGNAL(axisRemoved(QAbstractAxis*)), m_themeManager, SLOT(handleAxisRemoved(QAbstractAxis*)));
683 QObject::connect(m_dataset, SIGNAL(axisRemoved(QAbstractAxis*)), m_themeManager, SLOT(handleAxisRemoved(QAbstractAxis*)));
684 }
684 }
685
685
686 QChartPrivate::~QChartPrivate()
686 QChartPrivate::~QChartPrivate()
687 {
687 {
688 }
688 }
689
689
690 void QChartPrivate::init()
690 void QChartPrivate::init()
691 {
691 {
692 m_legend = new LegendScroller(q_ptr);
692 m_legend = new LegendScroller(q_ptr);
693 q_ptr->setTheme(QChart::ChartThemeLight);
693 q_ptr->setTheme(QChart::ChartThemeLight);
694 q_ptr->setLayout(m_presenter->layout());
694 q_ptr->setLayout(m_presenter->layout());
695 }
695 }
696
696
697 void QChartPrivate::zoomIn(qreal factor)
697 void QChartPrivate::zoomIn(qreal factor)
698 {
698 {
699 QRectF rect = m_presenter->geometry();
699 QRectF rect = m_presenter->geometry();
700 rect.setWidth(rect.width() / factor);
700 rect.setWidth(rect.width() / factor);
701 rect.setHeight(rect.height() / factor);
701 rect.setHeight(rect.height() / factor);
702 rect.moveCenter(m_presenter->geometry().center());
702 rect.moveCenter(m_presenter->geometry().center());
703 zoomIn(rect);
703 zoomIn(rect);
704 }
704 }
705
705
706 void QChartPrivate::zoomIn(const QRectF &rect)
706 void QChartPrivate::zoomIn(const QRectF &rect)
707 {
707 {
708 if (!rect.isValid())
708 if (!rect.isValid())
709 return;
709 return;
710
710
711 QRectF r = rect.normalized();
711 QRectF r = rect.normalized();
712 const QRectF geometry = m_presenter->geometry();
712 const QRectF geometry = m_presenter->geometry();
713 r.translate(-geometry.topLeft());
713 r.translate(-geometry.topLeft());
714
714
715 if (!r.isValid())
715 if (!r.isValid())
716 return;
716 return;
717
717
718 QPointF zoomPoint(r.center().x() / geometry.width(), r.center().y() / geometry.height());
718 QPointF zoomPoint(r.center().x() / geometry.width(), r.center().y() / geometry.height());
719 m_presenter->setState(ChartPresenter::ZoomInState,zoomPoint);
719 m_presenter->setState(ChartPresenter::ZoomInState,zoomPoint);
720 m_dataset->zoomInDomain(r);
720 m_dataset->zoomInDomain(r);
721 m_presenter->setState(ChartPresenter::ShowState,QPointF());
721 m_presenter->setState(ChartPresenter::ShowState,QPointF());
722
722
723 }
723 }
724
724
725 void QChartPrivate::zoomOut(qreal factor)
725 void QChartPrivate::zoomOut(qreal factor)
726 {
726 {
727 const QRectF geometry = m_presenter->geometry();
727 const QRectF geometry = m_presenter->geometry();
728
728
729 QRectF r;
729 QRectF r;
730 r.setSize(geometry.size() / factor);
730 r.setSize(geometry.size() / factor);
731 r.moveCenter(QPointF(geometry.size().width()/2 ,geometry.size().height()/2));
731 r.moveCenter(QPointF(geometry.size().width()/2 ,geometry.size().height()/2));
732 if (!r.isValid())
732 if (!r.isValid())
733 return;
733 return;
734
734
735 QPointF zoomPoint(r.center().x() / geometry.width(), r.center().y() / geometry.height());
735 QPointF zoomPoint(r.center().x() / geometry.width(), r.center().y() / geometry.height());
736 m_presenter->setState(ChartPresenter::ZoomOutState,zoomPoint);
736 m_presenter->setState(ChartPresenter::ZoomOutState,zoomPoint);
737 m_dataset->zoomOutDomain(r);
737 m_dataset->zoomOutDomain(r);
738 m_presenter->setState(ChartPresenter::ShowState,QPointF());
738 m_presenter->setState(ChartPresenter::ShowState,QPointF());
739 }
739 }
740
740
741 void QChartPrivate::scroll(qreal dx, qreal dy)
741 void QChartPrivate::scroll(qreal dx, qreal dy)
742 {
742 {
743 if (dx < 0) m_presenter->setState(ChartPresenter::ScrollLeftState,QPointF());
743 if (dx < 0) m_presenter->setState(ChartPresenter::ScrollLeftState,QPointF());
744 if (dx > 0) m_presenter->setState(ChartPresenter::ScrollRightState,QPointF());
744 if (dx > 0) m_presenter->setState(ChartPresenter::ScrollRightState,QPointF());
745 if (dy < 0) m_presenter->setState(ChartPresenter::ScrollUpState,QPointF());
745 if (dy < 0) m_presenter->setState(ChartPresenter::ScrollUpState,QPointF());
746 if (dy > 0) m_presenter->setState(ChartPresenter::ScrollDownState,QPointF());
746 if (dy > 0) m_presenter->setState(ChartPresenter::ScrollDownState,QPointF());
747
747
748 m_dataset->scrollDomain(dx, dy);
748 m_dataset->scrollDomain(dx, dy);
749 m_presenter->setState(ChartPresenter::ShowState,QPointF());
749 m_presenter->setState(ChartPresenter::ShowState,QPointF());
750 }
750 }
751
751
752 #include "moc_qchart.cpp"
752 #include "moc_qchart.cpp"
753
753
754 QTCOMMERCIALCHART_END_NAMESPACE
754 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,281 +1,282
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 "qchartview.h"
21 #include "qchartview.h"
22 #include "qchartview_p.h"
22 #include "qchartview_p.h"
23 #include "qchart_p.h"
23 #include "qchart_p.h"
24 #include <QGraphicsScene>
24 #include <QGraphicsScene>
25 #include <QRubberBand>
25 #include <QRubberBand>
26 #include <qmath.h>
26
27
27 /*!
28 /*!
28 \enum QChartView::RubberBand
29 \enum QChartView::RubberBand
29
30
30 This enum describes the different types of rubber bands that can be used for zoom rect selection
31 This enum describes the different types of rubber bands that can be used for zoom rect selection
31
32
32 \value NoRubberBand
33 \value NoRubberBand
33 \value VerticalRubberBand
34 \value VerticalRubberBand
34 \value HorizonalRubberBand
35 \value HorizonalRubberBand
35 \value RectangleRubberBand
36 \value RectangleRubberBand
36 */
37 */
37
38
38 /*!
39 /*!
39 \class QChartView
40 \class QChartView
40 \brief Standalone charting widget.
41 \brief Standalone charting widget.
41
42
42 QChartView is a standalone widget that can display charts. It does not require separate
43 QChartView is a standalone widget that can display charts. It does not require separate
43 QGraphicsScene to work. If you want to display a chart in your existing QGraphicsScene,
44 QGraphicsScene to work. If you want to display a chart in your existing QGraphicsScene,
44 you need to use the QChart (or QPolarChart) class instead.
45 you need to use the QChart (or QPolarChart) class instead.
45
46
46 \sa QChart, QPolarChart
47 \sa QChart, QPolarChart
47 */
48 */
48
49
49 QTCOMMERCIALCHART_BEGIN_NAMESPACE
50 QTCOMMERCIALCHART_BEGIN_NAMESPACE
50
51
51 /*!
52 /*!
52 Constructs a chartView object with parent \a parent.
53 Constructs a chartView object with parent \a parent.
53 */
54 */
54
55
55 QChartView::QChartView(QWidget *parent)
56 QChartView::QChartView(QWidget *parent)
56 : QGraphicsView(parent),
57 : QGraphicsView(parent),
57 d_ptr(new QChartViewPrivate(this))
58 d_ptr(new QChartViewPrivate(this))
58 {
59 {
59
60
60 }
61 }
61
62
62 /*!
63 /*!
63 Constructs a chartview object with parent \a parent to display a \a chart.
64 Constructs a chartview object with parent \a parent to display a \a chart.
64 Ownership of the \a chart is passed to chartview.
65 Ownership of the \a chart is passed to chartview.
65 */
66 */
66
67
67 QChartView::QChartView(QChart *chart, QWidget *parent)
68 QChartView::QChartView(QChart *chart, QWidget *parent)
68 : QGraphicsView(parent),
69 : QGraphicsView(parent),
69 d_ptr(new QChartViewPrivate(this, chart))
70 d_ptr(new QChartViewPrivate(this, chart))
70 {
71 {
71
72
72 }
73 }
73
74
74
75
75 /*!
76 /*!
76 Destroys the chartview object and the associated chart.
77 Destroys the chartview object and the associated chart.
77 */
78 */
78 QChartView::~QChartView()
79 QChartView::~QChartView()
79 {
80 {
80 }
81 }
81
82
82 /*!
83 /*!
83 Returns the pointer to the associated chart.
84 Returns the pointer to the associated chart.
84 */
85 */
85 QChart *QChartView::chart() const
86 QChart *QChartView::chart() const
86 {
87 {
87 return d_ptr->m_chart;
88 return d_ptr->m_chart;
88 }
89 }
89
90
90 /*!
91 /*!
91 Sets the current chart to \a chart. Ownership of the new chart is passed to chartview
92 Sets the current chart to \a chart. Ownership of the new chart is passed to chartview
92 and ownership of the previous chart is released.
93 and ownership of the previous chart is released.
93
94
94 To avoid memory leaks users need to make sure the previous chart is deleted.
95 To avoid memory leaks users need to make sure the previous chart is deleted.
95 */
96 */
96
97
97 void QChartView::setChart(QChart *chart)
98 void QChartView::setChart(QChart *chart)
98 {
99 {
99 d_ptr->setChart(chart);
100 d_ptr->setChart(chart);
100 }
101 }
101
102
102 /*!
103 /*!
103 Sets the rubber band flags to \a rubberBand.
104 Sets the rubber band flags to \a rubberBand.
104 Selected flags determine the way zooming is performed.
105 Selected flags determine the way zooming is performed.
105
106
106 \note Rubber band zooming is not supported for polar charts.
107 \note Rubber band zooming is not supported for polar charts.
107 */
108 */
108 void QChartView::setRubberBand(const RubberBands &rubberBand)
109 void QChartView::setRubberBand(const RubberBands &rubberBand)
109 {
110 {
110 d_ptr->m_rubberBandFlags = rubberBand;
111 d_ptr->m_rubberBandFlags = rubberBand;
111
112
112 if (!d_ptr->m_rubberBandFlags) {
113 if (!d_ptr->m_rubberBandFlags) {
113 delete d_ptr->m_rubberBand;
114 delete d_ptr->m_rubberBand;
114 d_ptr->m_rubberBand = 0;
115 d_ptr->m_rubberBand = 0;
115 return;
116 return;
116 }
117 }
117
118
118 if (!d_ptr->m_rubberBand) {
119 if (!d_ptr->m_rubberBand) {
119 d_ptr->m_rubberBand = new QRubberBand(QRubberBand::Rectangle, this);
120 d_ptr->m_rubberBand = new QRubberBand(QRubberBand::Rectangle, this);
120 d_ptr->m_rubberBand->setEnabled(true);
121 d_ptr->m_rubberBand->setEnabled(true);
121 }
122 }
122 }
123 }
123
124
124 /*!
125 /*!
125 Returns the rubber band flags that are currently being used by the widget.
126 Returns the rubber band flags that are currently being used by the widget.
126 */
127 */
127 QChartView::RubberBands QChartView::rubberBand() const
128 QChartView::RubberBands QChartView::rubberBand() const
128 {
129 {
129 return d_ptr->m_rubberBandFlags;
130 return d_ptr->m_rubberBandFlags;
130 }
131 }
131
132
132 /*!
133 /*!
133 If Left mouse button is pressed and the rubber band is enabled the \a event is accepted and the rubber band is displayed on the screen allowing the user to select the zoom area.
134 If Left mouse button is pressed and the rubber band is enabled the \a event is accepted and the rubber band is displayed on the screen allowing the user to select the zoom area.
134 If different mouse button is pressed and/or the rubber band is disabled then the \a event is passed to QGraphicsView::mousePressEvent() implementation.
135 If different mouse button is pressed and/or the rubber band is disabled then the \a event is passed to QGraphicsView::mousePressEvent() implementation.
135 */
136 */
136 void QChartView::mousePressEvent(QMouseEvent *event)
137 void QChartView::mousePressEvent(QMouseEvent *event)
137 {
138 {
138 if (d_ptr->m_rubberBand && d_ptr->m_rubberBand->isEnabled() && event->button() == Qt::LeftButton) {
139 if (d_ptr->m_rubberBand && d_ptr->m_rubberBand->isEnabled() && event->button() == Qt::LeftButton) {
139
140
140 QRectF plotArea = d_ptr->m_chart->plotArea();
141 QRectF plotArea = d_ptr->m_chart->plotArea();
141
142
142 if (plotArea.contains(event->pos())) {
143 if (plotArea.contains(event->pos())) {
143 d_ptr->m_rubberBandOrigin = event->pos();
144 d_ptr->m_rubberBandOrigin = event->pos();
144 d_ptr->m_rubberBand->setGeometry(QRect(d_ptr->m_rubberBandOrigin, QSize()));
145 d_ptr->m_rubberBand->setGeometry(QRect(d_ptr->m_rubberBandOrigin, QSize()));
145 d_ptr->m_rubberBand->show();
146 d_ptr->m_rubberBand->show();
146 event->accept();
147 event->accept();
147 }
148 }
148 } else {
149 } else {
149 QGraphicsView::mousePressEvent(event);
150 QGraphicsView::mousePressEvent(event);
150 }
151 }
151 }
152 }
152
153
153 /*!
154 /*!
154 If the rubber band rectange has been displayed in pressEvent then \a event data is used to update the rubber band geometry.
155 If the rubber band rectange has been displayed in pressEvent then \a event data is used to update the rubber band geometry.
155 Otherwise the default QGraphicsView::mouseMoveEvent implementation is called.
156 Otherwise the default QGraphicsView::mouseMoveEvent implementation is called.
156 */
157 */
157 void QChartView::mouseMoveEvent(QMouseEvent *event)
158 void QChartView::mouseMoveEvent(QMouseEvent *event)
158 {
159 {
159 if (d_ptr->m_rubberBand && d_ptr->m_rubberBand->isVisible()) {
160 if (d_ptr->m_rubberBand && d_ptr->m_rubberBand->isVisible()) {
160 QRect rect = d_ptr->m_chart->plotArea().toRect();
161 QRect rect = d_ptr->m_chart->plotArea().toRect();
161 int width = event->pos().x() - d_ptr->m_rubberBandOrigin.x();
162 int width = event->pos().x() - d_ptr->m_rubberBandOrigin.x();
162 int height = event->pos().y() - d_ptr->m_rubberBandOrigin.y();
163 int height = event->pos().y() - d_ptr->m_rubberBandOrigin.y();
163 if (!d_ptr->m_rubberBandFlags.testFlag(VerticalRubberBand)) {
164 if (!d_ptr->m_rubberBandFlags.testFlag(VerticalRubberBand)) {
164 d_ptr->m_rubberBandOrigin.setY(rect.top());
165 d_ptr->m_rubberBandOrigin.setY(rect.top());
165 height = rect.height();
166 height = rect.height();
166 }
167 }
167 if (!d_ptr->m_rubberBandFlags.testFlag(HorizonalRubberBand)) {
168 if (!d_ptr->m_rubberBandFlags.testFlag(HorizonalRubberBand)) {
168 d_ptr->m_rubberBandOrigin.setX(rect.left());
169 d_ptr->m_rubberBandOrigin.setX(rect.left());
169 width = rect.width();
170 width = rect.width();
170 }
171 }
171 d_ptr->m_rubberBand->setGeometry(QRect(d_ptr->m_rubberBandOrigin.x(), d_ptr->m_rubberBandOrigin.y(), width, height).normalized());
172 d_ptr->m_rubberBand->setGeometry(QRect(d_ptr->m_rubberBandOrigin.x(), d_ptr->m_rubberBandOrigin.y(), width, height).normalized());
172 } else {
173 } else {
173 QGraphicsView::mouseMoveEvent(event);
174 QGraphicsView::mouseMoveEvent(event);
174 }
175 }
175 }
176 }
176
177
177 /*!
178 /*!
178 If left mouse button is released and the rubber band is enabled then \a event is accepted and
179 If left mouse button is released and the rubber band is enabled then \a event is accepted and
179 the view is zoomed into the rect specified by the rubber band.
180 the view is zoomed into the rect specified by the rubber band.
180 If it is a right mouse button \a event then the rubber band is dismissed and the zoom is canceled.
181 If it is a right mouse button \a event then the rubber band is dismissed and the zoom is canceled.
181 */
182 */
182 void QChartView::mouseReleaseEvent(QMouseEvent *event)
183 void QChartView::mouseReleaseEvent(QMouseEvent *event)
183 {
184 {
184 if (d_ptr->m_rubberBand) {
185 if (d_ptr->m_rubberBand) {
185 if (event->button() == Qt::LeftButton && d_ptr->m_rubberBand->isVisible()) {
186 if (event->button() == Qt::LeftButton && d_ptr->m_rubberBand->isVisible()) {
186 d_ptr->m_rubberBand->hide();
187 d_ptr->m_rubberBand->hide();
187 QRectF rect = d_ptr->m_rubberBand->geometry();
188 QRectF rect = d_ptr->m_rubberBand->geometry();
188 // Since plotArea uses QRectF and rubberband uses QRect, we can't just blindly use
189 // Since plotArea uses QRectF and rubberband uses QRect, we can't just blindly use
189 // rubberband's dimensions for vertical and horizontal rubberbands, where one
190 // rubberband's dimensions for vertical and horizontal rubberbands, where one
190 // dimension must match the corresponding plotArea dimension exactly.
191 // dimension must match the corresponding plotArea dimension exactly.
191 if (d_ptr->m_rubberBandFlags == VerticalRubberBand) {
192 if (d_ptr->m_rubberBandFlags == VerticalRubberBand) {
192 rect.setX(d_ptr->m_chart->plotArea().x());
193 rect.setX(d_ptr->m_chart->plotArea().x());
193 rect.setWidth(d_ptr->m_chart->plotArea().width());
194 rect.setWidth(d_ptr->m_chart->plotArea().width());
194 } else if (d_ptr->m_rubberBandFlags == HorizonalRubberBand) {
195 } else if (d_ptr->m_rubberBandFlags == HorizonalRubberBand) {
195 rect.setY(d_ptr->m_chart->plotArea().y());
196 rect.setY(d_ptr->m_chart->plotArea().y());
196 rect.setHeight(d_ptr->m_chart->plotArea().height());
197 rect.setHeight(d_ptr->m_chart->plotArea().height());
197 }
198 }
198 d_ptr->m_chart->zoomIn(rect);
199 d_ptr->m_chart->zoomIn(rect);
199 event->accept();
200 event->accept();
200 }
201 }
201
202
202 if (event->button() == Qt::RightButton) {
203 if (event->button() == Qt::RightButton) {
203 d_ptr->m_chart->zoomOut();
204 d_ptr->m_chart->zoomOut();
204 event->accept();
205 event->accept();
205 }
206 }
206 } else {
207 } else {
207 QGraphicsView::mouseReleaseEvent(event);
208 QGraphicsView::mouseReleaseEvent(event);
208 }
209 }
209 }
210 }
210
211
211 /*!
212 /*!
212 Resizes and updates the chart area using the \a event data
213 Resizes and updates the chart area using the \a event data
213 */
214 */
214 void QChartView::resizeEvent(QResizeEvent *event)
215 void QChartView::resizeEvent(QResizeEvent *event)
215 {
216 {
216 QGraphicsView::resizeEvent(event);
217 QGraphicsView::resizeEvent(event);
217 d_ptr->resize();
218 d_ptr->resize();
218 }
219 }
219
220
220 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
221 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
221
222
222 QChartViewPrivate::QChartViewPrivate(QChartView *q, QChart *chart)
223 QChartViewPrivate::QChartViewPrivate(QChartView *q, QChart *chart)
223 : q_ptr(q),
224 : q_ptr(q),
224 m_scene(new QGraphicsScene(q)),
225 m_scene(new QGraphicsScene(q)),
225 m_chart(chart),
226 m_chart(chart),
226 m_rubberBand(0),
227 m_rubberBand(0),
227 m_rubberBandFlags(QChartView::NoRubberBand)
228 m_rubberBandFlags(QChartView::NoRubberBand)
228 {
229 {
229 q_ptr->setFrameShape(QFrame::NoFrame);
230 q_ptr->setFrameShape(QFrame::NoFrame);
230 q_ptr->setBackgroundRole(QPalette::Window);
231 q_ptr->setBackgroundRole(QPalette::Window);
231 q_ptr->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
232 q_ptr->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
232 q_ptr->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
233 q_ptr->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
233 q_ptr->setScene(m_scene);
234 q_ptr->setScene(m_scene);
234 q_ptr->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
235 q_ptr->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
235 if (!m_chart)
236 if (!m_chart)
236 m_chart = new QChart();
237 m_chart = new QChart();
237 m_scene->addItem(m_chart);
238 m_scene->addItem(m_chart);
238 }
239 }
239
240
240 QChartViewPrivate::~QChartViewPrivate()
241 QChartViewPrivate::~QChartViewPrivate()
241 {
242 {
242 }
243 }
243
244
244 void QChartViewPrivate::setChart(QChart *chart)
245 void QChartViewPrivate::setChart(QChart *chart)
245 {
246 {
246 Q_ASSERT(chart);
247 Q_ASSERT(chart);
247
248
248 if (m_chart == chart)
249 if (m_chart == chart)
249 return;
250 return;
250
251
251 if (m_chart)
252 if (m_chart)
252 m_scene->removeItem(m_chart);
253 m_scene->removeItem(m_chart);
253
254
254 m_chart = chart;
255 m_chart = chart;
255 m_scene->addItem(m_chart);
256 m_scene->addItem(m_chart);
256
257
257 resize();
258 resize();
258 }
259 }
259
260
260 const qreal rad2deg(57.2957795);
261 const qreal rad2deg(57.2957795);
261
262
262 void QChartViewPrivate::resize()
263 void QChartViewPrivate::resize()
263 {
264 {
264 // Flip chart width and height if the view has been rotated
265 // Flip chart width and height if the view has been rotated
265 // more than 45 degrees from the horizontal so it fits better into the view.
266 // more than 45 degrees from the horizontal so it fits better into the view.
266 qreal angle = acos(q_ptr->transform().m11()) * rad2deg;
267 qreal angle = qAcos(q_ptr->transform().m11()) * rad2deg;
267 QSize chartSize = q_ptr->size();
268 QSize chartSize = q_ptr->size();
268
269
269 if (angle > 45.0 && angle < 135.0) {
270 if (angle > 45.0 && angle < 135.0) {
270 chartSize.setHeight(q_ptr->size().width());
271 chartSize.setHeight(q_ptr->size().width());
271 chartSize.setWidth(q_ptr->size().height());
272 chartSize.setWidth(q_ptr->size().height());
272 }
273 }
273
274
274 m_chart->resize(chartSize);
275 m_chart->resize(chartSize);
275 q_ptr->setMinimumSize(m_chart->minimumSize().toSize());
276 q_ptr->setMinimumSize(m_chart->minimumSize().toSize());
276 q_ptr->setSceneRect(m_chart->geometry());
277 q_ptr->setSceneRect(m_chart->geometry());
277 }
278 }
278
279
279 #include "moc_qchartview.cpp"
280 #include "moc_qchartview.cpp"
280
281
281 QTCOMMERCIALCHART_END_NAMESPACE
282 QTCOMMERCIALCHART_END_NAMESPACE
General Comments 0
You need to be logged in to leave comments. Login now