##// END OF EJS Templates
Refactors Domain and Axis...
Michal Klocek -
r1698:da7242791c36
parent child
Show More
@@ -0,0 +1,15
1 INCLUDEPATH += $$PWD
2 DEPENDPATH += $$PWD
3
4 SOURCES += \
5 $$PWD/chartcategoriesaxisx.cpp \
6 $$PWD/chartcategoriesaxisy.cpp \
7 $$PWD/qbarcategoriesaxis.cpp
8
9 PRIVATE_HEADERS += \
10 $$PWD/chartcategoriesaxisx_p.h \
11 $$PWD/chartcategoriesaxisy_p.h \
12 $$PWD/qbarcategoriesaxis_p.h
13
14 PUBLIC_HEADERS += \
15 $$PWD/qbarcategoriesaxis.h No newline at end of file
@@ -0,0 +1,12
1 INCLUDEPATH += $$PWD
2 DEPENDPATH += $$PWD
3
4 SOURCES += \
5 $$PWD/qintervalsaxis.cpp
6
7
8 PRIVATE_HEADERS += \
9 $$PWD/qintervalaxis_p.h
10
11 PUBLIC_HEADERS += \
12 $$PWD/qintervalaxis.h
@@ -0,0 +1,15
1 INCLUDEPATH += $$PWD
2 DEPENDPATH += $$PWD
3
4 SOURCES += \
5 $$PWD/chartvaluesaxisx.cpp \
6 $$PWD/chartvaluesaxisy.cpp \
7 $$PWD/qvaluesaxis.cpp \
8
9 PRIVATE_HEADERS += \
10 $$PWD/chartvaluesaxisx_p.h \
11 $$PWD/chartvaluesaxisy_p.h \
12 $$PWD/qvaluesaxis_p.h
13
14 PUBLIC_HEADERS += \
15 $$PWD/qvaluesaxis.h No newline at end of file
@@ -1,145 +1,150
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "areachartitem_p.h"
22 22 #include "qareaseries.h"
23 23 #include "qareaseries_p.h"
24 24 #include "qlineseries.h"
25 25 #include "chartpresenter_p.h"
26 #include "domain_p.h"
26 27 #include <QPainter>
27 28 #include <QGraphicsSceneMouseEvent>
28 29 #include <QDebug>
29 30
30 31
31 32 QTCOMMERCIALCHART_BEGIN_NAMESPACE
32 33
33 34 //TODO: optimize : remove points which are not visible
34 35
35 36 AreaChartItem::AreaChartItem(QAreaSeries *areaSeries, ChartPresenter *presenter)
36 37 : ChartItem(presenter),
37 38 m_series(areaSeries),
38 39 m_upper(0),
39 40 m_lower(0),
40 41 m_pointsVisible(false)
41 42 {
42 43 setZValue(ChartPresenter::LineChartZValue);
43 44 m_upper = new AreaBoundItem(this,m_series->upperSeries(),presenter);
44 if (m_series->lowerSeries())
45 if (m_series->lowerSeries()){
45 46 m_lower = new AreaBoundItem(this,m_series->lowerSeries(),presenter);
47 }
46 48
47 49 QObject::connect(m_series->d_func(),SIGNAL(updated()),this,SLOT(handleUpdated()));
48 50 QObject::connect(m_series, SIGNAL(visibleChanged()), this, SLOT(handleUpdated()));
49 51 QObject::connect(this,SIGNAL(clicked(QPointF)),areaSeries,SIGNAL(clicked(QPointF)));
50 52
51 53 handleUpdated();
52 54 }
53 55
54 56 AreaChartItem::~AreaChartItem()
55 57 {
56 58 delete m_upper;
57 59 delete m_lower;
58 60 }
59 61
60 62 QRectF AreaChartItem::boundingRect() const
61 63 {
62 64 return m_rect;
63 65 }
64 66
65 67 QPainterPath AreaChartItem::shape() const
66 68 {
67 69 return m_path;
68 70 }
69 71
70 72 void AreaChartItem::updatePath()
71 73 {
72 74 QPainterPath path;
73 75
74 76 path = m_upper->shape();
75 77
76 78 if (m_lower) {
77 79 path.connectPath(m_lower->shape().toReversed());
78 80 } else {
79 81 QPointF first = path.pointAtPercent(0);
80 82 QPointF last = path.pointAtPercent(1);
81 83 path.lineTo(last.x(),m_clipRect.bottom());
82 84 path.lineTo(first.x(),m_clipRect.bottom());
83 85 }
84 86 path.closeSubpath();
85 87 prepareGeometryChange();
86 88 m_path = path;
87 89 m_rect = path.boundingRect();
88 90 update();
89 91 }
90 92
91 93 void AreaChartItem::handleUpdated()
92 94 {
93 95 setVisible(m_series->isVisible());
94 96 m_pointsVisible = m_series->pointsVisible();
95 97 m_linePen = m_series->pen();
96 98 m_brush = m_series->brush();
97 99 m_pointPen = m_series->pen();
98 100 m_pointPen.setWidthF(2 * m_pointPen.width());
99 101
100 102 update();
101 103 }
102 104
103 void AreaChartItem::handleDomainChanged(qreal minX, qreal maxX, qreal minY, qreal maxY)
105 void AreaChartItem::handleDomainUpdated()
104 106 {
105 m_upper->handleDomainChanged(minX,maxX,minY,maxY);
106 if (m_lower)
107 m_lower->handleDomainChanged(minX,maxX,minY,maxY);
107 m_upper->setDomain(domain());
108 m_upper->handleDomainUpdated();
109 if (m_lower){
110 m_lower->setDomain(domain());
111 m_lower->handleDomainUpdated();
112 }
108 113 }
109 114
110 115 void AreaChartItem::handleGeometryChanged(const QRectF &rect)
111 116 {
112 117 m_clipRect=rect.translated(-rect.topLeft());
113 118 setPos(rect.topLeft());
114 119 m_upper->handleGeometryChanged(rect);
115 120 if (m_lower)
116 121 m_lower->handleGeometryChanged(rect);
117 122 }
118 123
119 124 void AreaChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
120 125 {
121 126 Q_UNUSED(widget)
122 127 Q_UNUSED(option)
123 128
124 129 painter->save();
125 130 painter->setPen(m_linePen);
126 131 painter->setBrush(m_brush);
127 132 painter->setClipRect(m_clipRect);
128 133 painter->drawPath(m_path);
129 134 if (m_pointsVisible) {
130 135 painter->setPen(m_pointPen);
131 136 painter->drawPoints(m_upper->geometryPoints());
132 137 if (m_lower)
133 138 painter->drawPoints(m_lower->geometryPoints());
134 139 }
135 140 painter->restore();
136 141 }
137 142
138 143 void AreaChartItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
139 144 {
140 145 emit clicked(m_upper->calculateDomainPoint(event->pos()));
141 146 }
142 147
143 148 #include "moc_areachartitem_p.cpp"
144 149
145 150 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,103 +1,103
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 // W A R N I N G
22 22 // -------------
23 23 //
24 24 // This file is not part of the QtCommercial Chart API. It exists purely as an
25 25 // implementation detail. This header file may change from version to
26 26 // version without notice, or even be removed.
27 27 //
28 28 // We mean it.
29 29
30 30 #ifndef AREACHARTITEM_H
31 31 #define AREACHARTITEM_H
32 32
33 33 #include "qchartglobal.h"
34 34 #include "linechartitem_p.h"
35 35 #include <QPen>
36 36
37 37 QTCOMMERCIALCHART_BEGIN_NAMESPACE
38 38
39 39 class QAreaSeries;
40 40 class AreaChartItem;
41 41
42 42 class AreaChartItem : public ChartItem
43 43 {
44 44 Q_OBJECT
45 45 public:
46 46 AreaChartItem(QAreaSeries *areaSeries, ChartPresenter *presenter);
47 47 ~AreaChartItem();
48 48
49 49 //from QGraphicsItem
50 50 QRectF boundingRect() const;
51 51 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
52 52 QPainterPath shape() const;
53 53
54 54 LineChartItem* upperLineItem() const { return m_upper; }
55 55 LineChartItem* lowerLineItem() const { return m_lower; }
56 56
57 57 void updatePath();
58 58
59 59 protected:
60 60 void mousePressEvent(QGraphicsSceneMouseEvent *event);
61 61
62 62 Q_SIGNALS:
63 63 void clicked(const QPointF &point);
64 64
65 65 public Q_SLOTS:
66 66 void handleUpdated();
67 void handleDomainChanged(qreal minX, qreal maxX, qreal minY, qreal maxY);
67 void handleDomainUpdated();
68 68 void handleGeometryChanged(const QRectF &size);
69 69
70 70 private:
71 71 QAreaSeries* m_series;
72 72 LineChartItem* m_upper;
73 73 LineChartItem* m_lower;
74 74 QPainterPath m_path;
75 75 QRectF m_rect;
76 76 QRectF m_clipRect;
77 77 QPen m_linePen;
78 78 QPen m_pointPen;
79 79 QBrush m_brush;
80 80 bool m_pointsVisible;
81 81
82 82 };
83 83
84 84 class AreaBoundItem : public LineChartItem
85 85 {
86 86 public:
87 87 AreaBoundItem(AreaChartItem *item,QLineSeries *lineSeries,ChartPresenter* presenter) : LineChartItem(lineSeries, 0), m_item(item) {
88 88 setPresenter(presenter);
89 89 }
90 90 ~AreaBoundItem() {}
91 91
92 92 void updateGeometry() {
93 93 LineChartItem::updateGeometry();
94 94 m_item->updatePath();
95 95 }
96 96
97 97 private:
98 98 AreaChartItem* m_item;
99 99 };
100 100
101 101 QTCOMMERCIALCHART_END_NAMESPACE
102 102
103 103 #endif
@@ -1,397 +1,395
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "qareaseries.h"
22 22 #include "qareaseries_p.h"
23 23 #include "qlineseries.h"
24 24 #include "areachartitem_p.h"
25 25 #include "legendmarker_p.h"
26 26 #include "domain_p.h"
27 27 #include "chartdataset_p.h"
28 28 #include "charttheme_p.h"
29 29 #include "chartanimator_p.h"
30 30 #include "qvaluesaxis.h"
31 31
32 32 QTCOMMERCIALCHART_BEGIN_NAMESPACE
33 33
34 34 /*!
35 35 \class QAreaSeries
36 36 \brief The QAreaSeries class is used for making area charts.
37 37
38 38 \mainclass
39 39
40 40 An area chart is used to show quantitative data. It is based on line chart, in the way that area between axis and the line
41 41 is emphasized with color. Since the area chart is based on line chart, QAreaSeries constructor needs QLineSeries instance,
42 42 which defines "upper" boundary of the area. "Lower" boundary is defined by default by axis X. Instead of axis X "lower" boundary can be specified by other line.
43 43 In that case QAreaSeries should be initiated with two QLineSeries instances. Please note terms "upper" and "lower" boundary can be misleading in cases
44 44 where "lower" boundary had bigger values than the "upper" one, however the main point that area between these two boundary lines will be filled.
45 45
46 46 See the \l {AreaChart Example} {area chart example} to learn how to create a simple area chart.
47 47 \image examples_areachart.png
48 48 */
49 49 /*!
50 50 \qmlclass AreaSeries QAreaSeries
51 51
52 52 The following QML shows how to create a simple area chart:
53 53 \snippet ../demos/qmlchart/qml/qmlchart/View4.qml 1
54 54 \beginfloatleft
55 55 \image demos_qmlchart4.png
56 56 \endfloat
57 57 \clearfloat
58 58 */
59 59
60 60 /*!
61 61 \property QAreaSeries::upperSeries
62 62 \brief The upper one of the two line series used to define area series boundaries.
63 63 */
64 64 /*!
65 65 \qmlproperty LineSeries AreaSeries::upperSeries
66 66 The upper one of the two line series used to define area series boundaries.
67 67 */
68 68
69 69 /*!
70 70 \property QAreaSeries::lowerSeries
71 71 The lower one of the two line series used to define are series boundaries. Note if
72 72 QAreaSeries was counstucted wihtout a\ lowerSeries this is null.
73 73 */
74 74 /*!
75 75 \qmlproperty LineSeries AreaSeries::lowerSeries
76 76 The lower one of the two line series used to define are series boundaries. Note if
77 77 AreaSeries was counstucted wihtout a\ lowerSeries this is null.
78 78 */
79 79
80 80 /*!
81 81 \property QAreaSeries::color
82 82 Fill (brush) color of the series. This is a convenience property for modifying the color of brush.
83 83 \sa QAreaSeries::brush()
84 84 */
85 85 /*!
86 86 \qmlproperty color AreaSeries::color
87 87 Fill (brush) color of the series.
88 88 */
89 89
90 90 /*!
91 91 \property QAreaSeries::borderColor
92 92 Line (pen) color of the series. This is a convenience property for modifying the color of pen.
93 93 \sa QAreaSeries::pen()
94 94 */
95 95 /*!
96 96 \qmlproperty color AreaSeries::borderColor
97 97 Line (pen) color of the series.
98 98 */
99 99
100 100 /*!
101 101 \fn QPen QAreaSeries::pen() const
102 102 \brief Returns the pen used to draw line for this series.
103 103 \sa setPen()
104 104 */
105 105
106 106 /*!
107 107 \fn QPen QAreaSeries::brush() const
108 108 \brief Returns the brush used to draw line for this series.
109 109 \sa setBrush()
110 110 */
111 111
112 112 /*!
113 113 \fn void QAreaSeries::colorChanged(QColor color)
114 114 \brief Signal is emitted when the fill (brush) color has changed to \a color.
115 115 */
116 116 /*!
117 117 \qmlsignal AreaSeries::onColorChanged(color color)
118 118 Signal is emitted when the fill (brush) color has changed to \a color.
119 119 */
120 120
121 121 /*!
122 122 \fn void QAreaSeries::borderColorChanged(QColor color)
123 123 \brief Signal is emitted when the line (pen) color has changed to \a color.
124 124 */
125 125 /*!
126 126 \qmlsignal AreaSeries::onBorderColorChanged(color color)
127 127 Signal is emitted when the line (pen) color has changed to \a color.
128 128 */
129 129
130 130 /*!
131 131 \fn void QAreaSeries::clicked(const QPointF& point)
132 132 \brief Signal is emitted when user clicks the \a point on area chart.
133 133 */
134 134 /*!
135 135 \qmlsignal AreaSeries::onClicked(QPointF point)
136 136 Signal is emitted when user clicks the \a point on area chart.
137 137 */
138 138
139 139 /*!
140 140 \fn void QAreaSeries::selected()
141 141 The signal is emitted if the user selects/deselects the XY series. The logic for maintaining selections should be
142 142 implemented by the user of QAreaSeries API.
143 143 */
144 144 /*!
145 145 \qmlsignal AreaSeries::onSelected()
146 146 The signal is emitted if the user selects/deselects the XY series. The logic for maintaining selections should be
147 147 implemented by the user of AreaSeries API.
148 148 */
149 149
150 150 /*!
151 151 \fn void QAreaSeriesPrivate::updated()
152 152 \brief \internal
153 153 */
154 154
155 155 /*!
156 156 Constructs area series object which is a child of \a upperSeries. Area will be spanned between \a
157 157 upperSeries line and \a lowerSeries line. If no \a lowerSeries is passed to constructor, area is specified by axis x (y=0) instead.
158 158 When series object is added to QChartView or QChart instance ownerships is transferred.
159 159 */
160 160 QAreaSeries::QAreaSeries(QLineSeries *upperSeries, QLineSeries *lowerSeries)
161 161 : QAbstractSeries(*new QAreaSeriesPrivate(upperSeries,lowerSeries,this),upperSeries)
162 162 {
163 163 }
164 164
165 165 /*!
166 166 Constructs area series object without upper or lower series with \a parent object.
167 167 */
168 168 QAreaSeries::QAreaSeries(QObject *parent)
169 169 : QAbstractSeries(*new QAreaSeriesPrivate(0, 0, this), parent)
170 170 {
171 171 }
172 172
173 173 /*!
174 174 Destroys the object.
175 175 */
176 176 QAreaSeries::~QAreaSeries()
177 177 {
178 178 }
179 179
180 180 /*!
181 181 Returns QChartSeries::SeriesTypeArea.
182 182 */
183 183 QAbstractSeries::SeriesType QAreaSeries::type() const
184 184 {
185 185 return QAbstractSeries::SeriesTypeArea;
186 186 }
187 187
188 188 /*!
189 189 Sets the \a series that is to be used as the area chart upper series.
190 190 */
191 191 void QAreaSeries::setUpperSeries(QLineSeries* series)
192 192 {
193 193 Q_D(QAreaSeries);
194 194 d->m_upperSeries = series;
195 195 }
196 196
197 197 QLineSeries* QAreaSeries::upperSeries() const
198 198 {
199 199 Q_D(const QAreaSeries);
200 200 return d->m_upperSeries;
201 201 }
202 202
203 203 /*!
204 204 Sets the \a series that is to be used as the area chart lower series.
205 205 */
206 206 void QAreaSeries::setLowerSeries(QLineSeries* series)
207 207 {
208 208 Q_D(QAreaSeries);
209 209 d->m_lowerSeries = series;
210 210 }
211 211
212 212 QLineSeries* QAreaSeries::lowerSeries() const
213 213 {
214 214 Q_D(const QAreaSeries);
215 215 return d->m_lowerSeries;
216 216 }
217 217
218 218 /*!
219 219 Sets \a pen used for drawing area outline.
220 220 */
221 221 void QAreaSeries::setPen(const QPen &pen)
222 222 {
223 223 Q_D(QAreaSeries);
224 224 if (d->m_pen != pen) {
225 225 d->m_pen = pen;
226 226 emit d->updated();
227 227 }
228 228 }
229 229
230 230 QPen QAreaSeries::pen() const
231 231 {
232 232 Q_D(const QAreaSeries);
233 233 return d->m_pen;
234 234 }
235 235
236 236 /*!
237 237 Sets \a brush used for filling the area.
238 238 */
239 239 void QAreaSeries::setBrush(const QBrush &brush)
240 240 {
241 241 Q_D(QAreaSeries);
242 242 if (d->m_brush != brush) {
243 243 d->m_brush = brush;
244 244 emit d->updated();
245 245 }
246 246 }
247 247
248 248 QBrush QAreaSeries::brush() const
249 249 {
250 250 Q_D(const QAreaSeries);
251 251 return d->m_brush;
252 252 }
253 253
254 254 void QAreaSeries::setColor(const QColor &color)
255 255 {
256 256 QBrush b = brush();
257 257 if (b.color() != color) {
258 258 b.setColor(color);
259 259 setBrush(b);
260 260 emit colorChanged(color);
261 261 }
262 262 }
263 263
264 264 QColor QAreaSeries::color() const
265 265 {
266 266 return brush().color();
267 267 }
268 268
269 269 void QAreaSeries::setBorderColor(const QColor &color)
270 270 {
271 271 QPen p = pen();
272 272 if (p.color() != color) {
273 273 p.setColor(color);
274 274 setPen(p);
275 275 emit borderColorChanged(color);
276 276 }
277 277 }
278 278
279 279 QColor QAreaSeries::borderColor() const
280 280 {
281 281 return pen().color();
282 282 }
283 283
284 284 /*!
285 285 Sets if data points are \a visible and should be drawn on line.
286 286 */
287 287 void QAreaSeries::setPointsVisible(bool visible)
288 288 {
289 289 Q_D(QAreaSeries);
290 290 if (d->m_pointsVisible != visible) {
291 291 d->m_pointsVisible = visible;
292 292 emit d->updated();
293 293 }
294 294 }
295 295
296 296 /*!
297 297 Returns if the points are drawn for this series.
298 298 \sa setPointsVisible()
299 299 */
300 300 bool QAreaSeries::pointsVisible() const
301 301 {
302 302 Q_D(const QAreaSeries);
303 303 return d->m_pointsVisible;
304 304 }
305 305
306 306 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
307 307
308 308 QAreaSeriesPrivate::QAreaSeriesPrivate(QLineSeries *upperSeries, QLineSeries *lowerSeries,QAreaSeries* q) :
309 309 QAbstractSeriesPrivate(q),
310 310 m_upperSeries(upperSeries),
311 311 m_lowerSeries(lowerSeries),
312 312 m_pointsVisible(false)
313 313 {
314 314 }
315 315
316 316 void QAreaSeriesPrivate::scaleDomain(Domain& domain)
317 317 {
318 318 Q_Q(QAreaSeries);
319 319
320 320 qreal minX(domain.minX());
321 321 qreal minY(domain.minY());
322 322 qreal maxX(domain.maxX());
323 323 qreal maxY(domain.maxY());
324 int tickXCount(domain.tickXCount());
325 int tickYCount(domain.tickYCount());
326 324
327 325 QLineSeries* upperSeries = q->upperSeries();
328 326 QLineSeries* lowerSeries = q->lowerSeries();
329 327
330 328 const QList<QPointF>& points = upperSeries->points();
331 329
332 330 for (int i = 0; i < points.count(); i++)
333 331 {
334 332 qreal x = points[i].x();
335 333 qreal y = points[i].y();
336 334 minX = qMin(minX, x);
337 335 minY = qMin(minY, y);
338 336 maxX = qMax(maxX, x);
339 337 maxY = qMax(maxY, y);
340 338 }
341 339 if(lowerSeries) {
342 340
343 341 const QList<QPointF>& points = lowerSeries->points();
344 342
345 343 for (int i = 0; i < points.count(); i++)
346 344 {
347 345 qreal x = points[i].x();
348 346 qreal y = points[i].y();
349 347 minX = qMin(minX, x);
350 348 minY = qMin(minY, y);
351 349 maxX = qMax(maxX, x);
352 350 maxY = qMax(maxY, y);
353 351 }}
354 352
355 domain.setRange(minX,maxX,minY,maxY,tickXCount,tickYCount);
353 domain.setRange(minX,maxX,minY,maxY);
356 354 }
357 355
358 356 Chart* QAreaSeriesPrivate::createGraphics(ChartPresenter* presenter)
359 357 {
360 358 Q_Q(QAreaSeries);
361 359
362 360 AreaChartItem* area = new AreaChartItem(q,presenter);
363 361 if(presenter->animationOptions().testFlag(QChart::SeriesAnimations)) {
364 362 area->upperLineItem()->setAnimator(presenter->animator());
365 363 area->upperLineItem()->setAnimation(new XYAnimation(area->upperLineItem()));
366 364 if(q->lowerSeries()) {
367 365 area->lowerLineItem()->setAnimator(presenter->animator());
368 366 area->lowerLineItem()->setAnimation(new XYAnimation(area->lowerLineItem()));
369 367 }
370 368 }
371 369 presenter->chartTheme()->decorate(q, presenter->dataSet()->seriesIndex(q));
372 370 return area;
373 371 }
374 372
375 373 QList<LegendMarker*> QAreaSeriesPrivate::createLegendMarker(QLegend* legend)
376 374 {
377 375 Q_Q(QAreaSeries);
378 376 QList<LegendMarker*> list;
379 377 return list << new AreaLegendMarker(q,legend);
380 378 }
381 379
382 380
383 381 void QAreaSeriesPrivate::initializeAxis(QAbstractAxis* axis)
384 382 {
385 383 Q_UNUSED(axis);
386 384 }
387 385
388 386 QAbstractAxis::AxisType QAreaSeriesPrivate::defaultAxisType(Qt::Orientation orientation) const
389 387 {
390 388 Q_UNUSED(orientation);
391 389 return QAbstractAxis::AxisTypeValues;
392 390 }
393 391
394 392 #include "moc_qareaseries.cpp"
395 393 #include "moc_qareaseries_p.cpp"
396 394
397 395 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,30 +1,16
1 include(valuesaxis/valuesaxis.pri)
2 include(categoriesaxis/categoriesaxis.pri)
3
1 4 INCLUDEPATH += $$PWD
2 5 DEPENDPATH += $$PWD
3 6
4 7 SOURCES += \
5 8 $$PWD/chartaxis.cpp \
6 $$PWD/chartvaluesaxisx.cpp \
7 $$PWD/chartvaluesaxisy.cpp \
8 $$PWD/chartcategoriesaxisx.cpp \
9 $$PWD/chartcategoriesaxisy.cpp \
10 $$PWD/qbarcategoriesaxis.cpp \
11 # $$PWD/qintervalaxis.cpp \
12 $$PWD/qvaluesaxis.cpp \
13 9 $$PWD/qabstractaxis.cpp
14 10
15 11 PRIVATE_HEADERS += \
16 12 $$PWD/chartaxis_p.h \
17 $$PWD/chartvaluesaxisx_p.h \
18 $$PWD/chartvaluesaxisy_p.h \
19 $$PWD/chartcategoriesaxisx_p.h \
20 $$PWD/chartcategoriesaxisy_p.h \
21 $$PWD/qbarcategoriesaxis_p.h \
22 # $$PWD/qintervalaxis_p.h \
23 $$PWD/qvaluesaxis_p.h \
24 13 $$PWD/qabstractaxis_p.h
25 14
26 15 PUBLIC_HEADERS += \
27 $$PWD/qbarcategoriesaxis.h \
28 # $$PWD/qintervalaxis.h \
29 $$PWD/qvaluesaxis.h \
30 16 $$PWD/qabstractaxis.h
@@ -1,117 +1,117
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "chartcategoriesaxisx_p.h"
22 22 #include "chartpresenter_p.h"
23 23 #include "chartanimator_p.h"
24 24 #include "qbarcategoriesaxis.h"
25 25 #include <QGraphicsLayout>
26 26 #include <QFontMetrics>
27 27
28 28 static int label_padding = 5;
29 29
30 30 QTCOMMERCIALCHART_BEGIN_NAMESPACE
31 31
32 32 ChartCategoriesAxisX::ChartCategoriesAxisX(QBarCategoriesAxis *axis,ChartPresenter *presenter) : ChartAxis(axis,presenter),
33 33 m_categoriesAxis(axis)
34 34 {
35 35
36 36 }
37 37
38 38 ChartCategoriesAxisX::~ChartCategoriesAxisX()
39 39 {
40 40 }
41 41
42 42 QVector<qreal> ChartCategoriesAxisX::calculateLayout() const
43 43 {
44 Q_ASSERT(m_ticksCount>=2);
44 Q_ASSERT(m_categoriesAxis->categories().count()>=2);
45 45
46 46 QVector<qreal> points;
47 points.resize(m_ticksCount);
47 points.resize(m_categoriesAxis->categories().count());
48 48
49 49 // TODO: shift logic
50 const qreal deltaX = m_rect.width()/(m_ticksCount-1);
51 for (int i = 0; i < m_ticksCount; ++i) {
50 const qreal deltaX = m_rect.width()/(m_categoriesAxis->categories().count()-1);
51 for (int i = 0; i < m_categoriesAxis->categories().count(); ++i) {
52 52 int x = i * deltaX + m_rect.left();
53 53 points[i] = x;
54 54 }
55 55 return points;
56 56 }
57 57
58 58 void ChartCategoriesAxisX::updateGeometry()
59 59 {
60 60 const QVector<qreal>& layout = ChartAxis::layout();
61 61
62 62 m_minWidth = 0;
63 63 m_minHeight = 0;
64 64
65 65 if(layout.isEmpty()) return;
66 66
67 67 QStringList ticksList;
68 68
69 69 createCategoryLabels(ticksList,m_min,m_max,m_categoriesAxis->categories());
70 70
71 71 QList<QGraphicsItem *> lines = m_grid->childItems();
72 72 QList<QGraphicsItem *> labels = m_labels->childItems();
73 73 QList<QGraphicsItem *> shades = m_shades->childItems();
74 74 QList<QGraphicsItem *> axis = m_axis->childItems();
75 75
76 76 Q_ASSERT(labels.size() == ticksList.size());
77 77 Q_ASSERT(layout.size() == ticksList.size());
78 78
79 79 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(axis.at(0));
80 80 lineItem->setLine(m_rect.left(), m_rect.bottom(), m_rect.right(), m_rect.bottom());
81 81
82 82 for (int i = 0; i < layout.size(); ++i) {
83 83 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(lines.at(i));
84 84 lineItem->setLine(layout[i], m_rect.top(), layout[i], m_rect.bottom());
85 85 QGraphicsSimpleTextItem *labelItem = static_cast<QGraphicsSimpleTextItem*>(labels.at(i));
86 86 if (i>=1) {
87 87 labelItem->setText(ticksList.at(i-1));
88 88 const QRectF& rect = labelItem->boundingRect();
89 89 QPointF center = rect.center();
90 90 labelItem->setTransformOriginPoint(center.x(), center.y());
91 91 labelItem->setPos(layout[i] - (layout[i] - layout[i-1])/2 - center.x(), m_rect.bottom() + label_padding);
92 92 m_minWidth+=rect.width();
93 93 m_minHeight=qMax(rect.height()+label_padding,m_minHeight);
94 94 }else{
95 95 labelItem->setVisible(false);
96 96 }
97 97
98 98 if ((i+1)%2 && i>1) {
99 99 QGraphicsRectItem *rectItem = static_cast<QGraphicsRectItem*>(shades.at(i/2-1));
100 100 rectItem->setRect(layout[i-1],m_rect.top(),layout[i]-layout[i-1],m_rect.height());
101 101 }
102 102 lineItem = static_cast<QGraphicsLineItem*>(axis.at(i+1));
103 103 lineItem->setLine(layout[i],m_rect.bottom(),layout[i],m_rect.bottom()+5);
104 104 }
105 105 }
106 106
107 107 void ChartCategoriesAxisX::handleAxisUpdated()
108 108 {
109 109 if(m_categoriesAxis->categories()!=m_categories)
110 110 {
111 111 m_categories=m_categoriesAxis->categories();
112 112 if(ChartAxis::layout().count()==m_categories.size()+1) updateGeometry();
113 113 }
114 114 ChartAxis::handleAxisUpdated();
115 115 }
116 116
117 117 QTCOMMERCIALCHART_END_NAMESPACE
1 NO CONTENT: file renamed from src/axis/chartcategoriesaxisx_p.h to src/axis/categoriesaxis/chartcategoriesaxisx_p.h
@@ -1,120 +1,120
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "chartcategoriesaxisy_p.h"
22 22 #include "chartpresenter_p.h"
23 23 #include "chartanimator_p.h"
24 24 #include "qbarcategoriesaxis.h"
25 25 #include <QGraphicsLayout>
26 26 #include <QFontMetrics>
27 27 #include <QBarCategoriesAxis>
28 28
29 29 static int label_padding = 5;
30 30
31 31 QTCOMMERCIALCHART_BEGIN_NAMESPACE
32 32
33 33 ChartCategoriesAxisY::ChartCategoriesAxisY(QBarCategoriesAxis *axis,ChartPresenter *presenter) : ChartAxis(axis,presenter),
34 34 m_categoriesAxis(axis)
35 35 {
36 36 }
37 37
38 38 ChartCategoriesAxisY::~ChartCategoriesAxisY()
39 39 {
40 40 }
41 41
42 42 QVector<qreal> ChartCategoriesAxisY::calculateLayout() const
43 43 {
44 Q_ASSERT(m_ticksCount>=2);
44 Q_ASSERT(m_categoriesAxis->categories().count()>=2);
45 45
46 46 QVector<qreal> points;
47 points.resize(m_ticksCount);
47 points.resize(m_categoriesAxis->categories().count());
48 48
49 const qreal deltaY = m_rect.height()/(m_ticksCount-1);
50 for (int i = 0; i < m_ticksCount; ++i) {
49 const qreal deltaY = m_rect.height()/(m_categoriesAxis->categories().count()-1);
50 for (int i = 0; i < m_categoriesAxis->categories().count(); ++i) {
51 51 int y = i * -deltaY + m_rect.bottom();
52 52 points[i] = y;
53 53 }
54 54
55 55 return points;
56 56 }
57 57
58 58 void ChartCategoriesAxisY::updateGeometry()
59 59 {
60 60 const QVector<qreal>& layout = ChartAxis::layout();
61 61
62 62 m_minWidth = 0;
63 63 m_minHeight = 0;
64 64
65 65 if(layout.isEmpty()) return;
66 66
67 67 QStringList ticksList;
68 68
69 69 createCategoryLabels(ticksList,m_min,m_max,m_categoriesAxis->categories());
70 70
71 71 QList<QGraphicsItem *> lines = m_grid->childItems();
72 72 QList<QGraphicsItem *> labels = m_labels->childItems();
73 73 QList<QGraphicsItem *> shades = m_shades->childItems();
74 74 QList<QGraphicsItem *> axis = m_axis->childItems();
75 75
76 76 Q_ASSERT(labels.size() == ticksList.size());
77 77 Q_ASSERT(layout.size() == ticksList.size());
78 78
79 79 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(axis.at(0));
80 80 lineItem->setLine(m_rect.left() , m_rect.top(), m_rect.left(), m_rect.bottom());
81 81
82 82 for (int i = 0; i < layout.size(); ++i) {
83 83 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(lines.at(i));
84 84 lineItem->setLine(m_rect.left() , layout[i], m_rect.right(), layout[i]);
85 85 QGraphicsSimpleTextItem *labelItem = static_cast<QGraphicsSimpleTextItem*>(labels.at(i));
86 86 if(i>=1){
87 87 labelItem->setText(ticksList.at(i-1));
88 88 const QRectF& rect = labelItem->boundingRect();
89 89 QPointF center = rect.center();
90 90 labelItem->setTransformOriginPoint(center.x(), center.y());
91 91 labelItem->setPos(m_rect.left() - rect.width() - label_padding , layout[i] - (layout[i] - layout[i-1])/2 -center.y());
92 92 m_minWidth+=rect.width();
93 93 m_minHeight=qMax(rect.height()+label_padding,m_minHeight);
94 94 }else{
95 95 labelItem->setVisible(false);
96 96 }
97 97
98 98
99 99 if ((i+1)%2 && i>1) {
100 100 QGraphicsRectItem *rectItem = static_cast<QGraphicsRectItem*>(shades.at(i/2-1));
101 101 rectItem->setRect(m_rect.left(),layout[i],m_rect.width(),layout[i-1]-layout[i]);
102 102 }
103 103 lineItem = static_cast<QGraphicsLineItem*>(axis.at(i+1));
104 104 lineItem->setLine(m_rect.left()-5,layout[i],m_rect.left(),layout[i]);
105 105 }
106 106 }
107 107
108 108
109 109 void ChartCategoriesAxisY::handleAxisUpdated()
110 110 {
111 111
112 112 if(m_categoriesAxis->categories()!=m_categories)
113 113 {
114 114 m_categories=m_categoriesAxis->categories();
115 115 if(ChartAxis::layout().count()==m_categories.size()+1) updateGeometry();
116 116 }
117 117 ChartAxis::handleAxisUpdated();
118 118 }
119 119
120 120 QTCOMMERCIALCHART_END_NAMESPACE
1 NO CONTENT: file renamed from src/axis/chartcategoriesaxisy_p.h to src/axis/categoriesaxis/chartcategoriesaxisy_p.h
@@ -1,442 +1,427
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "qbarcategoriesaxis.h"
22 22 #include "qbarcategoriesaxis_p.h"
23 23 #include "chartcategoriesaxisx_p.h"
24 24 #include "chartcategoriesaxisy_p.h"
25 25 #include "domain_p.h"
26 26 #include <qmath.h>
27 27 #include <QDebug>
28 28
29 29 QTCOMMERCIALCHART_BEGIN_NAMESPACE
30 30 /*!
31 31 \class QBarCategoriesAxis
32 32 \brief The QBarCategoriesAxis class is used for manipulating chart's axis.
33 33 \mainclass
34 34
35 35 BarCategoriesAxis can be setup to show axis line with tick marks, grid lines and shades.
36 36 Categories are drawn between ticks. Note that you can use this also with lineseries too.
37 37 See the \l {Line and BarChart Example} {Line and BarChart Example} to learn how to do that.
38 38 */
39 39
40 40 /*!
41 41 \qmlclass BarCategoriesAxis QBarCategoriesAxis
42 42 \brief The Axis element is used for manipulating chart's axes.
43 43
44 44 Axis can be setup to show axis line with tick marks, grid lines and shades.
45 45 Categories are drawn between ticks. Note that you can use this also with lineseries too.
46 46
47 47 To access BarCategoriesAxis you can use ChartView API. For example:
48 48 \code
49 49 ChartView {
50 50 BarCategoriesAxis {
51 51 id: categoryAxis
52 52 categories: ["Jan", "Feb", "Mar", "Apr", "May", "Jun" ]
53 53 }
54 54 // Add a few series...
55 55 }
56 56 \endcode
57 57 */
58 58
59 59 /*!
60 60 \property QBarCategoriesAxis::categories
61 61 Defines the categories of axis
62 62 */
63 63 /*!
64 64 \qmlproperty QStringList BarCategoriesAxis::categories
65 65 Defines the categories of axis
66 66 */
67 67
68 68 /*!
69 69 \property QBarCategoriesAxis::min
70 70 Defines the minimum value on the axis.
71 71 */
72 72 /*!
73 73 \qmlproperty QString BarCategoriesAxis::min
74 74 Defines the minimum value on the axis.
75 75 */
76 76
77 77 /*!
78 78 \property QBarCategoriesAxis::max
79 79 Defines the maximum value on the axis.
80 80 */
81 81 /*!
82 82 \qmlproperty QString BarCategoriesAxis::max
83 83 Defines the maximum value on the axis.
84 84 */
85 85
86 86
87 87 /*!
88 88 \fn void QBarCategoriesAxis::categoriesChanged()
89 89 Axis emits signal when the categories of the axis has changed.
90 90 */
91 91 /*!
92 92 \fn void QBarCategoriesAxis::minChanged(const QString &min)
93 93 Axis emits signal when \a min of axis has changed.
94 94 */
95 95 /*!
96 96 \qmlsignal BarCategoriesAxis::onMinChanged(const QString &min)
97 97 Axis emits signal when \a min of axis has changed.
98 98 */
99 99
100 100 /*!
101 101 \fn void QBarCategoriesAxis::maxChanged(const QString &max)
102 102 Axis emits signal when \a max of axis has changed.
103 103 */
104 104 /*!
105 105 \qmlsignal BarCategoriesAxis::onMaxChanged(const QString &max)
106 106 Axis emits signal when \a max of axis has changed.
107 107 */
108 108
109 109 /*!
110 110 \fn void QBarCategoriesAxis::rangeChanged(const QString &min, const QString &max)
111 111 Axis emits signal when \a min or \a max of axis has changed.
112 112 */
113 113
114 114 /*!
115 115 Constructs an axis object which is a child of \a parent.
116 116 */
117 117 QBarCategoriesAxis::QBarCategoriesAxis(QObject *parent):
118 118 QAbstractAxis(*new QBarCategoriesAxisPrivate(this),parent)
119 119 {
120 120 }
121 121
122 122 /*!
123 123 Destroys the object
124 124 */
125 125 QBarCategoriesAxis::~QBarCategoriesAxis()
126 126 {
127 127 }
128 128
129 129 /*!
130 130 \internal
131 131 */
132 132 QBarCategoriesAxis::QBarCategoriesAxis(QBarCategoriesAxisPrivate &d,QObject *parent):QAbstractAxis(d,parent)
133 133 {
134 134
135 135 }
136 136
137 137 /*!
138 138 Appends \a categories to axis
139 139 */
140 140 void QBarCategoriesAxis::append(const QStringList &categories)
141 141 {
142 142 if(categories.isEmpty()) return;
143 143
144 144 Q_D(QBarCategoriesAxis);
145 145 if (d->m_categories.isEmpty()) {
146 146 d->m_categories.append(categories);
147 147 setRange(categories.first(),categories.last());
148 148 }else{
149 149 d->m_categories.append(categories);
150 150 }
151 151 emit d->updated();
152 152 emit categoriesChanged();
153 153 }
154 154
155 155 /*!
156 156 Appends \a category to axis
157 157 */
158 158 void QBarCategoriesAxis::append(const QString &category)
159 159 {
160 160 Q_D(QBarCategoriesAxis);
161 161 if (d->m_categories.isEmpty()) {
162 162 d->m_categories.append(category);
163 163 setRange(category,category);
164 164 }else{
165 165 d->m_categories.append(category);
166 166 }
167 167 emit d->updated();
168 168 emit categoriesChanged();
169 169 }
170 170
171 171 /*!
172 172 Removes \a category from axis
173 173 */
174 174 void QBarCategoriesAxis::remove(const QString &category)
175 175 {
176 176 Q_D(QBarCategoriesAxis);
177 177 if (d->m_categories.contains(category)) {
178 178 d->m_categories.removeAt(d->m_categories.indexOf(category));
179 179 setRange(d->m_categories.first(),d->m_categories.last());
180 180 emit d->updated();
181 181 emit categoriesChanged();
182 182 }
183 183 }
184 184
185 185 /*!
186 186 Inserts \a category to axis at \a index
187 187 */
188 188 void QBarCategoriesAxis::insert(int index, const QString &category)
189 189 {
190 190 Q_D(QBarCategoriesAxis);
191 191 if (d->m_categories.isEmpty()) {
192 192 d->m_categories.insert(index,category);
193 193 setRange(category,category);
194 194 }else{
195 195 d->m_categories.insert(index,category);
196 196 }
197 197 emit d->updated();
198 198 emit categoriesChanged();
199 199 }
200 200
201 201 /*!
202 202 Removes all categories.
203 203 */
204 204 void QBarCategoriesAxis::clear()
205 205 {
206 206 Q_D(QBarCategoriesAxis);
207 207 d->m_categories.clear();
208 208 setRange(QString::null,QString::null);
209 209 emit d->updated();
210 210 emit categoriesChanged();
211 211 }
212 212
213 213 void QBarCategoriesAxis::setCategories(const QStringList &categories)
214 214 {
215 215 Q_D(QBarCategoriesAxis);
216 216 if(d->m_categories!=categories){
217 217 d->m_categories = categories;
218 218 setRange(categories.first(),categories.last());
219 219 emit d->updated();
220 220 emit categoriesChanged();
221 221 }
222 222 }
223 223
224 224 QStringList QBarCategoriesAxis::categories()
225 225 {
226 226 Q_D(QBarCategoriesAxis);
227 227 return d->m_categories;
228 228 }
229 229
230 230 /*!
231 231 Returns number of categories.
232 232 */
233 233 int QBarCategoriesAxis::count() const
234 234 {
235 235 Q_D(const QBarCategoriesAxis);
236 236 return d->m_categories.count();
237 237 }
238 238
239 239 /*!
240 240 Returns category at \a index. Index must be valid.
241 241 */
242 242 QString QBarCategoriesAxis::at(int index) const
243 243 {
244 244 Q_D(const QBarCategoriesAxis);
245 245 return d->m_categories.at(index);
246 246 }
247 247
248 248 /*!
249 249 Sets minimum category to \a min.
250 250 */
251 251 void QBarCategoriesAxis::setMin(const QString& min)
252 252 {
253 253 Q_D(QBarCategoriesAxis);
254 setRange(min,d->m_maxCategory);
254 if (d->m_minCategory!=min && d->m_categories.contains(min)) {
255 d->m_minCategory = min;
256 d->emitUpdated();
257 emit minChanged(min);
258 }
259
255 260 }
256 261
257 262 /*!
258 263 Returns minimum category.
259 264 */
260 265 QString QBarCategoriesAxis::min() const
261 266 {
262 267 Q_D(const QBarCategoriesAxis);
263 268 return d->m_minCategory;
264 269 }
265 270
266 271 /*!
267 272 Sets maximum category to \a max.
268 273 */
269 274 void QBarCategoriesAxis::setMax(const QString& max)
270 275 {
271 276 Q_D(QBarCategoriesAxis);
272 setRange(d->m_minCategory,max);
277 if (d->m_maxCategory!=max && d->m_categories.contains(max)) {
278 d->m_maxCategory = max;
279 d->emitUpdated();
280 emit maxChanged(max);
281 }
282
273 283 }
274 284
275 285 /*!
276 286 Returns maximum category
277 287 */
278 288 QString QBarCategoriesAxis::max() const
279 289 {
280 290 Q_D(const QBarCategoriesAxis);
281 291 return d->m_maxCategory;
282 292 }
283 293
284 294 /*!
285 295 Sets range from \a minCategory to \a maxCategory
286 296 */
287 297 void QBarCategoriesAxis::setRange(const QString& minCategory, const QString& maxCategory)
288 298 {
289 Q_D(QBarCategoriesAxis);
290
291 int minIndex = d->m_categories.indexOf(minCategory);
292 if (minIndex == -1) {
293 return;
294 }
295 int maxIndex = d->m_categories.indexOf(maxCategory);
296 if (maxIndex == -1) {
297 return;
298 }
299
300 if (maxIndex <= minIndex) {
301 // max must be greater than min
302 return;
303 }
304
305 bool changed = false;
306 if (!qFuzzyIsNull(d->m_min - (minIndex))||d->m_minCategory!=minCategory) {
307 d->m_minCategory = minCategory;
308 d->m_min = minIndex;
309 emit minChanged(minCategory);
310 changed = true;
311 }
312
313 if (!qFuzzyIsNull(d->m_max - (maxIndex))||d->m_maxCategory!=maxCategory ) {
314 d->m_max = maxIndex;
315 d->m_maxCategory = maxCategory;
316 emit maxChanged(maxCategory);
317 changed = true;
318 }
319
320 if (changed) {
321 d->emitRange();
322 }
299 setMin(minCategory);
300 setMax(maxCategory);
323 301 }
324 302
325 303 /*!
326 304 Returns the type of the axis
327 305 */
328 306 QAbstractAxis::AxisType QBarCategoriesAxis::type() const
329 307 {
330 308 return AxisTypeCategories;
331 309 }
332 310
333 311 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
334 312
335 313 QBarCategoriesAxisPrivate::QBarCategoriesAxisPrivate(QBarCategoriesAxis* q):
336 314 QAbstractAxisPrivate(q)
337 315 {
338 316
339 317 }
340 318
341 319 QBarCategoriesAxisPrivate::~QBarCategoriesAxisPrivate()
342 320 {
343 321
344 322 }
345 323
346 324 void QBarCategoriesAxisPrivate::setMin(const QVariant &min)
347 325 {
348 326 setRange(min,m_maxCategory);
349 327 }
350 328
351 329 void QBarCategoriesAxisPrivate::setMax(const QVariant &max)
352 330 {
353 331 setRange(m_minCategory,max);
354 332 }
355 333
356 334 void QBarCategoriesAxisPrivate::setRange(const QVariant &min, const QVariant &max)
357 335 {
358 336 Q_Q(QBarCategoriesAxis);
359 337 QString value1 = min.toString();
360 338 QString value2 = max.toString();
361 339 q->setRange(value1,value2);
362 340 }
363 341
364 int QBarCategoriesAxisPrivate::ticksCount() const
342 qreal QBarCategoriesAxisPrivate::min()
343 {
344 //TODO:: cache it
345 return m_categories.indexOf(m_minCategory) + 0.5;
346 }
347
348 qreal QBarCategoriesAxisPrivate::max()
365 349 {
366 return m_categories.count()+1;
350 //TODO:: cache it
351 return m_categories.indexOf(m_maxCategory) + 0.5;
367 352 }
368 353
369 void QBarCategoriesAxisPrivate::handleAxisRangeChanged(qreal min, qreal max,int count)
354 void QBarCategoriesAxisPrivate::handleDomainUpdated()
370 355 {
371 356 // Q_Q(QBarCategoriesAxis);
372 m_min = min;
373 m_max = max;
374 m_ticksCount = count;
357
375 358 // TODO: causes crash in some situations. added to known issues
376 359 /*
377 360 int minIndex = qFloor(min);
378 361 int maxIndex = qFloor(max);
379 362
380 363 if (minIndex < 0) {
381 364 minIndex = 0;
382 365 }
383 366 if (maxIndex > m_categories.count()-1){
384 367 maxIndex = m_categories.count()-1;
385 368 if (maxIndex<0) {
386 369 maxIndex = 0;
387 370 }
388 371 }
389 372
390 373 bool changed = false;
391 374 if (m_minCategory != m_categories.at(minIndex)) {
392 375 m_minCategory = m_categories.at(minIndex);
393 376 emit q->minChanged(m_minCategory);
394 377 changed = true;
395 378 }
396 379
397 380 if (m_maxCategory != m_categories.at(maxIndex)) {
398 381 m_maxCategory = m_categories.at(maxIndex);
399 382 emit q->maxChanged(m_maxCategory);
400 383 changed = true;
401 384 }
402 385
403 386 if (changed) {
404 387 emit q->rangeChanged(m_minCategory, m_maxCategory);
405 388 }
406 389 */
407 390 }
408 391
409 392 ChartAxis* QBarCategoriesAxisPrivate::createGraphics(ChartPresenter* presenter)
410 393 {
411 394 Q_Q(QBarCategoriesAxis);
412 395 if(m_orientation == Qt::Vertical){
413 396 return new ChartCategoriesAxisY(q,presenter);
414 397 }else{
415 398 return new ChartCategoriesAxisX(q,presenter);
416 399 }
417 400 }
418 401
402 /*
419 403 void QBarCategoriesAxisPrivate::emitRange()
420 404 {
421 405 emit changed(m_min -0.5, m_max +0.5, qCeil(m_max + 0.5) -qCeil(m_min - 0.5) +1, false);
422 406 }
407 */
423 408
424 409 void QBarCategoriesAxisPrivate::intializeDomain(Domain* domain)
425 410 {
426 411 Q_UNUSED(domain);
427 412 // TODO: this causes crash now. added to known issues.
428 413 /*
429 414 if (qFuzzyCompare(m_max, m_min)) {
430 415 if(m_orientation==Qt::Vertical){
431 416 handleAxisRangeChanged(domain->minY(),domain->maxY(),domain->tickXCount());
432 417 }else{
433 418 handleAxisRangeChanged(domain->minX(),domain->maxX(),domain->tickYCount());
434 419 }
435 420 }
436 421 */
437 422 }
438 423
439 424 #include "moc_qbarcategoriesaxis.cpp"
440 425 #include "moc_qbarcategoriesaxis_p.cpp"
441 426
442 427 QTCOMMERCIALCHART_END_NAMESPACE
1 NO CONTENT: file renamed from src/axis/qbarcategoriesaxis.h to src/axis/categoriesaxis/qbarcategoriesaxis.h
@@ -1,77 +1,72
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 // W A R N I N G
22 22 // -------------
23 23 //
24 24 // This file is not part of the QtCommercial Chart API. It exists purely as an
25 25 // implementation detail. This header file may change from version to
26 26 // version without notice, or even be removed.
27 27 //
28 28 // We mean it.
29 29
30 30 #ifndef QBARCATEGORIESAXIS_P_H
31 31 #define QBARCATEGORIESAXIS_P_H
32 32
33 33 #include "qbarcategoriesaxis.h"
34 34 #include "qabstractaxis_p.h"
35 35
36 36 QTCOMMERCIALCHART_BEGIN_NAMESPACE
37 37
38 38 class Domain;
39 39
40 40 class QBarCategoriesAxisPrivate : public QAbstractAxisPrivate
41 41 {
42 42 Q_OBJECT
43 43
44 44 public:
45 45 QBarCategoriesAxisPrivate(QBarCategoriesAxis *q);
46 46 ~QBarCategoriesAxisPrivate();
47 47
48 48 public:
49 49 ChartAxis* createGraphics(ChartPresenter* presenter);
50 50 void intializeDomain(Domain* domain);
51 void emitRange();
51 void handleDomainUpdated();
52 qreal min();
53 qreal max();
52 54
53 55 private:
54 56 //range handling
55 57 void setMin(const QVariant &min);
56 58 void setMax(const QVariant &max);
57 59 void setRange(const QVariant &min, const QVariant &max);
58 int ticksCount() const;
59
60 Q_SIGNALS:
61 void changed(qreal min, qreal max, int tickCount,bool niceNumbers);
62
63 public Q_SLOTS:
64 void handleAxisRangeChanged(qreal min, qreal max,int count);
65 60
66 61 private:
67 62 QStringList m_categories;
68 63 QString m_minCategory;
69 64 QString m_maxCategory;
70 65
71 66 private:
72 67 Q_DECLARE_PUBLIC(QBarCategoriesAxis)
73 68 };
74 69
75 70 QTCOMMERCIALCHART_END_NAMESPACE
76 71
77 72 #endif // QBARCATEGORIESAXIS_P_H
@@ -1,391 +1,395
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "chartaxis_p.h"
22 22 #include "qabstractaxis.h"
23 23 #include "qabstractaxis_p.h"
24 24 #include "chartpresenter_p.h"
25 25 #include "chartanimator_p.h"
26 #include "domain_p.h"
26 27 #include <QPainter>
27 28 #include <QDebug>
28 29 #include <qmath.h>
29 30
30 31 QTCOMMERCIALCHART_BEGIN_NAMESPACE
31 32
32 33 ChartAxis::ChartAxis(QAbstractAxis *axis,ChartPresenter *presenter) : Chart(presenter),
33 34 m_chartAxis(axis),
34 35 m_labelsAngle(0),
35 36 m_grid(new QGraphicsItemGroup(presenter->rootItem())),
36 37 m_shades(new QGraphicsItemGroup(presenter->rootItem())),
37 38 m_labels(new QGraphicsItemGroup(presenter->rootItem())),
38 39 m_axis(new QGraphicsItemGroup(presenter->rootItem())),
39 40 m_min(0),
40 41 m_max(0),
41 m_ticksCount(0),
42 42 m_animation(0),
43 43 m_minWidth(0),
44 44 m_minHeight(0)
45 45 {
46 46 //initial initialization
47 47 m_axis->setZValue(ChartPresenter::AxisZValue);
48 48 m_axis->setHandlesChildEvents(false);
49 49
50 50 m_shades->setZValue(ChartPresenter::ShadesZValue);
51 51 m_grid->setZValue(ChartPresenter::GridZValue);
52 52
53 53 QObject::connect(m_chartAxis->d_ptr.data(),SIGNAL(updated()),this,SLOT(handleAxisUpdated()));
54 54
55 55 QGraphicsSimpleTextItem item;
56 56 m_font = item.font();
57
58 handleAxisUpdated();
59 57 }
60 58
61 59 ChartAxis::~ChartAxis()
62 60 {
63 61 }
64 62
65 63 void ChartAxis::setAnimation(AxisAnimation* animation)
66 64 {
67 65 m_animation=animation;
68 66 }
69 67
70 68 void ChartAxis::setLayout(QVector<qreal> &layout)
71 69 {
72 70 m_layoutVector=layout;
73 71 }
74 72
75 73 void ChartAxis::createItems(int count)
76 74 {
77 75 if (m_axis->children().size() == 0)
78 76 m_axis->addToGroup(new AxisItem(this));
79 77 for (int i = 0; i < count; ++i) {
80 78 m_grid->addToGroup(new QGraphicsLineItem());
81 79 m_labels->addToGroup(new QGraphicsSimpleTextItem());
82 80 m_axis->addToGroup(new QGraphicsLineItem());
83 81 if ((m_grid->childItems().size())%2 && m_grid->childItems().size()>2) m_shades->addToGroup(new QGraphicsRectItem());
84 82 }
85 83 }
86 84
87 85 void ChartAxis::deleteItems(int count)
88 86 {
89 87 QList<QGraphicsItem *> lines = m_grid->childItems();
90 88 QList<QGraphicsItem *> labels = m_labels->childItems();
91 89 QList<QGraphicsItem *> shades = m_shades->childItems();
92 90 QList<QGraphicsItem *> axis = m_axis->childItems();
93 91
94 92 for (int i = 0; i < count; ++i) {
95 93 if (lines.size()%2 && lines.size() > 1) delete(shades.takeLast());
96 94 delete(lines.takeLast());
97 95 delete(labels.takeLast());
98 96 delete(axis.takeLast());
99 97 }
100 98 }
101 99
102 100 void ChartAxis::updateLayout(QVector<qreal> &layout)
103 101 {
104 102 int diff = m_layoutVector.size() - layout.size();
105 103
106 104 if (diff>0) {
107 105 deleteItems(diff);
108 106 }
109 107 else if (diff<0) {
110 108 createItems(-diff);
111 109 }
112 110
113 if( diff!=0) handleAxisUpdated();
111 if(diff<0) handleAxisUpdated();
114 112
115 113 if (m_animation) {
116 114 switch(presenter()->state()){
117 115 case ChartPresenter::ZoomInState:
118 116 m_animation->setAnimationType(AxisAnimation::ZoomInAnimation);
119 117 m_animation->setAnimationPoint(presenter()->statePoint());
120 118 break;
121 119 case ChartPresenter::ZoomOutState:
122 120 m_animation->setAnimationType(AxisAnimation::ZoomOutAnimation);
123 121 m_animation->setAnimationPoint(presenter()->statePoint());
124 122 break;
125 123 case ChartPresenter::ScrollUpState:
126 124 case ChartPresenter::ScrollLeftState:
127 125 m_animation->setAnimationType(AxisAnimation::MoveBackwordAnimation);
128 126 break;
129 127 case ChartPresenter::ScrollDownState:
130 128 case ChartPresenter::ScrollRightState:
131 129 m_animation->setAnimationType(AxisAnimation::MoveForwardAnimation);
132 130 break;
133 131 case ChartPresenter::ShowState:
134 132 m_animation->setAnimationType(AxisAnimation::DefaultAnimation);
135 133 break;
136 134 }
137 135 m_animation->setValues(m_layoutVector,layout);
138 136 presenter()->startAnimation(m_animation);
139 137 }
140 138 else {
141 139 setLayout(layout);
142 140 updateGeometry();
143 141 }
144 142 }
145 143
146 144 void ChartAxis::setAxisOpacity(qreal opacity)
147 145 {
148 146 m_axis->setOpacity(opacity);
149 147 }
150 148
151 149 qreal ChartAxis::axisOpacity() const
152 150 {
153 151 return m_axis->opacity();
154 152 }
155 153
156 154 void ChartAxis::setGridOpacity(qreal opacity)
157 155 {
158 156 m_grid->setOpacity(opacity);
159 157 }
160 158
161 159 qreal ChartAxis::gridOpacity() const
162 160 {
163 161 return m_grid->opacity();
164 162 }
165 163
166 164 void ChartAxis::setLabelsOpacity(qreal opacity)
167 165 {
168 166 m_labels->setOpacity(opacity);
169 167 }
170 168
171 169 qreal ChartAxis::labelsOpacity() const
172 170 {
173 171 return m_labels->opacity();
174 172 }
175 173
176 174 void ChartAxis::setShadesOpacity(qreal opacity)
177 175 {
178 176 m_shades->setOpacity(opacity);
179 177 }
180 178
181 179 qreal ChartAxis::shadesOpacity() const
182 180 {
183 181 return m_shades->opacity();
184 182 }
185 183
186 184 void ChartAxis::setLabelsAngle(int angle)
187 185 {
188 186 foreach(QGraphicsItem* item , m_labels->childItems()) {
189 187 item->setRotation(angle);
190 188 }
191 189
192 190 m_labelsAngle=angle;
193 191 }
194 192
195 193 void ChartAxis::setLabelsPen(const QPen &pen)
196 194 {
197 195 foreach(QGraphicsItem* item , m_labels->childItems()) {
198 196 static_cast<QGraphicsSimpleTextItem*>(item)->setPen(pen);
199 197 }
200 198 }
201 199
202 200 void ChartAxis::setLabelsBrush(const QBrush &brush)
203 201 {
204 202 foreach(QGraphicsItem* item , m_labels->childItems()) {
205 203 static_cast<QGraphicsSimpleTextItem*>(item)->setBrush(brush);
206 204 }
207 205 }
208 206
209 207 void ChartAxis::setLabelsFont(const QFont &font)
210 208 {
211 209 foreach(QGraphicsItem* item , m_labels->childItems()) {
212 210 static_cast<QGraphicsSimpleTextItem*>(item)->setFont(font);
213 211 }
214 212 m_font = font;
215 213 }
216 214
217 215 void ChartAxis::setShadesBrush(const QBrush &brush)
218 216 {
219 217 foreach(QGraphicsItem* item , m_shades->childItems()) {
220 218 static_cast<QGraphicsRectItem*>(item)->setBrush(brush);
221 219 }
222 220 }
223 221
224 222 void ChartAxis::setShadesPen(const QPen &pen)
225 223 {
226 224 foreach(QGraphicsItem* item , m_shades->childItems()) {
227 225 static_cast<QGraphicsRectItem*>(item)->setPen(pen);
228 226 }
229 227 }
230 228
231 229 void ChartAxis::setAxisPen(const QPen &pen)
232 230 {
233 231 foreach(QGraphicsItem* item , m_axis->childItems()) {
234 232 static_cast<QGraphicsLineItem*>(item)->setPen(pen);
235 233 }
236 234 }
237 235
238 236 void ChartAxis::setGridPen(const QPen &pen)
239 237 {
240 238 foreach(QGraphicsItem* item , m_grid->childItems()) {
241 239 static_cast<QGraphicsLineItem*>(item)->setPen(pen);
242 240 }
243 241 }
244 242
245 243 bool ChartAxis::isEmpty()
246 244 {
247 return m_rect.isEmpty() || qFuzzyIsNull(m_min - m_max) || m_ticksCount==0;
245 return m_rect.isEmpty() || qFuzzyIsNull(m_min - m_max);
248 246 }
249 247
250 //handlers
251
252 void ChartAxis::handleAxisCategoriesUpdated()
248 void ChartAxis::handleDomainUpdated()
253 249 {
254 if (isEmpty()) return;
255 updateLayout(m_layoutVector);
250 Domain* domain = qobject_cast<Domain*>(sender());
251 qreal min(0);
252 qreal max(0);
253
254 if(m_chartAxis->orientation()==Qt::Horizontal) {
255 min = domain->minX();
256 max = domain->maxX();
257 }
258 else if (m_chartAxis->orientation()==Qt::Vertical)
259 {
260 min = domain->minY();
261 max = domain->maxY();
262 }
263
264 if (!qFuzzyIsNull(m_min - min) || !qFuzzyIsNull(m_max - max))
265 {
266 m_min = min;
267 m_max = max;
268
269 if (!isEmpty()) {
270 QVector<qreal> layout = calculateLayout();
271 updateLayout(layout);
272 }
273 }
256 274 }
257 275
258 276 void ChartAxis::handleAxisUpdated()
259 277 {
260
261 if (isEmpty()) return;
278 if(isEmpty()) return;
262 279
263 280 if (!m_chartAxis->isVisible()) {
264 281 setAxisOpacity(0);
265 282 setGridOpacity(0);
266 283 setLabelsOpacity(0);
267 284 setShadesOpacity(0);
268 285 }
269 286 else {
270 287
271 288 if (m_chartAxis->isArrowVisible()) {
272 289 setAxisOpacity(100);
273 290 }
274 291 else {
275 292 setAxisOpacity(0);
276 293 }
277 294
278 295 if (m_chartAxis->isGridLineVisible()) {
279 296 setGridOpacity(100);
280 297 }
281 298 else {
282 299 setGridOpacity(0);
283 300 }
284 301
285 302 if (m_chartAxis->labelsVisible()) {
286 303 setLabelsOpacity(100);
287 304 }
288 305 else {
289 306 setLabelsOpacity(0);
290 307 }
291 308
292 309 if (m_chartAxis->shadesVisible()) {
293 310 setShadesOpacity(100);
294 311 }
295 312 else {
296 313 setShadesOpacity(0);
297 314 }
298 315 }
316
299 317 setLabelsAngle(m_chartAxis->labelsAngle());
300 318 setAxisPen(m_chartAxis->axisPen());
301 319 setLabelsPen(m_chartAxis->labelsPen());
302 320 setLabelsBrush(m_chartAxis->labelsBrush());
303 321 setLabelsFont(m_chartAxis->labelsFont());
304 322 setGridPen(m_chartAxis->gridLinePen());
305 323 setShadesPen(m_chartAxis->shadesPen());
306 324 setShadesBrush(m_chartAxis->shadesBrush());
307 325
308 326 }
309 327
310 void ChartAxis::handleRangeChanged(qreal min, qreal max,int tickCount)
311 {
312 if (qFuzzyIsNull(min - max) || tickCount < 2)
313 return;
314
315 m_min = min;
316 m_max = max;
317 m_ticksCount= tickCount;
318
319 if (isEmpty()) return;
320 QVector<qreal> layout = calculateLayout();
321 updateLayout(layout);
322 }
323
324 328 void ChartAxis::handleGeometryChanged(const QRectF &rect)
325 329 {
326 330 if(m_rect != rect)
327 331 {
328 332 m_rect = rect;
329 333 if (isEmpty()) return;
330 334 QVector<qreal> layout = calculateLayout();
331 335 updateLayout(layout);
332 336 }
333 337 }
334 338
335 339
336 340 qreal ChartAxis::minimumWidth()
337 341 {
338 342 if(m_minWidth == 0) updateGeometry();
339 343 return m_minWidth;
340 344 }
341 345
342 346 qreal ChartAxis::minimumHeight()
343 347 {
344 348 if(m_minHeight == 0) updateGeometry();
345 349 return m_minHeight;
346 350 }
347 351
348 352
349 353 void ChartAxis::axisSelected()
350 354 {
351 355 qDebug()<<"TODO: axis clicked";
352 356 }
353 357
354 358
355 359 void ChartAxis::createNumberLabels(QStringList &labels,qreal min, qreal max, int ticks) const
356 360 {
357 361 Q_ASSERT(max>min);
358 362 Q_ASSERT(ticks>1);
359 363
360 364 int n = qMax(int(-floor(log10((max-min)/(ticks-1)))),0);
361 365 n++;
362 366 for (int i=0; i< ticks; i++) {
363 367 qreal value = min + (i * (max - min)/ (ticks-1));
364 368 labels << QString::number(value,'f',n);
365 369 }
366 370 }
367 371
368 372 void ChartAxis::createCategoryLabels(QStringList &labels,qreal min, qreal max,const QStringList &categories) const
369 373 {
370 374 Q_ASSERT(max>min);
371 375 Q_UNUSED(max);
372 376
373 377 int x = qCeil(min);
374 378 int count = 0;
375 379
376 380 // Try to find category for x coordinate
377 while (count < m_ticksCount) {
381 while (count < categories.count()) {
378 382 if ((x < categories.count()) && (x >= 0)) {
379 383 labels << categories.at(x);
380 384 } else {
381 385 // No label for x coordinate
382 386 labels << "";
383 387 }
384 388 x++;
385 389 count++;
386 390 }
387 391 }
388 392
389 393 #include "moc_chartaxis_p.cpp"
390 394
391 395 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,165 +1,163
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 // W A R N I N G
22 22 // -------------
23 23 //
24 24 // This file is not part of the QtCommercial Chart API. It exists purely as an
25 25 // implementation detail. This header file may change from version to
26 26 // version without notice, or even be removed.
27 27 //
28 28 // We mean it.
29 29
30 30 #ifndef CHARTAXIS_H
31 31 #define CHARTAXIS_H
32 32
33 33 #include "qchartglobal.h"
34 34 #include "chart_p.h"
35 35 #include "axisanimation_p.h"
36 36 #include <QGraphicsItem>
37 37 #include <QFont>
38 38
39 39 QTCOMMERCIALCHART_BEGIN_NAMESPACE
40 40
41 41 class QAbstractAxis;
42 42 class ChartPresenter;
43 43
44 44 class ChartAxis : public Chart
45 45 {
46 46 Q_OBJECT
47 47 public:
48 48 enum AxisType{ X_AXIS,Y_AXIS };
49 49
50 50 ChartAxis(QAbstractAxis *axis, ChartPresenter *presenter);
51 51 ~ChartAxis();
52 52
53 53 virtual AxisType axisType() const = 0;
54 54
55 55 void setAxisOpacity(qreal opacity);
56 56 qreal axisOpacity() const;
57 57
58 58 void setGridOpacity(qreal opacity);
59 59 qreal gridOpacity() const;
60 60
61 61 void setLabelsOpacity(qreal opacity);
62 62 qreal labelsOpacity() const;
63 63
64 64 void setShadesOpacity(qreal opacity);
65 65 qreal shadesOpacity() const;
66 66
67 67 void setLabelsAngle(int angle);
68 68 int labelsAngle()const { return m_labelsAngle; }
69 69
70 70 void setShadesBrush(const QBrush &brush);
71 71 void setShadesPen(const QPen &pen);
72 72
73 73 void setAxisPen(const QPen &pen);
74 74 void setGridPen(const QPen &pen);
75 75
76 76 void setLabelsPen(const QPen &pen);
77 77 void setLabelsBrush(const QBrush &brush);
78 78 void setLabelsFont(const QFont &font);
79 79
80 80 void setLayout(QVector<qreal> &layout);
81 81 QVector<qreal> layout() const { return m_layoutVector; }
82 82
83 83 void setAnimation(AxisAnimation* animation);
84 84 ChartAnimation* animation() const { return m_animation; };
85 85
86 86 QRectF geometry() const { return m_rect; }
87 87
88 88 qreal minimumWidth();
89 89 qreal minimumHeight();
90 90
91 91 protected:
92 92 virtual void updateGeometry() = 0;
93 93 virtual QVector<qreal> calculateLayout() const = 0;
94 94 void createNumberLabels(QStringList &labels,qreal min, qreal max,int ticks) const;
95 95 void createCategoryLabels(QStringList &labels,qreal min, qreal max,const QStringList &categories) const;
96 96
97 97 public Q_SLOTS:
98 98 virtual void handleAxisUpdated();
99 void handleAxisCategoriesUpdated();
100 void handleRangeChanged(qreal min , qreal max,int tickCount);
99 virtual void handleDomainUpdated();
101 100 void handleGeometryChanged(const QRectF &size);
102 101
103 102 private:
104 103 inline bool isEmpty();
105 104 void createItems(int count);
106 105 void deleteItems(int count);
107 106 void updateLayout(QVector<qreal> &layout);
108 107 void axisSelected();
109 108
110 109 protected:
111 110 QAbstractAxis* m_chartAxis;
112 111 QRectF m_rect;
113 112 int m_labelsAngle;
114 113 QScopedPointer<QGraphicsItemGroup> m_grid;
115 114 QScopedPointer<QGraphicsItemGroup> m_shades;
116 115 QScopedPointer<QGraphicsItemGroup> m_labels;
117 116 QScopedPointer<QGraphicsItemGroup> m_axis;
118 117 QVector<qreal> m_layoutVector;
119 118 qreal m_min;
120 119 qreal m_max;
121 int m_ticksCount;
122 120 AxisAnimation *m_animation;
123 121 qreal m_minWidth;
124 122 qreal m_minHeight;
125 123 QFont m_font;
126 124
127 125 friend class AxisAnimation;
128 126 friend class AxisItem;
129 127
130 128 };
131 129
132 130 class AxisItem: public QGraphicsLineItem
133 131 {
134 132
135 133 public:
136 134 explicit AxisItem(ChartAxis *axis, QGraphicsItem *parent = 0) : QGraphicsLineItem(parent), m_axis(axis) {}
137 135
138 136 protected:
139 137 void mousePressEvent(QGraphicsSceneMouseEvent *event)
140 138 {
141 139 Q_UNUSED(event)
142 140 m_axis->axisSelected();
143 141 }
144 142
145 143 QRectF boundingRect() const
146 144 {
147 145 return shape().boundingRect();
148 146 }
149 147
150 148 QPainterPath shape() const
151 149 {
152 150 QPainterPath path = QGraphicsLineItem::shape();
153 151 QRectF rect = path.boundingRect();
154 152 path.addRect(rect.adjusted(0,0,m_axis->axisType()!=ChartAxis::X_AXIS?8:0,m_axis->axisType()!=ChartAxis::Y_AXIS?8:0));
155 153 return path;
156 154 }
157 155
158 156 private:
159 157 ChartAxis* m_axis;
160 158
161 159 };
162 160
163 161 QTCOMMERCIALCHART_END_NAMESPACE
164 162
165 163 #endif /* AXISITEM_H_ */
1 NO CONTENT: file renamed from src/axis/qintervalaxis.cpp to src/axis/intervalsaxis/qintervalaxis.cpp
1 NO CONTENT: file renamed from src/axis/qintervalaxis.h to src/axis/intervalsaxis/qintervalaxis.h
1 NO CONTENT: file renamed from src/axis/qintervalaxis_p.h to src/axis/intervalsaxis/qintervalaxis_p.h
@@ -1,634 +1,651
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "qabstractaxis.h"
22 22 #include "qabstractaxis_p.h"
23 23
24 24 QTCOMMERCIALCHART_BEGIN_NAMESPACE
25 25
26 26 /*!
27 27 \class QAbstractAxis
28 28 \brief The QAbstractAxis class is used for manipulating chart's axis.
29 29 \mainclass
30 30
31 31 There is only one x Axis visible at the time, however there can be multiple y axes.
32 32 Each chart series can be bound to exactly one Y axis and the shared common X axis.
33 33 Axis can be setup to show axis line with tick marks, grid lines and shades.
34 34 */
35 35
36 36 /*!
37 37 \qmlclass AbstractAxis QAbstractAxis
38 38 \brief The Axis element is used for manipulating chart's axes
39 39
40 40 There is only one x Axis visible at the time, however there can be multiple y axes on a ChartView.
41 41 Each chart series can be bound to exactly one Y axis and the shared common X axis.
42 42 Axis can be setup to show axis line with tick marks, grid lines and shades.
43 43
44 44 To access Axes you can use ChartView API. For example:
45 45 \code
46 46 ChartView {
47 47 axisX.min: 0
48 48 axisX.max: 3
49 49 axisX.ticksCount: 4
50 50 axisY.min: 0
51 51 axisY.max: 4
52 52 // Add a few series...
53 53 }
54 54 \endcode
55 55 */
56 56
57 57 /*!
58 58 \enum QAbstractAxis::AxisType
59 59
60 60 The type of the series object.
61 61
62 62 \value AxisTypeNoAxis
63 63 \value AxisTypeValues
64 64 \value AxisTypeCategories
65 65 */
66 66
67 67 /*!
68 68 *\fn void QAbstractAxis::type() const
69 69 Returns the type of the axis
70 70 */
71 71
72 72 /*!
73 73 \property QAbstractAxis::arrowVisible
74 74 The visibility of the axis arrow
75 75 */
76 76 /*!
77 77 \qmlproperty bool AbstractAxis::arrrowVisible
78 78 The visibility of the axis arrow
79 79 */
80 80
81 81 /*!
82 82 \property QAbstractAxis::labelsVisible
83 83 Defines if axis labels are visible.
84 84 */
85 85 /*!
86 86 \qmlproperty bool AbstractAxis::labelsVisible
87 87 Defines if axis labels are visible.
88 88 */
89 89
90 90 /*!
91 91 \property QAbstractAxis::visible
92 92 The visibility of the axis.
93 93 */
94 94 /*!
95 95 \qmlproperty bool AbstractAxis::visible
96 96 The visibility of the axis.
97 97 */
98 98
99 99 /*!
100 100 \property QAbstractAxis::gridVisible
101 101 The visibility of the grid lines.
102 102 */
103 103 /*!
104 104 \qmlproperty bool AbstractAxis::gridVisible
105 105 The visibility of the grid lines.
106 106 */
107 107
108 108 /*!
109 109 \property QAbstractAxis::color
110 110 The color of the axis and ticks.
111 111 */
112 112 /*!
113 113 \qmlproperty color AbstractAxis::color
114 114 The color of the axis and ticks.
115 115 */
116 116
117 117 /*!
118 118 \property QAbstractAxis::labelsFont
119 119 The font of the axis labels.
120 120 */
121 121
122 122 /*!
123 123 \qmlproperty Font AbstractAxis::labelsFont
124 124 The font of the axis labels.
125 125
126 126 See the \l {Font} {QML Font Element} for detailed documentation.
127 127 */
128 128
129 129 /*!
130 130 \property QAbstractAxis::labelsColor
131 131 The color of the axis labels.
132 132 */
133 133 /*!
134 134 \qmlproperty color AbstractAxis::labelsColor
135 135 The color of the axis labels.
136 136 */
137 137
138 138 /*!
139 139 \property QAbstractAxis::labelsAngle
140 140 The angle of the axis labels in degrees.
141 141 */
142 142 /*!
143 143 \qmlproperty int AbstractAxis::labelsAngle
144 144 The angle of the axis labels in degrees.
145 145 */
146 146
147 147 /*!
148 148 \property QAbstractAxis::shadesVisible
149 149 The visibility of the axis shades.
150 150 */
151 151 /*!
152 152 \qmlproperty bool AbstractAxis::shadesVisible
153 153 The visibility of the axis shades.
154 154 */
155 155
156 156 /*!
157 157 \property QAbstractAxis::shadesColor
158 158 The fill (brush) color of the axis shades.
159 159 */
160 160 /*!
161 161 \qmlproperty color AbstractAxis::shadesColor
162 162 The fill (brush) color of the axis shades.
163 163 */
164 164
165 165 /*!
166 166 \property QAbstractAxis::shadesBorderColor
167 167 The border (pen) color of the axis shades.
168 168 */
169 169 /*!
170 170 \qmlproperty color AbstractAxis::shadesBorderColor
171 171 The border (pen) color of the axis shades.
172 172 */
173 173
174 174 /*!
175 175 \fn void QAbstractAxis::visibleChanged(bool visible)
176 176 Visiblity of the axis has changed to \a visible.
177 177 */
178 178 /*!
179 179 \qmlsignal AbstractAxis::onVisibleChanged(bool visible)
180 180 Visiblity of the axis has changed to \a visible.
181 181 */
182 182
183 183 /*!
184 184 \fn void QAbstractAxis::arrowVisibleChanged(bool visible)
185 185 Visiblity of the axis arrow has changed to \a visible.
186 186 */
187 187 /*!
188 188 \qmlsignal AbstractAxis::onArrowVisibleChanged(bool visible)
189 189 Visiblity of the axis arrow has changed to \a visible.
190 190 */
191 191
192 192 /*!
193 193 \fn void QAbstractAxis::labelsVisibleChanged(bool visible)
194 194 Visiblity of the labels of the axis has changed to \a visible.
195 195 */
196 196 /*!
197 197 \qmlsignal AbstractAxis::onLabelsVisibleChanged(bool visible)
198 198 Visiblity of the labels of the axis has changed to \a visible.
199 199 */
200 200
201 201 /*!
202 202 \fn void QAbstractAxis::gridVisibleChanged(bool visible)
203 203 Visiblity of the grid lines of the axis has changed to \a visible.
204 204 */
205 205 /*!
206 206 \qmlsignal AbstractAxis::onGridVisibleChanged(bool visible)
207 207 Visiblity of the grid lines of the axis has changed to \a visible.
208 208 */
209 209
210 210 /*!
211 211 \fn void QAbstractAxis::colorChanged(QColor color)
212 212 Emitted if the \a color of the axis is changed.
213 213 */
214 214 /*!
215 215 \qmlsignal AbstractAxis::onColorChanged(QColor color)
216 216 Emitted if the \a color of the axis is changed.
217 217 */
218 218
219 219 /*!
220 220 \fn void QAbstractAxis::labelsColorChanged(QColor color)
221 221 Emitted if the \a color of the axis labels is changed.
222 222 */
223 223 /*!
224 224 \qmlsignal AbstractAxis::onLabelsColorChanged(QColor color)
225 225 Emitted if the \a color of the axis labels is changed.
226 226 */
227 227
228 228 /*!
229 229 \fn void QAbstractAxis::shadesVisibleChanged(bool)
230 230 Emitted if the visibility of the axis shades is changed to \a visible.
231 231 */
232 232 /*!
233 233 \qmlsignal AbstractAxis::onShadesVisibleChanged(bool visible)
234 234 Emitted if the visibility of the axis shades is changed to \a visible.
235 235 */
236 236
237 237 /*!
238 238 \fn void QAbstractAxis::shadesColorChanged(QColor color)
239 239 Emitted if the \a color of the axis shades is changed.
240 240 */
241 241 /*!
242 242 \qmlsignal AbstractAxis::onShadesColorChanged(QColor color)
243 243 Emitted if the \a color of the axis shades is changed.
244 244 */
245 245
246 246 /*!
247 247 \fn void QAbstractAxis::shadesBorderColorChanged(QColor)
248 248 Emitted if the border \a color of the axis shades is changed.
249 249 */
250 250 /*!
251 251 \qmlsignal AbstractAxis::onBorderColorChanged(QColor color)
252 252 Emitted if the border \a color of the axis shades is changed.
253 253 */
254 254
255 255 /*!
256 256 \internal
257 257 Constructs new axis object which is a child of \a parent. Ownership is taken by
258 258 QChart when axis added.
259 259 */
260 260
261 261 QAbstractAxis::QAbstractAxis(QAbstractAxisPrivate &d, QObject *parent) :
262 262 QObject(parent),
263 263 d_ptr(&d)
264 264 {
265 265 }
266 266
267 267 /*!
268 268 Destructor of the axis object. When axis is added to chart, chart object takes ownership.
269 269 */
270 270
271 271 QAbstractAxis::~QAbstractAxis()
272 272 {
273 273 }
274 274
275 275 /*!
276 276 Sets \a pen used to draw axis line and ticks.
277 277 */
278 278 void QAbstractAxis::setAxisPen(const QPen &pen)
279 279 {
280 280 if (d_ptr->m_axisPen!=pen) {
281 281 d_ptr->m_axisPen = pen;
282 emit d_ptr->updated();
282 d_ptr->emitUpdated();
283 283 }
284 284 }
285 285
286 286 /*!
287 287 Returns pen used to draw axis and ticks.
288 288 */
289 289 QPen QAbstractAxis::axisPen() const
290 290 {
291 291 return d_ptr->m_axisPen;
292 292 }
293 293
294 294 void QAbstractAxis::setAxisPenColor(QColor color)
295 295 {
296 296 QPen p = d_ptr->m_axisPen;
297 297 if (p.color() != color) {
298 298 p.setColor(color);
299 299 setAxisPen(p);
300 300 emit colorChanged(color);
301 301 }
302 302 }
303 303
304 304 QColor QAbstractAxis::axisPenColor() const
305 305 {
306 306 return d_ptr->m_axisPen.color();
307 307 }
308 308
309 309 /*!
310 310 Sets if axis and ticks are \a visible.
311 311 */
312 312 void QAbstractAxis::setArrowVisible(bool visible)
313 313 {
314 314 if (d_ptr->m_arrowVisible != visible) {
315 315 d_ptr->m_arrowVisible = visible;
316 emit d_ptr->updated();
316 d_ptr->emitUpdated();
317 317 emit arrowVisibleChanged(visible);
318 318 }
319 319 }
320 320
321 321 bool QAbstractAxis::isArrowVisible() const
322 322 {
323 323 return d_ptr->m_arrowVisible;
324 324 }
325 325
326 326 void QAbstractAxis::setGridLineVisible(bool visible)
327 327 {
328 328 if (d_ptr->m_gridLineVisible != visible) {
329 329 d_ptr->m_gridLineVisible = visible;
330 emit d_ptr->updated();
330 d_ptr->emitUpdated();
331 331 emit gridVisibleChanged(visible);
332 332 }
333 333 }
334 334
335 335 bool QAbstractAxis::isGridLineVisible() const
336 336 {
337 337 return d_ptr->m_gridLineVisible;
338 338 }
339 339
340 340 /*!
341 341 Sets \a pen used to draw grid line.
342 342 */
343 343 void QAbstractAxis::setGridLinePen(const QPen &pen)
344 344 {
345 345 if (d_ptr->m_gridLinePen != pen) {
346 346 d_ptr->m_gridLinePen = pen;
347 emit d_ptr->updated();
347 d_ptr->emitUpdated();
348 348 }
349 349 }
350 350
351 351 /*!
352 352 Returns pen used to draw grid.
353 353 */
354 354 QPen QAbstractAxis::gridLinePen() const
355 355 {
356 356 return d_ptr->m_gridLinePen;
357 357 }
358 358
359 359 void QAbstractAxis::setLabelsVisible(bool visible)
360 360 {
361 361 if (d_ptr->m_labelsVisible != visible) {
362 362 d_ptr->m_labelsVisible = visible;
363 emit d_ptr->updated();
363 d_ptr->emitUpdated();
364 364 emit labelsVisibleChanged(visible);
365 365 }
366 366 }
367 367
368 368 bool QAbstractAxis::labelsVisible() const
369 369 {
370 370 return d_ptr->m_labelsVisible;
371 371 }
372 372
373 373 /*!
374 374 Sets \a pen used to draw labels.
375 375 */
376 376 void QAbstractAxis::setLabelsPen(const QPen &pen)
377 377 {
378 378 if (d_ptr->m_labelsPen != pen) {
379 379 d_ptr->m_labelsPen = pen;
380 emit d_ptr->updated();
380 d_ptr->emitUpdated();
381 381 }
382 382 }
383 383
384 384 /*!
385 385 Returns the pen used to labels.
386 386 */
387 387 QPen QAbstractAxis::labelsPen() const
388 388 {
389 389 return d_ptr->m_labelsPen;
390 390 }
391 391
392 392 /*!
393 393 Sets \a brush used to draw labels.
394 394 */
395 395 void QAbstractAxis::setLabelsBrush(const QBrush &brush)
396 396 {
397 397 if (d_ptr->m_labelsBrush != brush) {
398 398 d_ptr->m_labelsBrush = brush;
399 emit d_ptr->updated();
399 d_ptr->emitUpdated();
400 400 }
401 401 }
402 402
403 403 /*!
404 404 Returns brush used to draw labels.
405 405 */
406 406 QBrush QAbstractAxis::labelsBrush() const
407 407 {
408 408 return d_ptr->m_labelsBrush;
409 409 }
410 410
411 411 /*!
412 412 Sets \a font used to draw labels.
413 413 */
414 414 void QAbstractAxis::setLabelsFont(const QFont &font)
415 415 {
416 416 if (d_ptr->m_labelsFont != font) {
417 417 d_ptr->m_labelsFont = font;
418 emit d_ptr->updated();
418 d_ptr->emitUpdated();
419 419 }
420 420 }
421 421
422 422 /*!
423 423 Returns font used to draw labels.
424 424 */
425 425 QFont QAbstractAxis::labelsFont() const
426 426 {
427 427 return d_ptr->m_labelsFont;
428 428 }
429 429
430 430 void QAbstractAxis::setLabelsAngle(int angle)
431 431 {
432 432 if (d_ptr->m_labelsAngle != angle) {
433 433 d_ptr->m_labelsAngle = angle;
434 emit d_ptr->updated();
434 d_ptr->emitUpdated();
435 435 }
436 436 }
437 437
438 438 int QAbstractAxis::labelsAngle() const
439 439 {
440 440 return d_ptr->m_labelsAngle;
441 441 }
442 442
443 443 void QAbstractAxis::setLabelsColor(QColor color)
444 444 {
445 445 QBrush b = d_ptr->m_labelsBrush;
446 446 if (b.color() != color) {
447 447 b.setColor(color);
448 448 setLabelsBrush(b);
449 449 emit labelsColorChanged(color);
450 450 }
451 451 }
452 452
453 453 QColor QAbstractAxis::labelsColor() const
454 454 {
455 455 return d_ptr->m_labelsBrush.color();
456 456 }
457 457
458 458 void QAbstractAxis::setShadesVisible(bool visible)
459 459 {
460 460 if (d_ptr->m_shadesVisible != visible) {
461 461 d_ptr->m_shadesVisible = visible;
462 emit d_ptr->updated();
462 d_ptr->emitUpdated();
463 463 emit shadesVisibleChanged(visible);
464 464 }
465 465 }
466 466
467 467 bool QAbstractAxis::shadesVisible() const
468 468 {
469 469 return d_ptr->m_shadesVisible;
470 470 }
471 471
472 472 /*!
473 473 Sets \a pen used to draw shades.
474 474 */
475 475 void QAbstractAxis::setShadesPen(const QPen &pen)
476 476 {
477 477 if (d_ptr->m_shadesPen != pen) {
478 478 d_ptr->m_shadesPen = pen;
479 emit d_ptr->updated();
479 d_ptr->emitUpdated();
480 480 }
481 481 }
482 482
483 483 /*!
484 484 Returns pen used to draw shades.
485 485 */
486 486 QPen QAbstractAxis::shadesPen() const
487 487 {
488 488 return d_ptr->m_shadesPen;
489 489 }
490 490
491 491 /*!
492 492 Sets \a brush used to draw shades.
493 493 */
494 494 void QAbstractAxis::setShadesBrush(const QBrush &brush)
495 495 {
496 496 if (d_ptr->m_shadesBrush != brush) {
497 497 d_ptr->m_shadesBrush = brush;
498 emit d_ptr->updated();
498 d_ptr->emitUpdated();
499 499 emit shadesColorChanged(brush.color());
500 500 }
501 501 }
502 502
503 503 /*!
504 504 Returns brush used to draw shades.
505 505 */
506 506 QBrush QAbstractAxis::shadesBrush() const
507 507 {
508 508 return d_ptr->m_shadesBrush;
509 509 }
510 510
511 511 void QAbstractAxis::setShadesColor(QColor color)
512 512 {
513 513 QBrush b = d_ptr->m_shadesBrush;
514 514 b.setColor(color);
515 515 setShadesBrush(b);
516 516 }
517 517
518 518 QColor QAbstractAxis::shadesColor() const
519 519 {
520 520 return d_ptr->m_shadesBrush.color();
521 521 }
522 522
523 523 void QAbstractAxis::setShadesBorderColor(QColor color)
524 524 {
525 525 QPen p = d_ptr->m_shadesPen;
526 526 p.setColor(color);
527 527 setShadesPen(p);
528 528 }
529 529
530 530 QColor QAbstractAxis::shadesBorderColor() const
531 531 {
532 532 return d_ptr->m_shadesPen.color();
533 533 }
534 534
535 535
536 536 bool QAbstractAxis::isVisible() const
537 537 {
538 538 return d_ptr->m_visible;
539 539 }
540 540
541 541 /*!
542 542 Sets axis, shades, labels and grid lines to be visible.
543 543 */
544 544 void QAbstractAxis::setVisible(bool visible)
545 545 {
546 546 if(d_ptr->m_visible!=visible){
547 547 d_ptr->m_visible=visible;
548 d_ptr->emitUpdated();
548 549 emit visibleChanged(visible);
549 emit d_ptr->updated();
550 550 }
551 551 }
552 552
553 553
554 554 /*!
555 555 Sets axis, shades, labels and grid lines to be visible.
556 556 */
557 557 void QAbstractAxis::show()
558 558 {
559 559 setVisible(true);
560 560 }
561 561
562 562 /*!
563 563 Sets axis, shades, labels and grid lines to not be visible.
564 564 */
565 565 void QAbstractAxis::hide()
566 566 {
567 567 setVisible(false);
568 568 }
569 569
570 570 /*!
571 571 Sets the minimum value shown on the axis.
572 572 Depending on the actual axis type the \a min paramter is converted to appropriate type.
573 573 If the conversion is impossible then the function call does nothing
574 574 */
575 575 void QAbstractAxis::setMin(const QVariant &min)
576 576 {
577 577 d_ptr->setMin(min);
578 578 }
579 579
580 580 /*!
581 581 Sets the maximum value shown on the axis.
582 582 Depending on the actual axis type the \a max paramter is converted to appropriate type.
583 583 If the conversion is impossible then the function call does nothing
584 584 */
585 585 void QAbstractAxis::setMax(const QVariant &max)
586 586 {
587 587 d_ptr->setMax(max);
588 588 }
589 589
590 590 /*!
591 591 Sets the range shown on the axis.
592 592 Depending on the actual axis type the \a min and \a max paramters are converted to appropriate types.
593 593 If the conversion is impossible then the function call does nothing.
594 594 */
595 595 void QAbstractAxis::setRange(const QVariant &min, const QVariant &max)
596 596 {
597 597 d_ptr->setRange(min,max);
598 598 }
599 599
600 600
601 601 Qt::Orientation QAbstractAxis::orientation()
602 602 {
603 603 return d_ptr->m_orientation;
604 604 }
605 605
606 606 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
607 607
608 608 QAbstractAxisPrivate::QAbstractAxisPrivate(QAbstractAxis* q):
609 609 q_ptr(q),
610 m_orientation(Qt::Orientation(0)),
610 611 m_visible(false),
611 612 m_arrowVisible(true),
612 613 m_gridLineVisible(true),
613 614 m_labelsVisible(true),
614 615 m_labelsAngle(0),
615 616 m_shadesVisible(false),
616 617 m_shadesBrush(Qt::SolidPattern),
617 618 m_shadesOpacity(1.0),
618 m_orientation(Qt::Orientation(0)),
619 m_min(0),
620 m_max(0),
621 m_ticksCount(5)
619 m_dirty(false)
622 620 {
623 621
624 622 }
625 623
626 624 QAbstractAxisPrivate::~QAbstractAxisPrivate()
627 625 {
628 626
629 627 }
630 628
629 void QAbstractAxisPrivate::emitUpdated()
630 {
631 if(!m_dirty){
632 m_dirty=true;
633 emit updated();
634 }
635 }
636
637 void QAbstractAxisPrivate::setDirty(bool dirty)
638 {
639 m_dirty=dirty;
640 }
641
642 void QAbstractAxisPrivate::setOrientation(Qt::Orientation orientation)
643 {
644 m_orientation=orientation;
645 }
646
647
631 648 #include "moc_qabstractaxis.cpp"
632 649 #include "moc_qabstractaxis_p.cpp"
633 650
634 651 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,96 +1,105
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 // W A R N I N G
22 22 // -------------
23 23 //
24 24 // This file is not part of the QtCommercial Chart API. It exists purely as an
25 25 // implementation detail. This header file may change from version to
26 26 // version without notice, or even be removed.
27 27 //
28 28 // We mean it.
29 29
30 30 #ifndef QABSTRACTAXIS_P_H
31 31 #define QABSTRACTAXIS_P_H
32 32
33 33 #include "qabstractaxis.h"
34 34
35 35 QTCOMMERCIALCHART_BEGIN_NAMESPACE
36 36
37 37 class ChartPresenter;
38 38 class ChartAxis;
39 39 class Domain;
40 40
41 class QAbstractAxisPrivate : public QObject
41 class QTCOMMERCIALCHART_AUTOTEST_EXPORT QAbstractAxisPrivate : public QObject
42 42 {
43 43 Q_OBJECT
44 44 public:
45 45 QAbstractAxisPrivate(QAbstractAxis *q);
46 46 ~QAbstractAxisPrivate();
47 47
48 Q_SIGNALS:
49 void updated();
50
51 48 public:
49
52 50 virtual ChartAxis* createGraphics(ChartPresenter* presenter) = 0;
53 virtual void emitRange() = 0;
54 51 virtual void intializeDomain(Domain* domain) = 0;
55 52
56 protected:
53 void emitUpdated();
54 void setDirty(bool dirty);
55 bool isDirty(){ return m_dirty; };
56 void setOrientation(Qt::Orientation orientation);
57 Qt::Orientation orientation() const { return m_orientation; }
58
57 59 virtual void setMin(const QVariant &min) = 0;
60 virtual qreal min() = 0;
61
58 62 virtual void setMax(const QVariant &max) = 0;
63 virtual qreal max() = 0;
64
59 65 virtual void setRange(const QVariant &min, const QVariant &max) = 0;
60 virtual int ticksCount() const = 0;
61 66
62 public:
67 public Q_SLOTS:
68 virtual void handleDomainUpdated() = 0;
69
70 Q_SIGNALS:
71 void updated();
72
73 protected:
63 74 QAbstractAxis *q_ptr;
75 Qt::Orientation m_orientation;
76
77 private:
64 78 bool m_visible;
65 79
66 80 bool m_arrowVisible;
67 81 QPen m_axisPen;
68 82 QBrush m_axisBrush;
69 83
70 84 bool m_gridLineVisible;
71 85 QPen m_gridLinePen;
72 86
73 87 bool m_labelsVisible;
74 88 QPen m_labelsPen;
75 89 QBrush m_labelsBrush;
76 90 QFont m_labelsFont;
77 91 int m_labelsAngle;
78 92
79 93 bool m_shadesVisible;
80 94 QPen m_shadesPen;
81 95 QBrush m_shadesBrush;
82 96 qreal m_shadesOpacity;
83 97
84 Qt::Orientation m_orientation;
85
86 // range
87 qreal m_min;
88 qreal m_max;
89 int m_ticksCount;
98 bool m_dirty;
90 99
91 100 friend class QAbstractAxis;
92 101 };
93 102
94 103 QTCOMMERCIALCHART_END_NAMESPACE
95 104
96 105 #endif
@@ -1,112 +1,122
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "chartvaluesaxisx_p.h"
22 22 #include "qabstractaxis.h"
23 23 #include "chartpresenter_p.h"
24 24 #include "chartanimator_p.h"
25 #include "qvaluesaxis.h"
25 26 #include <QGraphicsLayout>
26 27 #include <QDebug>
27 28 #include <QFontMetrics>
28 29 #include <cmath>
29 30
30 31 static int label_padding = 5;
31 32
32 33 QTCOMMERCIALCHART_BEGIN_NAMESPACE
33 34
34 ChartValuesAxisX::ChartValuesAxisX(QAbstractAxis *axis,ChartPresenter *presenter) : ChartAxis(axis,presenter)
35 ChartValuesAxisX::ChartValuesAxisX(QAbstractAxis *axis,ChartPresenter *presenter) : ChartAxis(axis,presenter),
36 m_tickCount(0)
35 37 {
36 38 }
37 39
38 40 ChartValuesAxisX::~ChartValuesAxisX()
39 41 {
40 42 }
41 43
42 44 QVector<qreal> ChartValuesAxisX::calculateLayout() const
43 45 {
44 Q_ASSERT(m_ticksCount>=2);
46 Q_ASSERT(m_tickCount>=2);
45 47
46 48 QVector<qreal> points;
47 points.resize(m_ticksCount);
49 points.resize(m_tickCount);
48 50
49 const qreal deltaX = m_rect.width()/(m_ticksCount-1);
50 for (int i = 0; i < m_ticksCount; ++i) {
51 const qreal deltaX = m_rect.width()/(m_tickCount-1);
52 for (int i = 0; i < m_tickCount; ++i) {
51 53 int x = i * deltaX + m_rect.left();
52 54 points[i] = x;
53 55 }
54 56 return points;
55 57 }
56 58
57 59 void ChartValuesAxisX::updateGeometry()
58 60 {
59 61 const QVector<qreal>& layout = ChartAxis::layout();
60 62
61 63 m_minWidth = 0;
62 64 m_minHeight = 0;
63 65
64 66 if(layout.isEmpty()) return;
65 67
66 68 QStringList ticksList;
67 69
68 70 createNumberLabels(ticksList,m_min,m_max,layout.size());
69 71
70 72 QList<QGraphicsItem *> lines = m_grid->childItems();
71 73 QList<QGraphicsItem *> labels = m_labels->childItems();
72 74 QList<QGraphicsItem *> shades = m_shades->childItems();
73 75 QList<QGraphicsItem *> axis = m_axis->childItems();
74 76
75 77 Q_ASSERT(labels.size() == ticksList.size());
76 78 Q_ASSERT(layout.size() == ticksList.size());
77 79
78 80 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(axis.at(0));
79 81 lineItem->setLine(m_rect.left(), m_rect.bottom(), m_rect.right(), m_rect.bottom());
80 82
81 83 qreal width = 0;
82 84 for (int i = 0; i < layout.size(); ++i) {
83 85 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(lines.at(i));
84 86 lineItem->setLine(layout[i], m_rect.top(), layout[i], m_rect.bottom());
85 87 QGraphicsSimpleTextItem *labelItem = static_cast<QGraphicsSimpleTextItem*>(labels.at(i));
86 88 labelItem->setText(ticksList.at(i));
87 89 const QRectF& rect = labelItem->boundingRect();
88 90 QPointF center = rect.center();
89 91 labelItem->setTransformOriginPoint(center.x(), center.y());
90 92 labelItem->setPos(layout[i] - center.x(), m_rect.bottom() + label_padding);
91 93
92 94 if(labelItem->pos().x()<=width){
93 95 labelItem->setVisible(false);
94 96 lineItem->setVisible(false);
95 97 }else{
96 98 labelItem->setVisible(true);
97 99 lineItem->setVisible(true);
98 100 width=rect.width()+labelItem->pos().x();
99 101 }
100 102 m_minWidth+=rect.width();
101 103 m_minHeight=qMax(rect.height(),m_minHeight);
102 104
103 105 if ((i+1)%2 && i>1) {
104 106 QGraphicsRectItem *rectItem = static_cast<QGraphicsRectItem*>(shades.at(i/2-1));
105 107 rectItem->setRect(layout[i-1],m_rect.top(),layout[i]-layout[i-1],m_rect.height());
106 108 }
107 109 lineItem = static_cast<QGraphicsLineItem*>(axis.at(i+1));
108 110 lineItem->setLine(layout[i],m_rect.bottom(),layout[i],m_rect.bottom()+5);
109 111 }
110 112 }
111 113
114 void ChartValuesAxisX::handleAxisUpdated()
115 {
116 //TODO:: fix this
117 QValuesAxis* axis = qobject_cast<QValuesAxis*>(m_chartAxis);
118 m_tickCount = axis->ticksCount();
119 ChartAxis::handleAxisUpdated();
120 }
121
112 122 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,59 +1,60
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 // W A R N I N G
22 22 // -------------
23 23 //
24 24 // This file is not part of the QtCommercial Chart API. It exists purely as an
25 25 // implementation detail. This header file may change from version to
26 26 // version without notice, or even be removed.
27 27 //
28 28 // We mean it.
29 29
30 30 #ifndef CHARTVALUESAXISX_H
31 31 #define CHARTVALUESAXISX_H
32 32
33 33 #include "chartaxis_p.h"
34 34
35 35 QTCOMMERCIALCHART_BEGIN_NAMESPACE
36 36
37 37 class QAbstractAxis;
38 38 class ChartPresenter;
39 39
40 40 class ChartValuesAxisX : public ChartAxis
41 41 {
42 42 public:
43 43 ChartValuesAxisX(QAbstractAxis *axis, ChartPresenter *presenter);
44 44 ~ChartValuesAxisX();
45 45
46 46 AxisType axisType() const { return X_AXIS;}
47 47
48 48 protected:
49 void handleAxisUpdated();
49 50 QVector<qreal> calculateLayout() const;
50 51 void updateGeometry();
51 52
52 53 private:
53 void createLabels(QStringList &labels,qreal min, qreal max,int ticks) const;
54 int m_tickCount;
54 55
55 56 };
56 57
57 58 QTCOMMERCIALCHART_END_NAMESPACE
58 59
59 60 #endif /* CHARTVALUESAXISX_H */
@@ -1,117 +1,128
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "chartvaluesaxisy_p.h"
22 22 #include "qabstractaxis.h"
23 23 #include "chartpresenter_p.h"
24 24 #include "chartanimator_p.h"
25 #include "qvaluesaxis.h"
25 26 #include <QGraphicsLayout>
26 27 #include <QDebug>
27 28 #include <QFontMetrics>
28 29 #include <cmath>
29 30
30 31 static int label_padding = 5;
31 32
32 33 QTCOMMERCIALCHART_BEGIN_NAMESPACE
33 34
34 ChartValuesAxisY::ChartValuesAxisY(QAbstractAxis *axis,ChartPresenter *presenter) : ChartAxis(axis,presenter)
35 ChartValuesAxisY::ChartValuesAxisY(QAbstractAxis *axis,ChartPresenter *presenter) : ChartAxis(axis,presenter),
36 m_tickCount(0)
35 37 {
36 38 }
37 39
38 40 ChartValuesAxisY::~ChartValuesAxisY()
39 41 {
40 42 }
41 43
42 44 QVector<qreal> ChartValuesAxisY::calculateLayout() const
43 45 {
44 Q_ASSERT(m_ticksCount>=2);
46 Q_ASSERT(m_tickCount>=2);
45 47
46 48 QVector<qreal> points;
47 points.resize(m_ticksCount);
49 points.resize(m_tickCount);
48 50
49 const qreal deltaY = m_rect.height()/(m_ticksCount-1);
50 for (int i = 0; i < m_ticksCount; ++i) {
51 const qreal deltaY = m_rect.height()/(m_tickCount-1);
52 for (int i = 0; i < m_tickCount; ++i) {
51 53 int y = i * -deltaY + m_rect.bottom();
52 54 points[i] = y;
53 55 }
54 56
55 57 return points;
56 58 }
57 59
58 60 void ChartValuesAxisY::updateGeometry()
59 61 {
60 62 const QVector<qreal> &layout = ChartAxis::layout();
61 63 m_minWidth = 0;
62 64 m_minHeight = 0;
63 65
64 66 if(layout.isEmpty()) return;
65 67
66 68 QStringList ticksList;
67 69
68 70 createNumberLabels(ticksList,m_min,m_max,layout.size());
69 71
70 72 QList<QGraphicsItem *> lines = m_grid->childItems();
71 73 QList<QGraphicsItem *> labels = m_labels->childItems();
72 74 QList<QGraphicsItem *> shades = m_shades->childItems();
73 75 QList<QGraphicsItem *> axis = m_axis->childItems();
74 76
75 77 Q_ASSERT(labels.size() == ticksList.size());
76 78 Q_ASSERT(layout.size() == ticksList.size());
77 79
78 80 qreal height = 2*m_rect.bottom();
79 81
80 82 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(axis.at(0));
81 83 lineItem->setLine(m_rect.left() , m_rect.top(), m_rect.left(), m_rect.bottom());
82 84
83 85 for (int i = 0; i < layout.size(); ++i) {
84 86 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(lines.at(i));
85 87 lineItem->setLine(m_rect.left() , layout[i], m_rect.right(), layout[i]);
86 88 QGraphicsSimpleTextItem *labelItem = static_cast<QGraphicsSimpleTextItem*>(labels.at(i));
87 89
88 90 labelItem->setText(ticksList.at(i));
89 91 const QRectF& rect = labelItem->boundingRect();
90 92
91 93 QPointF center = rect.center();
92 94 labelItem->setTransformOriginPoint(center.x(), center.y());
93 95 labelItem->setPos(m_rect.left() - rect.width() - label_padding , layout[i]-center.y());
94 96
95 97 if(labelItem->pos().y()+rect.height()>height) {
96 98 labelItem->setVisible(false);
97 99 lineItem->setVisible(false);
98 100 }
99 101 else {
100 102 labelItem->setVisible(true);
101 103 lineItem->setVisible(true);
102 104 height=labelItem->pos().y();
103 105 }
104 106
105 107 m_minWidth=qMax(rect.width()+label_padding,m_minWidth);
106 108 m_minHeight+=rect.height();
107 109
108 110 if ((i+1)%2 && i>1) {
109 111 QGraphicsRectItem *rectItem = static_cast<QGraphicsRectItem*>(shades.at(i/2-1));
110 112 rectItem->setRect(m_rect.left(),layout[i],m_rect.width(),layout[i-1]-layout[i]);
111 113 }
112 114 lineItem = static_cast<QGraphicsLineItem*>(axis.at(i+1));
113 115 lineItem->setLine(m_rect.left()-5,layout[i],m_rect.left(),layout[i]);
114 116 }
115 117 }
116 118
119 void ChartValuesAxisY::handleAxisUpdated()
120 {
121 //TODO:: fix this
122 QValuesAxis* axis = qobject_cast<QValuesAxis*>(m_chartAxis);
123 m_tickCount = axis->ticksCount();
124 ChartAxis::handleAxisUpdated();
125 }
126
127
117 128 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,55 +1,58
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 // W A R N I N G
22 22 // -------------
23 23 //
24 24 // This file is not part of the QtCommercial Chart API. It exists purely as an
25 25 // implementation detail. This header file may change from version to
26 26 // version without notice, or even be removed.
27 27 //
28 28 // We mean it.
29 29
30 30 #ifndef CHARTVALUESAXISY_H
31 31 #define CHARTVALUESAXISY_H
32 32
33 33 #include "chartaxis_p.h"
34 34
35 35 QTCOMMERCIALCHART_BEGIN_NAMESPACE
36 36
37 37 class QAbstractAxis;
38 38 class ChartPresenter;
39 39
40 40 class ChartValuesAxisY : public ChartAxis
41 41 {
42 42 public:
43 43 ChartValuesAxisY(QAbstractAxis *axis, ChartPresenter *presenter);
44 44 ~ChartValuesAxisY();
45 45
46 46 AxisType axisType() const { return Y_AXIS;}
47 47
48 48 protected:
49 49 QVector<qreal> calculateLayout() const;
50 50 void updateGeometry();
51 void handleAxisUpdated();
52 private:
53 int m_tickCount;
51 54 };
52 55
53 56 QTCOMMERCIALCHART_END_NAMESPACE
54 57
55 58 #endif /* CHARTVALUESAXISY_H */
@@ -1,326 +1,362
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "qvaluesaxis.h"
22 22 #include "qvaluesaxis_p.h"
23 23 #include "chartvaluesaxisx_p.h"
24 24 #include "chartvaluesaxisy_p.h"
25 25 #include "domain_p.h"
26 #include <cmath>
26 27 #include <QDebug>
27 28
28 29 QTCOMMERCIALCHART_BEGIN_NAMESPACE
29 30 /*!
30 31 \class QValuesAxis
31 32 \brief The QValuesAxis class is used for manipulating chart's axis.
32 33 \mainclass
33 34
34 35 ValuesAxis can be setup to show axis line with tick marks, grid lines and shades.
35 36 Values of axis are drawn to position of ticks
36 37 */
37 38
38 39 /*!
39 40 \qmlclass ValuesAxis QValuesAxis
40 41 \brief The ValuesAxis element is used for manipulating chart's axes
41 42
42 43 ValueAxis can be setup to show axis line with tick marks, grid lines and shades.
43 44 Values of axis are drawn to position of ticks
44 45
45 46 To access Axes you can use ChartView API. For example:
46 47 \code
47 48 ChartView {
48 49 ValuesAxis {
49 50 id: xAxis
50 51 min: 0
51 52 max: 10
52 53 }
53 54 // Add a few series...
54 55 }
55 56 \endcode
56 57 */
57 58
58 59 /*!
59 60 \property QValuesAxis::min
60 61 Defines the minimum value on the axis.
61 62 */
62 63 /*!
63 64 \qmlproperty real ValuesAxis::min
64 65 Defines the minimum value on the axis.
65 66 */
66 67
67 68 /*!
68 69 \property QValuesAxis::max
69 70 Defines the maximum value on the axis.
70 71 */
71 72 /*!
72 73 \qmlproperty real ValuesAxis::max
73 74 Defines the maximum value on the axis.
74 75 */
75 76
76 77 /*!
77 78 \fn void QValuesAxis::minChanged(qreal min)
78 79 Axis emits signal when \a min of axis has changed.
79 80 */
80 81 /*!
81 82 \qmlsignal ValuesAxis::onMinChanged(real min)
82 83 Axis emits signal when \a min of axis has changed.
83 84 */
84 85
85 86 /*!
86 87 \fn void QValuesAxis::maxChanged(qreal max)
87 88 Axis emits signal when \a max of axis has changed.
88 89 */
89 90 /*!
90 91 \qmlsignal ValuesAxis::onMaxChanged(real max)
91 92 Axis emits signal when \a max of axis has changed.
92 93 */
93 94
94 95 /*!
95 96 \fn void QValuesAxis::rangeChanged(qreal min, qreal max)
96 97 Axis emits signal when \a min or \a max of axis has changed.
97 98 */
98 99
99 100 /*!
100 101 \property QValuesAxis::ticksCount
101 102 The number of tick marks for the axis.
102 103 */
103 104
104 105 /*!
105 106 \qmlproperty int ValuesAxis::ticksCount
106 107 The number of tick marks for the axis.
107 108 */
108 109
109 110 /*!
110 111 \property QValuesAxis::niceNumbersEnabled
111 112 Whether the nice numbers algorithm is enabled or not for the axis.
112 113 */
113 114
114 115 /*!
115 116 \qmlproperty bool ValuesAxis::niceNumbersEnabled
116 117 Whether the nice numbers algorithm is enabled or not for the axis.
117 118 */
118 119
119 120 /*!
120 121 Constructs an axis object which is a child of \a parent.
121 122 */
122 123 QValuesAxis::QValuesAxis(QObject *parent) :
123 124 QAbstractAxis(*new QValuesAxisPrivate(this),parent)
124 125 {
125 126
126 127 }
127 128
128 129 /*!
129 130 \internal
130 131 */
131 132 QValuesAxis::QValuesAxis(QValuesAxisPrivate &d,QObject *parent) : QAbstractAxis(d,parent)
132 133 {
133 134
134 135 }
135 136
136 137 /*!
137 138 Destroys the object
138 139 */
139 140 QValuesAxis::~QValuesAxis()
140 141 {
141 142
142 143 }
143 144
144 145 void QValuesAxis::setMin(qreal min)
145 146 {
146 147 Q_D(QValuesAxis);
147 148 setRange(min,d->m_max);
148 149 }
149 150
150 151 qreal QValuesAxis::min() const
151 152 {
152 153 Q_D(const QValuesAxis);
153 154 return d->m_min;
154 155 }
155 156
156 157 void QValuesAxis::setMax(qreal max)
157 158 {
158 159 Q_D(QValuesAxis);
159 160 setRange(d->m_min,max);
160 161 }
161 162
162 163 qreal QValuesAxis::max() const
163 164 {
164 165 Q_D(const QValuesAxis);
165 166 return d->m_max;
166 167 }
167 168
168 169 /*!
169 170 Sets range from \a min to \a max on the axis.
170 171 */
171 172 void QValuesAxis::setRange(qreal min, qreal max)
172 173 {
173 174 Q_D(QValuesAxis);
174 175 bool changed = false;
176
175 177 if (!qFuzzyIsNull(d->m_min - min)) {
176 178 d->m_min = min;
177 179 changed = true;
178 180 emit minChanged(min);
179 181 }
180 182
181 183 if (!qFuzzyIsNull(d->m_max - max)) {
182 184 d->m_max = max;
183 185 changed = true;
184 186 emit maxChanged(max);
185 187 }
186 188
189 if(d->m_niceNumbers) d->looseNiceNumbers(d->m_min, d->m_max, d->m_tickCount);
190
187 191 if (changed) {
188 d->emitRange();
189 192 emit rangeChanged(d->m_min,d->m_max);
193 d->emitUpdated();
190 194 }
191 195 }
192 196
193 197 /*!
194 198 Sets \a count for ticks on the axis.
195 199 */
196 200 void QValuesAxis::setTicksCount(int count)
197 201 {
198 202 Q_D(QValuesAxis);
199 if (d->m_ticksCount != count) {
200 d->m_ticksCount = count;
201 emit d->changed(d->m_min, d->m_max, d->m_ticksCount, d->m_niceNumbers);
203 if (d->m_tickCount != count) {
204 d->m_tickCount = count;
205 d->emitUpdated();
202 206 }
203 207 }
204 208
205 209 /*!
206 210 \fn int QValuesAxis::ticksCount() const
207 211 Return number of ticks on the axis
208 212 */
209 213 int QValuesAxis::ticksCount() const
210 214 {
211 215 Q_D(const QValuesAxis);
212 return d->m_ticksCount;
216 return d->m_tickCount;
213 217 }
214 218
215 219 void QValuesAxis::setNiceNumbersEnabled(bool enable)
216 220 {
217 221 Q_D(QValuesAxis);
218 222 if (d->m_niceNumbers != enable){
219 223 d->m_niceNumbers = enable;
220 emit d->changed(d->m_min, d->m_max, d->m_ticksCount, d->m_niceNumbers);
224 if(enable) setRange(d->min(),d->max());
221 225 }
222 226 }
223 227
224 228 bool QValuesAxis::niceNumbersEnabled() const
225 229 {
226 230 Q_D(const QValuesAxis);
227 231 return d->m_niceNumbers;
228 232 }
229 233
230 234 /*!
231 235 Returns the type of the axis
232 236 */
233 237 QAbstractAxis::AxisType QValuesAxis::type() const
234 238 {
235 239 return AxisTypeValues;
236 240 }
237 241
238 242 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
239 243
240 244 QValuesAxisPrivate::QValuesAxisPrivate(QValuesAxis* q):
241 245 QAbstractAxisPrivate(q),
246 m_min(0),
247 m_max(0),
248 m_tickCount(5),
242 249 m_niceNumbers(false)
243 250 {
244 251
245 252 }
246 253
247 254 QValuesAxisPrivate::~QValuesAxisPrivate()
248 255 {
249 256
250 257 }
251 258
252 void QValuesAxisPrivate::handleAxisRangeChanged(qreal min, qreal max,int count)
259 void QValuesAxisPrivate::handleDomainUpdated()
253 260 {
254 261 Q_Q(QValuesAxis);
255 q->setRange(min,max);
256 q->setTicksCount(count);
262 Domain* domain = qobject_cast<Domain*>(sender());
263 Q_ASSERT(domain);
264
265 if(orientation()==Qt::Horizontal){
266 q->setRange(domain->minX(),domain->maxX());
267 }else if(orientation()==Qt::Vertical){
268 q->setRange(domain->minY(),domain->maxY());
269 }
257 270 }
258 271
259 272
260 273 void QValuesAxisPrivate::setMin(const QVariant &min)
261 274 {
262 275 Q_Q(QValuesAxis);
263 276 bool ok;
264 277 qreal value = min.toReal(&ok);
265 278 if(ok) q->setMin(value);
266 279 }
267 280
268 281 void QValuesAxisPrivate::setMax(const QVariant &max)
269 282 {
270 283
271 284 Q_Q(QValuesAxis);
272 285 bool ok;
273 286 qreal value = max.toReal(&ok);
274 287 if(ok) q->setMax(value);
275 288 }
276 289
277 290 void QValuesAxisPrivate::setRange(const QVariant &min, const QVariant &max)
278 291 {
279 292 Q_Q(QValuesAxis);
280 293 bool ok1;
281 294 bool ok2;
282 295 qreal value1 = min.toReal(&ok1);
283 296 qreal value2 = max.toReal(&ok2);
284 297 if(ok1&&ok2) q->setRange(value1,value2);
285 298 }
286 299
287 int QValuesAxisPrivate::ticksCount() const
288 {
289 return m_ticksCount;
290 }
291
292 300 ChartAxis* QValuesAxisPrivate::createGraphics(ChartPresenter* presenter)
293 301 {
294 302 Q_Q(QValuesAxis);
295 303 if(m_orientation == Qt::Vertical){
296 304 return new ChartValuesAxisY(q,presenter);
297 305 }else{
298 306 return new ChartValuesAxisX(q,presenter);
299 307 }
300 308
301 309 }
302 310
303 void QValuesAxisPrivate::emitRange()
304 {
305 emit changed(m_min, m_max, m_ticksCount, m_niceNumbers);
306 }
307
308 311 void QValuesAxisPrivate::intializeDomain(Domain* domain)
309 312 {
310 313 if(qFuzzyCompare(m_max,m_min)) {
311 314 if(m_orientation==Qt::Vertical){
312 315 m_min = domain->minY();
313 316 m_max = domain->maxY();
314 m_ticksCount = domain->tickYCount();
315 317 }else{
316 318 m_min = domain->minX();
317 319 m_max = domain->maxX();
318 m_ticksCount = domain->tickXCount();
319 320 }
320 321 }
321 322 }
322 323
324 //algorithm defined by Paul S.Heckbert GraphicalGems I
325
326 void QValuesAxisPrivate::looseNiceNumbers(qreal &min, qreal &max, int &ticksCount) const
327 {
328 qreal range = niceNumber(max-min,true); //range with ceiling
329 qreal step = niceNumber(range/(ticksCount-1),false);
330 min = floor(min/step);
331 max = ceil(max/step);
332 ticksCount = int(max-min) +1;
333 min*=step;
334 max*=step;
335 }
336
337 //nice numbers can be expressed as form of 1*10^n, 2* 10^n or 5*10^n
338
339 qreal QValuesAxisPrivate::niceNumber(qreal x,bool ceiling) const
340 {
341 qreal z = pow(10,floor(log10(x))); //find corresponding number of the form of 10^n than is smaller than x
342 qreal q = x/z;//q<10 && q>=1;
343
344 if(ceiling) {
345 if(q <= 1.0) q=1;
346 else if(q <= 2.0) q=2;
347 else if(q <= 5.0) q=5;
348 else q=10;
349 }
350 else {
351 if(q < 1.5) q=1;
352 else if(q < 3.0) q=2;
353 else if(q < 7.0) q=5;
354 else q=10;
355 }
356 return q*z;
357 }
358
323 359 #include "moc_qvaluesaxis.cpp"
324 360 #include "moc_qvaluesaxis_p.cpp"
325 361
326 362 QTCOMMERCIALCHART_END_NAMESPACE
1 NO CONTENT: file renamed from src/axis/qvaluesaxis.h to src/axis/valuesaxis/qvaluesaxis.h
@@ -1,69 +1,72
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 // W A R N I N G
22 22 // -------------
23 23 //
24 24 // This file is not part of the QtCommercial Chart API. It exists purely as an
25 25 // implementation detail. This header file may change from version to
26 26 // version without notice, or even be removed.
27 27 //
28 28 // We mean it.
29 29
30 30 #ifndef QVALUESAXIS_P_H
31 31 #define QVALUESAXIS_P_H
32 32
33 33 #include "qvaluesaxis.h"
34 34 #include "qabstractaxis_p.h"
35 35
36 36 QTCOMMERCIALCHART_BEGIN_NAMESPACE
37 37
38 38 class QValuesAxisPrivate : public QAbstractAxisPrivate
39 39 {
40 40 Q_OBJECT
41 41 public:
42 42 QValuesAxisPrivate(QValuesAxis *q);
43 43 ~QValuesAxisPrivate();
44 44
45 Q_SIGNALS:
46 void changed(qreal min, qreal max, int tickCount,bool niceNumbers);
47
48 public Q_SLOTS:
49 void handleAxisRangeChanged(qreal min, qreal max,int count);
50
51 45 public:
52 46 ChartAxis* createGraphics(ChartPresenter* presenter);
53 47 void intializeDomain(Domain* domain);
54 void emitRange();
48 void handleDomainUpdated();
49 qreal min(){ return m_min; };
50 qreal max(){ return m_max; };
55 51
56 52 protected:
57 53 void setMin(const QVariant &min);
58 54 void setMax(const QVariant &max);
59 55 void setRange(const QVariant &min, const QVariant &max);
60 56 int ticksCount() const;
61 57
62 58 private:
59 void looseNiceNumbers(qreal &min, qreal &max, int &ticksCount) const;
60 qreal niceNumber(qreal x,bool ceiling) const;
61
62 private:
63 qreal m_min;
64 qreal m_max;
65 int m_tickCount;
63 66 bool m_niceNumbers;
64 67 Q_DECLARE_PUBLIC(QValuesAxis)
65 68 };
66 69
67 70 QTCOMMERCIALCHART_END_NAMESPACE
68 71
69 72 #endif // QVALUESAXIS_P_H
@@ -1,179 +1,179
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "abstractbarchartitem_p.h"
22 22 #include "bar_p.h"
23 23 #include "qbarset.h"
24 24 #include "qbarset_p.h"
25 25 #include "qabstractbarseries.h"
26 26 #include "qabstractbarseries_p.h"
27 27 #include "qchart.h"
28 28 #include "chartpresenter_p.h"
29 29 #include "chartanimator_p.h"
30 30 #include "abstractbaranimation_p.h"
31 31 #include "chartdataset_p.h"
32 32 #include <QPainter>
33 33
34 34 QTCOMMERCIALCHART_BEGIN_NAMESPACE
35 35
36 36 AbstractBarChartItem::AbstractBarChartItem(QAbstractBarSeries *series, ChartPresenter *presenter) :
37 37 ChartItem(presenter),
38 38 m_animation(0),
39 39 m_series(series)
40 40 {
41 41 setFlag(ItemClipsChildrenToShape);
42 42 connect(series->d_func(), SIGNAL(updatedBars()), this, SLOT(handleLayoutChanged()));
43 43 connect(series->d_func(), SIGNAL(labelsVisibleChanged(bool)), this, SLOT(handleLabelsVisibleChanged(bool)));
44 44 connect(series->d_func(), SIGNAL(restructuredBars()), this, SLOT(handleDataStructureChanged()));
45 45 connect(series, SIGNAL(visibleChanged()), this, SLOT(handleVisibleChanged()));
46 46 setZValue(ChartPresenter::BarSeriesZValue);
47 47 handleDataStructureChanged();
48 48 }
49 49
50 50 AbstractBarChartItem::~AbstractBarChartItem()
51 51 {
52 52 }
53 53
54 54 void AbstractBarChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
55 55 {
56 56 Q_UNUSED(painter);
57 57 Q_UNUSED(option);
58 58 Q_UNUSED(widget);
59 59 }
60 60
61 61 QRectF AbstractBarChartItem::boundingRect() const
62 62 {
63 63 return m_rect;
64 64 }
65 65
66 66 void AbstractBarChartItem::applyLayout(const QVector<QRectF> &layout)
67 67 {
68 68 if (m_animation) {
69 69 m_animation->setup(m_layout,layout);
70 70 presenter()->startAnimation(m_animation);
71 71
72 72 } else {
73 73 setLayout(layout);
74 74 update();
75 75 }
76 76 }
77 77
78 78 void AbstractBarChartItem::setAnimation(AbstractBarAnimation *animation)
79 79 {
80 80 m_animation = animation;
81 81 }
82 82
83 83 void AbstractBarChartItem::setLayout(const QVector<QRectF> &layout)
84 84 {
85 85 if (layout.count() != m_bars.count())
86 86 return;
87 87
88 m_layout = layout;
88 m_layout = layout;
89 89
90 90 for (int i=0; i < m_bars.count(); i++) {
91 91 m_bars.at(i)->setRect(layout.at(i));
92 92 }
93 93 }
94 94 //handlers
95 95
96 void AbstractBarChartItem::handleDomainChanged(qreal minX, qreal maxX, qreal minY, qreal maxY)
96 void AbstractBarChartItem::handleDomainUpdated()
97 97 {
98 m_domainMinX = minX;
99 m_domainMaxX = maxX;
100 m_domainMinY = minY;
101 m_domainMaxY = maxY;
98 m_domainMinX = domain()->minX();
99 m_domainMaxX = domain()->maxX();
100 m_domainMinY = domain()->minY();
101 m_domainMaxY = domain()->maxY();
102 102 handleLayoutChanged();
103 103 }
104 104
105 105 void AbstractBarChartItem::handleGeometryChanged(const QRectF &rect)
106 106 {
107 107 prepareGeometryChange();
108 108 m_rect = rect;
109 109 handleLayoutChanged();
110 110 }
111 111
112 112 void AbstractBarChartItem::handleLayoutChanged()
113 113 {
114 114 if ((m_rect.width() <= 0) || (m_rect.height() <= 0)) {
115 115 // rect size zero.
116 116 return;
117 117 }
118 118 QVector<QRectF> layout = calculateLayout();
119 119 applyLayout(layout);
120 120 }
121 121
122 122 void AbstractBarChartItem::handleLabelsVisibleChanged(bool visible)
123 123 {
124 124 foreach (QGraphicsSimpleTextItem* label, m_labels) {
125 125 label->setVisible(visible);
126 126 }
127 127 update();
128 128 }
129 129
130 130 void AbstractBarChartItem::handleDataStructureChanged()
131 131 {
132 132 foreach(QGraphicsItem *item, childItems()) {
133 133 delete item;
134 134 }
135 135
136 136 m_bars.clear();
137 137 m_labels.clear();
138 138 m_layout.clear();
139 139
140 140 bool labelsVisible = m_series->isLabelsVisible();
141 141
142 142 // Create new graphic items for bars
143 143 for (int c = 0; c < m_series->d_func()->categoryCount(); c++) {
144 144 for (int s = 0; s < m_series->count(); s++) {
145 145 QBarSet *set = m_series->d_func()->barsetAt(s);
146 146
147 147 // Bars
148 148 Bar *bar = new Bar(set,c,this);
149 149 m_bars.append(bar);
150 150 connect(bar, SIGNAL(clicked(int, QBarSet*)), m_series, SIGNAL(clicked(int, QBarSet*)));
151 151 connect(bar, SIGNAL(hovered(bool, QBarSet*)), m_series, SIGNAL(hovered(bool, QBarSet*)));
152 152 connect(bar, SIGNAL(clicked(int, QBarSet*)), set, SIGNAL(clicked(int)));
153 153 connect(bar, SIGNAL(hovered(bool, QBarSet*)), set, SIGNAL(hovered(bool)));
154 154 m_layout.append(QRectF(0, 0, 0, 0));
155 155
156 156 // Labels
157 157 QGraphicsSimpleTextItem *label = new QGraphicsSimpleTextItem(this);
158 158 label->setVisible(labelsVisible);
159 159 m_labels.append(label);
160 160 }
161 161 }
162 162
163 163 // TODO: Is this the right place to call it?
164 164 presenter()->chartTheme()->decorate(m_series, presenter()->dataSet()->seriesIndex(m_series));
165 165 handleLayoutChanged();
166 166 }
167 167
168 168 void AbstractBarChartItem::handleVisibleChanged()
169 169 {
170 170 bool visible = m_series->isVisible();
171 171 handleLabelsVisibleChanged(visible);
172 172 foreach(QGraphicsItem *item, childItems()) {
173 173 item->setVisible(visible);
174 174 }
175 175 }
176 176
177 177 #include "moc_abstractbarchartitem_p.cpp"
178 178
179 179 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,94 +1,92
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 // W A R N I N G
22 22 // -------------
23 23 //
24 24 // This file is not part of the QtCommercial Chart API. It exists purely as an
25 25 // implementation detail. This header file may change from version to
26 26 // version without notice, or even be removed.
27 27 //
28 28 // We mean it.
29 29
30 30
31 31 #ifndef ABSTRACTBARCHARTITEM_H
32 32 #define ABSTRACTBARCHARTITEM_H
33 33
34 34 #include "chartitem_p.h"
35 35 #include "qabstractbarseries.h"
36 36 #include <QPen>
37 37 #include <QBrush>
38 38
39 39 QTCOMMERCIALCHART_BEGIN_NAMESPACE
40 40
41 41 class Bar;
42 42 class QAxisCategories;
43 43 class QChart;
44 44 class AbstractBarAnimation;
45 45
46 46 class AbstractBarChartItem : public ChartItem
47 47 {
48 48 Q_OBJECT
49 49 public:
50 50 AbstractBarChartItem(QAbstractBarSeries *series, ChartPresenter *presenter);
51 51 virtual ~AbstractBarChartItem();
52 52
53 53 public:
54 54 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
55 55 QRectF boundingRect() const;
56 56
57 57 virtual QVector<QRectF> calculateLayout() = 0;
58 58 virtual void applyLayout(const QVector<QRectF> &layout);
59 59 virtual void setAnimation(AbstractBarAnimation* animation);
60 60 void setLayout(const QVector<QRectF> &layout);
61 61 void updateLayout(const QVector<QRectF> &layout);
62
63
64 62 QRectF geometry() const { return m_rect;}
65 63
66 64 public Q_SLOTS:
67 void handleDomainChanged(qreal minX, qreal maxX, qreal minY, qreal maxY);
65 void handleDomainUpdated();
68 66 void handleGeometryChanged(const QRectF &size);
69 67 void handleLayoutChanged();
70 68 void handleLabelsVisibleChanged(bool visible);
71 69 void handleDataStructureChanged(); // structure of of series has changed, recreate graphic items
72 70 void handleVisibleChanged();
73 71
74 72 protected:
75 73
76 74 qreal m_domainMinX;
77 75 qreal m_domainMaxX;
78 76 qreal m_domainMinY;
79 77 qreal m_domainMaxY;
80 78
81 79 QRectF m_rect;
82 80 QVector<QRectF> m_layout;
83 81
84 82 AbstractBarAnimation *m_animation;
85 83
86 84 // Not owned.
87 85 QAbstractBarSeries *m_series;
88 86 QList<Bar *> m_bars;
89 87 QList<QGraphicsSimpleTextItem *> m_labels;
90 88 };
91 89
92 90 QTCOMMERCIALCHART_END_NAMESPACE
93 91
94 92 #endif // ABSTRACTBARCHARTITEM_H
@@ -1,729 +1,726
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "qabstractbarseries.h"
22 22 #include "qabstractbarseries_p.h"
23 23 #include "qbarset.h"
24 24 #include "qbarset_p.h"
25 25 #include "domain_p.h"
26 26 #include "legendmarker_p.h"
27 27 #include "chartdataset_p.h"
28 28 #include "charttheme_p.h"
29 29 #include "chartanimator_p.h"
30 30 #include "qvaluesaxis.h"
31 31 #include "qbarcategoriesaxis.h"
32 32
33 33 QTCOMMERCIALCHART_BEGIN_NAMESPACE
34 34
35 35 /*!
36 36 \class QAbstractBarSeries
37 37 \brief Series for creating a bar chart
38 38 \mainclass
39 39
40 40 QAbstractBarSeries represents a series of data shown as bars. The purpose of this class is to draw bars to
41 41 the position defined by data. Single bar is defined by QPointF, where x value is the x-coordinate of the bar
42 42 and y-value is the height of the bar. The category names are ignored with this series and x-axis
43 43 shows the x-values.
44 44
45 45 See the \l {BarChart Example} {bar chart example} to learn how to create a simple bar chart.
46 46 \image examples_barchart.png
47 47
48 48 \sa QBarSet, QStackedBarSeries, QPercentBarSeries
49 49 */
50 50 /*!
51 51 \qmlclass AbstractBarSeries QAbstractBarSeries
52 52 \inherits QAbstractSeries
53 53
54 54 The following QML shows how to create a simple bar chart:
55 55 \snippet ../demos/qmlchart/qml/qmlchart/View6.qml 1
56 56
57 57 \beginfloatleft
58 58 \image demos_qmlchart6.png
59 59 \endfloat
60 60 \clearfloat
61 61 */
62 62
63 63 /*!
64 64 \property QAbstractBarSeries::barWidth
65 65 The width of the bars of the series. The unit of \a width is the unit of x-axis. The minimum width for bars
66 66 is zero and negative values are treated as zero. Setting the width to zero means that width of the bar on screen
67 67 is one pixel no matter what the scale of x-axis is. Bars wider than zero are scaled with x-axis.
68 68 Note that with QBarSeries this value means the width of one group of bars instead of just one bar.
69 69 \sa QBarSeries
70 70 */
71 71 /*!
72 72 \qmlproperty real AbstractBarSeries::barWidth
73 73 The width of the bars of the series. The unit of width is the unit of x-axis. The minimum width for bars
74 74 is zero and negative values are treated as zero. Setting the width to zero means that width of the bar on screen
75 75 is one pixel no matter what the scale of x-axis is. Bars wider than zero are scaled with x-axis.
76 76 Note that with QBarSeries this value means the width of one group of bars instead of just one bar.
77 77 */
78 78
79 79 /*!
80 80 \property QAbstractBarSeries::count
81 81 Holds the number of sets in series.
82 82 */
83 83 /*!
84 84 \qmlproperty int AbstractBarSeries::count
85 85 Holds the number of sets in series.
86 86 */
87 87
88 88 /*!
89 89 \property QAbstractBarSeries::labelsVisible
90 90 Defines the visibility of the labels in series
91 91 */
92 92 /*!
93 93 \qmlproperty bool AbstractBarSeries::labelsVisible
94 94 Defines the visibility of the labels in series
95 95 */
96 96
97 97 /*!
98 98 \fn void QAbstractBarSeries::clicked(int index, QBarSet *barset)
99 99 The signal is emitted if the user clicks with a mouse on top of QBarSet \a barset.
100 100 Clicked bar inside set is indexed by \a index
101 101 */
102 102 /*!
103 103 \qmlsignal AbstractBarSeries::onClicked(int index, BarSet barset)
104 104 The signal is emitted if the user clicks with a mouse on top of BarSet.
105 105 Clicked bar inside set is indexed by \a index
106 106 */
107 107
108 108 /*!
109 109 \fn void QAbstractBarSeries::hovered(bool status, QBarSet* barset)
110 110
111 111 The signal is emitted if mouse is hovered on top of series.
112 112 Parameter \a barset is the pointer of barset, where hover happened.
113 113 Parameter \a status is true, if mouse entered on top of series, false if mouse left from top of series.
114 114 */
115 115 /*!
116 116 \qmlsignal AbstractBarSeries::onHovered(bool status, BarSet barset)
117 117
118 118 The signal is emitted if mouse is hovered on top of series.
119 119 Parameter \a barset is the pointer of barset, where hover happened.
120 120 Parameter \a status is true, if mouse entered on top of series, false if mouse left from top of series.
121 121 */
122 122
123 123 /*!
124 124 \fn void QAbstractBarSeries::countChanged()
125 125 This signal is emitted when barset count has been changed, for example by append or remove.
126 126 */
127 127 /*!
128 128 \qmlsignal AbstractBarSeries::onCountChanged()
129 129 This signal is emitted when barset count has been changed, for example by append or remove.
130 130 */
131 131
132 132 /*!
133 133 \fn void QAbstractBarSeries::labelsVisibleChanged()
134 134 This signal is emitted when labels visibility have changed.
135 135 \sa isLabelsVisible(), setLabelsVisible()
136 136 */
137 137
138 138 /*!
139 139 \fn void QAbstractBarSeries::barsetsAdded(QList<QBarSet*> sets)
140 140 This signal is emitted when \a sets have been added to the series.
141 141 \sa append(), insert()
142 142 */
143 143 /*!
144 144 \qmlsignal AbstractBarSeries::onAdded(BarSet barset)
145 145 Emitted when \a barset has been added to the series.
146 146 */
147 147
148 148 /*!
149 149 \fn void QAbstractBarSeries::barsetsRemoved(QList<QBarSet*> sets)
150 150 This signal is emitted when \a sets have been removed from the series.
151 151 \sa remove()
152 152 */
153 153 /*!
154 154 \qmlsignal AbstractBarSeries::onRemoved(BarSet barset)
155 155 Emitted when \a barset has been removed from the series.
156 156 */
157 157
158 158 /*!
159 159 \qmlmethod BarSet AbstractBarSeries::at(int index)
160 160 Returns bar set at \a index. Returns null if the index is not valid.
161 161 */
162 162
163 163 /*!
164 164 \qmlmethod BarSet AbstractBarSeries::append(string label, VariantList values)
165 165 Adds a new bar set with \a label and \a values to \a index. Values can be a list of reals or a list of XYPoints.
166 166 For example:
167 167 \code
168 168 myBarSeries.append("set 1", [0, 0.2, 0.2, 0.5, 0.4, 1.5, 0.9]);
169 169 myBarSeries.append("set 2", [Qt.point(0, 1), Qt.point(2, 2.5), Qt.point(3.5, 2.2)]);
170 170 \endcode
171 171 */
172 172
173 173 /*!
174 174 \qmlmethod BarSet AbstractBarSeries::insert(int index, string label, VariantList values)
175 175 Inserts a new bar set with \a label and \a values to \a index. Values can be a list of reals or a list of XYPoints.
176 176 If index is zero or smaller, the new barset is prepended. If the index is count or bigger, the new barset is
177 177 appended.
178 178 \sa AbstractBarSeries::append()
179 179 */
180 180
181 181 /*!
182 182 \qmlmethod bool AbstractBarSeries::remove(BarSet barset)
183 183 Removes the barset from the series. Returns true if successfull, false otherwise.
184 184 */
185 185
186 186 /*!
187 187 \qmlmethod AbstractBarSeries::clear()
188 188 Removes all barsets from the series.
189 189 */
190 190
191 191 /*!
192 192 Constructs empty QAbstractBarSeries.
193 193 QAbstractBarSeries is QObject which is a child of a \a parent.
194 194 */
195 195 QAbstractBarSeries::QAbstractBarSeries(QObject *parent) :
196 196 QAbstractSeries(*new QAbstractBarSeriesPrivate(this),parent)
197 197 {
198 198 }
199 199
200 200 /*!
201 201 Destructs abstractbarseries and owned barsets.
202 202 */
203 203 QAbstractBarSeries::~QAbstractBarSeries()
204 204 {
205 205 Q_D(QAbstractBarSeries);
206 206 if(d->m_dataset){
207 207 d->m_dataset->removeSeries(this);
208 208 }
209 209 }
210 210
211 211 /*!
212 212 \internal
213 213 */
214 214 QAbstractBarSeries::QAbstractBarSeries(QAbstractBarSeriesPrivate &d, QObject *parent) :
215 215 QAbstractSeries(d,parent)
216 216 {
217 217 }
218 218
219 219 /*!
220 220 Sets the width of the bars of the series. The unit of \a width is the unit of x-axis. The minimum width for bars
221 221 is zero and negative values are treated as zero. Setting the width to zero means that width of the bar on screen
222 222 is one pixel no matter what the scale of x-axis is. Bars wider than zero are scaled with x-axis.
223 223 Note that with \link QBarSeries \endlink this value means the width of one group of bars instead of just one bar.
224 224 */
225 225 void QAbstractBarSeries::setBarWidth(qreal width)
226 226 {
227 227 Q_D(QAbstractBarSeries);
228 228 d->setBarWidth(width);
229 229 }
230 230
231 231 /*!
232 232 Returns the width of the bars of the series.
233 233 \sa setBarWidth()
234 234 */
235 235 qreal QAbstractBarSeries::barWidth() const
236 236 {
237 237 Q_D(const QAbstractBarSeries);
238 238 return d->barWidth();
239 239 }
240 240
241 241 /*!
242 242 Adds a set of bars to series. Takes ownership of \a set. If the set is null or is already in series, it won't be appended.
243 243 Returns true, if appending succeeded.
244 244 */
245 245 bool QAbstractBarSeries::append(QBarSet *set)
246 246 {
247 247 Q_D(QAbstractBarSeries);
248 248 bool success = d->append(set);
249 249 if (success) {
250 250 QList<QBarSet*> sets;
251 251 sets.append(set);
252 252 emit barsetsAdded(sets);
253 253 emit countChanged();
254 254 }
255 255 return success;
256 256 }
257 257
258 258 /*!
259 259 Removes a set of bars from series. Releases ownership of \a set. Doesn't delete \a set.
260 260 Returns true, if set was removed.
261 261 */
262 262 bool QAbstractBarSeries::remove(QBarSet *set)
263 263 {
264 264 Q_D(QAbstractBarSeries);
265 265 bool success = d->remove(set);
266 266 if (success) {
267 267 QList<QBarSet*> sets;
268 268 sets.append(set);
269 269 emit barsetsRemoved(sets);
270 270 emit countChanged();
271 271 }
272 272 return success;
273 273 }
274 274
275 275 /*!
276 276 Adds a list of barsets to series. Takes ownership of \a sets.
277 277 Returns true, if all sets were appended succesfully. If any of the sets is null or is already appended to series,
278 278 nothing is appended and function returns false. If any of the sets is in list more than once, nothing is appended
279 279 and function returns false.
280 280 */
281 281 bool QAbstractBarSeries::append(QList<QBarSet* > sets)
282 282 {
283 283 Q_D(QAbstractBarSeries);
284 284 bool success = d->append(sets);
285 285 if (success) {
286 286 emit barsetsAdded(sets);
287 287 emit countChanged();
288 288 }
289 289 return success;
290 290 }
291 291
292 292 /*!
293 293 Insert a set of bars to series at \a index postion. Takes ownership of \a set. If the set is null or is already in series, it won't be appended.
294 294 Returns true, if inserting succeeded.
295 295
296 296 */
297 297 bool QAbstractBarSeries::insert(int index, QBarSet *set)
298 298 {
299 299 Q_D(QAbstractBarSeries);
300 300 bool success = d->insert(index, set);
301 301 if (success) {
302 302 QList<QBarSet*> sets;
303 303 sets.append(set);
304 304 emit barsetsAdded(sets);
305 305 emit countChanged();
306 306 }
307 307 return success;
308 308 }
309 309
310 310 /*!
311 311 Removes all of the bar sets from the series
312 312 */
313 313 void QAbstractBarSeries::clear()
314 314 {
315 315 Q_D(QAbstractBarSeries);
316 316 QList<QBarSet *> sets = barSets();
317 317 bool success = d->remove(sets);
318 318 if (success) {
319 319 emit barsetsRemoved(sets);
320 320 emit countChanged();
321 321 }
322 322 }
323 323
324 324 /*!
325 325 Returns number of sets in series.
326 326 */
327 327 int QAbstractBarSeries::count() const
328 328 {
329 329 Q_D(const QAbstractBarSeries);
330 330 return d->m_barSets.count();
331 331 }
332 332
333 333 /*!
334 334 Returns a list of sets in series. Keeps ownership of sets.
335 335 */
336 336 QList<QBarSet*> QAbstractBarSeries::barSets() const
337 337 {
338 338 Q_D(const QAbstractBarSeries);
339 339 return d->m_barSets;
340 340 }
341 341
342 342 /*!
343 343 Sets the visibility of labels in series to \a visible
344 344 */
345 345 void QAbstractBarSeries::setLabelsVisible(bool visible)
346 346 {
347 347 Q_D(QAbstractBarSeries);
348 348 if (d->m_labelsVisible != visible) {
349 349 d->setLabelsVisible(visible);
350 350 emit labelsVisibleChanged();
351 351 }
352 352 }
353 353
354 354 /*!
355 355 Returns the visibility of labels
356 356 */
357 357 bool QAbstractBarSeries::isLabelsVisible() const
358 358 {
359 359 Q_D(const QAbstractBarSeries);
360 360 return d->m_labelsVisible;
361 361 }
362 362
363 363 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
364 364
365 365 QAbstractBarSeriesPrivate::QAbstractBarSeriesPrivate(QAbstractBarSeries *q) :
366 366 QAbstractSeriesPrivate(q),
367 367 m_barWidth(0.5), // Default value is 50% of category width
368 368 m_labelsVisible(false),
369 369 m_visible(true)
370 370 {
371 371 }
372 372
373 373 int QAbstractBarSeriesPrivate::categoryCount() const
374 374 {
375 375 // No categories defined. return count of longest set.
376 376 int count = 0;
377 377 for (int i=0; i<m_barSets.count(); i++) {
378 378 if (m_barSets.at(i)->count() > count) {
379 379 count = m_barSets.at(i)->count();
380 380 }
381 381 }
382 382
383 383 return count;
384 384 }
385 385
386 386 void QAbstractBarSeriesPrivate::setBarWidth(qreal width)
387 387 {
388 388 if (width < 0.0) {
389 389 width = 0.0;
390 390 }
391 391 m_barWidth = width;
392 392 emit updatedBars();
393 393 }
394 394
395 395 qreal QAbstractBarSeriesPrivate::barWidth() const
396 396 {
397 397 return m_barWidth;
398 398 }
399 399
400 400 QBarSet* QAbstractBarSeriesPrivate::barsetAt(int index)
401 401 {
402 402 return m_barSets.at(index);
403 403 }
404 404
405 405 void QAbstractBarSeriesPrivate::setVisible(bool visible)
406 406 {
407 407 m_visible = visible;
408 408 emit updatedBars();
409 409 }
410 410
411 411 void QAbstractBarSeriesPrivate::setLabelsVisible(bool visible)
412 412 {
413 413 m_labelsVisible = visible;
414 414 emit labelsVisibleChanged(visible);
415 415 }
416 416
417 417 qreal QAbstractBarSeriesPrivate::min()
418 418 {
419 419 if (m_barSets.count() <= 0) {
420 420 return 0;
421 421 }
422 422 qreal min = INT_MAX;
423 423
424 424 for (int i = 0; i < m_barSets.count(); i++) {
425 425 int categoryCount = m_barSets.at(i)->count();
426 426 for (int j = 0; j < categoryCount; j++) {
427 427 qreal temp = m_barSets.at(i)->at(j);
428 428 if (temp < min)
429 429 min = temp;
430 430 }
431 431 }
432 432 return min;
433 433 }
434 434
435 435 qreal QAbstractBarSeriesPrivate::max()
436 436 {
437 437 if (m_barSets.count() <= 0) {
438 438 return 0;
439 439 }
440 440 qreal max = INT_MIN;
441 441
442 442 for (int i = 0; i < m_barSets.count(); i++) {
443 443 int categoryCount = m_barSets.at(i)->count();
444 444 for (int j = 0; j < categoryCount; j++) {
445 445 qreal temp = m_barSets.at(i)->at(j);
446 446 if (temp > max)
447 447 max = temp;
448 448 }
449 449 }
450 450
451 451 return max;
452 452 }
453 453
454 454 qreal QAbstractBarSeriesPrivate::valueAt(int set, int category)
455 455 {
456 456 if ((set < 0) || (set >= m_barSets.count())) {
457 457 // No set, no value.
458 458 return 0;
459 459 } else if ((category < 0) || (category >= m_barSets.at(set)->count())) {
460 460 // No category, no value.
461 461 return 0;
462 462 }
463 463
464 464 return m_barSets.at(set)->at(category);
465 465 }
466 466
467 467 qreal QAbstractBarSeriesPrivate::percentageAt(int set, int category)
468 468 {
469 469 if ((set < 0) || (set >= m_barSets.count())) {
470 470 // No set, no value.
471 471 return 0;
472 472 } else if ((category < 0) || (category >= m_barSets.at(set)->count())) {
473 473 // No category, no value.
474 474 return 0;
475 475 }
476 476
477 477 qreal value = m_barSets.at(set)->at(category);
478 478 qreal sum = categorySum(category);
479 479 if ( qFuzzyIsNull(sum) ) {
480 480 return 0;
481 481 }
482 482
483 483 return value / sum;
484 484 }
485 485
486 486 qreal QAbstractBarSeriesPrivate::categorySum(int category)
487 487 {
488 488 qreal sum(0);
489 489 int count = m_barSets.count(); // Count sets
490 490 for (int set = 0; set < count; set++) {
491 491 if (category < m_barSets.at(set)->count())
492 492 sum += m_barSets.at(set)->at(category);
493 493 }
494 494 return sum;
495 495 }
496 496
497 497 qreal QAbstractBarSeriesPrivate::absoluteCategorySum(int category)
498 498 {
499 499 qreal sum(0);
500 500 int count = m_barSets.count(); // Count sets
501 501 for (int set = 0; set < count; set++) {
502 502 if (category < m_barSets.at(set)->count())
503 503 sum += qAbs(m_barSets.at(set)->at(category));
504 504 }
505 505 return sum;
506 506 }
507 507
508 508 qreal QAbstractBarSeriesPrivate::maxCategorySum()
509 509 {
510 510 qreal max = INT_MIN;
511 511 int count = categoryCount();
512 512 for (int i = 0; i < count; i++) {
513 513 qreal sum = categorySum(i);
514 514 if (sum > max)
515 515 max = sum;
516 516 }
517 517 return max;
518 518 }
519 519
520 520 qreal QAbstractBarSeriesPrivate::minX()
521 521 {
522 522 if (m_barSets.count() <= 0) {
523 523 return 0;
524 524 }
525 525 qreal min = INT_MAX;
526 526
527 527 for (int i = 0; i < m_barSets.count(); i++) {
528 528 int categoryCount = m_barSets.at(i)->count();
529 529 for (int j = 0; j < categoryCount; j++) {
530 530 qreal temp = m_barSets.at(i)->d_ptr.data()->m_values.at(j).x();
531 531 if (temp < min)
532 532 min = temp;
533 533 }
534 534 }
535 535 return min;
536 536 }
537 537
538 538 qreal QAbstractBarSeriesPrivate::maxX()
539 539 {
540 540 if (m_barSets.count() <= 0) {
541 541 return 0;
542 542 }
543 543 qreal max = INT_MIN;
544 544
545 545 for (int i = 0; i < m_barSets.count(); i++) {
546 546 int categoryCount = m_barSets.at(i)->count();
547 547 for (int j = 0; j < categoryCount; j++) {
548 548 qreal temp = m_barSets.at(i)->d_ptr.data()->m_values.at(j).x();
549 549 if (temp > max)
550 550 max = temp;
551 551 }
552 552 }
553 553
554 554 return max;
555 555 }
556 556
557 557
558 558 void QAbstractBarSeriesPrivate::scaleDomain(Domain& domain)
559 559 {
560 560 qreal minX(domain.minX());
561 561 qreal minY(domain.minY());
562 562 qreal maxX(domain.maxX());
563 563 qreal maxY(domain.maxY());
564 int tickXCount(domain.tickXCount());
565 int tickYCount(domain.tickYCount());
566 564
567 565 qreal seriesMinX = this->minX();
568 566 qreal seriesMaxX = this->maxX();
569 567 qreal y = max();
570 568 minX = qMin(minX, seriesMinX - (qreal)0.5);
571 569 minY = qMin(minY, y);
572 570 maxX = qMax(maxX, seriesMaxX + (qreal)0.5);
573 571 maxY = qMax(maxY, y);
574 tickXCount = categoryCount()+1;
575 572
576 domain.setRange(minX,maxX,minY,maxY,tickXCount,tickYCount);
573 domain.setRange(minX,maxX,minY,maxY);
577 574 }
578 575
579 576 Chart* QAbstractBarSeriesPrivate::createGraphics(ChartPresenter* presenter)
580 577 {
581 578 Q_UNUSED(presenter);
582 579 qWarning() << "QAbstractBarSeriesPrivate::createGraphics called";
583 580 return 0;
584 581 }
585 582
586 583 QList<LegendMarker*> QAbstractBarSeriesPrivate::createLegendMarker(QLegend* legend)
587 584 {
588 585 Q_Q(QAbstractBarSeries);
589 586 QList<LegendMarker*> markers;
590 587 foreach(QBarSet* set, q->barSets()) {
591 588 BarLegendMarker* marker = new BarLegendMarker(q,set,legend);
592 589 markers << marker;
593 590 }
594 591
595 592 return markers;
596 593 }
597 594
598 595 bool QAbstractBarSeriesPrivate::append(QBarSet *set)
599 596 {
600 597 Q_Q(QAbstractBarSeries);
601 598 if ((m_barSets.contains(set)) || (set == 0)) {
602 599 // Fail if set is already in list or set is null.
603 600 return false;
604 601 }
605 602 m_barSets.append(set);
606 603 QObject::connect(set->d_ptr.data(), SIGNAL(updatedBars()), this, SIGNAL(updatedBars()));
607 604 QObject::connect(set->d_ptr.data(), SIGNAL(restructuredBars()), this, SIGNAL(restructuredBars()));
608 605 emit restructuredBars(); // this notifies barchartitem
609 606 if (m_dataset) {
610 607 m_dataset->updateSeries(q); // this notifies legend
611 608 }
612 609 return true;
613 610 }
614 611
615 612 bool QAbstractBarSeriesPrivate::remove(QBarSet *set)
616 613 {
617 614 Q_Q(QAbstractBarSeries);
618 615 if (!m_barSets.contains(set)) {
619 616 // Fail if set is not in list
620 617 return false;
621 618 }
622 619 m_barSets.removeOne(set);
623 620 QObject::disconnect(set->d_ptr.data(), SIGNAL(updatedBars()), this, SIGNAL(updatedBars()));
624 621 QObject::disconnect(set->d_ptr.data(), SIGNAL(restructuredBars()), this, SIGNAL(restructuredBars()));
625 622 emit restructuredBars(); // this notifies barchartitem
626 623 if (m_dataset) {
627 624 m_dataset->updateSeries(q); // this notifies legend
628 625 }
629 626 return true;
630 627 }
631 628
632 629 bool QAbstractBarSeriesPrivate::append(QList<QBarSet* > sets)
633 630 {
634 631 Q_Q(QAbstractBarSeries);
635 632 foreach (QBarSet* set, sets) {
636 633 if ((set == 0) || (m_barSets.contains(set))) {
637 634 // Fail if any of the sets is null or is already appended.
638 635 return false;
639 636 }
640 637 if (sets.count(set) != 1) {
641 638 // Also fail if same set is more than once in given list.
642 639 return false;
643 640 }
644 641 }
645 642
646 643 foreach (QBarSet* set, sets) {
647 644 m_barSets.append(set);
648 645 QObject::connect(set->d_ptr.data(), SIGNAL(updatedBars()), this, SIGNAL(updatedBars()));
649 646 QObject::connect(set->d_ptr.data(), SIGNAL(restructuredBars()), this, SIGNAL(restructuredBars()));
650 647 }
651 648 emit restructuredBars(); // this notifies barchartitem
652 649 if (m_dataset) {
653 650 m_dataset->updateSeries(q); // this notifies legend
654 651 }
655 652 return true;
656 653 }
657 654
658 655 bool QAbstractBarSeriesPrivate::remove(QList<QBarSet* > sets)
659 656 {
660 657 Q_Q(QAbstractBarSeries);
661 658 if (sets.count() == 0) {
662 659 return false;
663 660 }
664 661 foreach (QBarSet* set, sets) {
665 662 if ((set == 0) || (!m_barSets.contains(set))) {
666 663 // Fail if any of the sets is null or is not in series
667 664 return false;
668 665 }
669 666 if (sets.count(set) != 1) {
670 667 // Also fail if same set is more than once in given list.
671 668 return false;
672 669 }
673 670 }
674 671
675 672 foreach (QBarSet* set, sets) {
676 673 m_barSets.removeOne(set);
677 674 QObject::disconnect(set->d_ptr.data(), SIGNAL(updatedBars()), this, SIGNAL(updatedBars()));
678 675 QObject::disconnect(set->d_ptr.data(), SIGNAL(restructuredBars()), this, SIGNAL(restructuredBars()));
679 676 }
680 677
681 678 emit restructuredBars(); // this notifies barchartitem
682 679 if (m_dataset) {
683 680 m_dataset->updateSeries(q); // this notifies legend
684 681 }
685 682 return true;
686 683 }
687 684
688 685 bool QAbstractBarSeriesPrivate::insert(int index, QBarSet *set)
689 686 {
690 687 Q_Q(QAbstractBarSeries);
691 688 if ((m_barSets.contains(set)) || (set == 0)) {
692 689 // Fail if set is already in list or set is null.
693 690 return false;
694 691 }
695 692 m_barSets.insert(index, set);
696 693 QObject::connect(set->d_ptr.data(), SIGNAL(updatedBars()), this, SIGNAL(updatedBars()));
697 694 QObject::connect(set->d_ptr.data(), SIGNAL(restructuredBars()), this, SIGNAL(restructuredBars()));
698 695 emit restructuredBars(); // this notifies barchartitem
699 696 if (m_dataset) {
700 697 m_dataset->updateSeries(q); // this notifies legend
701 698 }
702 699 return true;
703 700 }
704 701
705 702 void QAbstractBarSeriesPrivate::initializeAxis(QAbstractAxis* axis)
706 703 {
707 704 if(axis->type()==QAbstractAxis::AxisTypeCategories && axis->orientation()==Qt::Horizontal)
708 705 {
709 706 QBarCategoriesAxis* cataxis = qobject_cast<QBarCategoriesAxis*>(axis);
710 707 Q_ASSERT(cataxis);
711 708 QStringList categories;
712 709 for (int i(1); i < categoryCount()+1; i++)
713 710 categories << QString::number(i);
714 711 cataxis->append(categories);
715 712 }
716 713 }
717 714
718 715 QAbstractAxis::AxisType QAbstractBarSeriesPrivate::defaultAxisType(Qt::Orientation orientation) const
719 716 {
720 717 Q_UNUSED(orientation);
721 718 return QAbstractAxis::AxisTypeNoAxis;
722 719 }
723 720
724 721
725 722 #include "moc_qabstractbarseries.cpp"
726 723 #include "moc_qabstractbarseries_p.cpp"
727 724
728 725
729 726 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,127 +1,124
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "qbarseries.h"
22 22 #include "qbarseries_p.h"
23 23 #include "barchartitem_p.h"
24 24 #include "chartdataset_p.h"
25 25 #include "charttheme_p.h"
26 26 #include "chartanimator_p.h"
27 27 #include "baranimation_p.h"
28 28 #include "qvaluesaxis.h"
29 29
30 30 QTCOMMERCIALCHART_BEGIN_NAMESPACE
31 31
32 32 /*!
33 33 \class QBarSeries
34 34 \brief Series for creating bar chart
35 35 \mainclass
36 36
37 37 QBarSeries represents a series of data shown as bars. The purpose of this class is to draw bars
38 38 as groups, where bars in same category are grouped next to each other. QBarSeries groups the data
39 39 from sets to categories, which are defined by a QStringList.
40 40
41 41 See the \l {BarChart Example} {bar chart example} to learn how to create a grouped bar chart.
42 42 \image examples_barchart.png
43 43
44 44 \sa QBarSet, QPercentBarSeries, QAbstractBarSeries, QStackedBarSeries
45 45 */
46 46 /*!
47 47 \qmlclass BarSeries QBarSeries
48 48 \inherits AbstractBarSeries
49 49
50 50 The following QML shows how to create a simple grouped bar chart:
51 51 \snippet ../demos/qmlchart/qml/qmlchart/View6.qml 1
52 52 \beginfloatleft
53 53 \image demos_qmlchart6.png
54 54 \endfloat
55 55 \clearfloat
56 56 */
57 57
58 58 /*!
59 59 Constructs empty QBarSeries.
60 60 QBarSeries is QObject which is a child of a \a parent.
61 61 */
62 62 QBarSeries::QBarSeries(QObject *parent)
63 63 : QAbstractBarSeries(*new QBarSeriesPrivate(this), parent)
64 64 {
65 65 }
66 66
67 67 /*!
68 68 Returns QChartSeries::SeriesTypeBar.
69 69 */
70 70 QAbstractSeries::SeriesType QBarSeries::type() const
71 71 {
72 72 return QAbstractSeries::SeriesTypeBar;
73 73 }
74 74
75 75 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
76 76
77 77 QBarSeriesPrivate::QBarSeriesPrivate(QBarSeries *q) : QAbstractBarSeriesPrivate(q)
78 78 {
79 79
80 80 }
81 81
82 82 void QBarSeriesPrivate::scaleDomain(Domain& domain)
83 83 {
84 84 qreal minX(domain.minX());
85 85 qreal minY(domain.minY());
86 86 qreal maxX(domain.maxX());
87 87 qreal maxY(domain.maxY());
88 int tickXCount(domain.tickXCount());
89 int tickYCount(domain.tickYCount());
90 88
91 89 qreal x = categoryCount();
92 90 qreal y = max();
93 91 minX = qMin(minX, - (qreal)0.5);
94 92 minY = qMin(minY, y);
95 93 maxX = qMax(maxX, x - (qreal)0.5);
96 94 maxY = qMax(maxY, y);
97 tickXCount = x+1;
98 95
99 domain.setRange(minX,maxX,minY,maxY,tickXCount,tickYCount);
96 domain.setRange(minX,maxX,minY,maxY);
100 97 }
101 98
102 99
103 100 Chart* QBarSeriesPrivate::createGraphics(ChartPresenter* presenter)
104 101 {
105 102 Q_Q(QBarSeries);
106 103
107 104 BarChartItem* bar = new BarChartItem(q,presenter);
108 105 if(presenter->animationOptions().testFlag(QChart::SeriesAnimations)) {
109 106 bar->setAnimator(presenter->animator());
110 107 bar->setAnimation(new BarAnimation(bar));
111 108 }
112 109 presenter->chartTheme()->decorate(q, presenter->dataSet()->seriesIndex(q));
113 110 return bar;
114 111 }
115 112
116 113 QAbstractAxis::AxisType QBarSeriesPrivate::defaultAxisType(Qt::Orientation orientation) const
117 114 {
118 115 if(orientation==Qt::Horizontal)
119 116 return QAbstractAxis::AxisTypeCategories;
120 117 else
121 118 return QAbstractAxis::AxisTypeValues;
122 119 }
123 120
124 121 #include "moc_qbarseries.cpp"
125 122
126 123 QTCOMMERCIALCHART_END_NAMESPACE
127 124
@@ -1,90 +1,87
1 1 #include "qhorizontalbarseries.h"
2 2 #include "qhorizontalbarseries_p.h"
3 3 #include "horizontalbarchartitem_p.h"
4 4 #include "horizontalbaranimation_p.h"
5 5 #include "qbarcategoriesaxis.h"
6 6
7 7 #include "chartdataset_p.h"
8 8 #include "charttheme_p.h"
9 9
10 10
11 11 QTCOMMERCIALCHART_BEGIN_NAMESPACE
12 12
13 13 QHorizontalBarSeries::QHorizontalBarSeries(QObject *parent) :
14 14 QAbstractBarSeries(*new QHorizontalBarSeriesPrivate(this), parent)
15 15 {
16 16 }
17 17
18 18 QAbstractSeries::SeriesType QHorizontalBarSeries::type() const
19 19 {
20 20 return QAbstractSeries::SeriesTypeHorizontalBar;
21 21 }
22 22
23 23
24 24
25 25 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
26 26
27 27 QHorizontalBarSeriesPrivate::QHorizontalBarSeriesPrivate(QHorizontalBarSeries *q) : QAbstractBarSeriesPrivate(q)
28 28 {
29 29
30 30 }
31 31
32 32 void QHorizontalBarSeriesPrivate::scaleDomain(Domain& domain)
33 33 {
34 34 qreal minX(domain.minX());
35 35 qreal minY(domain.minY());
36 36 qreal maxX(domain.maxX());
37 37 qreal maxY(domain.maxY());
38 int tickXCount(domain.tickXCount());
39 int tickYCount(domain.tickYCount());
40 38
41 39 qreal y = categoryCount();
42 40 qreal x = max();
43 41 minX = qMin(minX, x);
44 42 minY = qMin(minY, - (qreal)0.5);
45 43 maxX = qMax(maxX, x);
46 44 maxY = qMax(maxY, y - (qreal)0.5);
47 tickYCount = y+1;
48 45
49 domain.setRange(minX,maxX,minY,maxY,tickXCount,tickYCount);
46 domain.setRange(minX,maxX,minY,maxY);
50 47 }
51 48
52 49
53 50 Chart* QHorizontalBarSeriesPrivate::createGraphics(ChartPresenter* presenter)
54 51 {
55 52 Q_Q(QHorizontalBarSeries);
56 53
57 54 HorizontalBarChartItem* bar = new HorizontalBarChartItem(q,presenter);
58 55 if(presenter->animationOptions().testFlag(QChart::SeriesAnimations)) {
59 56 bar->setAnimator(presenter->animator());
60 57 bar->setAnimation(new HorizontalBarAnimation(bar));
61 58 }
62 59 presenter->chartTheme()->decorate(q, presenter->dataSet()->seriesIndex(q));
63 60 return bar;
64 61 }
65 62
66 63 void QHorizontalBarSeriesPrivate::initializeAxis(QAbstractAxis* axis)
67 64 {
68 65
69 66 if(axis->type()==QAbstractAxis::AxisTypeCategories && axis->orientation()==Qt::Vertical)
70 67 {
71 68 QBarCategoriesAxis* cataxis = qobject_cast<QBarCategoriesAxis*>(axis);
72 69 Q_ASSERT(cataxis);
73 70 QStringList categories;
74 71 for (int i(1); i < categoryCount()+1; i++)
75 72 categories << QString::number(i);
76 73 cataxis->append(categories);
77 74 }
78 75 }
79 76
80 77 QAbstractAxis::AxisType QHorizontalBarSeriesPrivate::defaultAxisType(Qt::Orientation orientation) const
81 78 {
82 79 if(orientation==Qt::Vertical)
83 80 return QAbstractAxis::AxisTypeCategories;
84 81 else
85 82 return QAbstractAxis::AxisTypeValues;
86 83 }
87 84
88 85 #include "moc_qhorizontalbarseries.cpp"
89 86
90 87 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,75 +1,72
1 1 #include "qhorizontalpercentbarseries.h"
2 2 #include "qhorizontalpercentbarseries_p.h"
3 3 #include "horizontalpercentbarchartitem_p.h"
4 4 #include "horizontalpercentbaranimation_p.h"
5 5
6 6 #include "chartdataset_p.h"
7 7 #include "charttheme_p.h"
8 8
9 9 QTCOMMERCIALCHART_BEGIN_NAMESPACE
10 10
11 11 QHorizontalPercentBarSeries::QHorizontalPercentBarSeries(QObject *parent) :
12 12 QAbstractBarSeries(*new QHorizontalPercentBarSeriesPrivate(this), parent)
13 13 {
14 14 }
15 15
16 16 QAbstractSeries::SeriesType QHorizontalPercentBarSeries::type() const
17 17 {
18 18 return QAbstractSeries::SeriesTypeHorizontalPercentBar;
19 19 }
20 20
21 21
22 22
23 23 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
24 24
25 25 QHorizontalPercentBarSeriesPrivate::QHorizontalPercentBarSeriesPrivate(QHorizontalPercentBarSeries *q) : QAbstractBarSeriesPrivate(q)
26 26 {
27 27
28 28 }
29 29
30 30 void QHorizontalPercentBarSeriesPrivate::scaleDomain(Domain& domain)
31 31 {
32 32 qreal minX(domain.minX());
33 33 qreal minY(domain.minY());
34 34 qreal maxX(domain.maxX());
35 35 qreal maxY(domain.maxY());
36 int tickXCount(domain.tickXCount());
37 int tickYCount(domain.tickYCount());
38 36
39 37 qreal y = categoryCount();
40 38 minX = 0;
41 39 maxX = 100;
42 40 minY = qMin(minY, - (qreal)0.5);
43 41 maxY = qMax(maxY, y - (qreal)0.5);
44 tickYCount = y+1;
45 42
46 domain.setRange(minX,maxX,minY,maxY,tickXCount,tickYCount);
43 domain.setRange(minX,maxX,minY,maxY);
47 44 }
48 45
49 46 Chart* QHorizontalPercentBarSeriesPrivate::createGraphics(ChartPresenter* presenter)
50 47 {
51 48 Q_Q(QHorizontalPercentBarSeries);
52 49
53 50 HorizontalPercentBarChartItem* bar = new HorizontalPercentBarChartItem(q,presenter);
54 51 if(presenter->animationOptions().testFlag(QChart::SeriesAnimations)) {
55 52 bar->setAnimator(presenter->animator());
56 53 bar->setAnimation(new HorizontalPercentBarAnimation(bar));
57 54 }
58 55 presenter->chartTheme()->decorate(q, presenter->dataSet()->seriesIndex(q));
59 56 return bar;
60 57 }
61 58
62 59 QAbstractAxis::AxisType QHorizontalPercentBarSeriesPrivate::defaultAxisXType() const
63 60 {
64 61 return QAbstractAxis::AxisTypeValues;
65 62 }
66 63
67 64 QAbstractAxis::AxisType QHorizontalPercentBarSeriesPrivate::defaultAxisYType() const
68 65 {
69 66 return QAbstractAxis::AxisTypeCategories;
70 67 }
71 68
72 69
73 70 #include "moc_qhorizontalpercentbarseries.cpp"
74 71
75 72 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,76 +1,73
1 1 #include "qhorizontalstackedbarseries.h"
2 2 #include "qhorizontalstackedbarseries_p.h"
3 3 #include "horizontalstackedbarchartitem_p.h"
4 4 #include "horizontalstackedbaranimation_p.h"
5 5
6 6 #include "chartdataset_p.h"
7 7 #include "charttheme_p.h"
8 8
9 9 QTCOMMERCIALCHART_BEGIN_NAMESPACE
10 10
11 11 QHorizontalStackedBarSeries::QHorizontalStackedBarSeries(QObject *parent) :
12 12 QAbstractBarSeries(*new QHorizontalStackedBarSeriesPrivate(this), parent)
13 13 {
14 14 }
15 15
16 16 QAbstractSeries::SeriesType QHorizontalStackedBarSeries::type() const
17 17 {
18 18 return QAbstractSeries::SeriesTypeHorizontalStackedBar;
19 19 }
20 20
21 21
22 22
23 23 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
24 24
25 25 QHorizontalStackedBarSeriesPrivate::QHorizontalStackedBarSeriesPrivate(QHorizontalStackedBarSeries *q) : QAbstractBarSeriesPrivate(q)
26 26 {
27 27
28 28 }
29 29
30 30 void QHorizontalStackedBarSeriesPrivate::scaleDomain(Domain& domain)
31 31 {
32 32 qreal minX(domain.minX());
33 33 qreal minY(domain.minY());
34 34 qreal maxX(domain.maxX());
35 35 qreal maxY(domain.maxY());
36 int tickXCount(domain.tickXCount());
37 int tickYCount(domain.tickYCount());
38 36
39 37 qreal y = categoryCount();
40 38 qreal x = maxCategorySum();
41 39 minX = qMin(minX, x);
42 40 minY = qMin(minY, - (qreal)0.5);
43 41 maxX = qMax(maxX, x);
44 42 maxY = qMax(maxY, y - (qreal)0.5);
45 tickYCount = y+1;
46 43
47 domain.setRange(minX,maxX,minY,maxY,tickXCount,tickYCount);
44 domain.setRange(minX,maxX,minY,maxY);
48 45 }
49 46
50 47 Chart* QHorizontalStackedBarSeriesPrivate::createGraphics(ChartPresenter* presenter)
51 48 {
52 49 Q_Q(QHorizontalStackedBarSeries);
53 50
54 51 HorizontalStackedBarChartItem* bar = new HorizontalStackedBarChartItem(q,presenter);
55 52 if(presenter->animationOptions().testFlag(QChart::SeriesAnimations)) {
56 53 bar->setAnimator(presenter->animator());
57 54 bar->setAnimation(new HorizontalStackedBarAnimation(bar));
58 55 }
59 56 presenter->chartTheme()->decorate(q, presenter->dataSet()->seriesIndex(q));
60 57 return bar;
61 58 }
62 59
63 60 QAbstractAxis::AxisType QHorizontalStackedBarSeriesPrivate::defaultAxisXType() const
64 61 {
65 62 return QAbstractAxis::AxisTypeValues;
66 63 }
67 64
68 65 QAbstractAxis::AxisType QHorizontalStackedBarSeriesPrivate::defaultAxisYType() const
69 66 {
70 67 return QAbstractAxis::AxisTypeCategories;
71 68 }
72 69
73 70
74 71 #include "moc_qhorizontalstackedbarseries.cpp"
75 72
76 73 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,127 +1,124
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "qpercentbarseries.h"
22 22 #include "qpercentbarseries_p.h"
23 23 #include "percentbarchartitem_p.h"
24 24 #include "chartdataset_p.h"
25 25 #include "charttheme_p.h"
26 26 #include "chartanimator_p.h"
27 27 #include "qvaluesaxis.h"
28 28 #include "percentbaranimation_p.h"
29 29
30 30 QTCOMMERCIALCHART_BEGIN_NAMESPACE
31 31
32 32 /*!
33 33 \class QPercentBarSeries
34 34 \brief Series for creating percent bar chart
35 35 \mainclass
36 36
37 37 QPercentBarSeries represents a series of data shown as bars. The purpose of this class is to draw bars
38 38 as stacks, where each bar is shown as percentage of all bars in that category.
39 39 QPercentBarSeries groups the data from sets to categories, which are defined by a QStringList.
40 40
41 41 See the \l {PercentbarChart Example} {percent bar chart example} to learn how to create a percent bar chart.
42 42 \image examples_percentbarchart.png
43 43
44 44 \sa QBarSet, QStackedBarSeries, QAbstractBarSeries
45 45 */
46 46 /*!
47 47 \qmlclass PercentBarSeries QPercentBarSeries
48 48 \inherits QAbstractBarSeries
49 49
50 50 The following QML shows how to create a simple percent bar chart:
51 51 \snippet ../demos/qmlchart/qml/qmlchart/View8.qml 1
52 52 \beginfloatleft
53 53 \image demos_qmlchart8.png
54 54 \endfloat
55 55 \clearfloat
56 56 */
57 57
58 58 /*!
59 59 Constructs empty QPercentBarSeries.
60 60 QPercentBarSeries is QObject which is a child of a \a parent.
61 61 */
62 62 QPercentBarSeries::QPercentBarSeries(QObject *parent)
63 63 : QAbstractBarSeries(*new QPercentBarSeriesPrivate(this), parent)
64 64 {
65 65 }
66 66
67 67 /*!
68 68 Returns QChartSeries::SeriesTypePercentBar.
69 69 */
70 70 QAbstractSeries::SeriesType QPercentBarSeries::type() const
71 71 {
72 72 return QAbstractSeries::SeriesTypePercentBar;
73 73 }
74 74
75 75 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
76 76
77 77 QPercentBarSeriesPrivate::QPercentBarSeriesPrivate(QPercentBarSeries *q) : QAbstractBarSeriesPrivate(q)
78 78 {
79 79
80 80 }
81 81
82 82 void QPercentBarSeriesPrivate::scaleDomain(Domain& domain)
83 83 {
84 84 qreal minX(domain.minX());
85 85 qreal minY(domain.minY());
86 86 qreal maxX(domain.maxX());
87 87 qreal maxY(domain.maxY());
88 int tickXCount(domain.tickXCount());
89 int tickYCount(domain.tickYCount());
90 88
91 89 qreal x = categoryCount();
92 90 minX = qMin(minX, - (qreal)0.5);
93 91 maxX = qMax(maxX, x - (qreal)0.5);
94 92 minY = 0;
95 93 maxY = 100;
96 tickXCount = x+1;
97 94
98 domain.setRange(minX,maxX,minY,maxY,tickXCount,tickYCount);
95 domain.setRange(minX,maxX,minY,maxY);
99 96 }
100 97
101 98
102 99 Chart* QPercentBarSeriesPrivate::createGraphics(ChartPresenter* presenter)
103 100 {
104 101 Q_Q(QPercentBarSeries);
105 102
106 103 PercentBarChartItem* bar = new PercentBarChartItem(q,presenter);
107 104 if(presenter->animationOptions().testFlag(QChart::SeriesAnimations)) {
108 105 bar->setAnimator(presenter->animator());
109 106 bar->setAnimation(new PercentBarAnimation(bar));
110 107 }
111 108 presenter->chartTheme()->decorate(q, presenter->dataSet()->seriesIndex(q));
112 109 return bar;
113 110 }
114 111
115 112 QAbstractAxis::AxisType QPercentBarSeriesPrivate::defaultAxisType(Qt::Orientation orientation) const
116 113 {
117 114 if(orientation==Qt::Horizontal)
118 115 return QAbstractAxis::AxisTypeCategories;
119 116 else
120 117 return QAbstractAxis::AxisTypeValues;
121 118 }
122 119
123 120
124 121 #include "moc_qpercentbarseries.cpp"
125 122
126 123 QTCOMMERCIALCHART_END_NAMESPACE
127 124
@@ -1,129 +1,126
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "qstackedbarseries.h"
22 22 #include "qstackedbarseries_p.h"
23 23 #include "stackedbarchartitem_p.h"
24 24 #include "chartdataset_p.h"
25 25 #include "charttheme_p.h"
26 26 #include "chartanimator_p.h"
27 27 #include "qvaluesaxis.h"
28 28 #include "stackedbaranimation_p.h"
29 29
30 30 QTCOMMERCIALCHART_BEGIN_NAMESPACE
31 31
32 32 /*!
33 33 \class QStackedBarSeries
34 34 \brief Series for creating stacked bar chart
35 35 \mainclass
36 36
37 37 QStackedBarSeries represents a series of data shown as bars. The purpose of this class is to draw bars
38 38 as stacks, where bars in same category are stacked on top of each other.
39 39 QStackedBarSeries groups the data from sets to categories, which are defined by QStringList.
40 40
41 41 See the \l {StackedbarChart Example} {stacked bar chart example} to learn how to create a stacked bar chart.
42 42 \image examples_stackedbarchart.png
43 43
44 44 \sa QBarSet, QPercentBarSeries, QAbstractBarSeries
45 45 */
46 46
47 47 /*!
48 48 \qmlclass StackedBarSeries QStackedBarSeries
49 49 \inherits AbstractBarSeries
50 50
51 51 The following QML shows how to create a simple stacked bar chart:
52 52 \snippet ../demos/qmlchart/qml/qmlchart/View7.qml 1
53 53 \beginfloatleft
54 54 \image demos_qmlchart7.png
55 55 \endfloat
56 56 \clearfloat
57 57 */
58 58
59 59 /*!
60 60 Constructs empty QStackedBarSeries.
61 61 QStackedBarSeries is QObject which is a child of a \a parent.
62 62 */
63 63 QStackedBarSeries::QStackedBarSeries(QObject *parent)
64 64 : QAbstractBarSeries(*new QStackedBarSeriesPrivate(this), parent)
65 65 {
66 66 }
67 67
68 68 /*!
69 69 Returns QChartSeries::SeriesTypeStackedBar.
70 70 */
71 71 QAbstractSeries::SeriesType QStackedBarSeries::type() const
72 72 {
73 73 return QAbstractSeries::SeriesTypeStackedBar;
74 74 }
75 75
76 76 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
77 77
78 78 QStackedBarSeriesPrivate::QStackedBarSeriesPrivate(QStackedBarSeries *q) : QAbstractBarSeriesPrivate(q)
79 79 {
80 80
81 81 }
82 82
83 83 void QStackedBarSeriesPrivate::scaleDomain(Domain& domain)
84 84 {
85 85 qreal minX(domain.minX());
86 86 qreal minY(domain.minY());
87 87 qreal maxX(domain.maxX());
88 88 qreal maxY(domain.maxY());
89 int tickXCount(domain.tickXCount());
90 int tickYCount(domain.tickYCount());
91 89
92 90 qreal x = categoryCount();
93 91 qreal y = maxCategorySum();
94 92 minX = qMin(minX, - (qreal)0.5);
95 93 minY = qMin(minY, y);
96 94 maxX = qMax(maxX, x - (qreal)0.5);
97 95 maxY = qMax(maxY, y);
98 tickXCount = x+1;
99 96
100 domain.setRange(minX,maxX,minY,maxY,tickXCount,tickYCount);
97 domain.setRange(minX,maxX,minY,maxY);
101 98 }
102 99
103 100
104 101 Chart* QStackedBarSeriesPrivate::createGraphics(ChartPresenter* presenter)
105 102 {
106 103 Q_Q(QStackedBarSeries);
107 104
108 105 StackedBarChartItem* bar = new StackedBarChartItem(q,presenter);
109 106 if(presenter->animationOptions().testFlag(QChart::SeriesAnimations)) {
110 107 bar->setAnimator(presenter->animator());
111 108 bar->setAnimation(new StackedBarAnimation(bar));
112 109 }
113 110 presenter->chartTheme()->decorate(q, presenter->dataSet()->seriesIndex(q));
114 111 return bar;
115 112 }
116 113
117 114 QAbstractAxis::AxisType QStackedBarSeriesPrivate::defaultAxisType(Qt::Orientation orientation) const
118 115 {
119 116 if(orientation==Qt::Horizontal)
120 117 return QAbstractAxis::AxisTypeCategories;
121 118 else
122 119 return QAbstractAxis::AxisTypeValues;
123 120 }
124 121
125 122
126 123 #include "moc_qstackedbarseries.cpp"
127 124
128 125 QTCOMMERCIALCHART_END_NAMESPACE
129 126
@@ -1,82 +1,88
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "chart_p.h"
22 22 #include "chartpresenter_p.h"
23 23 #include "domain_p.h"
24 24
25 25 QTCOMMERCIALCHART_BEGIN_NAMESPACE
26 26
27 27 Chart::Chart(ChartPresenter *presenter):QObject(presenter),
28 28 m_animator(0),
29 29 m_presenter(presenter),
30 30 m_domain(0)
31 31 {
32 32 }
33 33
34 34 void Chart::setAnimator(ChartAnimator* animator)
35 35 {
36 36 m_animator=animator;
37 37 }
38 38
39 39 ChartAnimator* Chart::animator() const
40 40 {
41 41 return m_animator;
42 42 }
43 43
44 44
45 45 void Chart::setPresenter(ChartPresenter *presenter)
46 46 {
47 47 m_presenter=presenter;
48 48 }
49 49
50 50 ChartPresenter* Chart::presenter() const
51 51 {
52 52 return m_presenter;
53 53 }
54 54
55 55 void Chart::setDomain(Domain *domain)
56 56 {
57 57 m_domain=domain;
58 58 }
59 59
60 60 Domain* Chart::domain() const
61 61 {
62 62 return m_domain;
63 63 }
64 64
65 65 void Chart::handleGeometryChanged(const QRectF& rect)
66 66 {
67 67 Q_UNUSED(rect);
68 68 qWarning()<<"Slot not implemented";
69 69 }
70 70
71 71 void Chart::handleDomainChanged(qreal minX,qreal maxX,qreal minY,qreal maxY)
72 72 {
73 73 Q_UNUSED(minX);
74 74 Q_UNUSED(maxX);
75 75 Q_UNUSED(minY);
76 76 Q_UNUSED(maxY);
77 77 qWarning()<<"Slot not implemented";
78 78 }
79 79
80 void Chart::handleDomainUpdated()
81 {
82 qWarning()<<"Slot not implemented";
83 }
84
85
80 86 #include "moc_chart_p.cpp"
81 87
82 88 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,70 +1,71
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 // W A R N I N G
22 22 // -------------
23 23 //
24 24 // This file is not part of the QtCommercial Chart API. It exists purely as an
25 25 // implementation detail. This header file may change from version to
26 26 // version without notice, or even be removed.
27 27 //
28 28 // We mean it.
29 29
30 30 #ifndef CHART_H
31 31 #define CHART_H
32 32
33 33 #include "qchartglobal.h"
34 34 #include <QObject>
35 35 #include <QRect>
36 36
37 37 QTCOMMERCIALCHART_BEGIN_NAMESPACE
38 38
39 39 class ChartAnimator;
40 40 class ChartPresenter;
41 41 class ChartAnimation;
42 42 class Domain;
43 43
44 44 class Chart: public QObject
45 45 {
46 46 Q_OBJECT
47 47 public:
48 48 explicit Chart(ChartPresenter *presenter);
49 49
50 50 public Q_SLOTS:
51 51 virtual void handleGeometryChanged(const QRectF& rect);
52 52 virtual void handleDomainChanged(qreal minX,qreal maxX,qreal minY,qreal maxY);
53 virtual void handleDomainUpdated();
53 54
54 55 void setAnimator(ChartAnimator* animator);
55 56 ChartAnimator* animator() const;
56 57 void setPresenter(ChartPresenter *presenter);
57 58 ChartPresenter* presenter() const;
58 59 void setDomain(Domain *domain);
59 60 Domain* domain() const;
60 61 virtual ChartAnimation* animation() const { return 0; };
61 62
62 63 private:
63 64 ChartAnimator* m_animator;
64 65 ChartPresenter* m_presenter;
65 66 Domain* m_domain;
66 67 };
67 68
68 69 QTCOMMERCIALCHART_END_NAMESPACE
69 70
70 71 #endif
@@ -1,429 +1,429
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "chartdataset_p.h"
22 22 #include "qchart.h"
23 23 #include "qvaluesaxis.h"
24 24 #include "qbarcategoriesaxis.h"
25 25 #include "qvaluesaxis_p.h"
26 26 #include "qabstractseries_p.h"
27 27 #include "qabstractbarseries.h"
28 28 #include "qstackedbarseries.h"
29 29 #include "qpercentbarseries.h"
30 30 #include "qpieseries.h"
31 31
32 32 QTCOMMERCIALCHART_BEGIN_NAMESPACE
33 33
34 34 ChartDataSet::ChartDataSet(QChart *parent):QObject(parent)
35 35 {
36 36
37 37 }
38 38
39 39 ChartDataSet::~ChartDataSet()
40 40 {
41 41 removeAllSeries();
42 42 }
43 43
44 44 void ChartDataSet::addSeries(QAbstractSeries* series)
45 45 {
46 46 Domain* domain = m_seriesDomainMap.value(series);
47 47
48 48 if(domain) {
49 49 qWarning() << "Can not add series. Series already on the chart";
50 50 return;
51 51 }
52 52
53 53 domain = new Domain(series);
54 54 m_seriesDomainMap.insert(series,domain);
55 55 series->d_ptr->scaleDomain(*domain);
56 56
57 57 createSeriesIndex(series);
58 58
59 59 series->setParent(this); // take ownership
60 60 series->d_ptr->m_chart = qobject_cast<QChart*>(parent());
61 61 series->d_ptr->m_dataset = this;
62 62
63 63 emit seriesAdded(series,domain);
64 64
65 65 }
66 66
67 67 void ChartDataSet::removeSeries(QAbstractSeries* series)
68 68 {
69 69
70 70 if(!m_seriesDomainMap.contains(series)) {
71 71 qWarning()<<"Can not remove series. Series not found on the chart.";
72 72 return;
73 73 }
74 74
75 75 emit seriesRemoved(series);
76 76
77 77 Domain* domain = m_seriesDomainMap.take(series);
78 78 delete domain;
79 79 domain = 0;
80 80
81 81 removeSeriesIndex(series);
82 82
83 83 series->setParent(0);
84 84 series->d_ptr->m_chart = 0;
85 85 series->d_ptr->m_dataset = 0;
86 86
87 87 removeAxes(series);
88 88 }
89 89
90 90
91 91
92 92 void ChartDataSet::createSeriesIndex(QAbstractSeries* series)
93 93 {
94 94 QMapIterator<int, QAbstractSeries*> i(m_indexSeriesMap);
95 95
96 96 int key=0;
97 97 while (i.hasNext()) {
98 98 i.next();
99 99 if(i.key()!=key) {
100 100 break;
101 101 }
102 102 key++;
103 103 }
104 104
105 105 m_indexSeriesMap.insert(key,series);
106 106 }
107 107
108 108 void ChartDataSet::removeSeriesIndex(QAbstractSeries* series)
109 109 {
110 110 int key = seriesIndex(series);
111 111 Q_ASSERT(key!=-1);
112 112 m_indexSeriesMap.remove(key);
113 113 }
114 114
115 115 void ChartDataSet::createDefaultAxes()
116 116 {
117 117
118 118 if(m_seriesDomainMap.isEmpty()) return;
119 119
120 120 QAbstractAxis::AxisTypes typeX(0);
121 121 QAbstractAxis::AxisTypes typeY(0);
122 122
123 123 QMapIterator<QAbstractSeries*, Domain*> i(m_seriesDomainMap);
124 124 while (i.hasNext()) {
125 125 i.next();
126 126 removeAxes(i.key());
127 127 }
128 128
129 129 i.toFront();
130 130
131 131 while (i.hasNext()) {
132 132 i.next();
133 133 QAbstractAxis* axisX = m_seriesAxisXMap.value(i.key());
134 134 QAbstractAxis* axisY = m_seriesAxisYMap.value(i.key());
135 135 if(axisX) typeX&=axisX->type();
136 136 else typeX|=i.key()->d_ptr->defaultAxisType(Qt::Horizontal);
137 137 if(axisY) typeY&=axisY->type();
138 138 else typeY|=i.key()->d_ptr->defaultAxisType(Qt::Vertical);
139 139 }
140 140
141 141 createAxes(typeX,Qt::Horizontal);
142 142 createAxes(typeY,Qt::Vertical);
143 143 }
144 144
145 145 void ChartDataSet::createAxes(QAbstractAxis::AxisTypes type,Qt::Orientation orientation)
146 146 {
147 147 QMapIterator<QAbstractSeries*, Domain*> i(m_seriesDomainMap);
148 148
149 149 if(type.testFlag(QAbstractAxis::AxisTypeValues) && type.testFlag(QAbstractAxis::AxisTypeCategories))
150 150 {
151 151 while (i.hasNext()) {
152 152 i.next();
153 153 QAbstractAxis* axis = createAxis(i.key()->d_ptr->defaultAxisType(orientation),orientation);
154 154 if(!axis) continue;
155 155 initializeAxis(axis,i.key());
156 156 emit axisAdded(axis,i.value());
157 157 }
158 158
159 159 }
160 160 else if(!type.testFlag(QAbstractAxis::AxisTypeNoAxis)) {
161 161 QAbstractAxis* axis = createAxis(QAbstractAxis::AxisType(int(type)),orientation);
162 162 i.toFront();
163 163 while (i.hasNext()) {
164 164 i.next();
165 165 initializeAxis(axis,i.key());
166 166 }
167 167 emit axisAdded(axis,i.value());
168 168 }
169 169 }
170 170
171 171
172 172 QAbstractAxis* ChartDataSet::createAxis(QAbstractAxis::AxisType type,Qt::Orientation orientation)
173 173 {
174 174 QAbstractAxis* axis =0;
175 175
176 176 switch(type) {
177 177 case QAbstractAxis::AxisTypeValues:
178 178 axis = new QValuesAxis(this);
179 179 break;
180 180 case QAbstractAxis::AxisTypeCategories:
181 181 axis = new QBarCategoriesAxis(this);
182 182 break;
183 183 default:
184 184 axis = 0;
185 185 break;
186 186 }
187 187
188 188 if(axis)
189 axis->d_ptr->m_orientation=orientation;
189 axis->d_ptr->setOrientation(orientation);
190 190
191 191 return axis;
192 192 }
193 193
194 194 void ChartDataSet::initializeAxis(QAbstractAxis* axis,QAbstractSeries* series)
195 195 {
196 196 Domain* domain = m_seriesDomainMap.value(series);
197 197 axis->d_ptr->intializeDomain(domain);
198 198 series->d_ptr->initializeAxis(axis);
199 199 if(axis->orientation()==Qt::Horizontal) {
200 QObject::connect(axis->d_ptr.data(),SIGNAL(changed(qreal,qreal,int,bool)),domain,SLOT(handleAxisXChanged(qreal,qreal,int,bool)));
201 QObject::connect(domain,SIGNAL(rangeXChanged(qreal,qreal,int)),axis->d_ptr.data(),SLOT(handleAxisRangeChanged(qreal,qreal,int)));
200 QObject::connect(axis->d_ptr.data(),SIGNAL(updated()),domain,SLOT(handleAxisUpdated()));
201 QObject::connect(domain,SIGNAL(updated()),axis->d_ptr.data(),SLOT(handleDomainUpdated()));
202 202 m_seriesAxisXMap.insert(series,axis);
203 203 }
204 204 else {
205 QObject::connect(axis->d_ptr.data(),SIGNAL(changed(qreal,qreal,int,bool)),domain,SLOT(handleAxisYChanged(qreal,qreal,int,bool)));
206 QObject::connect(domain,SIGNAL(rangeYChanged(qreal,qreal,int)),axis->d_ptr.data(),SLOT(handleAxisRangeChanged(qreal,qreal,int)));
205 QObject::connect(axis->d_ptr.data(),SIGNAL(updated()),domain,SLOT(handleAxisUpdated()));
206 QObject::connect(domain,SIGNAL(updated()),axis->d_ptr.data(),SLOT(handleDomainUpdated()));
207 207 m_seriesAxisYMap.insert(series,axis);
208 208 }
209 axis->d_ptr->emitRange();
209 axis->d_ptr->emitUpdated();
210 210 }
211 211
212 212 void ChartDataSet::removeAxes(QAbstractSeries* series)
213 213 {
214 214 QAbstractAxis* axisX = m_seriesAxisXMap.take(series);
215 215
216 216 if(axisX) {
217 217 QList<QAbstractAxis*> axesX = m_seriesAxisXMap.values();
218 218 int x = axesX.indexOf(axisX);
219 219
220 220 if(x==-1) {
221 221 emit axisRemoved(axisX);
222 222 axisX->deleteLater();
223 223 }
224 224 }
225 225
226 226 QAbstractAxis* axisY = m_seriesAxisYMap.take(series);
227 227
228 228 if(axisY) {
229 229 QList<QAbstractAxis*> axesY = m_seriesAxisYMap.values();
230 230
231 231 int y = axesY.indexOf(axisY);
232 232
233 233 if(y==-1) {
234 234 emit axisRemoved(axisY);
235 235 axisY->deleteLater();
236 236 }
237 237 }
238 238 }
239 239
240 240 void ChartDataSet::removeAllSeries()
241 241 {
242 242 QList<QAbstractSeries*> series = m_seriesDomainMap.keys();
243 243 foreach(QAbstractSeries *s , series) {
244 244 removeSeries(s);
245 245 }
246 246
247 247 Q_ASSERT(m_seriesAxisXMap.count()==0);
248 248 Q_ASSERT(m_seriesAxisXMap.count()==0);
249 249 Q_ASSERT(m_seriesDomainMap.count()==0);
250 250
251 251 qDeleteAll(series);
252 252 }
253 253
254 254 void ChartDataSet::zoomInDomain(const QRectF& rect, const QSizeF& size)
255 255 {
256 256 //for performance reasons block, signals and scale "full" domain one by one. Gives twice less screen updates
257 257
258 258
259 259 blockAxisSignals(true);
260 260
261 261 QMapIterator<QAbstractSeries*, Domain*> i(m_seriesDomainMap);
262 262
263 263 while (i.hasNext()) {
264 264 i.next();
265 265 i.value()->zoomIn(rect,size);
266 266 }
267 267
268 268 blockAxisSignals(false);
269 269
270 270 }
271 271
272 272 void ChartDataSet::zoomOutDomain(const QRectF& rect, const QSizeF& size)
273 273 {
274 274 //for performance reasons block, signals and scale "full" domain one by one. Gives twice less screen updates
275 275
276 276 blockAxisSignals(true);
277 277
278 278 QMapIterator<QAbstractSeries*, Domain*> i(m_seriesDomainMap);
279 279
280 280 while (i.hasNext()) {
281 281 i.next();
282 282 i.value()->zoomOut(rect,size);
283 283 }
284 284
285 285 blockAxisSignals(false);
286 286 }
287 287
288 288 void ChartDataSet::blockAxisSignals(bool enabled)
289 289 {
290 290 QMapIterator<QAbstractSeries*, Domain*> i(m_seriesDomainMap);
291 291 while (i.hasNext()) {
292 292 i.next();
293 293 QAbstractAxis* axisX = m_seriesAxisXMap.value(i.key());
294 294 QAbstractAxis* axisY = m_seriesAxisYMap.value(i.key());
295 295 if(axisX) axisX->d_ptr->blockSignals(enabled);
296 296 if(axisY) axisY->d_ptr->blockSignals(enabled);
297 297 }
298 298 }
299 299
300 300 int ChartDataSet::seriesCount(QAbstractSeries::SeriesType type)
301 301 {
302 302 int count=0;
303 303 QMapIterator<QAbstractSeries*, Domain*> i(m_seriesDomainMap);
304 304 while (i.hasNext()) {
305 305 i.next();
306 306 if(i.key()->type()==type) count++;
307 307 }
308 308 return count;
309 309 }
310 310
311 311 int ChartDataSet::seriesIndex(QAbstractSeries *series)
312 312 {
313 313 QMapIterator<int, QAbstractSeries*> i(m_indexSeriesMap);
314 314 while (i.hasNext()) {
315 315 i.next();
316 316 if (i.value() == series)
317 317 return i.key();
318 318 }
319 319 return -1;
320 320 }
321 321
322 322 QAbstractAxis* ChartDataSet::axisX(QAbstractSeries *series) const
323 323 {
324 324 if(series == 0) {
325 325
326 326 QMapIterator<QAbstractSeries*, QAbstractAxis *> i(m_seriesAxisXMap);
327 327
328 328 while (i.hasNext()) {
329 329 i.next();
330 330 if(i.value()->isVisible()) return i.value();
331 331 }
332 332 return 0;
333 333 }
334 334 return m_seriesAxisXMap.value(series);
335 335 }
336 336
337 337 QAbstractAxis* ChartDataSet::axisY(QAbstractSeries *series) const
338 338 {
339 339 if(series == 0) {
340 340 QMapIterator<QAbstractSeries*, QAbstractAxis *> i(m_seriesAxisYMap);
341 341
342 342 while (i.hasNext()) {
343 343 i.next();
344 344 if(i.value()->isVisible()) return i.value();
345 345 }
346 346 return 0;
347 347 }
348 348 return m_seriesAxisYMap.value(series);
349 349 }
350 350
351 351 void ChartDataSet::setAxis(QAbstractSeries *series, QAbstractAxis *axis, Qt::Orientation orientation)
352 352 {
353 353 Q_ASSERT(axis);
354 354
355 355 Domain* domain = m_seriesDomainMap.value(series);
356 356
357 357 if(!domain) {
358 358 qWarning() << "Series not found on the chart.";
359 359 return;
360 360 }
361 361
362 362 if(orientation==Qt::Horizontal && axis->orientation()==Qt::Vertical) {
363 363 qWarning()<<"Axis already defined as axis Y";
364 364 return;
365 365 }
366 366
367 367 if(orientation==Qt::Vertical && axis->orientation()==Qt::Horizontal) {
368 368 qWarning()<<"Axis already defined as axis X";
369 369 return;
370 370 }
371 371
372 axis->d_ptr->m_orientation=orientation;
372 axis->d_ptr->setOrientation(orientation);
373 373
374 374 QMap<QAbstractSeries*, QAbstractAxis*> *seriesAxisMap;
375 375
376 376 if(orientation==Qt::Vertical) {
377 377 seriesAxisMap= &m_seriesAxisYMap;
378 378
379 379 }else{
380 380 seriesAxisMap= &m_seriesAxisXMap;
381 381 }
382 382
383 383 QAbstractAxis *oldAxis = seriesAxisMap->take(series);
384 384 QList<QAbstractAxis*> axes = seriesAxisMap->values();
385 385
386 386 if(oldAxis) {
387 387 if(axes.indexOf(oldAxis)==-1) {
388 388 emit axisRemoved(oldAxis);
389 389 oldAxis->deleteLater();
390 390 }
391 391 }
392 392
393 393 if(axes.indexOf(axis)==-1) {
394 394 initializeAxis(axis,series);
395 395 emit axisAdded(axis,domain);
396 396 }else{
397 397 initializeAxis(axis,series);
398 398 }
399 399 }
400 400
401 401 Domain* ChartDataSet::domain(QAbstractSeries *series) const
402 402 {
403 403 return m_seriesDomainMap.value(series);
404 404 }
405 405
406 406 void ChartDataSet::scrollDomain(qreal dx,qreal dy,const QSizeF& size)
407 407 {
408 408 blockAxisSignals(true);
409 409 QMapIterator<QAbstractSeries*, Domain*> i(m_seriesDomainMap);
410 410 while (i.hasNext()) {
411 411 i.next();
412 412 i.value()->move(dx,dy,size);
413 413 }
414 414 blockAxisSignals(false);
415 415 }
416 416
417 417 QList<QAbstractSeries*> ChartDataSet::series() const
418 418 {
419 419 return m_seriesDomainMap.keys();
420 420 }
421 421
422 422 void ChartDataSet::updateSeries(QAbstractSeries *series)
423 423 {
424 424 emit seriesUpdated(series);
425 425 }
426 426
427 427 #include "moc_chartdataset_p.cpp"
428 428
429 429 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,474 +1,466
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20 #include "chartpresenter_p.h"
21 21 #include "qchart.h"
22 22 #include "qchart_p.h"
23 23 #include "qabstractaxis.h"
24 24 #include "qabstractaxis_p.h"
25 25 #include "chartdataset_p.h"
26 26 #include "charttheme_p.h"
27 27 #include "chartanimator_p.h"
28 28 #include "chartanimation_p.h"
29 29 #include "qabstractseries_p.h"
30 30 #include "qareaseries.h"
31 31 #include "chartaxis_p.h"
32 32 //#include "chartaxisx_p.h"
33 33 //#include "chartaxisy_p.h"
34 34 #include "areachartitem_p.h"
35 35 #include "chartbackground_p.h"
36 36 #include "chartlayout_p.h"
37 37 #include <QTimer>
38 38
39 39 QTCOMMERCIALCHART_BEGIN_NAMESPACE
40 40
41 41 ChartPresenter::ChartPresenter(QChart* chart,ChartDataSet* dataset):QObject(chart),
42 42 m_chart(chart),
43 43 m_animator(0),
44 44 m_dataset(dataset),
45 45 m_chartTheme(0),
46 46 m_options(QChart::NoAnimation),
47 47 m_state(ShowState),
48 48 m_layout(new ChartLayout(this)),
49 49 m_backgroundItem(0),
50 50 m_titleItem(0)
51 51 {
52 52
53 53 }
54 54
55 55 ChartPresenter::~ChartPresenter()
56 56 {
57 57 delete m_chartTheme;
58 58 }
59 59
60 60 void ChartPresenter::setGeometry(const QRectF& rect)
61 61 {
62 62
63 63 Q_ASSERT(rect.isValid());
64 64
65 65 if(m_rect!=rect) {
66 66 m_rect=rect;
67 67 emit geometryChanged(m_rect);
68 68 }
69 69 }
70 70
71 71 void ChartPresenter::handleAxisAdded(QAbstractAxis* axis,Domain* domain)
72 72 {
73 73 ChartAxis* item = axis->d_ptr->createGraphics(this);
74 74 item->setDomain(domain);
75 75
76 76 if(m_options.testFlag(QChart::GridAxisAnimations)){
77 77 item->setAnimator(m_animator);
78 78 item->setAnimation(new AxisAnimation(item));
79 79 }
80 80
81 if(item->axisType()==ChartAxis::X_AXIS){
82 m_chartTheme->decorate(axis,true);
83 QObject::connect(domain,SIGNAL(rangeXChanged(qreal,qreal,int)),item,SLOT(handleRangeChanged(qreal,qreal,int)));
84 //initialize
85 item->handleRangeChanged(domain->minX(),domain->maxX(),domain->tickXCount());
86
87 }
88 else{
89 m_chartTheme->decorate(axis,false);
90 QObject::connect(domain,SIGNAL(rangeYChanged(qreal,qreal,int)),item,SLOT(handleRangeChanged(qreal,qreal,int)));
91 //initialize
92 item->handleRangeChanged(domain->minY(),domain->maxY(),domain->tickYCount());
93 }
94
95 81 QObject::connect(this,SIGNAL(geometryChanged(QRectF)),item,SLOT(handleGeometryChanged(QRectF)));
82 QObject::connect(domain,SIGNAL(updated()),item,SLOT(handleDomainUpdated()));
96 83 QObject::connect(axis,SIGNAL(visibleChanged(bool)),this,SLOT(handleAxisVisibleChanged(bool)));
84
97 85 //initialize
86 domain->emitUpdated();
87 m_chartTheme->decorate(axis);
88 axis->d_ptr->setDirty(false);
89 axis->d_ptr->emitUpdated();
98 90 if(m_rect.isValid()) item->handleGeometryChanged(m_rect);
99 //reload visiblity
91
100 92 m_axisItems.insert(axis, item);
101 93 selectVisibleAxis();
102
103 94 }
104 95
105 96 void ChartPresenter::handleAxisRemoved(QAbstractAxis* axis)
106 97 {
107 98 ChartAxis* item = m_axisItems.take(axis);
108 99 Q_ASSERT(item);
109 100 selectVisibleAxis();
110 101 if(m_animator) m_animator->removeAnimation(item);
111 102 item->deleteLater();
112 103 }
113 104
114 105
115 106 void ChartPresenter::handleSeriesAdded(QAbstractSeries* series,Domain* domain)
116 107 {
117 108 Chart *item = series->d_ptr->createGraphics(this);
118 109 Q_ASSERT(item);
119 110 item->setDomain(domain);
120 111
121 112 QObject::connect(this,SIGNAL(geometryChanged(QRectF)),item,SLOT(handleGeometryChanged(QRectF)));
122 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),item,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
113 QObject::connect(domain,SIGNAL(updated()),item,SLOT(handleDomainUpdated()));
123 114 //initialize
124 item->handleDomainChanged(domain->minX(),domain->maxX(),domain->minY(),domain->maxY());
115 item->handleDomainUpdated();
116
125 117 if(m_rect.isValid()) item->handleGeometryChanged(m_rect);
126 118 m_chartItems.insert(series,item);
127 119 }
128 120
129 121 void ChartPresenter::handleSeriesRemoved(QAbstractSeries* series)
130 122 {
131 123 Chart* item = m_chartItems.take(series);
132 124 Q_ASSERT(item);
133 125 if(m_animator) {
134 126 //small hack to handle area animations
135 127 if(series->type() == QAbstractSeries::SeriesTypeArea){
136 128 QAreaSeries* areaSeries = static_cast<QAreaSeries*>(series);
137 129 AreaChartItem* area = static_cast<AreaChartItem*>(item);
138 130 m_animator->removeAnimation(area->upperLineItem());
139 131 if(areaSeries->lowerSeries()) m_animator->removeAnimation(area->lowerLineItem());
140 132 }else
141 133 m_animator->removeAnimation(item);
142 134 }
143 135 item->deleteLater();
144 136 }
145 137
146 138 void ChartPresenter::selectVisibleAxis()
147 139 {
148 140 QMapIterator<QAbstractAxis*, ChartAxis*> i(m_axisItems);
149 141
150 142 while (i.hasNext()) {
151 143 i.next();
152 144 i.key()->hide();
153 145 }
154 146
155 147 i.toFront();
156 148
157 149 bool axisX=false;
158 150 bool axisY=false;
159 151
160 152 while (i.hasNext()) {
161 153 i.next();
162 if(i.key()->d_ptr->m_orientation==Qt::Vertical && !axisY) {
154 if(i.key()->orientation()==Qt::Vertical && !axisY) {
163 155 axisY=true;
164 156 i.key()->show();
165 157 }
166 if(i.key()->d_ptr->m_orientation==Qt::Horizontal && !axisX) {
158 if(i.key()->orientation()==Qt::Horizontal && !axisX) {
167 159 axisX=true;
168 160 i.key()->show();
169 161 }
170 162
171 163 }
172 164 }
173 165
174 166
175 167 void ChartPresenter::handleAxisVisibleChanged(bool visible)
176 168 {
177 169 QAbstractAxis* axis = static_cast<QAbstractAxis*> (sender());
178 170 Q_ASSERT(axis);
179 171 if(visible){
180 172
181 173 QMapIterator<QAbstractAxis*, ChartAxis*> i(m_axisItems);
182 174
183 175 while (i.hasNext()) {
184 176 i.next();
185 177 if(i.key()==axis) {
186 178 continue;
187 179 }
188 if(i.key()->d_ptr->m_orientation==axis->d_ptr->m_orientation) {
180 if(i.key()->orientation()==axis->orientation()) {
189 181 i.key()->setVisible(false);
190 182 }
191 183 }
192 184 }
193 185 }
194 186
195 187 void ChartPresenter::setTheme(QChart::ChartTheme theme,bool force)
196 188 {
197 189 if(m_chartTheme && m_chartTheme->id() == theme) return;
198 190 delete m_chartTheme;
199 191 m_chartTheme = ChartTheme::createTheme(theme);
200 192 m_chartTheme->setForced(force);
201 193 m_chartTheme->decorate(m_chart);
202 194 m_chartTheme->decorate(m_chart->legend());
203 195 resetAllElements();
204 196
205 197 // We do not want "force" to stay on.
206 198 // Bar/pie are calling decorate when adding/removing slices/bars which means
207 199 // that to preserve users colors "force" must not be on.
208 200 m_chartTheme->setForced(false);
209 201 }
210 202
211 203 QChart::ChartTheme ChartPresenter::theme()
212 204 {
213 205 return m_chartTheme->id();
214 206 }
215 207
216 208 void ChartPresenter::setAnimationOptions(QChart::AnimationOptions options)
217 209 {
218 210 if(m_options!=options) {
219 211
220 212 m_options=options;
221 213
222 214 if(m_options!=QChart::NoAnimation && !m_animator) {
223 215 m_animator= new ChartAnimator(this);
224 216 }
225 217 resetAllElements();
226 218 }
227 219
228 220 }
229 221
230 222 void ChartPresenter::resetAllElements()
231 223 {
232 224 QMapIterator<QAbstractAxis*, ChartAxis*> i(m_axisItems);
233 225 while (i.hasNext()) {
234 226 i.next();
235 227 Domain* domain = i.value()->domain();
236 228 QAbstractAxis* axis = i.key();
237 229 handleAxisRemoved(axis);
238 230 handleAxisAdded(axis,domain);
239 231 }
240 232
241 233 QMapIterator<QAbstractSeries*, Chart*> j(m_chartItems);
242 234 while (j.hasNext()) {
243 235 j.next();
244 236 Domain* domain = j.value()->domain();
245 237 QAbstractSeries* series = j.key();
246 238 handleSeriesRemoved(series);
247 239 handleSeriesAdded(series,domain);
248 240 }
249 241 }
250 242
251 243 void ChartPresenter::zoomIn(qreal factor)
252 244 {
253 245 QRectF rect = geometry();
254 246 rect.setWidth(rect.width()/factor);
255 247 rect.setHeight(rect.height()/factor);
256 248 rect.moveCenter(geometry().center());
257 249 zoomIn(rect);
258 250 }
259 251
260 252 void ChartPresenter::zoomIn(const QRectF& rect)
261 253 {
262 254 QRectF r = rect.normalized();
263 255 r.translate(-geometry().topLeft());
264 256 if (!r.isValid())
265 257 return;
266 258
267 259 m_state = ZoomInState;
268 260 m_statePoint = QPointF(r.center().x()/geometry().width(),r.center().y()/geometry().height());
269 261 m_dataset->zoomInDomain(r,geometry().size());
270 262 m_state = ShowState;
271 263 }
272 264
273 265 void ChartPresenter::zoomOut(qreal factor)
274 266 {
275 267 m_state = ZoomOutState;
276 268
277 269 QRectF chartRect;
278 270 chartRect.setSize(geometry().size());
279 271
280 272 QRectF rect;
281 273 rect.setSize(chartRect.size()/factor);
282 274 rect.moveCenter(chartRect.center());
283 275 if (!rect.isValid())
284 276 return;
285 277 m_statePoint = QPointF(rect.center().x()/geometry().width(),rect.center().y()/geometry().height());
286 278 m_dataset->zoomOutDomain(rect, chartRect.size());
287 279 m_state = ShowState;
288 280 }
289 281
290 282 void ChartPresenter::scroll(qreal dx,qreal dy)
291 283 {
292 284 if(dx<0) m_state=ScrollLeftState;
293 285 if(dx>0) m_state=ScrollRightState;
294 286 if(dy<0) m_state=ScrollUpState;
295 287 if(dy>0) m_state=ScrollDownState;
296 288
297 289 m_dataset->scrollDomain(dx,dy,geometry().size());
298 290 m_state = ShowState;
299 291 }
300 292
301 293 QChart::AnimationOptions ChartPresenter::animationOptions() const
302 294 {
303 295 return m_options;
304 296 }
305 297
306 298 void ChartPresenter::createBackgroundItem()
307 299 {
308 300 if (!m_backgroundItem) {
309 301 m_backgroundItem = new ChartBackground(rootItem());
310 302 m_backgroundItem->setPen(Qt::NoPen);
311 303 m_backgroundItem->setZValue(ChartPresenter::BackgroundZValue);
312 304 }
313 305 }
314 306
315 307 void ChartPresenter::createTitleItem()
316 308 {
317 309 if (!m_titleItem) {
318 310 m_titleItem = new QGraphicsSimpleTextItem(rootItem());
319 311 m_titleItem->setZValue(ChartPresenter::BackgroundZValue);
320 312 }
321 313 }
322 314
323 315
324 316 void ChartPresenter::handleAnimationFinished()
325 317 {
326 318 m_animations.removeAll(qobject_cast<ChartAnimation*>(sender()));
327 319 if(m_animations.empty()) emit animationsFinished();
328 320 }
329 321
330 322 void ChartPresenter::startAnimation(ChartAnimation* animation)
331 323 {
332 324 if (animation->state() != QAbstractAnimation::Stopped) animation->stop();
333 325 QObject::connect(animation, SIGNAL(finished()),this,SLOT(handleAnimationFinished()),Qt::UniqueConnection);
334 326 if(!m_animations.isEmpty()){
335 327 m_animations.append(animation);
336 328 }
337 329 QTimer::singleShot(0, animation, SLOT(start()));
338 330 }
339 331
340 332 QGraphicsRectItem* ChartPresenter::backgroundItem()
341 333 {
342 334 return m_backgroundItem;
343 335 }
344 336
345 337 void ChartPresenter::setBackgroundBrush(const QBrush& brush)
346 338 {
347 339 createBackgroundItem();
348 340 m_backgroundItem->setBrush(brush);
349 341 m_layout->invalidate();
350 342 }
351 343
352 344 QBrush ChartPresenter::backgroundBrush() const
353 345 {
354 346 if (!m_backgroundItem) return QBrush();
355 347 return m_backgroundItem->brush();
356 348 }
357 349
358 350 void ChartPresenter::setBackgroundPen(const QPen& pen)
359 351 {
360 352 createBackgroundItem();
361 353 m_backgroundItem->setPen(pen);
362 354 m_layout->invalidate();
363 355 }
364 356
365 357 QPen ChartPresenter::backgroundPen() const
366 358 {
367 359 if (!m_backgroundItem) return QPen();
368 360 return m_backgroundItem->pen();
369 361 }
370 362
371 363 QGraphicsItem* ChartPresenter::titleItem()
372 364 {
373 365 return m_titleItem;
374 366 }
375 367
376 368 void ChartPresenter::setTitle(const QString& title)
377 369 {
378 370 createTitleItem();
379 371 m_titleItem->setText(title);
380 372 m_layout->invalidate();
381 373 }
382 374
383 375 QString ChartPresenter::title() const
384 376 {
385 377 if (!m_titleItem) return QString();
386 378 return m_titleItem->text();
387 379 }
388 380
389 381 void ChartPresenter::setTitleFont(const QFont& font)
390 382 {
391 383 createTitleItem();
392 384 m_titleItem->setFont(font);
393 385 m_layout->invalidate();
394 386 }
395 387
396 388 QFont ChartPresenter::titleFont() const
397 389 {
398 390 if (!m_titleItem) return QFont();
399 391 return m_titleItem->font();
400 392 }
401 393
402 394 void ChartPresenter::setTitleBrush(const QBrush &brush)
403 395 {
404 396 createTitleItem();
405 397 m_titleItem->setBrush(brush);
406 398 m_layout->invalidate();
407 399 }
408 400
409 401 QBrush ChartPresenter::titleBrush() const
410 402 {
411 403 if (!m_titleItem) return QBrush();
412 404 return m_titleItem->brush();
413 405 }
414 406
415 407 void ChartPresenter::setBackgroundVisible(bool visible)
416 408 {
417 409 createBackgroundItem();
418 410 m_backgroundItem->setVisible(visible);
419 411 }
420 412
421 413
422 414 bool ChartPresenter::isBackgroundVisible() const
423 415 {
424 416 if (!m_backgroundItem) return false;
425 417 return m_backgroundItem->isVisible();
426 418 }
427 419
428 420 void ChartPresenter::setBackgroundDropShadowEnabled(bool enabled)
429 421 {
430 422 createBackgroundItem();
431 423 m_backgroundItem->setDropShadowEnabled(enabled);
432 424 }
433 425
434 426 bool ChartPresenter::isBackgroundDropShadowEnabled() const
435 427 {
436 428 if (!m_backgroundItem) return false;
437 429 return m_backgroundItem->isDropShadowEnabled();
438 430 }
439 431
440 432
441 433 QGraphicsLayout* ChartPresenter::layout()
442 434 {
443 435 return m_layout;
444 436 }
445 437
446 438 void ChartPresenter::setMarginsMinimum(const QRectF& margins)
447 439 {
448 440 Q_UNUSED(margins);
449 441 // m_layout->setMarginsMinimum(margins);
450 442 }
451 443
452 444 QRectF ChartPresenter::margins() const
453 445 {
454 446 return m_layout->margins();
455 447 }
456 448
457 449 QLegend* ChartPresenter::legend()
458 450 {
459 451 return m_chart->legend();
460 452 }
461 453
462 454 QList<ChartAxis*> ChartPresenter::axisItems() const
463 455 {
464 456 return m_axisItems.values();
465 457 }
466 458
467 459 void ChartPresenter::setVisible(bool visible)
468 460 {
469 461 m_chart->setVisible(visible);
470 462 }
471 463
472 464 #include "moc_chartpresenter_p.cpp"
473 465
474 466 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,389 +1,391
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "charttheme_p.h"
22 22 #include "qchart.h"
23 23 #include "qchart_p.h"
24 24 #include "qchartview.h"
25 25 #include "qlegend.h"
26 26 #include "qabstractaxis.h"
27 27 #include <QTime>
28 28
29 29 //series
30 30 #include "qbarset.h"
31 31 #include "qabstractbarseries.h"
32 32 #include "qstackedbarseries.h"
33 33 #include "qpercentbarseries.h"
34 34 #include "qlineseries.h"
35 35 #include "qareaseries.h"
36 36 #include "qscatterseries.h"
37 37 #include "qpieseries.h"
38 38 #include "qpieslice.h"
39 39 #include "qpieslice_p.h"
40 40 #include "qsplineseries.h"
41 41
42 42 //items
43 43 #include "chartaxis_p.h"
44 44 #include "abstractbarchartitem_p.h"
45 45 #include "stackedbarchartitem_p.h"
46 46 #include "percentbarchartitem_p.h"
47 47 #include "linechartitem_p.h"
48 48 #include "areachartitem_p.h"
49 49 #include "scatterchartitem_p.h"
50 50 #include "piechartitem_p.h"
51 51 #include "splinechartitem_p.h"
52 52
53 53 //themes
54 54 #include "chartthemesystem_p.h"
55 55 #include "chartthemelight_p.h"
56 56 #include "chartthemebluecerulean_p.h"
57 57 #include "chartthemedark_p.h"
58 58 #include "chartthemebrownsand_p.h"
59 59 #include "chartthemebluencs_p.h"
60 60 #include "chartthemehighcontrast_p.h"
61 61 #include "chartthemeblueicy_p.h"
62 62
63 63 QTCOMMERCIALCHART_BEGIN_NAMESPACE
64 64
65 65 ChartTheme::ChartTheme(QChart::ChartTheme id) :
66 66 m_masterFont(QFont("arial", 14)),
67 67 m_labelFont(QFont("arial", 10)),
68 68 m_labelBrush(QColor(QRgb(0x000000))),
69 69 m_axisLinePen(QPen(QRgb(0x000000))),
70 70 m_backgroundShadesPen(Qt::NoPen),
71 71 m_backgroundShadesBrush(Qt::NoBrush),
72 72 m_backgroundShades(BackgroundShadesNone),
73 73 m_backgroundDropShadowEnabled(false),
74 74 m_gridLinePen(QPen(QRgb(0x000000))),
75 75 m_force(false)
76 76 {
77 77 m_id = id;
78 78 qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
79 79 }
80 80
81 81
82 82 ChartTheme* ChartTheme::createTheme(QChart::ChartTheme theme)
83 83 {
84 84 switch(theme) {
85 85 case QChart::ChartThemeLight:
86 86 return new ChartThemeLight();
87 87 case QChart::ChartThemeBlueCerulean:
88 88 return new ChartThemeBlueCerulean();
89 89 case QChart::ChartThemeDark:
90 90 return new ChartThemeDark();
91 91 case QChart::ChartThemeBrownSand:
92 92 return new ChartThemeBrownSand();
93 93 case QChart::ChartThemeBlueNcs:
94 94 return new ChartThemeBlueNcs();
95 95 case QChart::ChartThemeHighContrast:
96 96 return new ChartThemeHighContrast();
97 97 case QChart::ChartThemeBlueIcy:
98 98 return new ChartThemeBlueIcy();
99 99 default:
100 100 return new ChartThemeSystem();
101 101 }
102 102 }
103 103
104 104 void ChartTheme::decorate(QChart *chart)
105 105 {
106 106 QBrush brush;
107 107
108 108 if(brush == chart->backgroundBrush() || m_force)
109 109 chart->setBackgroundBrush(m_chartBackgroundGradient);
110 110 chart->setTitleFont(m_masterFont);
111 111 chart->setTitleBrush(m_labelBrush);
112 112 chart->setDropShadowEnabled(m_backgroundDropShadowEnabled);
113 113 }
114 114
115 115 void ChartTheme::decorate(QLegend *legend)
116 116 {
117 117 QPen pen;
118 118 QBrush brush;
119 119 QFont font;
120 120
121 121 if (pen == legend->pen() || m_force)
122 122 legend->setPen(m_axisLinePen);
123 123
124 124 if (brush == legend->brush() || m_force)
125 125 legend->setBrush(m_chartBackgroundGradient);
126 126
127 127 if (font == legend->font() || m_force)
128 128 legend->setFont(m_labelFont);
129 129
130 130 if (brush == legend->labelBrush() || m_force)
131 131 legend->setLabelBrush(m_labelBrush);
132 132 }
133 133
134 134 void ChartTheme::decorate(QAreaSeries *series, int index)
135 135 {
136 136 QPen pen;
137 137 QBrush brush;
138 138
139 139 if (pen == series->pen() || m_force){
140 140 pen.setColor(colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 0.0));
141 141 pen.setWidthF(2);
142 142 series->setPen(pen);
143 143 }
144 144
145 145 if (brush == series->brush() || m_force) {
146 146 QBrush brush(m_seriesColors.at(index % m_seriesColors.size()));
147 147 series->setBrush(brush);
148 148 }
149 149 }
150 150
151 151
152 152 void ChartTheme::decorate(QLineSeries *series,int index)
153 153 {
154 154 QPen pen;
155 155 if(pen == series->pen() || m_force ){
156 156 pen.setColor(m_seriesColors.at(index%m_seriesColors.size()));
157 157 pen.setWidthF(2);
158 158 series->setPen(pen);
159 159 }
160 160 }
161 161
162 162 void ChartTheme::decorate(QAbstractBarSeries *series, int index)
163 163 {
164 164 QBrush brush;
165 165 QPen pen;
166 166 QList<QBarSet *> sets = series->barSets();
167 167
168 168 qreal takeAtPos = 0.5;
169 169 qreal step = 0.2;
170 170 if (sets.count() > 1 ) {
171 171 step = 1.0 / (qreal) sets.count();
172 172 if (sets.count() % m_seriesGradients.count())
173 173 step *= m_seriesGradients.count();
174 174 else
175 175 step *= (m_seriesGradients.count() - 1);
176 176 }
177 177
178 178 for (int i(0); i < sets.count(); i++) {
179 179 int colorIndex = (index + i) % m_seriesGradients.count();
180 180 if (i > 0 && i % m_seriesGradients.count() == 0) {
181 181 // There is no dedicated base color for each sets, generate more colors
182 182 takeAtPos += step;
183 183 if (takeAtPos == 1.0)
184 184 takeAtPos += step;
185 185 takeAtPos -= (int) takeAtPos;
186 186 }
187 187 if (brush == sets.at(i)->brush() || m_force )
188 188 sets.at(i)->setBrush(colorAt(m_seriesGradients.at(colorIndex), takeAtPos));
189 189
190 190 // Pick label color from the opposite end of the gradient.
191 191 // 0.3 as a boundary seems to work well.
192 192 if (takeAtPos < 0.3)
193 193 sets.at(i)->setLabelBrush(colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 1));
194 194 else
195 195 sets.at(i)->setLabelBrush(colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 0));
196 196
197 197 if (pen == sets.at(i)->pen() || m_force) {
198 198 QColor c = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 0.0);
199 199 sets.at(i)->setPen(c);
200 200 }
201 201 }
202 202 }
203 203
204 204 void ChartTheme::decorate(QScatterSeries *series, int index)
205 205 {
206 206 QPen pen;
207 207 QBrush brush;
208 208
209 209 if (pen == series->pen() || m_force) {
210 210 pen.setColor(colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 0.0));
211 211 pen.setWidthF(2);
212 212 series->setPen(pen);
213 213 }
214 214
215 215 if (brush == series->brush() || m_force) {
216 216 QBrush brush(m_seriesColors.at(index % m_seriesColors.size()));
217 217 series->setBrush(brush);
218 218 }
219 219 }
220 220
221 221 void ChartTheme::decorate(QPieSeries *series, int index)
222 222 {
223 223
224 224 for (int i(0); i < series->slices().count(); i++) {
225 225
226 226 QColor penColor = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 0.0);
227 227
228 228 // Get color for a slice from a gradient linearly, beginning from the start of the gradient
229 229 qreal pos = (qreal) (i + 1) / (qreal) series->count();
230 230 QColor brushColor = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), pos);
231 231
232 232 QPieSlice *s = series->slices().at(i);
233 233 QPieSlicePrivate *d = QPieSlicePrivate::fromSlice(s);
234 234
235 235 if (d->m_data.m_slicePen.isThemed() || m_force)
236 236 d->setPen(penColor, true);
237 237
238 238 if (d->m_data.m_sliceBrush.isThemed() || m_force)
239 239 d->setBrush(brushColor, true);
240 240
241 241 if (d->m_data.m_labelBrush.isThemed() || m_force)
242 242 d->setLabelBrush(m_labelBrush.color(), true);
243 243
244 244 if (d->m_data.m_labelFont.isThemed() || m_force)
245 245 d->setLabelFont(m_labelFont, true);
246 246 }
247 247 }
248 248
249 249 void ChartTheme::decorate(QSplineSeries *series, int index)
250 250 {
251 251 QPen pen;
252 252 if(pen == series->pen() || m_force){
253 253 pen.setColor(m_seriesColors.at(index%m_seriesColors.size()));
254 254 pen.setWidthF(2);
255 255 series->setPen(pen);
256 256 }
257 257 }
258 258
259 void ChartTheme::decorate(QAbstractAxis *axis,bool axisX)
259 void ChartTheme::decorate(QAbstractAxis *axis)
260 260 {
261 261 QPen pen;
262 262 QBrush brush;
263 263 QFont font;
264 264
265 bool axisX = axis->orientation()== Qt::Horizontal;
266
265 267 if (axis->isArrowVisible()) {
266 268
267 269 if(brush == axis->labelsBrush() || m_force){
268 270 axis->setLabelsBrush(m_labelBrush);
269 271 }
270 272 if(pen == axis->labelsPen() || m_force){
271 273 axis->setLabelsPen(Qt::NoPen); // NoPen for performance reasons
272 274 }
273 275
274 276
275 277 if (axis->shadesVisible() || m_force) {
276 278
277 279 if(brush == axis->shadesBrush() || m_force){
278 280 axis->setShadesBrush(m_backgroundShadesBrush);
279 281 }
280 282
281 283 if(pen == axis->shadesPen() || m_force){
282 284 axis->setShadesPen(m_backgroundShadesPen);
283 285 }
284 286
285 287 if( m_force && (m_backgroundShades == BackgroundShadesBoth
286 288 || (m_backgroundShades == BackgroundShadesVertical && axisX)
287 289 || (m_backgroundShades == BackgroundShadesHorizontal && !axisX))){
288 290 axis->setShadesVisible(true);
289 291
290 292 }
291 293 }
292 294
293 295 if(pen == axis->axisPen() || m_force){
294 296 axis->setAxisPen(m_axisLinePen);
295 297 }
296 298
297 299 if(pen == axis->gridLinePen() || m_force){
298 300 axis->setGridLinePen(m_gridLinePen);
299 301 }
300 302
301 303 if(font == axis->labelsFont() || m_force){
302 304 axis->setLabelsFont(m_labelFont);
303 305 }
304 306 }
305 307 }
306 308
307 309 void ChartTheme::generateSeriesGradients()
308 310 {
309 311 // Generate gradients in HSV color space
310 312 foreach (const QColor& color, m_seriesColors) {
311 313 QLinearGradient g;
312 314 qreal h = color.hsvHueF();
313 315 qreal s = color.hsvSaturationF();
314 316
315 317 // TODO: tune the algorithm to give nice results with most base colors defined in
316 318 // most themes. The rest of the gradients we can define manually in theme specific
317 319 // implementation.
318 320 QColor start = color;
319 321 start.setHsvF(h, 0.0, 1.0);
320 322 g.setColorAt(0.0, start);
321 323
322 324 g.setColorAt(0.5, color);
323 325
324 326 QColor end = color;
325 327 end.setHsvF(h, s, 0.25);
326 328 g.setColorAt(1.0, end);
327 329
328 330 m_seriesGradients << g;
329 331 }
330 332 }
331 333
332 334
333 335 QColor ChartTheme::colorAt(const QColor &start, const QColor &end, qreal pos)
334 336 {
335 337 Q_ASSERT(pos >= 0.0 && pos <= 1.0);
336 338 qreal r = start.redF() + ((end.redF() - start.redF()) * pos);
337 339 qreal g = start.greenF() + ((end.greenF() - start.greenF()) * pos);
338 340 qreal b = start.blueF() + ((end.blueF() - start.blueF()) * pos);
339 341 QColor c;
340 342 c.setRgbF(r, g, b);
341 343 return c;
342 344 }
343 345
344 346 QColor ChartTheme::colorAt(const QGradient &gradient, qreal pos)
345 347 {
346 348 Q_ASSERT(pos >= 0 && pos <= 1.0);
347 349
348 350 QGradientStops stops = gradient.stops();
349 351 int count = stops.count();
350 352
351 353 // find previous stop relative to position
352 354 QGradientStop prev = stops.first();
353 355 for (int i = 0; i < count; i++) {
354 356 QGradientStop stop = stops.at(i);
355 357 if (pos > stop.first)
356 358 prev = stop;
357 359
358 360 // given position is actually a stop position?
359 361 if (pos == stop.first) {
360 362 //qDebug() << "stop color" << pos;
361 363 return stop.second;
362 364 }
363 365 }
364 366
365 367 // find next stop relative to position
366 368 QGradientStop next = stops.last();
367 369 for (int i = count - 1; i >= 0; i--) {
368 370 QGradientStop stop = stops.at(i);
369 371 if (pos < stop.first)
370 372 next = stop;
371 373 }
372 374
373 375 //qDebug() << "prev" << prev.first << "pos" << pos << "next" << next.first;
374 376
375 377 qreal range = next.first - prev.first;
376 378 qreal posDelta = pos - prev.first;
377 379 qreal relativePos = posDelta / range;
378 380
379 381 //qDebug() << "range" << range << "posDelta" << posDelta << "relativePos" << relativePos;
380 382
381 383 return colorAt(prev.second, next.second, relativePos);
382 384 }
383 385
384 386 void ChartTheme::setForced(bool enabled)
385 387 {
386 388 m_force=enabled;
387 389 }
388 390
389 391 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,110 +1,110
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 // W A R N I N G
22 22 // -------------
23 23 //
24 24 // This file is not part of the QtCommercial Chart API. It exists purely as an
25 25 // implementation detail. This header file may change from version to
26 26 // version without notice, or even be removed.
27 27 //
28 28 // We mean it.
29 29
30 30 #ifndef CHARTTHEME_H
31 31 #define CHARTTHEME_H
32 32
33 33 #include "qchartglobal.h"
34 34 #include "qchart.h"
35 35 #include <QColor>
36 36 #include <QGradientStops>
37 37
38 38 QTCOMMERCIALCHART_BEGIN_NAMESPACE
39 39
40 40 class ChartItem;
41 41 class LineChartItem;
42 42 class QLineSeries;
43 43 class AbstractBarChartItem;
44 44 class QAbstractBarSeries;
45 45 class StackedBarChartItem;
46 46 class QStackedBarSeries;
47 47 class QPercentBarSeries;
48 48 class PercentBarChartItem;
49 49 class QScatterSeries;
50 50 class ScatterChartItem;
51 51 class PieChartItem;
52 52 class QPieSeries;
53 53 class SplineChartItem;
54 54 class QSplineSeries;
55 55 class AreaChartItem;
56 56 class QAreaSeries;
57 57
58 58 class ChartTheme
59 59 {
60 60 public:
61 61 enum BackgroundShadesMode {
62 62 BackgroundShadesNone = 0,
63 63 BackgroundShadesVertical,
64 64 BackgroundShadesHorizontal,
65 65 BackgroundShadesBoth
66 66 };
67 67
68 68 protected:
69 69 explicit ChartTheme(QChart::ChartTheme id = QChart::ChartThemeLight);
70 70 public:
71 71 static ChartTheme *createTheme(QChart::ChartTheme theme);
72 72 QChart::ChartTheme id() const {return m_id;}
73 73 void decorate(QChart *chart);
74 74 void decorate(QLegend *legend);
75 75 void decorate(QAbstractBarSeries *series, int index);
76 76 void decorate(QLineSeries *series, int index);
77 77 void decorate(QAreaSeries *series, int index);
78 78 void decorate(QScatterSeries *series, int index);
79 79 void decorate(QPieSeries *series, int index);
80 80 void decorate(QSplineSeries *series, int index);
81 void decorate(QAbstractAxis *axis, bool axisX);
81 void decorate(QAbstractAxis *axis);
82 82 void setForced(bool enabled);
83 83 bool isForced() { return m_force; }
84 84
85 85 public: // utils
86 86 void generateSeriesGradients();
87 87 static QColor colorAt(const QColor &start, const QColor &end, qreal pos);
88 88 static QColor colorAt(const QGradient &gradient, qreal pos);
89 89
90 90 protected:
91 91 QChart::ChartTheme m_id;
92 92 QList<QColor> m_seriesColors;
93 93 QList<QGradient> m_seriesGradients;
94 94 QLinearGradient m_chartBackgroundGradient;
95 95
96 96 QFont m_masterFont;
97 97 QFont m_labelFont;
98 98 QBrush m_labelBrush;
99 99 QPen m_axisLinePen;
100 100 QPen m_backgroundShadesPen;
101 101 QBrush m_backgroundShadesBrush;
102 102 BackgroundShadesMode m_backgroundShades;
103 103 bool m_backgroundDropShadowEnabled;
104 104 QPen m_gridLinePen;
105 105 bool m_force;
106 106 };
107 107
108 108 QTCOMMERCIALCHART_END_NAMESPACE
109 109
110 110 #endif // CHARTTHEME_H
@@ -1,302 +1,207
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "domain_p.h"
22 #include <cmath>
22 #include "qabstractaxis_p.h"
23 23
24 24 QTCOMMERCIALCHART_BEGIN_NAMESPACE
25 25
26 26 Domain::Domain(QObject* parent) : QObject(parent),
27 27 m_minX(0),
28 28 m_maxX(0),
29 29 m_minY(0),
30 m_maxY(0),
31 m_tickXCount(5),
32 m_tickYCount(5),
33 m_niceXNumbers(false),
34 m_niceYNumbers(false)
30 m_maxY(0)
35 31 {
36 32 }
37 33
38 34 Domain::~Domain()
39 35 {
40 36 }
41 37
42 38 void Domain::setRange(qreal minX, qreal maxX, qreal minY, qreal maxY)
43 39 {
44 setRange(minX, maxX, minY, maxY,m_tickXCount,m_tickYCount);
45 }
46
47 void Domain::setRange(qreal minX, qreal maxX, qreal minY, qreal maxY,int tickXCount,int tickYCount)
48 {
49 40 bool axisXChanged = false;
50 41 bool axisYChanged = false;
51 42
52 if(m_tickXCount!=tickXCount) {
53 m_tickXCount=tickXCount;
54 axisXChanged=true;
55 }
56
57 if(m_tickYCount!=tickYCount) {
58 m_tickYCount=tickYCount;
59 axisYChanged=true;
60 }
61
62 43 if (!qFuzzyIsNull(m_minX - minX) || !qFuzzyIsNull(m_maxX - maxX)) {
63 if(m_niceXNumbers) looseNiceNumbers(minX, maxX, m_tickXCount);
64 44 m_minX=minX;
65 45 m_maxX=maxX;
66 46 axisXChanged=true;
47 emit rangeXChanged(m_minX,m_maxX);
67 48 }
68 49
69 50 if (!qFuzzyIsNull(m_minY - minY) || !qFuzzyIsNull(m_maxY - maxY)) {
70 if(m_niceYNumbers) looseNiceNumbers(minY, maxY, m_tickYCount);
71 51 m_minY=minY;
72 52 m_maxY=maxY;
73 53 axisYChanged=true;
54 emit rangeYChanged(m_minY,m_maxY);
74 55 }
75 56
76 57 if(axisXChanged || axisYChanged) {
77 emit this->domainChanged(m_minX, m_maxX, m_minY, m_maxY);
78 }
79
80 if(axisXChanged) {
81 emit rangeXChanged(minX,maxX, m_tickXCount);
82 }
83
84 if(axisYChanged) {
85 emit rangeYChanged(minY,maxY, m_tickYCount);
58 emit updated();
86 59 }
87 60 }
88 61
89 62 void Domain::setRangeX(qreal min, qreal max)
90 63 {
91 64 setRange(min,max,m_minY, m_maxY);
92 65 }
93 66
94 void Domain::setRangeX(qreal min, qreal max, int tickCount)
95 {
96 setRange(min,max,m_minY, m_maxY,tickCount,m_tickYCount);
97 }
98
99 67 void Domain::setRangeY(qreal min, qreal max)
100 68 {
101 69 setRange(m_minX, m_maxX, min, max);
102 70 }
103 71
104 void Domain::setRangeY(qreal min, qreal max,int tickCount)
105 {
106 setRange(m_minX, m_maxX, min, max,m_tickXCount,tickCount);
107 }
108
109 72 void Domain::setMinX(qreal min)
110 73 {
111 74 setRange(min, m_maxX, m_minY, m_maxY);
112 75 }
113 76
114 77 void Domain::setMaxX(qreal max)
115 78 {
116 79 setRange(m_minX, max, m_minY, m_maxY);
117 80 }
118 81
119 82 void Domain::setMinY(qreal min)
120 83 {
121 84 setRange(m_minX, m_maxX, min, m_maxY);
122 85 }
123 86
124 87 void Domain::setMaxY(qreal max)
125 88 {
126 89 setRange(m_minX, m_maxX, m_minY, max);
127 90 }
128 91
129 92 qreal Domain::spanX() const
130 93 {
131 94 Q_ASSERT(m_maxX >= m_minX);
132 95 return m_maxX - m_minX;
133 96 }
134 97
135 98 qreal Domain::spanY() const
136 99 {
137 100 Q_ASSERT(m_maxY >= m_minY);
138 101 return m_maxY - m_minY;
139 102 }
140 103
141 104 bool Domain::isEmpty() const
142 105 {
143 106 return qFuzzyIsNull(spanX()) || qFuzzyIsNull(spanY());
144 107 }
145 108
146 109 void Domain::zoomIn(const QRectF& rect, const QSizeF& size)
147 110 {
148 111 qreal dx = spanX() / size.width();
149 112 qreal dy = spanY() / size.height();
150 113
151 114 qreal maxX = m_maxX;
152 115 qreal minX = m_minX;
153 116 qreal minY = m_minY;
154 117 qreal maxY = m_maxY;
155 118
156 119 maxX = minX + dx * rect.right();
157 120 minX = minX + dx * rect.left();
158 121 minY = maxY - dy * rect.bottom();
159 122 maxY = maxY - dy * rect.top();
160 123
161 int tickXCount = m_tickXCount;
162 int tickYCount = m_tickYCount;
163
164 if(m_niceXNumbers) {
165 looseNiceNumbers(minX, maxX, tickXCount);
166 }
167 if(m_niceYNumbers) {
168 looseNiceNumbers(minY, maxY, tickYCount);
169 }
170 setRange(minX,maxX,minY,maxY,tickXCount,tickYCount);
124 setRange(minX,maxX,minY,maxY);
171 125 }
172 126
173 127 void Domain::zoomOut(const QRectF& rect, const QSizeF& size)
174 128 {
175 129 qreal dx = spanX() / rect.width();
176 130 qreal dy = spanY() / rect.height();
177 131
178 132 qreal maxX = m_maxX;
179 133 qreal minX = m_minX;
180 134 qreal minY = m_minY;
181 135 qreal maxY = m_maxY;
182 136
183 137 minX = maxX - dx * rect.right();
184 138 maxX = minX + dx * size.width();
185 139 maxY = minY + dy * rect.bottom();
186 140 minY = maxY - dy * size.height();
187 141
188 int tickXCount = m_tickXCount;
189 int tickYCount = m_tickYCount;
190
191 if(m_niceXNumbers) {
192 looseNiceNumbers(minX, maxX, tickXCount);
193 }
194 if(m_niceYNumbers) {
195 looseNiceNumbers(minY, maxY, tickYCount);
196 }
197 setRange(minX,maxX,minY,maxY,tickXCount,tickYCount);
142 setRange(minX,maxX,minY,maxY);
198 143 }
199 144
200 145 void Domain::move(qreal dx,qreal dy,const QSizeF& size)
201 146 {
202 147 qreal x = spanX() / size.width();
203 148 qreal y = spanY() / size.height();
204 149
205 150 qreal maxX = m_maxX;
206 151 qreal minX = m_minX;
207 152 qreal minY = m_minY;
208 153 qreal maxY = m_maxY;
209 154
210 155 if(dx!=0) {
211 156 minX = minX + x * dx;
212 157 maxX = maxX + x * dx;
213 158 }
214 159 if(dy!=0) {
215 160 minY = minY + y * dy;
216 161 maxY = maxY + y * dy;
217 162 }
218 163 setRange(minX,maxX,minY,maxY);
219 164 }
220 165
221 void Domain::handleAxisXChanged(qreal min,qreal max,int tickXCount,bool niceNumbers)
166 void Domain::emitUpdated()
222 167 {
223 if (m_niceXNumbers != niceNumbers) {
224 m_niceXNumbers = niceNumbers;
225 //force recalculation
226 m_minX = 0;
227 m_maxX = 0;
228 }
229 setRange(min,max,m_minY, m_maxY,tickXCount,m_tickYCount);
168 emit updated();
230 169 }
231 170
232 void Domain::handleAxisYChanged(qreal min,qreal max,int tickYCount,bool niceNumbers)
171 void Domain::handleAxisUpdated()
233 172 {
234 if (m_niceYNumbers != niceNumbers) {
235 m_niceYNumbers = niceNumbers;
236 //force recalculation
237 m_minY = 0;
238 m_maxY = 0;
173 QAbstractAxisPrivate* axis = qobject_cast<QAbstractAxisPrivate*>(sender());
174 Q_ASSERT(axis);
175 axis->setDirty(false);
176 if(axis->orientation()==Qt::Horizontal){
177 setRangeX(axis->min(),axis->max());
178 }else if(axis->orientation()==Qt::Vertical){
179 setRangeY(axis->min(),axis->max());
239 180 }
240 setRange(m_minX, m_maxX, min, max,m_tickXCount,tickYCount);
241 }
242 181
243 //algorithm defined by Paul S.Heckbert GraphicalGems I
244
245 void Domain::looseNiceNumbers(qreal &min, qreal &max, int &ticksCount) const
246 {
247 qreal range = niceNumber(max-min,true); //range with ceiling
248 qreal step = niceNumber(range/(ticksCount-1),false);
249 min = floor(min/step);
250 max = ceil(max/step);
251 ticksCount = int(max-min) +1;
252 min*=step;
253 max*=step;
254 182 }
255 183
256 //nice numbers can be expressed as form of 1*10^n, 2* 10^n or 5*10^n
257
258 qreal Domain::niceNumber(qreal x,bool ceiling) const
259 {
260 qreal z = pow(10,floor(log10(x))); //find corresponding number of the form of 10^n than is smaller than x
261 qreal q = x/z;//q<10 && q>=1;
262
263 if(ceiling) {
264 if(q <= 1.0) q=1;
265 else if(q <= 2.0) q=2;
266 else if(q <= 5.0) q=5;
267 else q=10;
268 }
269 else {
270 if(q < 1.5) q=1;
271 else if(q < 3.0) q=2;
272 else if(q < 7.0) q=5;
273 else q=10;
274 }
275 return q*z;
276 }
277
278
279 184 bool QTCOMMERCIALCHART_AUTOTEST_EXPORT operator== (const Domain &domain1, const Domain &domain2)
280 185 {
281 186 return (qFuzzyIsNull(domain1.m_maxX - domain2.m_maxX) &&
282 187 qFuzzyIsNull(domain1.m_maxY - domain2.m_maxY) &&
283 188 qFuzzyIsNull(domain1.m_minX - domain2.m_minX) &&
284 189 qFuzzyIsNull(domain1.m_minY - domain2.m_minY));
285 190 }
286 191
287 192
288 193 bool QTCOMMERCIALCHART_AUTOTEST_EXPORT operator!= (const Domain &domain1, const Domain &domain2)
289 194 {
290 195 return !(domain1 == domain2);
291 196 }
292 197
293 198
294 199 QDebug QTCOMMERCIALCHART_AUTOTEST_EXPORT operator<<(QDebug dbg, const Domain &domain)
295 200 {
296 dbg.nospace() << "Domain("<<domain.m_minX<<','<<domain.m_maxX<<','<<domain.m_minY<<','<<domain.m_maxY<<')' << domain.m_tickXCount << "," << domain.m_tickYCount ;
201 dbg.nospace() << "Domain("<<domain.m_minX<<','<<domain.m_maxX<<','<<domain.m_minY<<','<<domain.m_maxY<<')';
297 202 return dbg.maybeSpace();
298 203 }
299 204
300 205 #include "moc_domain_p.cpp"
301 206
302 207 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,102 +1,88
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 // W A R N I N G
22 22 // -------------
23 23 //
24 24 // This file is not part of the QtCommercial Chart API. It exists purely as an
25 25 // implementation detail. This header file may change from version to
26 26 // version without notice, or even be removed.
27 27 //
28 28 // We mean it.
29 29
30 30 #ifndef DOMAIN_H
31 31 #define DOMAIN_H
32 32 #include "qchartglobal.h"
33 33 #include <QRectF>
34 34 #include <QSizeF>
35 35 #include <QDebug>
36 36
37 37 QTCOMMERCIALCHART_BEGIN_NAMESPACE
38 38
39 39 class QTCOMMERCIALCHART_AUTOTEST_EXPORT Domain: public QObject {
40 40 Q_OBJECT
41 41 public:
42 42 explicit Domain(QObject* object=0);
43 43 virtual ~Domain();
44 44
45 45 void setRange(qreal minX, qreal maxX, qreal minY, qreal maxY);
46 void setRange(qreal minX, qreal maxX, qreal minY, qreal maxY, int tickXCount, int tickYCount);
47 46 void setRangeX(qreal min, qreal max);
48 void setRangeX(qreal min, qreal max, int tickCount);
49 47 void setRangeY(qreal min, qreal max);
50 void setRangeY(qreal min, qreal max, int tickCount);
51 48 void setMinX(qreal min);
52 49 void setMaxX(qreal max);
53 50 void setMinY(qreal min);
54 51 void setMaxY(qreal max);
55 52
56 53 qreal minX() const { return m_minX; }
57 54 qreal maxX() const { return m_maxX; }
58 55 qreal minY() const { return m_minY; }
59 56 qreal maxY() const { return m_maxY; }
60 57
61 58 qreal spanX() const;
62 59 qreal spanY() const;
63 60 bool isEmpty() const;
64 61
65 int tickXCount() const {return m_tickXCount;}
66 int tickYCount() const {return m_tickYCount;}
67
68 62 friend bool QTCOMMERCIALCHART_AUTOTEST_EXPORT operator== (const Domain &domain1, const Domain &domain2);
69 63 friend bool QTCOMMERCIALCHART_AUTOTEST_EXPORT operator!= (const Domain &domain1, const Domain &domain2);
70 64 friend QDebug QTCOMMERCIALCHART_AUTOTEST_EXPORT operator<<(QDebug dbg, const Domain &domain);
71 65
72 66 void zoomIn(const QRectF& rect, const QSizeF& size);
73 67 void zoomOut(const QRectF& rect, const QSizeF& size);
74 68 void move(qreal dx,qreal dy,const QSizeF& size);
69 void emitUpdated();
75 70
76 71 Q_SIGNALS:
77 void domainChanged(qreal minX, qreal maxX, qreal minY, qreal maxY);
78 void rangeXChanged(qreal min, qreal max, int tickXCount);
79 void rangeYChanged(qreal min, qreal max, int tickYCount);
72 void updated();
73 void rangeXChanged(qreal min, qreal max);
74 void rangeYChanged(qreal min, qreal max);
80 75
81 76 public Q_SLOTS:
82 void handleAxisXChanged(qreal min,qreal max,int tickXCount = 5,bool niceNumbers = false);
83 void handleAxisYChanged(qreal min,qreal max,int tickYCount = 5,bool niceNumbers = false);
84
85 private:
86 void looseNiceNumbers(qreal &min, qreal &max, int &ticksCount) const;
87 qreal niceNumber(qreal x,bool celing) const;
77 void handleAxisUpdated();
88 78
89 79 private:
90 80 qreal m_minX;
91 81 qreal m_maxX;
92 82 qreal m_minY;
93 83 qreal m_maxY;
94 int m_tickXCount;
95 int m_tickYCount;
96 bool m_niceXNumbers;
97 bool m_niceYNumbers;
98 84 };
99 85
100 86 QTCOMMERCIALCHART_END_NAMESPACE
101 87
102 88 #endif
@@ -1,452 +1,450
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "qxyseries.h"
22 22 #include "qxyseries_p.h"
23 23 #include "domain_p.h"
24 24 #include "legendmarker_p.h"
25 25 #include "qvaluesaxis.h"
26 26
27 27 QTCOMMERCIALCHART_BEGIN_NAMESPACE
28 28
29 29 /*!
30 30 \class QXYSeries
31 31 \brief The QXYSeries class is a base class for line, spline and scatter series.
32 32 */
33 33 /*!
34 34 \qmlclass XYSeries
35 35 \inherits AbstractSeries
36 36 The XYSeries class is a base class for line, spline and scatter series.
37 37
38 38 The class cannot be instantiated directly.
39 39 */
40 40
41 41 /*!
42 42 \property QXYSeries::pointsVisible
43 43 Controls if the data points are visible and should be drawn.
44 44 */
45 45 /*!
46 46 \qmlproperty bool XYSeries::pointsVisible
47 47 Controls if the data points are visible and should be drawn.
48 48 */
49 49
50 50 /*!
51 51 \fn QPen QXYSeries::pen() const
52 52 \brief Returns pen used to draw points for series.
53 53 \sa setPen()
54 54 */
55 55
56 56 /*!
57 57 \fn QBrush QXYSeries::brush() const
58 58 \brief Returns brush used to draw points for series.
59 59 \sa setBrush()
60 60 */
61 61
62 62 /*!
63 63 \property QXYSeries::color
64 64 The color of the series. This is line (pen) color in case of QLineSeries or QSplineSeries and
65 65 fill (brush) color in case of QScatterSeries or QAreaSeries.
66 66 \sa QXYSeries::pen(), QXYSeries::brush()
67 67 */
68 68 /*!
69 69 \qmlproperty color XYSeries::color
70 70 The color of the series. This is line (pen) color in case of LineSeries or SplineSeries and
71 71 fill (brush) color in case of ScatterSeries or AreaSeries.
72 72 */
73 73
74 74 /*!
75 75 \fn void QXYSeries::clicked(const QPointF& point)
76 76 \brief Signal is emitted when user clicks the \a point on chart.
77 77 */
78 78 /*!
79 79 \qmlsignal XYSeries::onClicked(QPointF point)
80 80 Signal is emitted when user clicks the \a point on chart. For example:
81 81 \code
82 82 LineSeries {
83 83 XYPoint { x: 0; y: 0 }
84 84 XYPoint { x: 1.1; y: 2.1 }
85 85 onClicked: console.log("onClicked: " + point.x + ", " + point.y);
86 86 }
87 87 \endcode
88 88 */
89 89
90 90 /*!
91 91 \fn void QXYSeries::pointReplaced(int index)
92 92 Signal is emitted when a point has been replaced at \a index.
93 93 \sa replace()
94 94 */
95 95 /*!
96 96 \qmlsignal XYSeries::onPointReplaced(int index)
97 97 Signal is emitted when a point has been replaced at \a index.
98 98 */
99 99
100 100 /*!
101 101 \fn void QXYSeries::pointAdded(int index)
102 102 Signal is emitted when a point has been added at \a index.
103 103 \sa append(), insert()
104 104 */
105 105 /*!
106 106 \qmlsignal XYSeries::onPointAdded(int index)
107 107 Signal is emitted when a point has been added at \a index.
108 108 */
109 109
110 110 /*!
111 111 \fn void QXYSeries::pointRemoved(int index)
112 112 Signal is emitted when a point has been removed from \a index.
113 113 \sa remove()
114 114 */
115 115 /*!
116 116 \qmlsignal XYSeries::onPointRemoved(int index)
117 117 Signal is emitted when a point has been removed from \a index.
118 118 */
119 119
120 120 /*!
121 121 \fn void QXYSeries::colorChanged(QColor color)
122 122 \brief Signal is emitted when the line (pen) color has changed to \a color.
123 123 */
124 124 /*!
125 125 \qmlsignal XYSeries::onColorChanged(color color)
126 126 Signal is emitted when the line (pen) color has changed to \a color.
127 127 */
128 128
129 129 /*!
130 130 \fn void QXYSeriesPrivate::updated()
131 131 \brief \internal
132 132 */
133 133
134 134 /*!
135 135 \qmlmethod XYSeries::append(real x, real y)
136 136 Append point (\a x, \a y) to the series
137 137 */
138 138
139 139 /*!
140 140 \qmlmethod XYSeries::replace(real oldX, real oldY, real newX, real newY)
141 141 Replaces point (\a oldX, \a oldY) with point (\a newX, \a newY). Does nothing, if point (oldX, oldY) does not
142 142 exist.
143 143 */
144 144
145 145 /*!
146 146 \qmlmethod XYSeries::remove(real x, real y)
147 147 Removes point (\a x, \a y) from the series. Does nothing, if point (x, y) does not exist.
148 148 */
149 149
150 150 /*!
151 151 \qmlmethod XYSeries::insert(int index, real x, real y)
152 152 Inserts point (\a x, \a y) to the \a index. If index is 0 or smaller than 0 the point is prepended to the list of
153 153 points. If index is the same as or bigger than count, the point is appended to the list of points.
154 154 */
155 155
156 156 /*!
157 157 \qmlmethod QPointF XYSeries::at(int index)
158 158 Returns point at \a index. Returns (0, 0) if the index is not valid.
159 159 */
160 160
161 161 /*!
162 162 \internal
163 163
164 164 Constructs empty series object which is a child of \a parent.
165 165 When series object is added to QChartView or QChart instance ownerships is transferred.
166 166 */
167 167 QXYSeries::QXYSeries(QXYSeriesPrivate &d,QObject *parent) : QAbstractSeries(d, parent)
168 168 {
169 169 }
170 170
171 171 /*!
172 172 Destroys the object. Series added to QChartView or QChart instances are owned by those,
173 173 and are deleted when mentioned object are destroyed.
174 174 */
175 175 QXYSeries::~QXYSeries()
176 176 {
177 177 }
178 178
179 179 /*!
180 180 Adds data point \a x \a y to the series. Points are connected with lines on the chart.
181 181 */
182 182 void QXYSeries::append(qreal x,qreal y)
183 183 {
184 184 append(QPointF(x,y));
185 185 }
186 186
187 187 /*!
188 188 This is an overloaded function.
189 189 Adds data \a point to the series. Points are connected with lines on the chart.
190 190 */
191 191 void QXYSeries::append(const QPointF &point)
192 192 {
193 193 Q_D(QXYSeries);
194 194 d->m_points<<point;
195 195 // emit d->pointAdded(d->m_points.count()-1);
196 196 emit pointAdded(d->m_points.count()-1);
197 197 }
198 198
199 199 /*!
200 200 This is an overloaded function.
201 201 Adds list of data \a points to the series. Points are connected with lines on the chart.
202 202 */
203 203 void QXYSeries::append(const QList<QPointF> &points)
204 204 {
205 205 foreach(const QPointF& point , points) {
206 206 append(point);
207 207 }
208 208 }
209 209
210 210 /*!
211 211 Replaces data point \a oldX \a oldY with data point \a newX \a newY.
212 212 */
213 213 void QXYSeries::replace(qreal oldX,qreal oldY,qreal newX,qreal newY)
214 214 {
215 215 replace(QPointF(oldX,oldY),QPointF(newX,newY));
216 216 }
217 217
218 218 /*!
219 219 Replaces \a oldPoint with \a newPoint.
220 220 */
221 221 void QXYSeries::replace(const QPointF &oldPoint,const QPointF &newPoint)
222 222 {
223 223 Q_D(QXYSeries);
224 224 int index = d->m_points.indexOf(oldPoint);
225 225 if(index==-1) return;
226 226 d->m_points[index] = newPoint;
227 227 // emit d->pointReplaced(index);
228 228 emit pointReplaced(index);
229 229 }
230 230
231 231 /*!
232 232 Removes current \a x and \a y value.
233 233 */
234 234 void QXYSeries::remove(qreal x,qreal y)
235 235 {
236 236 remove(QPointF(x,y));
237 237 }
238 238
239 239 /*!
240 240 Removes current \a point x value.
241 241
242 242 Note: point y value is ignored.
243 243 */
244 244 void QXYSeries::remove(const QPointF &point)
245 245 {
246 246 Q_D(QXYSeries);
247 247 int index = d->m_points.indexOf(point);
248 248 if(index==-1) return;
249 249 d->m_points.remove(index);
250 250 // emit d->pointRemoved(index);
251 251 emit pointRemoved(index);
252 252 }
253 253
254 254 /*!
255 255 Inserts a \a point in the series at \a index position.
256 256 */
257 257 void QXYSeries::insert(int index, const QPointF &point)
258 258 {
259 259 Q_D(QXYSeries);
260 260 d->m_points.insert(index, point);
261 261 // emit d->pointAdded(index);
262 262 emit pointAdded(index);
263 263 }
264 264
265 265 /*!
266 266 Removes all points from the series.
267 267 */
268 268 void QXYSeries::clear()
269 269 {
270 270 Q_D(QXYSeries);
271 271 for (int i = d->m_points.size() - 1; i >= 0; i--)
272 272 remove(d->m_points.at(i));
273 273 }
274 274
275 275 /*!
276 276 \internal \a pos
277 277 */
278 278 QList<QPointF> QXYSeries::points() const
279 279 {
280 280 Q_D(const QXYSeries);
281 281 return d->m_points.toList();
282 282 }
283 283
284 284 /*!
285 285 Returns number of data points within series.
286 286 */
287 287 int QXYSeries::count() const
288 288 {
289 289 Q_D(const QXYSeries);
290 290 return d->m_points.count();
291 291 }
292 292
293 293
294 294 /*!
295 295 Sets \a pen used for drawing points on the chart. If the pen is not defined, the
296 296 pen from chart theme is used.
297 297 \sa QChart::setTheme()
298 298 */
299 299 void QXYSeries::setPen(const QPen &pen)
300 300 {
301 301 Q_D(QXYSeries);
302 302 if (d->m_pen != pen) {
303 303 bool emitColorChanged = d->m_pen.color() != pen.color();
304 304 d->m_pen = pen;
305 305 emit d->updated();
306 306 if (emitColorChanged)
307 307 emit colorChanged(pen.color());
308 308 }
309 309 }
310 310
311 311 QPen QXYSeries::pen() const
312 312 {
313 313 Q_D(const QXYSeries);
314 314 return d->m_pen;
315 315 }
316 316
317 317 /*!
318 318 Sets \a brush used for drawing points on the chart. If the brush is not defined, brush
319 319 from chart theme setting is used.
320 320 \sa QChart::setTheme()
321 321 */
322 322 void QXYSeries::setBrush(const QBrush &brush)
323 323 {
324 324 Q_D(QXYSeries);
325 325 if (d->m_brush!=brush) {
326 326 d->m_brush = brush;
327 327 emit d->updated();
328 328 }
329 329 }
330 330
331 331 QBrush QXYSeries::brush() const
332 332 {
333 333 Q_D(const QXYSeries);
334 334 return d->m_brush;
335 335 }
336 336
337 337 void QXYSeries::setColor(const QColor &color)
338 338 {
339 339 QPen p = pen();
340 340 if (p.color() != color) {
341 341 p.setColor(color);
342 342 setPen(p);
343 343 }
344 344 }
345 345
346 346 QColor QXYSeries::color() const
347 347 {
348 348 return pen().color();
349 349 }
350 350
351 351 void QXYSeries::setPointsVisible(bool visible)
352 352 {
353 353 Q_D(QXYSeries);
354 354 if (d->m_pointsVisible != visible){
355 355 d->m_pointsVisible = visible;
356 356 emit d->updated();
357 357 }
358 358 }
359 359
360 360 bool QXYSeries::pointsVisible() const
361 361 {
362 362 Q_D(const QXYSeries);
363 363 return d->m_pointsVisible;
364 364 }
365 365
366 366
367 367 /*!
368 368 Stream operator for adding a data \a point to the series.
369 369 \sa append()
370 370 */
371 371 QXYSeries& QXYSeries::operator<< (const QPointF &point)
372 372 {
373 373 append(point);
374 374 return *this;
375 375 }
376 376
377 377
378 378 /*!
379 379 Stream operator for adding a list of \a points to the series.
380 380 \sa append()
381 381 */
382 382
383 383 QXYSeries& QXYSeries::operator<< (const QList<QPointF>& points)
384 384 {
385 385 append(points);
386 386 return *this;
387 387 }
388 388
389 389 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
390 390
391 391
392 392 QXYSeriesPrivate::QXYSeriesPrivate(QXYSeries *q) :
393 393 QAbstractSeriesPrivate(q),
394 394 m_pointsVisible(false)
395 395 {
396 396 }
397 397
398 398 void QXYSeriesPrivate::scaleDomain(Domain& domain)
399 399 {
400 400 qreal minX(domain.minX());
401 401 qreal minY(domain.minY());
402 402 qreal maxX(domain.maxX());
403 403 qreal maxY(domain.maxY());
404 int tickXCount(domain.tickXCount());
405 int tickYCount(domain.tickYCount());
406 404
407 405 Q_Q(QXYSeries);
408 406
409 407 const QList<QPointF>& points = q->points();
410 408
411 409
412 410 if (points.isEmpty()){
413 411 minX = qMin(minX, (qreal)0.0);
414 412 minY = qMin(minY, (qreal)0.0);
415 413 maxX = qMax(maxX, (qreal)1.0);
416 414 maxY = qMax(maxY, (qreal)1.0);
417 415 }
418 416
419 417 for (int i = 0; i < points.count(); i++) {
420 418 qreal x = points[i].x();
421 419 qreal y = points[i].y();
422 420 minX = qMin(minX, x);
423 421 minY = qMin(minY, y);
424 422 maxX = qMax(maxX, x);
425 423 maxY = qMax(maxY, y);
426 424 }
427 425
428 domain.setRange(minX,maxX,minY,maxY,tickXCount,tickYCount);
426 domain.setRange(minX,maxX,minY,maxY);
429 427 }
430 428
431 429 QList<LegendMarker*> QXYSeriesPrivate::createLegendMarker(QLegend* legend)
432 430 {
433 431 Q_Q(QXYSeries);
434 432 QList<LegendMarker*> list;
435 433 return list << new XYLegendMarker(q,legend);
436 434 }
437 435
438 436 void QXYSeriesPrivate::initializeAxis(QAbstractAxis* axis)
439 437 {
440 438 Q_UNUSED(axis);
441 439 }
442 440
443 441 QAbstractAxis::AxisType QXYSeriesPrivate::defaultAxisType(Qt::Orientation orientation) const
444 442 {
445 443 Q_UNUSED(orientation);
446 444 return QAbstractAxis::AxisTypeValues;
447 445 }
448 446
449 447 #include "moc_qxyseries.cpp"
450 448 #include "moc_qxyseries_p.cpp"
451 449
452 450 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,222 +1,223
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "xychart_p.h"
22 22 #include "qxyseries.h"
23 23 #include "qxyseries_p.h"
24 24 #include "chartpresenter_p.h"
25 25 #include "chartanimator_p.h"
26 #include "domain_p.h"
26 27 #include <QPainter>
27 28 #include <QAbstractItemModel>
28 29 #include "qxymodelmapper.h"
29 30 #include <QDebug>
30 31
31 32 QTCOMMERCIALCHART_BEGIN_NAMESPACE
32 33
33 34 //TODO: optimize : remove points which are not visible
34 35
35 36 XYChart::XYChart(QXYSeries *series, ChartPresenter *presenter):Chart(presenter),
36 37 m_minX(0),
37 38 m_maxX(0),
38 39 m_minY(0),
39 40 m_maxY(0),
40 41 m_series(series),
41 42 m_animation(0),
42 43 m_dirty(true)
43 44 {
44 45 // QObject::connect(series->d_func(),SIGNAL(pointReplaced(int)),this,SLOT(handlePointReplaced(int)));
45 46 // QObject::connect(series->d_func(),SIGNAL(pointAdded(int)),this,SLOT(handlePointAdded(int)));
46 47 // QObject::connect(series->d_func(),SIGNAL(pointRemoved(int)),this,SLOT(handlePointRemoved(int)));
47 48 QObject::connect(series, SIGNAL(pointReplaced(int)), this,SLOT(handlePointReplaced(int)));
48 49 QObject::connect(series, SIGNAL(pointAdded(int)), this,SLOT(handlePointAdded(int)));
49 50 QObject::connect(series, SIGNAL(pointRemoved(int)), this,SLOT(handlePointRemoved(int)));
50 51 QObject::connect(this, SIGNAL(clicked(QPointF)), series,SIGNAL(clicked(QPointF)));
51 52 }
52 53
53 54 void XYChart::setGeometryPoints(const QVector<QPointF>& points)
54 55 {
55 56 m_points = points;
56 57 }
57 58
58 59 void XYChart::setClipRect(const QRectF &rect)
59 60 {
60 61 m_clipRect = rect;
61 62 }
62 63
63 64 void XYChart::setAnimation(XYAnimation* animation)
64 65 {
65 66 m_animation=animation;
66 67 }
67 68
68 69 void XYChart::setDirty(bool dirty)
69 70 {
70 71 m_dirty=dirty;
71 72 }
72 73
73 74 QPointF XYChart::calculateGeometryPoint(const QPointF &point) const
74 75 {
75 76 const qreal deltaX = m_size.width()/(m_maxX-m_minX);
76 77 const qreal deltaY = m_size.height()/(m_maxY-m_minY);
77 78 qreal x = (point.x() - m_minX)* deltaX;
78 79 qreal y = (point.y() - m_minY)*-deltaY + m_size.height();
79 80 return QPointF(x,y);
80 81 }
81 82
82 83 QPointF XYChart::calculateGeometryPoint(int index) const
83 84 {
84 85 const qreal deltaX = m_size.width()/(m_maxX-m_minX);
85 86 const qreal deltaY = m_size.height()/(m_maxY-m_minY);
86 87 const QList<QPointF>& vector = m_series->points();
87 88 qreal x = (vector[index].x() - m_minX)* deltaX;
88 89 qreal y = (vector[index].y() - m_minY)*-deltaY + m_size.height();
89 90 return QPointF(x,y);
90 91 }
91 92
92 93 QVector<QPointF> XYChart::calculateGeometryPoints() const
93 94 {
94 95 const qreal deltaX = m_size.width()/(m_maxX-m_minX);
95 96 const qreal deltaY = m_size.height()/(m_maxY-m_minY);
96 97
97 98 QVector<QPointF> result;
98 99 result.resize(m_series->count());
99 100 const QList<QPointF>& vector = m_series->points();
100 101 for (int i = 0; i < m_series->count(); ++i) {
101 102 qreal x = (vector[i].x() - m_minX)* deltaX;
102 103 qreal y = (vector[i].y() - m_minY)*-deltaY + m_size.height();
103 104 result[i].setX(x);
104 105 result[i].setY(y);
105 106 }
106 107 return result;
107 108 }
108 109
109 110 QPointF XYChart::calculateDomainPoint(const QPointF &point) const
110 111 {
111 112 const qreal deltaX = m_size.width()/(m_maxX-m_minX);
112 113 const qreal deltaY = m_size.height()/(m_maxY-m_minY);
113 114 qreal x = point.x()/deltaX +m_minX;
114 115 qreal y = (point.y()-m_size.height())/(-deltaY)+ m_minY;
115 116 return QPointF(x,y);
116 117 }
117 118
118 119 void XYChart::updateChart(QVector<QPointF> &oldPoints, QVector<QPointF> &newPoints,int index)
119 120 {
120 121
121 122 if (m_animation) {
122 123 m_animation->setup(oldPoints, newPoints, index);
123 124 setGeometryPoints(newPoints);
124 125 setDirty(false);
125 126 presenter()->startAnimation(m_animation);
126 127 }
127 128 else {
128 129 setGeometryPoints(newPoints);
129 130 updateGeometry();
130 131 }
131 132 }
132 133
133 134 //handlers
134 135
135 136 void XYChart::handlePointAdded(int index)
136 137 {
137 138 Q_ASSERT(index<m_series->count());
138 139 Q_ASSERT(index>=0);
139 140
140 141 QVector<QPointF> points;
141 142
142 143 if(m_dirty) {
143 144 points = calculateGeometryPoints();
144 145 } else {
145 146 points = m_points;
146 147 QPointF point = calculateGeometryPoint(index);
147 148 points.insert(index, point);
148 149 }
149 150
150 151 updateChart(m_points,points,index);
151 152 }
152 153
153 154 void XYChart::handlePointRemoved(int index)
154 155 {
155 156 Q_ASSERT(index<=m_series->count());
156 157 Q_ASSERT(index>=0);
157 158
158 159 QVector<QPointF> points;
159 160
160 161 if(m_dirty) {
161 162 points = calculateGeometryPoints();
162 163 } else {
163 164 points = m_points;
164 165 points.remove(index);
165 166 }
166 167
167 168 updateChart(m_points,points,index);
168 169 }
169 170
170 171 void XYChart::handlePointReplaced(int index)
171 172 {
172 173 Q_ASSERT(index<m_series->count());
173 174 Q_ASSERT(index>=0);
174 175
175 176 QVector<QPointF> points;
176 177
177 178 if(m_dirty) {
178 179 points = calculateGeometryPoints();
179 180 } else {
180 181 QPointF point = calculateGeometryPoint(index);
181 182 points = m_points;
182 183 points.replace(index,point);
183 184 }
184 185
185 186 updateChart(m_points,points,index);
186 187 }
187 188
188 void XYChart::handleDomainChanged(qreal minX, qreal maxX, qreal minY, qreal maxY)
189 void XYChart::handleDomainUpdated()
189 190 {
190 m_minX=minX;
191 m_maxX=maxX;
192 m_minY=minY;
193 m_maxY=maxY;
191 m_minX=domain()->minX();
192 m_maxX=domain()->maxX();
193 m_minY=domain()->minY();
194 m_maxY=domain()->maxY();
194 195 if (isEmpty()) return;
195 196
196 197 QVector<QPointF> points = calculateGeometryPoints();
197 198
198 199 updateChart(m_points,points);
199 200 }
200 201
201 202 void XYChart::handleGeometryChanged(const QRectF &rect)
202 203 {
203 204 Q_ASSERT(rect.isValid());
204 205 m_size=rect.size();
205 206 m_clipRect=rect.translated(-rect.topLeft());
206 207 m_origin=rect.topLeft();
207 208
208 209 if (isEmpty()) return;
209 210
210 211 QVector<QPointF> points = calculateGeometryPoints();
211 212
212 213 updateChart(m_points,points);
213 214 }
214 215
215 216 bool XYChart::isEmpty()
216 217 {
217 218 return !m_clipRect.isValid() || qFuzzyIsNull(m_maxX - m_minX) || qFuzzyIsNull(m_maxY - m_minY) || m_series->points().isEmpty();
218 219 }
219 220
220 221 #include "moc_xychart_p.cpp"
221 222
222 223 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,106 +1,106
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 // W A R N I N G
22 22 // -------------
23 23 //
24 24 // This file is not part of the QtCommercial Chart API. It exists purely as an
25 25 // implementation detail. This header file may change from version to
26 26 // version without notice, or even be removed.
27 27 //
28 28 // We mean it.
29 29
30 30 #ifndef XYCHARTITEM_H
31 31 #define XYCHARTITEM_H
32 32
33 33 #include "qchartglobal.h"
34 34 #include "chartitem_p.h"
35 35 #include "xyanimation_p.h"
36 36 #include "qvaluesaxis.h"
37 37 #include <QPen>
38 38
39 39 QTCOMMERCIALCHART_BEGIN_NAMESPACE
40 40
41 41 class ChartPresenter;
42 42 class QXYSeries;
43 43
44 44 class XYChart : public Chart
45 45 {
46 46 Q_OBJECT
47 47 public:
48 48 explicit XYChart(QXYSeries *series, ChartPresenter *presenter);
49 49 ~XYChart(){};
50 50
51 51 void setGeometryPoints(const QVector<QPointF>& points);
52 52 QVector<QPointF> geometryPoints() const { return m_points; }
53 53
54 54 void setClipRect(const QRectF &rect);
55 55 QRectF clipRect() const { return m_clipRect; }
56 56
57 57 QSizeF size() const { return m_size; }
58 58 QPointF origin() const { return m_origin; }
59 59
60 60 void setAnimation(XYAnimation* animation);
61 61 ChartAnimation* animation() const { return m_animation; }
62 62 virtual void updateGeometry() = 0;
63 63
64 64 bool isDirty() const { return m_dirty; }
65 65 void setDirty(bool dirty);
66 66
67 67 public Q_SLOTS:
68 68 void handlePointAdded(int index);
69 69 void handlePointRemoved(int index);
70 70 void handlePointReplaced(int index);
71 void handleDomainChanged(qreal minX, qreal maxX, qreal minY, qreal maxY);
71 void handleDomainUpdated();
72 72 void handleGeometryChanged(const QRectF &size);
73 73
74 74 Q_SIGNALS:
75 75 void clicked(const QPointF& point);
76 76
77 77 protected:
78 78 virtual void updateChart(QVector<QPointF> &oldPoints,QVector<QPointF> &newPoints,int index = -1);
79 79 QPointF calculateGeometryPoint(const QPointF &point) const;
80 80 QPointF calculateGeometryPoint(int index) const;
81 81 QPointF calculateDomainPoint(const QPointF &point) const;
82 82 QVector<QPointF> calculateGeometryPoints() const;
83 83
84 84 private:
85 85 inline bool isEmpty();
86 86
87 87 private:
88 88 qreal m_minX;
89 89 qreal m_maxX;
90 90 qreal m_minY;
91 91 qreal m_maxY;
92 92 QXYSeries* m_series;
93 93 QSizeF m_size;
94 94 QPointF m_origin;
95 95 QRectF m_clipRect;
96 96 QVector<QPointF> m_points;
97 97 XYAnimation* m_animation;
98 98 bool m_dirty;
99 99
100 100 friend class AreaChartItem;
101 101
102 102 };
103 103
104 104 QTCOMMERCIALCHART_END_NAMESPACE
105 105
106 106 #endif
@@ -1,623 +1,623
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include <QtTest/QtTest>
22 22 #include <qabstractaxis.h>
23 23 #include <qvaluesaxis.h>
24 24 #include <qbarcategoriesaxis.h>
25 25 #include <qlineseries.h>
26 26 #include <qareaseries.h>
27 27 #include <qscatterseries.h>
28 28 #include <qsplineseries.h>
29 29 #include <qpieseries.h>
30 30 #include <qbarseries.h>
31 31 #include <qpercentbarseries.h>
32 32 #include <qstackedbarseries.h>
33 33 #include <private/chartdataset_p.h>
34 34 #include <private/domain_p.h>
35 35 #include <tst_definitions.h>
36 36
37 37 QTCOMMERCIALCHART_USE_NAMESPACE
38 38
39 39 Q_DECLARE_METATYPE(Domain *)
40 40 Q_DECLARE_METATYPE(QAbstractAxis *)
41 41 Q_DECLARE_METATYPE(QAbstractSeries *)
42 42 Q_DECLARE_METATYPE(QList<QAbstractSeries *>)
43 43 Q_DECLARE_METATYPE(QList<QAbstractAxis *>)
44 44 Q_DECLARE_METATYPE(QLineSeries *)
45 45
46 46 class tst_ChartDataSet: public QObject {
47 47
48 48 Q_OBJECT
49 49
50 50 public Q_SLOTS:
51 51 void initTestCase();
52 52 void cleanupTestCase();
53 53 void init();
54 54 void cleanup();
55 55
56 56 private Q_SLOTS:
57 57 void chartdataset_data();
58 58 void chartdataset();
59 59 void addSeries_data();
60 60 void addSeries();
61 61 void setAxisX_data();
62 62 void setAxisX();
63 63 void setAxisY_data();
64 64 void setAxisY();
65 65 void removeSeries_data();
66 66 void removeSeries();
67 67 void removeAllSeries_data();
68 68 void removeAllSeries();
69 69 void seriesCount_data();
70 70 void seriesCount();
71 71 void seriesIndex_data();
72 72 void seriesIndex();
73 73 void domain_data();
74 74 void domain();
75 75 void zoomInDomain_data();
76 76 void zoomInDomain();
77 77 void zoomOutDomain_data();
78 78 void zoomOutDomain();
79 79 void scrollDomain_data();
80 80 void scrollDomain();
81 81
82 82 private:
83 83 ChartDataSet* m_dataset;
84 84 };
85 85
86 86 void tst_ChartDataSet::initTestCase()
87 87 {
88 88 qRegisterMetaType<Domain*>();
89 89 qRegisterMetaType<QAbstractAxis*>();
90 90 qRegisterMetaType<QAbstractSeries*>();
91 91 }
92 92
93 93 void tst_ChartDataSet::cleanupTestCase()
94 94 {
95 95 }
96 96
97 97 void tst_ChartDataSet::init()
98 98 {
99 99 m_dataset = new ChartDataSet();
100 100 }
101 101
102 102
103 103 void tst_ChartDataSet::cleanup()
104 104 {
105 105 QList<QAbstractSeries*> series = m_dataset->series();
106 106 foreach(QAbstractSeries* serie, series)
107 107 {
108 108 m_dataset->removeSeries(serie);
109 109 }
110 110 }
111 111
112 112 void tst_ChartDataSet::chartdataset_data()
113 113 {
114 114 }
115 115
116 116 void tst_ChartDataSet::chartdataset()
117 117 {
118 118 QVERIFY(m_dataset->axisX(0) == 0);
119 119 QVERIFY(m_dataset->axisY(0) == 0);
120 120 QLineSeries* series = new QLineSeries(this);
121 121 QCOMPARE(m_dataset->seriesIndex(series),-1);
122 122 QVERIFY(m_dataset->domain(series) == 0);
123 123 QVERIFY(m_dataset->axisX(series) == 0);
124 124 QVERIFY(m_dataset->axisY(series) == 0);
125 125 m_dataset->createDefaultAxes();
126 126 }
127 127
128 128
129 129 void tst_ChartDataSet::addSeries_data()
130 130 {
131 131 QTest::addColumn<QAbstractSeries*>("series");
132 132
133 133 QAbstractSeries* line = new QLineSeries(this);
134 134 QAbstractSeries* area = new QAreaSeries(static_cast<QLineSeries*>(line));
135 135 QAbstractSeries* scatter = new QScatterSeries(this);
136 136 QAbstractSeries* spline = new QSplineSeries(this);
137 137 QAbstractSeries* pie = new QPieSeries(this);
138 138 QAbstractSeries* bar = new QBarSeries(this);
139 139 QAbstractSeries* percent = new QPercentBarSeries(this);
140 140 QAbstractSeries* stacked = new QStackedBarSeries(this);
141 141
142 142 QTest::newRow("line") << line;
143 143 QTest::newRow("area") << area;
144 144 QTest::newRow("scatter") << scatter;
145 145 QTest::newRow("spline") << spline;
146 146 QTest::newRow("pie") << pie;
147 147 QTest::newRow("bar") << bar;
148 148 QTest::newRow("percent") << percent;
149 149 QTest::newRow("stacked") << stacked;
150 150 }
151 151
152 152 void tst_ChartDataSet::addSeries()
153 153 {
154 154
155 155 QFETCH(QAbstractSeries*, series);
156 156
157 157 QSignalSpy spy0(m_dataset, SIGNAL(axisAdded(QAbstractAxis*, Domain *)));
158 158 QSignalSpy spy1(m_dataset, SIGNAL(axisRemoved(QAbstractAxis*)));
159 159 QSignalSpy spy2(m_dataset, SIGNAL(seriesAdded(QAbstractSeries *, Domain *)));
160 160 QSignalSpy spy3(m_dataset, SIGNAL(seriesRemoved(QAbstractSeries *)));
161 161
162 162 m_dataset->addSeries(series);
163 163 m_dataset->createDefaultAxes();
164 164 if(series->type()==QAbstractSeries::SeriesTypePie){
165 165 TRY_COMPARE(spy0.count(), 0);
166 166 }else{
167 167 TRY_COMPARE(spy0.count(), 2);
168 168 }
169 169 TRY_COMPARE(spy1.count(), 0);
170 170 TRY_COMPARE(spy2.count(), 1);
171 171 TRY_COMPARE(spy3.count(), 0);
172 172 }
173 173
174 174
175 175 void tst_ChartDataSet::setAxisX_data()
176 176 {
177 177 QTest::addColumn<QList<QAbstractSeries*> >("seriesList");
178 178 QTest::addColumn<QList<QAbstractAxis*> >("axisList");
179 179 QTest::addColumn<int>("axisCount");
180 180
181 181 QAbstractSeries* line = new QLineSeries(this);
182 182 QAbstractSeries* area = new QAreaSeries(static_cast<QLineSeries*>(line));
183 183 QAbstractSeries* scatter = new QScatterSeries(this);
184 184 QAbstractSeries* spline = new QSplineSeries(this);
185 185 QAbstractSeries* pie = new QPieSeries(this);
186 186 QAbstractSeries* bar = new QBarSeries(this);
187 187 QAbstractSeries* percent = new QPercentBarSeries(this);
188 188 QAbstractSeries* stacked = new QStackedBarSeries(this);
189 189
190 190 QTest::newRow("line,spline,scatter: axis 0 axis1 axis 2")
191 191 << (QList<QAbstractSeries*>() << line << spline << scatter)
192 192 << (QList<QAbstractAxis*>() << new QValuesAxis(this) << new QValuesAxis(this) << new QValuesAxis(this)) << 3;
193 193
194 194 QTest::newRow("area: axis 0") << (QList<QAbstractSeries*>() << area)
195 195 << (QList<QAbstractAxis*>() << new QValuesAxis(this)) << 1;
196 196
197 197 QList<QAbstractAxis*> axes0;
198 198 axes0 << new QValuesAxis(this) << new QValuesAxis(this);
199 199 axes0 << axes0.last();
200 200 QTest::newRow("line,spline,scatter: axis 0 axis1 axis 1")
201 201 << (QList<QAbstractSeries*>() << line << spline << scatter)
202 202 << axes0 << 2;
203 203 //TODO: add more test cases
204 204 }
205 205
206 206 void tst_ChartDataSet::setAxisX()
207 207 {
208 208 QFETCH(QList<QAbstractSeries*>, seriesList);
209 209 QFETCH(QList<QAbstractAxis*>, axisList);
210 210 QFETCH(int, axisCount);
211 211
212 212 Q_ASSERT(seriesList.count() == axisList.count());
213 213
214 214 QSignalSpy spy0(m_dataset, SIGNAL(axisAdded(QAbstractAxis *,Domain*)));
215 215 QSignalSpy spy1(m_dataset, SIGNAL(axisRemoved(QAbstractAxis *)));
216 216 QSignalSpy spy2(m_dataset, SIGNAL(seriesAdded(QAbstractSeries *,Domain*)));
217 217 QSignalSpy spy3(m_dataset, SIGNAL(seriesRemoved(QAbstractSeries *)));
218 218
219 219 foreach(QAbstractSeries* series, seriesList){
220 220 m_dataset->addSeries(series);
221 221 }
222 222
223 223 TRY_COMPARE(spy0.count(), 0);
224 224 TRY_COMPARE(spy1.count(), 0);
225 225 TRY_COMPARE(spy2.count(), seriesList.count());
226 226 TRY_COMPARE(spy3.count(), 0);
227 227
228 228 QSignalSpy spy4(m_dataset, SIGNAL(axisAdded(QAbstractAxis*,Domain*)));
229 229 QSignalSpy spy5(m_dataset, SIGNAL(axisRemoved(QAbstractAxis*)));
230 230 QSignalSpy spy6(m_dataset, SIGNAL(seriesAdded(QAbstractSeries *,Domain*)));
231 231 QSignalSpy spy7(m_dataset, SIGNAL(seriesRemoved(QAbstractSeries *)));
232 232
233 233 for(int i=0 ; i < seriesList.count(); i++){
234 234 m_dataset->setAxis(seriesList.at(i),axisList.at(i),Qt::Horizontal);
235 235 }
236 236
237 237 TRY_COMPARE(spy4.count(), axisCount);
238 238 TRY_COMPARE(spy5.count(), 0);
239 239 TRY_COMPARE(spy6.count(), 0);
240 240 TRY_COMPARE(spy7.count(), 0);
241 241
242 242 for(int i=0 ; i < seriesList.count(); i++){
243 243 QVERIFY(m_dataset->axisX(seriesList.at(i)) == axisList.at(i));
244 244 }
245 245 }
246 246
247 247 void tst_ChartDataSet::setAxisY_data()
248 248 {
249 249 setAxisX_data();
250 250 }
251 251
252 252 void tst_ChartDataSet::setAxisY()
253 253 {
254 254 QFETCH(QList<QAbstractSeries*>, seriesList);
255 255 QFETCH(QList<QAbstractAxis*>, axisList);
256 256 QFETCH(int, axisCount);
257 257
258 258 Q_ASSERT(seriesList.count() == axisList.count());
259 259
260 260 QSignalSpy spy0(m_dataset, SIGNAL(axisAdded(QAbstractAxis*,Domain*)));
261 261 QSignalSpy spy1(m_dataset, SIGNAL(axisRemoved(QAbstractAxis*)));
262 262 QSignalSpy spy2(m_dataset, SIGNAL(seriesAdded(QAbstractSeries *,Domain*)));
263 263 QSignalSpy spy3(m_dataset, SIGNAL(seriesRemoved(QAbstractSeries *)));
264 264
265 265 foreach(QAbstractSeries* series, seriesList){
266 266 m_dataset->addSeries(series);
267 267 }
268 268
269 269 TRY_COMPARE(spy0.count(), 0);
270 270 TRY_COMPARE(spy1.count(), 0);
271 271 TRY_COMPARE(spy2.count(), seriesList.count());
272 272 TRY_COMPARE(spy3.count(), 0);
273 273
274 274 QSignalSpy spy4(m_dataset, SIGNAL(axisAdded(QAbstractAxis*,Domain*)));
275 275 QSignalSpy spy5(m_dataset, SIGNAL(axisRemoved(QAbstractAxis*)));
276 276 QSignalSpy spy6(m_dataset, SIGNAL(seriesAdded(QAbstractSeries *,Domain*)));
277 277 QSignalSpy spy7(m_dataset, SIGNAL(seriesRemoved(QAbstractSeries *)));
278 278
279 279 for(int i=0 ; i < seriesList.count(); i++){
280 280 m_dataset->setAxis(seriesList.at(i),axisList.at(i),Qt::Vertical);
281 281 }
282 282
283 283 TRY_COMPARE(spy4.count(), axisCount);
284 284 TRY_COMPARE(spy5.count(), 0);
285 285 TRY_COMPARE(spy6.count(), 0);
286 286 TRY_COMPARE(spy7.count(), 0);
287 287
288 288 for(int i=0 ; i < seriesList.count(); i++){
289 289 QVERIFY(m_dataset->axisY(seriesList.at(i)) == axisList.at(i));
290 290 }
291 291 }
292 292
293 293 void tst_ChartDataSet::removeSeries_data()
294 294 {
295 295 addSeries_data();
296 296 }
297 297
298 298 void tst_ChartDataSet::removeSeries()
299 299 {
300 300 QFETCH(QAbstractSeries*, series);
301 301
302 302 m_dataset->addSeries(series);
303 303 m_dataset->createDefaultAxes();
304 304
305 305 QSignalSpy spy0(m_dataset, SIGNAL(axisAdded(QAbstractAxis*, Domain *)));
306 306 QSignalSpy spy1(m_dataset, SIGNAL(axisRemoved(QAbstractAxis*)));
307 307 QSignalSpy spy2(m_dataset, SIGNAL(seriesAdded(QAbstractSeries *, Domain *)));
308 308 QSignalSpy spy3(m_dataset, SIGNAL(seriesRemoved(QAbstractSeries *)));
309 309
310 310 m_dataset->removeSeries(series);
311 311
312 312 TRY_COMPARE(spy0.count(), 0);
313 313 if (series->type() == QAbstractSeries::SeriesTypePie) {
314 314 TRY_COMPARE(spy1.count(), 0);
315 315 }
316 316 else {
317 317 TRY_COMPARE(spy1.count(), 2);
318 318 }
319 319 TRY_COMPARE(spy2.count(), 0);
320 320 TRY_COMPARE(spy3.count(), 1);
321 321 }
322 322
323 323 void tst_ChartDataSet::removeAllSeries_data()
324 324 {
325 325 QTest::addColumn<QList<QAbstractSeries*> >("seriesList");
326 326 QTest::addColumn<QList<QAbstractAxis*> >("axisList");
327 327 QTest::addColumn<int>("axisCount");
328 328
329 329 QTest::newRow("line,spline,scatter: axis 0 axis1 axis 2")
330 330 << (QList<QAbstractSeries*>() << new QLineSeries(this) << new QSplineSeries(this)
331 331 << new QScatterSeries(this))
332 332 << (QList<QAbstractAxis*>() << new QValuesAxis(this) << new QValuesAxis(this)
333 333 << new QValuesAxis(this)) << 3;
334 334 //TODO:
335 335 }
336 336
337 337 void tst_ChartDataSet::removeAllSeries()
338 338 {
339 339 QFETCH(QList<QAbstractSeries*>, seriesList);
340 340 QFETCH(QList<QAbstractAxis*>, axisList);
341 341 QFETCH(int, axisCount);
342 342
343 343 foreach(QAbstractSeries* series, seriesList) {
344 344 m_dataset->addSeries(series);
345 345 }
346 346
347 347 for (int i = 0; i < seriesList.count(); i++) {
348 348 m_dataset->setAxis(seriesList.at(i), axisList.at(i),Qt::Horizontal);
349 349 }
350 350
351 351 QSignalSpy spy0(m_dataset, SIGNAL(axisAdded(QAbstractAxis *, Domain *)));
352 352 QSignalSpy spy1(m_dataset, SIGNAL(axisRemoved(QAbstractAxis *)));
353 353 QSignalSpy spy2(m_dataset, SIGNAL(seriesAdded(QAbstractSeries *, Domain *)));
354 354 QSignalSpy spy3(m_dataset, SIGNAL(seriesRemoved(QAbstractSeries *)));
355 355
356 356 m_dataset->removeAllSeries();
357 357
358 358 TRY_COMPARE(spy0.count(), 0);
359 359 TRY_COMPARE(spy1.count(), axisCount);
360 360 TRY_COMPARE(spy2.count(), 0);
361 361 TRY_COMPARE(spy3.count(), seriesList.count());
362 362 }
363 363
364 364
365 365 void tst_ChartDataSet::seriesCount_data()
366 366 {
367 367 QTest::addColumn<QList<QAbstractSeries*> >("seriesList");
368 368 QTest::addColumn<int>("seriesCount");
369 369
370 370 QTest::newRow("line,line, line, spline 3") << (QList<QAbstractSeries*>() << new QLineSeries(this) << new QLineSeries(this) << new QLineSeries(this) << new QSplineSeries(this) ) << 3;
371 371 QTest::newRow("scatter,scatter, line, line 2") << (QList<QAbstractSeries*>() << new QScatterSeries(this) << new QScatterSeries(this) << new QLineSeries(this) << new QLineSeries(this) ) << 2;
372 372 }
373 373
374 374 void tst_ChartDataSet::seriesCount()
375 375 {
376 376 QFETCH(QList<QAbstractSeries*>, seriesList);
377 377 QFETCH(int, seriesCount);
378 378
379 379 foreach(QAbstractSeries* series, seriesList){
380 380 m_dataset->addSeries(series);
381 381 }
382 382
383 383 QSignalSpy spy0(m_dataset, SIGNAL(axisAdded(QAbstractAxis *, Domain *)));
384 384 QSignalSpy spy1(m_dataset, SIGNAL(axisRemoved(QAbstractAxis *)));
385 385 QSignalSpy spy2(m_dataset, SIGNAL(seriesAdded(QAbstractSeries *, Domain *)));
386 386 QSignalSpy spy3(m_dataset, SIGNAL(seriesRemoved(QAbstractSeries *)));
387 387
388 388 QCOMPARE(m_dataset->seriesCount(seriesList.at(0)->type()),seriesCount);
389 389 TRY_COMPARE(spy0.count(), 0);
390 390 TRY_COMPARE(spy1.count(), 0);
391 391 TRY_COMPARE(spy2.count(), 0);
392 392 TRY_COMPARE(spy3.count(), 0);
393 393 }
394 394
395 395 void tst_ChartDataSet::seriesIndex_data()
396 396 {
397 397 QTest::addColumn<QList<QAbstractSeries*> >("seriesList");
398 398
399 399 QTest::newRow("line,line, line, spline") << (QList<QAbstractSeries*>() << new QLineSeries(this) << new QLineSeries(this) << new QLineSeries(this) << new QSplineSeries(this) );
400 400 QTest::newRow("scatter,scatter, line, line") << (QList<QAbstractSeries*>() << new QScatterSeries(this) << new QScatterSeries(this) << new QLineSeries(this) << new QLineSeries(this) );
401 401 }
402 402
403 403 void tst_ChartDataSet::seriesIndex()
404 404 {
405 405
406 406 QFETCH(QList<QAbstractSeries*>, seriesList);
407 407
408 408 foreach(QAbstractSeries* series, seriesList) {
409 409 m_dataset->addSeries(series);
410 410 }
411 411
412 412 QSignalSpy spy0(m_dataset, SIGNAL(axisAdded(QAbstractAxis *,Domain*)));
413 413 QSignalSpy spy1(m_dataset, SIGNAL(axisRemoved(QAbstractAxis *)));
414 414 QSignalSpy spy2(m_dataset, SIGNAL(seriesAdded(QAbstractSeries*,Domain*)));
415 415 QSignalSpy spy3(m_dataset, SIGNAL(seriesRemoved(QAbstractSeries*)));
416 416
417 417 for (int i = 0; i < seriesList.count(); i++) {
418 418 QCOMPARE(m_dataset->seriesIndex(seriesList.at(i)), i);
419 419 }
420 420
421 421 TRY_COMPARE(spy0.count(), 0);
422 422 TRY_COMPARE(spy1.count(), 0);
423 423 TRY_COMPARE(spy2.count(), 0);
424 424 TRY_COMPARE(spy3.count(), 0);
425 425
426 426 foreach(QAbstractSeries* series, seriesList) {
427 427 m_dataset->removeSeries(series);
428 428 }
429 429
430 430 for (int i = 0; i < seriesList.count(); i++) {
431 431 QCOMPARE(m_dataset->seriesIndex(seriesList.at(i)), -1);
432 432 }
433 433
434 434 foreach(QAbstractSeries* series, seriesList) {
435 435 m_dataset->addSeries(series);
436 436 }
437 437
438 438 for (int i = 0; i < seriesList.count(); i++) {
439 439 QCOMPARE(m_dataset->seriesIndex(seriesList.at(i)), i);
440 440 }
441 441
442 442 m_dataset->removeSeries(seriesList.at(1));
443 443
444 444 for (int i = 0; i < seriesList.count(); i++) {
445 445 if (i != 1)
446 446 QCOMPARE(m_dataset->seriesIndex(seriesList.at(i)), i);
447 447 else
448 448 QCOMPARE(m_dataset->seriesIndex(seriesList.at(i)), -1);
449 449 }
450 450
451 451 m_dataset->addSeries(seriesList.at(1));
452 452
453 453 for (int i = 0; i < seriesList.count(); i++) {
454 454 QCOMPARE(m_dataset->seriesIndex(seriesList.at(i)), i);
455 455 }
456 456
457 457 m_dataset->removeSeries(seriesList.at(2));
458 458
459 459 for (int i = 0; i < seriesList.count(); i++) {
460 460 if (i != 2)
461 461 QCOMPARE(m_dataset->seriesIndex(seriesList.at(i)), i);
462 462 else
463 463 QCOMPARE(m_dataset->seriesIndex(seriesList.at(i)), -1);
464 464 }
465 465
466 466 m_dataset->removeSeries(seriesList.at(0));
467 467
468 468 for (int i = 0; i < seriesList.count(); i++) {
469 469 if (i != 2 && i != 0)
470 470 QCOMPARE(m_dataset->seriesIndex(seriesList.at(i)), i);
471 471 else
472 472 QCOMPARE(m_dataset->seriesIndex(seriesList.at(i)), -1);
473 473 }
474 474
475 475 m_dataset->addSeries(seriesList.at(2));
476 476 m_dataset->addSeries(seriesList.at(0));
477 477
478 478 for (int i = 0; i < seriesList.count(); i++) {
479 479 if (i == 2)
480 480 QCOMPARE(m_dataset->seriesIndex(seriesList.at(i)), 0);
481 481 else if (i == 0)
482 482 QCOMPARE(m_dataset->seriesIndex(seriesList.at(i)), 2);
483 483 else
484 484 QCOMPARE(m_dataset->seriesIndex(seriesList.at(i)), i);
485 485 }
486 486
487 487 }
488 488
489 489 void tst_ChartDataSet::domain_data()
490 490 {
491 491 addSeries_data();
492 492 }
493 493
494 494 void tst_ChartDataSet::domain()
495 495 {
496 496 QFETCH(QAbstractSeries*, series);
497 497
498 498 QSignalSpy spy0(m_dataset, SIGNAL(axisAdded(QAbstractAxis *, Domain *)));
499 499 QSignalSpy spy1(m_dataset, SIGNAL(axisRemoved(QAbstractAxis *)));
500 500 QSignalSpy spy2(m_dataset, SIGNAL(seriesAdded(QAbstractSeries *, Domain *)));
501 501 QSignalSpy spy3(m_dataset, SIGNAL(seriesRemoved(QAbstractSeries *)));
502 502
503 503 m_dataset->addSeries(series);
504 504 QVERIFY(m_dataset->domain(series));
505 505
506 506
507 507 TRY_COMPARE(spy0.count(), 0);
508 508 TRY_COMPARE(spy1.count(), 0);
509 509 TRY_COMPARE(spy2.count(), 1);
510 510
511 511 QList<QVariant> arguments = spy2.takeFirst();
512 512 Domain *domain = (Domain *) arguments.at(1).value<Domain *>();
513 513 QVERIFY(m_dataset->domain(series) == domain);
514 514
515 515 TRY_COMPARE(spy3.count(), 0);
516 516
517 517 }
518 518
519 519 void tst_ChartDataSet::zoomInDomain_data()
520 520 {
521 521 QTest::addColumn<bool >("sameAxis");
522 522 QTest::addColumn<QList<QAbstractSeries*> >("seriesList");
523 523 QTest::newRow("sameAxis: line,line, line, spline") << true << (QList<QAbstractSeries*>() << new QLineSeries(this) << new QLineSeries(this) << new QLineSeries(this) << new QSplineSeries(this) );
524 524 QTest::newRow("separeateAxis: line,line, line, spline") << false << (QList<QAbstractSeries*>() << new QLineSeries(this) << new QLineSeries(this) << new QLineSeries(this) << new QSplineSeries(this) );
525 525 }
526 526
527 527 void tst_ChartDataSet::zoomInDomain()
528 528 {
529 529 QFETCH(bool, sameAxis);
530 530 QFETCH(QList<QAbstractSeries*>, seriesList);
531 531
532 532 foreach(QAbstractSeries* series, seriesList) {
533 533 m_dataset->addSeries(series);
534 534 }
535 535
536 536 if(sameAxis) m_dataset->createDefaultAxes();
537 537
538 538 QList<QSignalSpy*> spyList;
539 539
540 540 foreach(QAbstractSeries* series, seriesList) {
541 spyList << new QSignalSpy(m_dataset->domain(series),SIGNAL(domainChanged(qreal,qreal,qreal,qreal)));
541 spyList << new QSignalSpy(m_dataset->domain(series),SIGNAL(updated()));
542 542 }
543 543
544 544 m_dataset->zoomInDomain(QRect(0, 0, 100, 100), QSize(1000, 1000));
545 545
546 546 foreach(QSignalSpy* spy, spyList) {
547 547 TRY_COMPARE(spy->count(), 1);
548 548 }
549 549
550 550 qDeleteAll(spyList);
551 551 }
552 552
553 553
554 554
555 555 void tst_ChartDataSet::zoomOutDomain_data()
556 556 {
557 557 zoomInDomain_data();
558 558 }
559 559
560 560 void tst_ChartDataSet::zoomOutDomain()
561 561 {
562 562 QFETCH(bool, sameAxis);
563 563 QFETCH(QList<QAbstractSeries*>, seriesList);
564 564
565 565 foreach(QAbstractSeries* series, seriesList) {
566 566 m_dataset->addSeries(series);
567 567 }
568 568
569 569 if (sameAxis)
570 570 m_dataset->createDefaultAxes();
571 571
572 572 QList<QSignalSpy*> spyList;
573 573
574 574 foreach(QAbstractSeries* series, seriesList) {
575 spyList << new QSignalSpy(m_dataset->domain(series), SIGNAL(domainChanged(qreal,qreal,qreal,qreal)));
575 spyList << new QSignalSpy(m_dataset->domain(series), SIGNAL(updated()));
576 576 }
577 577
578 578 m_dataset->zoomOutDomain(QRect(0, 0, 100, 100), QSize(1000, 1000));
579 579
580 580 foreach(QSignalSpy* spy, spyList) {
581 581 TRY_COMPARE(spy->count(), 1);
582 582 }
583 583
584 584 qDeleteAll (spyList);
585 585 }
586 586
587 587 void tst_ChartDataSet::scrollDomain_data()
588 588 {
589 589 zoomInDomain_data();
590 590 }
591 591
592 592 void tst_ChartDataSet::scrollDomain()
593 593 {
594 594 QFETCH(bool, sameAxis);
595 595 QFETCH(QList<QAbstractSeries*>, seriesList);
596 596
597 597 foreach(QAbstractSeries* series, seriesList) {
598 598 m_dataset->addSeries(series);
599 599 }
600 600
601 601 if (sameAxis)
602 602 m_dataset->createDefaultAxes();
603 603
604 604 QList<QSignalSpy*> spyList;
605 605
606 606 foreach(QAbstractSeries* series, seriesList) {
607 607 spyList
608 608 << new QSignalSpy(m_dataset->domain(series),
609 SIGNAL(domainChanged(qreal,qreal,qreal,qreal)));
609 SIGNAL(updated()));
610 610 }
611 611
612 612 m_dataset->scrollDomain(10, 10, QSize(1000, 1000));
613 613
614 614 foreach(QSignalSpy* spy, spyList) {
615 615 TRY_COMPARE(spy->count(), 1);
616 616 }
617 617
618 618 qDeleteAll(spyList);
619 619 }
620 620
621 621 QTEST_MAIN(tst_ChartDataSet)
622 622 #include "tst_chartdataset.moc"
623 623
@@ -1,711 +1,733
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include <QtTest/QtTest>
22 22 #include <private/domain_p.h>
23 #include <private/qabstractaxis_p.h>
23 24 #include <tst_definitions.h>
24 25
25 26 QTCOMMERCIALCHART_USE_NAMESPACE
26 27
27 28 Q_DECLARE_METATYPE(Domain*)
28 29 Q_DECLARE_METATYPE(QSizeF)
29 30
31
32 class AxisMock: public QAbstractAxisPrivate
33 {
34 Q_OBJECT
35 public:
36 AxisMock(Qt::Orientation orientation):QAbstractAxisPrivate(0){ setOrientation(orientation);};
37 ChartAxis* createGraphics(ChartPresenter* presenter){};
38 void intializeDomain(Domain* domain){};
39 void setMin(const QVariant &min){}
40 qreal min() { return m_min;}
41 void setMax(const QVariant &max){}
42 qreal max() { return m_max; }
43 void setRange(const QVariant &min, const QVariant &max){};
44
45 void handleDomainUpdated(){};
46 public:
47 qreal m_min;
48 qreal m_max;
49 };
50
30 51 class tst_Domain: public QObject
31 52 {
32 53 Q_OBJECT
33 54
34 55 public Q_SLOTS:
35 56 void initTestCase();
36 57 void cleanupTestCase();
37 58 void init();
38 59 void cleanup();
39 60
40 61 private Q_SLOTS:
41 62 void domain();
42 void handleAxisRangeXChanged_data();
43 void handleAxisRangeXChanged();
44 void handleAxisRangeYChanged_data();
45 void handleAxisRangeYChanged();
63 void handleAxisUpdatedX_data();
64 void handleAxisUpdatedX();
65 void handleAxisUpdatedY_data();
66 void handleAxisUpdatedY();
46 67 void isEmpty_data();
47 68 void isEmpty();
48 69 void maxX_data();
49 70 void maxX();
50 71 void maxY_data();
51 72 void maxY();
52 73 void minX_data();
53 74 void minX();
54 75 void minY_data();
55 76 void minY();
56 77 void operatorEquals_data();
57 78 void operatorEquals();
58 79 void setRange_data();
59 80 void setRange();
60 81 void setRangeX_data();
61 82 void setRangeX();
62 83 void setRangeY_data();
63 84 void setRangeY();
64 85 void spanX_data();
65 86 void spanX();
66 87 void spanY_data();
67 88 void spanY();
68 89 void zoom_data();
69 90 void zoom();
70 91 void move_data();
71 92 void move();
72 void handleAxisXChanged_data();
73 void handleAxisXChanged();
74 void handleAxisYChanged_data();
75 void handleAxisYChanged();
76 93 };
77 94
78 95 void tst_Domain::initTestCase()
79 96 {
80 97 }
81 98
82 99 void tst_Domain::cleanupTestCase()
83 100 {
84 101 }
85 102
86 103 void tst_Domain::init()
87 104 {
88 105 }
89 106
90 107 void tst_Domain::cleanup()
91 108 {
92 109 }
93 110
94 111 void tst_Domain::domain()
95 112 {
96 113 Domain domain;
97 114
98 115 QCOMPARE(domain.isEmpty(), true);
99 116 QCOMPARE(domain.maxX(), 0.0);
100 117 QCOMPARE(domain.maxY(), 0.0);
101 118 QCOMPARE(domain.minX(), 0.0);
102 119 QCOMPARE(domain.minY(), 0.0);
103 120 }
104 121
105 void tst_Domain::handleAxisRangeXChanged_data()
122 void tst_Domain::handleAxisUpdatedX_data()
106 123 {
107 124 QTest::addColumn<qreal>("min");
108 125 QTest::addColumn<qreal>("max");
109 126 QTest::newRow("-1 1") << -1.0 << 1.0;
110 127 QTest::newRow("0 1") << 0.0 << 1.0;
111 128 QTest::newRow("-1 0") << -1.0 << 0.0;
112 129 }
113 130
114 void tst_Domain::handleAxisRangeXChanged()
131 void tst_Domain::handleAxisUpdatedX()
115 132 {
116 133 QFETCH(qreal, min);
117 134 QFETCH(qreal, max);
118 135
119 136 Domain domain;
120 137
121 QSignalSpy spy0(&domain, SIGNAL(domainChanged(qreal,qreal,qreal,qreal)));
122 QSignalSpy spy1(&domain, SIGNAL(rangeXChanged(qreal,qreal,int)));
123 QSignalSpy spy2(&domain, SIGNAL(rangeYChanged(qreal,qreal,int)));
138 QSignalSpy spy0(&domain, SIGNAL(updated()));
139 QSignalSpy spy1(&domain, SIGNAL(rangeXChanged(qreal,qreal)));
140 QSignalSpy spy2(&domain, SIGNAL(rangeYChanged(qreal,qreal)));
124 141
125 domain.handleAxisXChanged(min, max);
142 AxisMock axis(Qt::Horizontal);
143 QObject::connect(&axis,SIGNAL(updated()),&domain,SLOT(handleAxisUpdated()));
144 axis.m_min=min;
145 axis.m_max=max;
146 axis.emitUpdated();
126 147
127 QList<QVariant> arg0 = spy0.first();
128 QVERIFY(qFuzzyIsNull(arg0.at(0).toReal() - min));
129 QVERIFY(qFuzzyIsNull(arg0.at(1).toReal() - max));
148 QVERIFY(qFuzzyIsNull(domain.minX() - min));
149 QVERIFY(qFuzzyIsNull(domain.maxX() - max));
130 150
131 151 QList<QVariant> arg1 = spy1.first();
132 152 QVERIFY(qFuzzyIsNull(arg1.at(0).toReal() - min));
133 153 QVERIFY(qFuzzyIsNull(arg1.at(1).toReal() - max));
134 154
135 155 TRY_COMPARE(spy0.count(), 1);
136 156 TRY_COMPARE(spy1.count(), 1);
137 157 TRY_COMPARE(spy2.count(), 0);
138 158
139 159 }
140 160
141 void tst_Domain::handleAxisRangeYChanged_data()
161 void tst_Domain::handleAxisUpdatedY_data()
142 162 {
143 163 QTest::addColumn<qreal>("min");
144 164 QTest::addColumn<qreal>("max");
145 165 QTest::newRow("-1 1") << -1.0 << 1.0;
146 166 QTest::newRow("0 1") << 0.0 << 1.0;
147 167 QTest::newRow("-1 0") << -1.0 << 0.0;
148 168 }
149 169
150 void tst_Domain::handleAxisRangeYChanged()
170 void tst_Domain::handleAxisUpdatedY()
151 171 {
152 172 QFETCH(qreal, min);
153 173 QFETCH(qreal, max);
154 174
155 175 Domain domain;
156 176
157 QSignalSpy spy0(&domain, SIGNAL(domainChanged(qreal,qreal,qreal,qreal)));
158 QSignalSpy spy1(&domain, SIGNAL(rangeXChanged(qreal,qreal,int)));
159 QSignalSpy spy2(&domain, SIGNAL(rangeYChanged(qreal,qreal,int)));
177 QSignalSpy spy0(&domain, SIGNAL(updated()));
178 QSignalSpy spy1(&domain, SIGNAL(rangeXChanged(qreal,qreal)));
179 QSignalSpy spy2(&domain, SIGNAL(rangeYChanged(qreal,qreal)));
160 180
161 domain.handleAxisYChanged(min, max, 5);
181 AxisMock axis(Qt::Vertical);
182 QObject::connect(&axis, SIGNAL(updated()), &domain, SLOT(handleAxisUpdated()));
183 axis.m_min = min;
184 axis.m_max = max;
185 axis.emitUpdated();
162 186
163 QList<QVariant> arg0 = spy0.first();
164 QVERIFY(qFuzzyIsNull(arg0.at(2).toReal() - min));
165 QVERIFY(qFuzzyIsNull(arg0.at(3).toReal() - max));
187 QVERIFY(qFuzzyIsNull(domain.minY() - min));
188 QVERIFY(qFuzzyIsNull(domain.maxY() - max));
166 189
167 190 QList<QVariant> arg1 = spy2.first();
168 191 QVERIFY(qFuzzyIsNull(arg1.at(0).toReal() - min));
169 192 QVERIFY(qFuzzyIsNull(arg1.at(1).toReal() - max));
170 193
171 194 TRY_COMPARE(spy0.count(), 1);
172 195 TRY_COMPARE(spy1.count(), 0);
173 196 TRY_COMPARE(spy2.count(), 1);
174 197 }
175 198
176 199 void tst_Domain::isEmpty_data()
177 200 {
178 201 QTest::addColumn<qreal>("minX");
179 202 QTest::addColumn<qreal>("maxX");
180 203 QTest::addColumn<qreal>("minY");
181 204 QTest::addColumn<qreal>("maxY");
182 205 QTest::addColumn<bool>("isEmpty");
183 206 QTest::newRow("0 0 0 0") << 0.0 << 0.0 << 0.0 << 0.0 << true;
184 207 QTest::newRow("0 1 0 0") << 0.0 << 1.0 << 0.0 << 0.0 << true;
185 208 QTest::newRow("0 0 0 1") << 0.0 << 1.0 << 0.0 << 0.0 << true;
186 209 QTest::newRow("0 1 0 1") << 0.0 << 1.0 << 0.0 << 1.0 << false;
187 210 }
188 211
189 212 void tst_Domain::isEmpty()
190 213 {
191 214 QFETCH(qreal, minX);
192 215 QFETCH(qreal, maxX);
193 216 QFETCH(qreal, minY);
194 217 QFETCH(qreal, maxY);
195 218 QFETCH(bool, isEmpty);
196 219
197 220 Domain domain;
198 221 domain.setRange(minX, maxX, minY, maxY);
199 222 QCOMPARE(domain.isEmpty(), isEmpty);
200 223 }
201 224
202 225 void tst_Domain::maxX_data()
203 226 {
204 227 QTest::addColumn<qreal>("maxX1");
205 228 QTest::addColumn<qreal>("maxX2");
206 229 QTest::addColumn<int>("count");
207 230 QTest::newRow("1") << 0.0 << 1.0 << 1;
208 231 QTest::newRow("1.0") << 1.0 << 1.0 << 1;
209 232 QTest::newRow("2.0") << 1.0 << 0.0 << 2;
210 233 }
211 234
212 235 void tst_Domain::maxX()
213 236 {
214 237 QFETCH(qreal, maxX1);
215 238 QFETCH(qreal, maxX2);
216 239 QFETCH(int, count);
217 240
218 241 Domain domain;
219 242
220 QSignalSpy spy0(&domain, SIGNAL(domainChanged(qreal,qreal,qreal,qreal)));
221 QSignalSpy spy1(&domain, SIGNAL(rangeXChanged(qreal,qreal,int)));
222 QSignalSpy spy2(&domain, SIGNAL(rangeYChanged(qreal,qreal,int)));
243 QSignalSpy spy0(&domain, SIGNAL(updated()));
244 QSignalSpy spy1(&domain, SIGNAL(rangeXChanged(qreal,qreal)));
245 QSignalSpy spy2(&domain, SIGNAL(rangeYChanged(qreal,qreal)));
223 246
224 247 domain.setMaxX(maxX1);
225 248 QCOMPARE(domain.maxX(), maxX1);
226 249 domain.setMaxX(maxX2);
227 250 QCOMPARE(domain.maxX(), maxX2);
228 251
229 252 TRY_COMPARE(spy0.count(), count);
230 253 TRY_COMPARE(spy1.count(), count);
231 254 TRY_COMPARE(spy2.count(), 0);
232 255
233 256 }
234 257
235 258 void tst_Domain::maxY_data()
236 259 {
237 260 QTest::addColumn<qreal>("maxY1");
238 261 QTest::addColumn<qreal>("maxY2");
239 262 QTest::addColumn<int>("count");
240 263 QTest::newRow("1") << 0.0 << 1.0 << 1;
241 264 QTest::newRow("1.0") << 1.0 << 1.0 << 1;
242 265 QTest::newRow("2.0") << 1.0 << 0.0 << 2;
243 266 }
244 267
245 268 void tst_Domain::maxY()
246 269 {
247 270 QFETCH(qreal, maxY1);
248 271 QFETCH(qreal, maxY2);
249 272 QFETCH(int, count);
250 273
251 274 Domain domain;
252 275
253 QSignalSpy spy0(&domain, SIGNAL(domainChanged(qreal,qreal,qreal,qreal)));
254 QSignalSpy spy1(&domain, SIGNAL(rangeXChanged(qreal,qreal,int)));
255 QSignalSpy spy2(&domain, SIGNAL(rangeYChanged(qreal,qreal,int)));
276 QSignalSpy spy0(&domain, SIGNAL(updated()));
277 QSignalSpy spy1(&domain, SIGNAL(rangeXChanged(qreal,qreal)));
278 QSignalSpy spy2(&domain, SIGNAL(rangeYChanged(qreal,qreal)));
256 279
257 280 domain.setMaxY(maxY1);
258 281 QCOMPARE(domain.maxY(), maxY1);
259 282 domain.setMaxY(maxY2);
260 283 QCOMPARE(domain.maxY(), maxY2);
261 284
262 285 TRY_COMPARE(spy0.count(), count);
263 286 TRY_COMPARE(spy1.count(), 0);
264 287 TRY_COMPARE(spy2.count(), count);
265 288 }
266 289
267 290 void tst_Domain::minX_data()
268 291 {
269 292 QTest::addColumn<qreal>("minX1");
270 293 QTest::addColumn<qreal>("minX2");
271 294 QTest::addColumn<int>("count");
272 295 QTest::newRow("1") << 0.0 << 1.0 << 1;
273 296 QTest::newRow("1.0") << 1.0 << 1.0 << 1;
274 297 QTest::newRow("2.0") << 1.0 << 0.0 << 2;
275 298 }
276 299
277 300 void tst_Domain::minX()
278 301 {
279 302 QFETCH(qreal, minX1);
280 303 QFETCH(qreal, minX2);
281 304 QFETCH(int, count);
282 305
283 306 Domain domain;
284 307
285 QSignalSpy spy0(&domain, SIGNAL(domainChanged(qreal,qreal,qreal,qreal)));
286 QSignalSpy spy1(&domain, SIGNAL(rangeXChanged(qreal,qreal,int)));
287 QSignalSpy spy2(&domain, SIGNAL(rangeYChanged(qreal,qreal,int)));
308 QSignalSpy spy0(&domain, SIGNAL(updated()));
309 QSignalSpy spy1(&domain, SIGNAL(rangeXChanged(qreal,qreal)));
310 QSignalSpy spy2(&domain, SIGNAL(rangeYChanged(qreal,qreal)));
288 311
289 312 domain.setMinX(minX1);
290 313 QCOMPARE(domain.minX(), minX1);
291 314 domain.setMinX(minX2);
292 315 QCOMPARE(domain.minX(), minX2);
293 316
294 317 TRY_COMPARE(spy0.count(), count);
295 318 TRY_COMPARE(spy1.count(), count);
296 319 TRY_COMPARE(spy2.count(), 0);
297 320 }
298 321
299 322 void tst_Domain::minY_data()
300 323 {
301 324 QTest::addColumn<qreal>("minY1");
302 325 QTest::addColumn<qreal>("minY2");
303 326 QTest::addColumn<int>("count");
304 327 QTest::newRow("1") << 0.0 << 1.0 << 1;
305 328 QTest::newRow("1.0") << 1.0 << 1.0 << 1;
306 329 QTest::newRow("2.0") << 1.0 << 0.0 << 2;
307 330 }
308 331
309 332 void tst_Domain::minY()
310 333 {
311 334 QFETCH(qreal, minY1);
312 335 QFETCH(qreal, minY2);
313 336 QFETCH(int, count);
314 337
315 338 Domain domain;
316 339
317 QSignalSpy spy0(&domain, SIGNAL(domainChanged(qreal,qreal,qreal,qreal)));
318 QSignalSpy spy1(&domain, SIGNAL(rangeXChanged(qreal,qreal,int)));
319 QSignalSpy spy2(&domain, SIGNAL(rangeYChanged(qreal,qreal,int)));
340 QSignalSpy spy0(&domain, SIGNAL(updated()));
341 QSignalSpy spy1(&domain, SIGNAL(rangeXChanged(qreal,qreal)));
342 QSignalSpy spy2(&domain, SIGNAL(rangeYChanged(qreal,qreal)));
320 343
321 344 domain.setMinY(minY1);
322 345 QCOMPARE(domain.minY(), minY1);
323 346 domain.setMinY(minY2);
324 347 QCOMPARE(domain.minY(), minY2);
325 348
326 349 TRY_COMPARE(spy0.count(), count);
327 350 TRY_COMPARE(spy1.count(), 0);
328 351 TRY_COMPARE(spy2.count(), count);
329 352 }
330 353
331 354 void tst_Domain::operatorEquals_data()
332 355 {
333 356
334 357 QTest::addColumn<Domain*>("domain1");
335 358 QTest::addColumn<Domain*>("domain2");
336 359 QTest::addColumn<bool>("equals");
337 360 QTest::addColumn<bool>("notEquals");
338 361 Domain* a;
339 362 Domain* b;
340 363 a = new Domain();
341 364 a->setRange(0, 100, 0, 100);
342 365 b = new Domain();
343 366 b->setRange(0, 100, 0, 100);
344 367 QTest::newRow("equals") << a << b << true << false;
345 368 a = new Domain();
346 369 a->setRange(0, 100, 0, 100);
347 370 b = new Domain();
348 371 b->setRange(0, 100, 0, 1);
349 372 QTest::newRow("equals") << a << b << false << true;
350 373 a = new Domain();
351 374 a->setRange(0, 100, 0, 100);
352 375 b = new Domain();
353 376 b->setRange(0, 1, 0, 100);
354 377 QTest::newRow("equals") << a << b << false << true;
355 378
356 379 }
357 380
358 381 void tst_Domain::operatorEquals()
359 382 {
360 383 QFETCH(Domain*, domain1);
361 384 QFETCH(Domain*, domain2);
362 385 QFETCH(bool, equals);
363 386 QFETCH(bool, notEquals);
364 387
365 388 Domain domain;
366 389
367 QSignalSpy spy0(&domain, SIGNAL(domainChanged(qreal,qreal,qreal,qreal)));
368 QSignalSpy spy1(&domain, SIGNAL(rangeXChanged(qreal,qreal,int)));
369 QSignalSpy spy2(&domain, SIGNAL(rangeYChanged(qreal,qreal,int)));
390 QSignalSpy spy0(&domain, SIGNAL(updated()));
391 QSignalSpy spy1(&domain, SIGNAL(rangeXChanged(qreal,qreal)));
392 QSignalSpy spy2(&domain, SIGNAL(rangeYChanged(qreal,qreal)));
370 393
371 394 QCOMPARE(*domain1==*domain2, equals);
372 395 QCOMPARE(*domain1!=*domain2, notEquals);
373 396
374 397 TRY_COMPARE(spy0.count(), 0);
375 398 TRY_COMPARE(spy1.count(), 0);
376 399 TRY_COMPARE(spy2.count(), 0);
377 400 }
378 401
379 402 void tst_Domain::setRange_data()
380 403 {
381 404 QTest::addColumn<qreal>("minX");
382 405 QTest::addColumn<qreal>("maxX");
383 406 QTest::addColumn<qreal>("minY");
384 407 QTest::addColumn<qreal>("maxY");
385 408 QTest::newRow("1,2,1,2") << 1.0 << 2.0 << 1.0 << 2.0;
386 409 QTest::newRow("1,3,1,3") << 1.0 << 3.0 << 1.0 << 3.0;
387 410 QTest::newRow("-1,5,-2,-1") << -1.0 << 5.0 << -2.0 << -1.0;
388 411 }
389 412
390 413 void tst_Domain::setRange()
391 414 {
392 415 QFETCH(qreal, minX);
393 416 QFETCH(qreal, maxX);
394 417 QFETCH(qreal, minY);
395 418 QFETCH(qreal, maxY);
396 419
397 420 Domain domain;
398 421
399 QSignalSpy spy0(&domain, SIGNAL(domainChanged(qreal,qreal,qreal,qreal)));
400 QSignalSpy spy1(&domain, SIGNAL(rangeXChanged(qreal,qreal,int)));
401 QSignalSpy spy2(&domain, SIGNAL(rangeYChanged(qreal,qreal,int)));
422 QSignalSpy spy0(&domain, SIGNAL(updated()));
423 QSignalSpy spy1(&domain, SIGNAL(rangeXChanged(qreal,qreal)));
424 QSignalSpy spy2(&domain, SIGNAL(rangeYChanged(qreal,qreal)));
402 425
403 426 domain.setRange(minX, maxX, minY, maxY);
404 427
405 428 QCOMPARE(domain.minX(), minX);
406 429 QCOMPARE(domain.maxX(), maxX);
407 430 QCOMPARE(domain.minY(), minY);
408 431 QCOMPARE(domain.maxY(), maxY);
409 432
410 433 TRY_COMPARE(spy0.count(), 1);
411 434 TRY_COMPARE(spy1.count(), 1);
412 435 TRY_COMPARE(spy2.count(), 1);
413 436
414 437 }
415 438
416 439 void tst_Domain::setRangeX_data()
417 440 {
418 441 QTest::addColumn<qreal>("min");
419 442 QTest::addColumn<qreal>("max");
420 443 QTest::newRow("-1 1") << -1.0 << 1.0;
421 444 QTest::newRow("0 1") << 0.0 << 1.0;
422 445 QTest::newRow("-1 0") << -1.0 << 0.0;
423 446 }
424 447
425 448 void tst_Domain::setRangeX()
426 449 {
427 450 QFETCH(qreal, min);
428 451 QFETCH(qreal, max);
429 452
430 453 Domain domain;
431 454
432 QSignalSpy spy0(&domain, SIGNAL(domainChanged(qreal,qreal,qreal,qreal)));
433 QSignalSpy spy1(&domain, SIGNAL(rangeXChanged(qreal,qreal,int)));
434 QSignalSpy spy2(&domain, SIGNAL(rangeYChanged(qreal,qreal,int)));
455 QSignalSpy spy0(&domain, SIGNAL(updated()));
456 QSignalSpy spy1(&domain, SIGNAL(rangeXChanged(qreal,qreal)));
457 QSignalSpy spy2(&domain, SIGNAL(rangeYChanged(qreal,qreal)));
435 458
436 459 domain.setRangeX(min, max);
437 460
438 QList<QVariant> arg0 = spy0.first();
439 QVERIFY(qFuzzyIsNull(arg0.at(0).toReal() - min));
440 QVERIFY(qFuzzyIsNull(arg0.at(1).toReal() - max));
461 QVERIFY(qFuzzyIsNull(domain.minX() - min));
462 QVERIFY(qFuzzyIsNull(domain.maxX() - max));
441 463
442 464 QList<QVariant> arg1 = spy1.first();
443 465 QVERIFY(qFuzzyIsNull(arg1.at(0).toReal() - min));
444 466 QVERIFY(qFuzzyIsNull(arg1.at(1).toReal() - max));
445 467
446 468 TRY_COMPARE(spy0.count(), 1);
447 469 TRY_COMPARE(spy1.count(), 1);
448 470 TRY_COMPARE(spy2.count(), 0);
449 471 }
450 472
451 473 void tst_Domain::setRangeY_data()
452 474 {
453 475 QTest::addColumn<qreal>("min");
454 476 QTest::addColumn<qreal>("max");
455 477 QTest::newRow("-1 1") << -1.0 << 1.0;
456 478 QTest::newRow("0 1") << 0.0 << 1.0;
457 479 QTest::newRow("-1 0") << -1.0 << 0.0;
458 480 }
459 481
460 482 void tst_Domain::setRangeY()
461 483 {
462 484 QFETCH(qreal, min);
463 485 QFETCH(qreal, max);
464 486
465 487 Domain domain;
466 488
467 QSignalSpy spy0(&domain, SIGNAL(domainChanged(qreal,qreal,qreal,qreal)));
468 QSignalSpy spy1(&domain, SIGNAL(rangeXChanged(qreal,qreal,int)));
469 QSignalSpy spy2(&domain, SIGNAL(rangeYChanged(qreal,qreal,int)));
489 QSignalSpy spy0(&domain, SIGNAL(updated()));
490 QSignalSpy spy1(&domain, SIGNAL(rangeXChanged(qreal,qreal)));
491 QSignalSpy spy2(&domain, SIGNAL(rangeYChanged(qreal,qreal)));
470 492
471 493 domain.setRangeY(min, max);
472 494
473 QList<QVariant> arg0 = spy0.first();
474 QVERIFY(qFuzzyIsNull(arg0.at(2).toReal() - min));
475 QVERIFY(qFuzzyIsNull(arg0.at(3).toReal() - max));
495 QVERIFY(qFuzzyIsNull(domain.minY() - min));
496 QVERIFY(qFuzzyIsNull(domain.maxY() - max));
476 497
477 498 QList<QVariant> arg1 = spy2.first();
478 499 QVERIFY(qFuzzyIsNull(arg1.at(0).toReal() - min));
479 500 QVERIFY(qFuzzyIsNull(arg1.at(1).toReal() - max));
480 501
481 502 TRY_COMPARE(spy0.count(), 1);
482 503 TRY_COMPARE(spy1.count(), 0);
483 504 TRY_COMPARE(spy2.count(), 1);
484 505 }
485 506
486 507 void tst_Domain::spanX_data()
487 508 {
488 509 QTest::addColumn<qreal>("minX");
489 510 QTest::addColumn<qreal>("maxX");
490 511 QTest::addColumn<qreal>("spanX");
491 512 QTest::newRow("1 2 1") << 1.0 << 2.0 << 1.0;
492 513 QTest::newRow("0 2 2") << 1.0 << 2.0 << 1.0;
493 514 }
494 515
495 516 void tst_Domain::spanX()
496 517 {
497 518 QFETCH(qreal, minX);
498 519 QFETCH(qreal, maxX);
499 520 QFETCH(qreal, spanX);
500 521
501 522 Domain domain;
502 523
503 524 domain.setRangeX(minX, maxX);
504 525
505 QSignalSpy spy0(&domain, SIGNAL(domainChanged(qreal,qreal,qreal,qreal)));
506 QSignalSpy spy1(&domain, SIGNAL(rangeXChanged(qreal,qreal,int)));
507 QSignalSpy spy2(&domain, SIGNAL(rangeYChanged(qreal,qreal,int)));
526 QSignalSpy spy0(&domain, SIGNAL(updated()));
527 QSignalSpy spy1(&domain, SIGNAL(rangeXChanged(qreal,qreal)));
528 QSignalSpy spy2(&domain, SIGNAL(rangeYChanged(qreal,qreal)));
508 529
509 530 QCOMPARE(domain.spanX(), spanX);
510 531
511 532 TRY_COMPARE(spy0.count(), 0);
512 533 TRY_COMPARE(spy1.count(), 0);
513 534 TRY_COMPARE(spy2.count(), 0);
514 535 }
515 536
516 537 void tst_Domain::spanY_data()
517 538 {
518 539 QTest::addColumn<qreal>("minY");
519 540 QTest::addColumn<qreal>("maxY");
520 541 QTest::addColumn<qreal>("spanY");
521 542 QTest::newRow("1 2 1") << 1.0 << 2.0 << 1.0;
522 543 QTest::newRow("0 2 2") << 1.0 << 2.0 << 1.0;
523 544 }
524 545
525 546 void tst_Domain::spanY()
526 547 {
527 548 QFETCH(qreal, minY);
528 549 QFETCH(qreal, maxY);
529 550 QFETCH(qreal, spanY);
530 551
531 552 Domain domain;
532 553
533 554 domain.setRangeY(minY, maxY);
534 555
535 QSignalSpy spy0(&domain, SIGNAL(domainChanged(qreal,qreal,qreal,qreal)));
536 QSignalSpy spy1(&domain, SIGNAL(rangeXChanged(qreal,qreal,int)));
537 QSignalSpy spy2(&domain, SIGNAL(rangeYChanged(qreal,qreal,int)));
556 QSignalSpy spy0(&domain, SIGNAL(updated()));
557 QSignalSpy spy1(&domain, SIGNAL(rangeXChanged(qreal,qreal)));
558 QSignalSpy spy2(&domain, SIGNAL(rangeYChanged(qreal,qreal)));
538 559
539 560 QCOMPARE(domain.spanY(), spanY);
540 561
541 562 TRY_COMPARE(spy0.count(), 0);
542 563 TRY_COMPARE(spy1.count(), 0);
543 564 TRY_COMPARE(spy2.count(), 0);
544 565 }
545 566
546 567 void tst_Domain::zoom_data()
547 568 {
548 569 QTest::addColumn<QRectF>("rect0");
549 570 QTest::addColumn<QSizeF>("size0");
550 571 QTest::addColumn<QRectF>("rect1");
551 572 QTest::addColumn<QSizeF>("size1");
552 573 QTest::addColumn<QRectF>("rect2");
553 574 QTest::addColumn<QSizeF>("size2");
554 575 QTest::newRow("first") << QRectF(10, 10, 100, 100) << QSizeF(1000, 1000)
555 576 << QRectF(20, 20, 100, 100) << QSizeF(1000, 1000) << QRectF(50, 50, 100, 100)
556 577 << QSizeF(1000, 1000);
557 578 QTest::newRow("scound") << QRectF(10, 10, 50, 50) << QSizeF(1000, 1000)
558 579 << QRectF(20, 20, 100, 100) << QSizeF(1000, 1000) << QRectF(50, 50, 100, 100)
559 580 << QSizeF(1000, 1000);
560 581 QTest::newRow("third") << QRectF(10, 10, 10, 10) << QSizeF(100, 100) << QRectF(20, 20, 20, 20)
561 582 << QSizeF(100, 100) << QRectF(50, 50, 50, 50) << QSizeF(100, 100);
562 583 }
563 584
564 585 void tst_Domain::zoom()
565 586 {
566 587 QFETCH(QRectF, rect0);
567 588 QFETCH(QSizeF, size0);
568 589 QFETCH(QRectF, rect1);
569 590 QFETCH(QSizeF, size1);
570 591 QFETCH(QRectF, rect2);
571 592 QFETCH(QSizeF, size2);
572 593
573 594 Domain domain;
574 595
575 596 domain.setRange(0, 1000, 0, 1000);
576 597
577 QSignalSpy spy0(&domain, SIGNAL(domainChanged(qreal,qreal,qreal,qreal)));
578 QSignalSpy spy1(&domain, SIGNAL(rangeXChanged(qreal,qreal,int)));
579 QSignalSpy spy2(&domain, SIGNAL(rangeYChanged(qreal,qreal,int)));
598 QSignalSpy spy0(&domain, SIGNAL(updated()));
599 QSignalSpy spy1(&domain, SIGNAL(rangeXChanged(qreal,qreal)));
600 QSignalSpy spy2(&domain, SIGNAL(rangeYChanged(qreal,qreal)));
580 601
581 602 Domain domain0;
582 603 domain0.setRange(domain.minX(), domain.maxX(), domain.minY(), domain.maxY());
583 604 domain.zoomIn(rect0, size0);
584 605 Domain domain1;
585 606 domain1.setRange(domain.minX(), domain.maxX(), domain.minY(), domain.maxY());
586 607 domain.zoomIn(rect1, size1);
587 608 Domain domain2;
588 609 domain2.setRange(domain.minX(), domain.maxX(), domain.minY(), domain.maxY());
589 610 domain.zoomIn(rect2, size2);
590 611 domain.zoomOut(rect2, size2);
591 612 QCOMPARE(domain == domain2, true);
592 613 domain.zoomOut(rect1, size1);
593 614 QCOMPARE(domain == domain1, true);
594 615 domain.zoomOut(rect0, size0);
595 616 QCOMPARE(domain == domain0, true);
596 617 TRY_COMPARE(spy0.count(), 6);
597 618 TRY_COMPARE(spy1.count(), 6);
598 619 TRY_COMPARE(spy2.count(), 6);
599 620 }
600 621
601 622 void tst_Domain::move_data()
602 623 {
603 624 QTest::addColumn<int>("dx");
604 625 QTest::addColumn<int>("dy");
605 626 QTest::addColumn<QSizeF>("size");
606 627 QTest::newRow("dx 100, dy 0, size 1000x1000") << 100 << 0 << QSizeF(1000, 1000);
607 628 QTest::newRow("dx 0, dy 100, size 1000x1000") << 0 << 100 << QSizeF(1000, 1000);
608 629 QTest::newRow("dx -100, dy 0, size 1000x1000") << -100 << 0 << QSizeF(1000, 1000);
609 630 QTest::newRow("dx 0, dy -100, size 1000x1000") << 0 << -100 << QSizeF(1000, 1000);
610 631 QTest::newRow("dx 100, dy 100, size 1000x1000") << 100 << 100 << QSizeF(1000, 1000);
611 632 QTest::newRow("dx 100, dy 50, size 1000x1000") << 100 << 50 << QSizeF(1000, 1000);
612 633 }
613 634
614 635 void tst_Domain::move()
615 636 {
616 637 QFETCH(int, dx);
617 638 QFETCH(int, dy);
618 639 QFETCH(QSizeF, size);
619 640 Domain domain;
620 641
621 642 domain.setRange(0, size.width(), 0, size.height());
622 643
623 QSignalSpy spy0(&domain, SIGNAL(domainChanged(qreal,qreal,qreal,qreal)));
624 QSignalSpy spy1(&domain, SIGNAL(rangeXChanged(qreal,qreal,int)));
625 QSignalSpy spy2(&domain, SIGNAL(rangeYChanged(qreal,qreal,int)));
644 QSignalSpy spy0(&domain, SIGNAL(updated()));
645 QSignalSpy spy1(&domain, SIGNAL(rangeXChanged(qreal,qreal)));
646 QSignalSpy spy2(&domain, SIGNAL(rangeYChanged(qreal,qreal)));
626 647
627 648 domain.move(dx, dy, size);
628 649
629 650 Domain result;
630 651 result.setRange(dx, size.width() + dx, dy, size.height() + dy);
631 652
632 653 QCOMPARE(domain == result, true);
633 654 TRY_COMPARE(spy0.count(), 1);
634 655 TRY_COMPARE(spy1.count(), (dx != 0 ? 1 : 0));
635 656 TRY_COMPARE(spy2.count(), (dy != 0 ? 1 : 0));
636 657 }
637 658
659 /*
638 660 void tst_Domain::handleAxisXChanged_data()
639 661 {
640 662 QTest::addColumn<qreal>("min");
641 663 QTest::addColumn<qreal>("max");
642 664 QTest::addColumn<int>("tickCount");
643 665 QTest::addColumn<bool>("niceNumbers");
644 666 QTest::addColumn<qreal>("resultMin");
645 667 QTest::addColumn<qreal>("resultMax");
646 668 QTest::addColumn<int>("resultTickCount");
647 669 QTest::newRow("0,100,5,false") << 0.0 << 100.0 << 5 << false << 0.0 << 100.0 << 5;
648 670 QTest::newRow("0,100,5,true") << 0.0 << 100.0 << 5 << true << 0.0 << 100.0 << 6;
649 671 QTest::newRow("0.1,99,5,true") << 0.1 << 99.0 << 5 << true << 0.0 << 100.0 << 6;
650 672 QTest::newRow("5,93.5,true") << 5.0 << 93.5 << 5 << true << 0.0 << 100.0 << 6;
651 673 }
652 674
653 675 void tst_Domain::handleAxisXChanged()
654 676 {
655 677 QFETCH(qreal, min);
656 678 QFETCH(qreal, max);
657 679 QFETCH(int, tickCount);
658 680 QFETCH(bool, niceNumbers);
659 681 QFETCH(qreal, resultMin);
660 682 QFETCH(qreal, resultMax);
661 683 QFETCH(int, resultTickCount);
662 684
663 685 Domain domain;
664 QSignalSpy spy0(&domain, SIGNAL(domainChanged(qreal,qreal,qreal,qreal)));
665 QSignalSpy spy1(&domain, SIGNAL(rangeXChanged(qreal,qreal,int)));
666 QSignalSpy spy2(&domain, SIGNAL(rangeYChanged(qreal,qreal,int)));
686 QSignalSpy spy0(&domain, SIGNAL(updated()));
687 QSignalSpy spy1(&domain, SIGNAL(rangeXChanged(qreal,qreal)));
688 QSignalSpy spy2(&domain, SIGNAL(rangeYChanged(qreal,qreal)));
667 689
668 domain.handleAxisXChanged(min, max, tickCount, niceNumbers);
690 // domain.handleAxisXChanged(min, max, tickCount, niceNumbers);
669 691
670 692 QCOMPARE(resultMin, domain.minX());
671 693 QCOMPARE(resultMax, domain.maxX());
672 QCOMPARE(resultTickCount, domain.tickXCount());
694 // QCOMPARE(resultTickCount, domain.tickXCount());
673 695 TRY_COMPARE(spy0.count(), 1);
674 696 TRY_COMPARE(spy1.count(), 1);
675 697 TRY_COMPARE(spy2.count(), 0);
676 698
677 699 }
678 700
679 701 void tst_Domain::handleAxisYChanged_data()
680 702 {
681 703 handleAxisXChanged_data();
682 704 }
683 705
684 706 void tst_Domain::handleAxisYChanged()
685 707 {
686 708 QFETCH(qreal, min);
687 709 QFETCH(qreal, max);
688 710 QFETCH(int, tickCount);
689 711 QFETCH(bool, niceNumbers);
690 712 QFETCH(qreal, resultMin);
691 713 QFETCH(qreal, resultMax);
692 714 QFETCH(int, resultTickCount);
693 715
694 716 Domain domain;
695 QSignalSpy spy0(&domain, SIGNAL(domainChanged(qreal,qreal,qreal,qreal)));
696 QSignalSpy spy1(&domain, SIGNAL(rangeXChanged(qreal,qreal,int)));
697 QSignalSpy spy2(&domain, SIGNAL(rangeYChanged(qreal,qreal,int)));
717 QSignalSpy spy0(&domain, SIGNAL(updated()));
718 QSignalSpy spy1(&domain, SIGNAL(rangeXChanged(qreal,qreal)));
719 QSignalSpy spy2(&domain, SIGNAL(rangeYChanged(qreal,qreal)));
698 720
699 domain.handleAxisYChanged(min, max, tickCount, niceNumbers);
721 // domain.handleAxisYChanged(min, max, tickCount, niceNumbers);
700 722
701 723 QCOMPARE(resultMin, domain.minY());
702 724 QCOMPARE(resultMax, domain.maxY());
703 QCOMPARE(resultTickCount, domain.tickYCount());
725 // QCOMPARE(resultTickCount, domain.tickYCount());
704 726 TRY_COMPARE(spy0.count(), 1);
705 727 TRY_COMPARE(spy1.count(), 0);
706 728 TRY_COMPARE(spy2.count(), 1);
707 729 }
708
730 */
709 731 QTEST_MAIN(tst_Domain)
710 732 #include "tst_domain.moc"
711 733
General Comments 0
You need to be logged in to leave comments. Login now