##// END OF EJS Templates
Additional fixes to label localization...
Miikka Heikkinen -
r2709:682630e62d58
parent child
Show More
@@ -1,400 +1,402
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2014 Digia Plc
3 ** Copyright (C) 2014 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Enterprise Charts Add-on.
7 ** This file is part of the Qt Enterprise Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Enterprise licenses may use this file in
10 ** Licensees holding valid Qt Enterprise licenses may use this file in
11 ** accordance with the Qt Enterprise License Agreement provided with the
11 ** accordance with the Qt Enterprise License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "chartaxiselement_p.h"
21 #include "chartaxiselement_p.h"
22 #include "qabstractaxis_p.h"
22 #include "qabstractaxis_p.h"
23 #include "chartpresenter_p.h"
23 #include "chartpresenter_p.h"
24 #include "abstractchartlayout_p.h"
24 #include "abstractchartlayout_p.h"
25 #include <qmath.h>
25 #include <qmath.h>
26 #include <QDateTime>
26 #include <QDateTime>
27 #include <QTextDocument>
27 #include <QTextDocument>
28
28
29 QTCOMMERCIALCHART_BEGIN_NAMESPACE
29 QTCOMMERCIALCHART_BEGIN_NAMESPACE
30
30
31 static const char *labelFormatMatchString = "%[\\-\\+#\\s\\d\\.lhjztL]*([dicuoxfegXFEG])";
31 static const char *labelFormatMatchString = "%[\\-\\+#\\s\\d\\.lhjztL]*([dicuoxfegXFEG])";
32 static const char *labelFormatMatchLocalizedString = "^([^%]*)%\\.?(\\d)*([defgEG])(.*)$";
32 static const char *labelFormatMatchLocalizedString = "^([^%]*)%\\.?(\\d)*([defgiEG])(.*)$";
33 static QRegExp *labelFormatMatcher = 0;
33 static QRegExp *labelFormatMatcher = 0;
34 static QRegExp *labelFormatMatcherLocalized = 0;
34 static QRegExp *labelFormatMatcherLocalized = 0;
35 class StaticLabelFormatMatcherDeleter
35 class StaticLabelFormatMatcherDeleter
36 {
36 {
37 public:
37 public:
38 StaticLabelFormatMatcherDeleter() {}
38 StaticLabelFormatMatcherDeleter() {}
39 ~StaticLabelFormatMatcherDeleter() {
39 ~StaticLabelFormatMatcherDeleter() {
40 delete labelFormatMatcher;
40 delete labelFormatMatcher;
41 delete labelFormatMatcherLocalized;
41 delete labelFormatMatcherLocalized;
42 }
42 }
43 };
43 };
44 static StaticLabelFormatMatcherDeleter staticLabelFormatMatcherDeleter;
44 static StaticLabelFormatMatcherDeleter staticLabelFormatMatcherDeleter;
45
45
46 ChartAxisElement::ChartAxisElement(QAbstractAxis *axis, QGraphicsItem *item, bool intervalAxis)
46 ChartAxisElement::ChartAxisElement(QAbstractAxis *axis, QGraphicsItem *item, bool intervalAxis)
47 : ChartElement(item),
47 : ChartElement(item),
48 m_axis(axis),
48 m_axis(axis),
49 m_animation(0),
49 m_animation(0),
50 m_grid(new QGraphicsItemGroup(item)),
50 m_grid(new QGraphicsItemGroup(item)),
51 m_arrow(new QGraphicsItemGroup(item)),
51 m_arrow(new QGraphicsItemGroup(item)),
52 m_shades(new QGraphicsItemGroup(item)),
52 m_shades(new QGraphicsItemGroup(item)),
53 m_labels(new QGraphicsItemGroup(item)),
53 m_labels(new QGraphicsItemGroup(item)),
54 m_title(new QGraphicsTextItem(item)),
54 m_title(new QGraphicsTextItem(item)),
55 m_intervalAxis(intervalAxis)
55 m_intervalAxis(intervalAxis)
56
56
57 {
57 {
58 //initial initialization
58 //initial initialization
59 m_arrow->setHandlesChildEvents(false);
59 m_arrow->setHandlesChildEvents(false);
60 m_arrow->setZValue(ChartPresenter::AxisZValue);
60 m_arrow->setZValue(ChartPresenter::AxisZValue);
61 m_labels->setZValue(ChartPresenter::AxisZValue);
61 m_labels->setZValue(ChartPresenter::AxisZValue);
62 m_shades->setZValue(ChartPresenter::ShadesZValue);
62 m_shades->setZValue(ChartPresenter::ShadesZValue);
63 m_grid->setZValue(ChartPresenter::GridZValue);
63 m_grid->setZValue(ChartPresenter::GridZValue);
64 m_title->setZValue(ChartPresenter::GridZValue);
64 m_title->setZValue(ChartPresenter::GridZValue);
65 m_title->document()->setDocumentMargin(ChartPresenter::textMargin());
65 m_title->document()->setDocumentMargin(ChartPresenter::textMargin());
66 handleVisibleChanged(axis->isVisible());
66 handleVisibleChanged(axis->isVisible());
67 connectSlots();
67 connectSlots();
68
68
69 setFlag(QGraphicsItem::ItemHasNoContents, true);
69 setFlag(QGraphicsItem::ItemHasNoContents, true);
70 }
70 }
71
71
72 ChartAxisElement::~ChartAxisElement()
72 ChartAxisElement::~ChartAxisElement()
73 {
73 {
74 }
74 }
75
75
76 void ChartAxisElement::connectSlots()
76 void ChartAxisElement::connectSlots()
77 {
77 {
78 QObject::connect(axis(), SIGNAL(visibleChanged(bool)), this, SLOT(handleVisibleChanged(bool)));
78 QObject::connect(axis(), SIGNAL(visibleChanged(bool)), this, SLOT(handleVisibleChanged(bool)));
79 QObject::connect(axis(), SIGNAL(lineVisibleChanged(bool)), this, SLOT(handleArrowVisibleChanged(bool)));
79 QObject::connect(axis(), SIGNAL(lineVisibleChanged(bool)), this, SLOT(handleArrowVisibleChanged(bool)));
80 QObject::connect(axis(), SIGNAL(gridVisibleChanged(bool)), this, SLOT(handleGridVisibleChanged(bool)));
80 QObject::connect(axis(), SIGNAL(gridVisibleChanged(bool)), this, SLOT(handleGridVisibleChanged(bool)));
81 QObject::connect(axis(), SIGNAL(labelsVisibleChanged(bool)), this, SLOT(handleLabelsVisibleChanged(bool)));
81 QObject::connect(axis(), SIGNAL(labelsVisibleChanged(bool)), this, SLOT(handleLabelsVisibleChanged(bool)));
82 QObject::connect(axis(), SIGNAL(shadesVisibleChanged(bool)), this, SLOT(handleShadesVisibleChanged(bool)));
82 QObject::connect(axis(), SIGNAL(shadesVisibleChanged(bool)), this, SLOT(handleShadesVisibleChanged(bool)));
83 QObject::connect(axis(), SIGNAL(labelsAngleChanged(int)), this, SLOT(handleLabelsAngleChanged(int)));
83 QObject::connect(axis(), SIGNAL(labelsAngleChanged(int)), this, SLOT(handleLabelsAngleChanged(int)));
84 QObject::connect(axis(), SIGNAL(linePenChanged(const QPen&)), this, SLOT(handleArrowPenChanged(const QPen&)));
84 QObject::connect(axis(), SIGNAL(linePenChanged(const QPen&)), this, SLOT(handleArrowPenChanged(const QPen&)));
85 QObject::connect(axis(), SIGNAL(labelsPenChanged(const QPen&)), this, SLOT(handleLabelsPenChanged(const QPen&)));
85 QObject::connect(axis(), SIGNAL(labelsPenChanged(const QPen&)), this, SLOT(handleLabelsPenChanged(const QPen&)));
86 QObject::connect(axis(), SIGNAL(labelsBrushChanged(const QBrush&)), this, SLOT(handleLabelsBrushChanged(const QBrush&)));
86 QObject::connect(axis(), SIGNAL(labelsBrushChanged(const QBrush&)), this, SLOT(handleLabelsBrushChanged(const QBrush&)));
87 QObject::connect(axis(), SIGNAL(labelsFontChanged(const QFont&)), this, SLOT(handleLabelsFontChanged(const QFont&)));
87 QObject::connect(axis(), SIGNAL(labelsFontChanged(const QFont&)), this, SLOT(handleLabelsFontChanged(const QFont&)));
88 QObject::connect(axis(), SIGNAL(gridLinePenChanged(const QPen&)), this, SLOT(handleGridPenChanged(const QPen&)));
88 QObject::connect(axis(), SIGNAL(gridLinePenChanged(const QPen&)), this, SLOT(handleGridPenChanged(const QPen&)));
89 QObject::connect(axis(), SIGNAL(shadesPenChanged(const QPen&)), this, SLOT(handleShadesPenChanged(const QPen&)));
89 QObject::connect(axis(), SIGNAL(shadesPenChanged(const QPen&)), this, SLOT(handleShadesPenChanged(const QPen&)));
90 QObject::connect(axis(), SIGNAL(shadesBrushChanged(const QBrush&)), this, SLOT(handleShadesBrushChanged(const QBrush&)));
90 QObject::connect(axis(), SIGNAL(shadesBrushChanged(const QBrush&)), this, SLOT(handleShadesBrushChanged(const QBrush&)));
91 QObject::connect(axis(), SIGNAL(titleTextChanged(const QString&)), this, SLOT(handleTitleTextChanged(const QString&)));
91 QObject::connect(axis(), SIGNAL(titleTextChanged(const QString&)), this, SLOT(handleTitleTextChanged(const QString&)));
92 QObject::connect(axis(), SIGNAL(titleFontChanged(const QFont&)), this, SLOT(handleTitleFontChanged(const QFont&)));
92 QObject::connect(axis(), SIGNAL(titleFontChanged(const QFont&)), this, SLOT(handleTitleFontChanged(const QFont&)));
93 QObject::connect(axis(), SIGNAL(titlePenChanged(const QPen&)), this, SLOT(handleTitlePenChanged(const QPen&)));
93 QObject::connect(axis(), SIGNAL(titlePenChanged(const QPen&)), this, SLOT(handleTitlePenChanged(const QPen&)));
94 QObject::connect(axis(), SIGNAL(titleBrushChanged(const QBrush&)), this, SLOT(handleTitleBrushChanged(const QBrush&)));
94 QObject::connect(axis(), SIGNAL(titleBrushChanged(const QBrush&)), this, SLOT(handleTitleBrushChanged(const QBrush&)));
95 QObject::connect(axis(), SIGNAL(titleVisibleChanged(bool)), this, SLOT(handleTitleVisibleChanged(bool)));
95 QObject::connect(axis(), SIGNAL(titleVisibleChanged(bool)), this, SLOT(handleTitleVisibleChanged(bool)));
96 QObject::connect(axis()->d_ptr.data(), SIGNAL(rangeChanged(qreal, qreal)), this, SLOT(handleRangeChanged(qreal, qreal)));
96 QObject::connect(axis()->d_ptr.data(), SIGNAL(rangeChanged(qreal, qreal)), this, SLOT(handleRangeChanged(qreal, qreal)));
97 }
97 }
98
98
99 void ChartAxisElement::handleArrowVisibleChanged(bool visible)
99 void ChartAxisElement::handleArrowVisibleChanged(bool visible)
100 {
100 {
101 m_arrow->setVisible(visible);
101 m_arrow->setVisible(visible);
102 }
102 }
103
103
104 void ChartAxisElement::handleGridVisibleChanged(bool visible)
104 void ChartAxisElement::handleGridVisibleChanged(bool visible)
105 {
105 {
106 m_grid->setVisible(visible);
106 m_grid->setVisible(visible);
107 }
107 }
108
108
109 void ChartAxisElement::handleLabelsVisibleChanged(bool visible)
109 void ChartAxisElement::handleLabelsVisibleChanged(bool visible)
110 {
110 {
111 QGraphicsLayoutItem::updateGeometry();
111 QGraphicsLayoutItem::updateGeometry();
112 presenter()->layout()->invalidate();
112 presenter()->layout()->invalidate();
113 m_labels->setVisible(visible);
113 m_labels->setVisible(visible);
114 }
114 }
115
115
116 void ChartAxisElement::handleShadesVisibleChanged(bool visible)
116 void ChartAxisElement::handleShadesVisibleChanged(bool visible)
117 {
117 {
118 m_shades->setVisible(visible);
118 m_shades->setVisible(visible);
119 }
119 }
120
120
121 void ChartAxisElement::handleTitleVisibleChanged(bool visible)
121 void ChartAxisElement::handleTitleVisibleChanged(bool visible)
122 {
122 {
123 QGraphicsLayoutItem::updateGeometry();
123 QGraphicsLayoutItem::updateGeometry();
124 presenter()->layout()->invalidate();
124 presenter()->layout()->invalidate();
125 m_title->setVisible(visible);
125 m_title->setVisible(visible);
126 }
126 }
127
127
128 void ChartAxisElement::handleLabelsAngleChanged(int angle)
128 void ChartAxisElement::handleLabelsAngleChanged(int angle)
129 {
129 {
130 foreach (QGraphicsItem *item, m_labels->childItems())
130 foreach (QGraphicsItem *item, m_labels->childItems())
131 item->setRotation(angle);
131 item->setRotation(angle);
132
132
133 QGraphicsLayoutItem::updateGeometry();
133 QGraphicsLayoutItem::updateGeometry();
134 presenter()->layout()->invalidate();
134 presenter()->layout()->invalidate();
135 }
135 }
136
136
137 void ChartAxisElement::handleLabelsPenChanged(const QPen &pen)
137 void ChartAxisElement::handleLabelsPenChanged(const QPen &pen)
138 {
138 {
139 Q_UNUSED(pen)
139 Q_UNUSED(pen)
140 }
140 }
141
141
142 void ChartAxisElement::handleLabelsBrushChanged(const QBrush &brush)
142 void ChartAxisElement::handleLabelsBrushChanged(const QBrush &brush)
143 {
143 {
144 foreach (QGraphicsItem *item, m_labels->childItems())
144 foreach (QGraphicsItem *item, m_labels->childItems())
145 static_cast<QGraphicsTextItem *>(item)->setDefaultTextColor(brush.color());
145 static_cast<QGraphicsTextItem *>(item)->setDefaultTextColor(brush.color());
146 }
146 }
147
147
148 void ChartAxisElement::handleLabelsFontChanged(const QFont &font)
148 void ChartAxisElement::handleLabelsFontChanged(const QFont &font)
149 {
149 {
150 foreach (QGraphicsItem *item, m_labels->childItems())
150 foreach (QGraphicsItem *item, m_labels->childItems())
151 static_cast<QGraphicsTextItem *>(item)->setFont(font);
151 static_cast<QGraphicsTextItem *>(item)->setFont(font);
152 QGraphicsLayoutItem::updateGeometry();
152 QGraphicsLayoutItem::updateGeometry();
153 presenter()->layout()->invalidate();
153 presenter()->layout()->invalidate();
154 }
154 }
155
155
156 void ChartAxisElement::handleTitleTextChanged(const QString &title)
156 void ChartAxisElement::handleTitleTextChanged(const QString &title)
157 {
157 {
158 QGraphicsLayoutItem::updateGeometry();
158 QGraphicsLayoutItem::updateGeometry();
159 presenter()->layout()->invalidate();
159 presenter()->layout()->invalidate();
160 if (title.isEmpty() || !m_title->isVisible())
160 if (title.isEmpty() || !m_title->isVisible())
161 m_title->setHtml(title);
161 m_title->setHtml(title);
162 }
162 }
163
163
164 void ChartAxisElement::handleTitlePenChanged(const QPen &pen)
164 void ChartAxisElement::handleTitlePenChanged(const QPen &pen)
165 {
165 {
166 Q_UNUSED(pen)
166 Q_UNUSED(pen)
167 }
167 }
168
168
169 void ChartAxisElement::handleTitleBrushChanged(const QBrush &brush)
169 void ChartAxisElement::handleTitleBrushChanged(const QBrush &brush)
170 {
170 {
171 m_title->setDefaultTextColor(brush.color());
171 m_title->setDefaultTextColor(brush.color());
172 }
172 }
173
173
174 void ChartAxisElement::handleTitleFontChanged(const QFont &font)
174 void ChartAxisElement::handleTitleFontChanged(const QFont &font)
175 {
175 {
176 if (m_title->font() != font) {
176 if (m_title->font() != font) {
177 m_title->setFont(font);
177 m_title->setFont(font);
178 QGraphicsLayoutItem::updateGeometry();
178 QGraphicsLayoutItem::updateGeometry();
179 presenter()->layout()->invalidate();
179 presenter()->layout()->invalidate();
180 }
180 }
181 }
181 }
182
182
183 void ChartAxisElement::handleVisibleChanged(bool visible)
183 void ChartAxisElement::handleVisibleChanged(bool visible)
184 {
184 {
185 setVisible(visible);
185 setVisible(visible);
186 if (!visible) {
186 if (!visible) {
187 m_grid->setVisible(visible);
187 m_grid->setVisible(visible);
188 m_arrow->setVisible(visible);
188 m_arrow->setVisible(visible);
189 m_shades->setVisible(visible);
189 m_shades->setVisible(visible);
190 m_labels->setVisible(visible);
190 m_labels->setVisible(visible);
191 m_title->setVisible(visible);
191 m_title->setVisible(visible);
192 } else {
192 } else {
193 m_grid->setVisible(axis()->isGridLineVisible());
193 m_grid->setVisible(axis()->isGridLineVisible());
194 m_arrow->setVisible(axis()->isLineVisible());
194 m_arrow->setVisible(axis()->isLineVisible());
195 m_shades->setVisible(axis()->shadesVisible());
195 m_shades->setVisible(axis()->shadesVisible());
196 m_labels->setVisible(axis()->labelsVisible());
196 m_labels->setVisible(axis()->labelsVisible());
197 m_title->setVisible(axis()->isTitleVisible());
197 m_title->setVisible(axis()->isTitleVisible());
198 }
198 }
199
199
200 if (presenter()) presenter()->layout()->invalidate();
200 if (presenter()) presenter()->layout()->invalidate();
201 }
201 }
202
202
203 void ChartAxisElement::handleRangeChanged(qreal min, qreal max)
203 void ChartAxisElement::handleRangeChanged(qreal min, qreal max)
204 {
204 {
205 Q_UNUSED(min);
205 Q_UNUSED(min);
206 Q_UNUSED(max);
206 Q_UNUSED(max);
207
207
208 if (!isEmpty()) {
208 if (!isEmpty()) {
209 QVector<qreal> layout = calculateLayout();
209 QVector<qreal> layout = calculateLayout();
210 updateLayout(layout);
210 updateLayout(layout);
211 QSizeF before = effectiveSizeHint(Qt::PreferredSize);
211 QSizeF before = effectiveSizeHint(Qt::PreferredSize);
212 QSizeF after = sizeHint(Qt::PreferredSize);
212 QSizeF after = sizeHint(Qt::PreferredSize);
213
213
214 if (before != after) {
214 if (before != after) {
215 QGraphicsLayoutItem::updateGeometry();
215 QGraphicsLayoutItem::updateGeometry();
216 // We don't want to call invalidate on layout, since it will change minimum size of
216 // We don't want to call invalidate on layout, since it will change minimum size of
217 // component, which we would like to avoid since it causes nasty flips when scrolling
217 // component, which we would like to avoid since it causes nasty flips when scrolling
218 // or zooming, instead recalculate layout and use plotArea for extra space.
218 // or zooming, instead recalculate layout and use plotArea for extra space.
219 presenter()->layout()->setGeometry(presenter()->layout()->geometry());
219 presenter()->layout()->setGeometry(presenter()->layout()->geometry());
220 }
220 }
221 }
221 }
222 }
222 }
223
223
224 bool ChartAxisElement::isEmpty()
224 bool ChartAxisElement::isEmpty()
225 {
225 {
226 return axisGeometry().isEmpty()
226 return axisGeometry().isEmpty()
227 || gridGeometry().isEmpty()
227 || gridGeometry().isEmpty()
228 || qFuzzyCompare(min(), max());
228 || qFuzzyCompare(min(), max());
229 }
229 }
230
230
231 qreal ChartAxisElement::min() const
231 qreal ChartAxisElement::min() const
232 {
232 {
233 return m_axis->d_ptr->min();
233 return m_axis->d_ptr->min();
234 }
234 }
235
235
236 qreal ChartAxisElement::max() const
236 qreal ChartAxisElement::max() const
237 {
237 {
238 return m_axis->d_ptr->max();
238 return m_axis->d_ptr->max();
239 }
239 }
240
240
241 QString ChartAxisElement::formatLabel(const QString &formatSpec, const QByteArray &array,
241 QString ChartAxisElement::formatLabel(const QString &formatSpec, const QByteArray &array,
242 qreal value, int precision, const QString &preStr,
242 qreal value, int precision, const QString &preStr,
243 const QString &postStr) const
243 const QString &postStr) const
244 {
244 {
245 QString retVal;
245 QString retVal;
246 if (!formatSpec.isEmpty()) {
246 if (!formatSpec.isEmpty()) {
247 if (formatSpec.at(0) == QLatin1Char('d')
247 if (formatSpec.at(0) == QLatin1Char('d')
248 || formatSpec.at(0) == QLatin1Char('i')
248 || formatSpec.at(0) == QLatin1Char('i')
249 || formatSpec.at(0) == QLatin1Char('c')) {
249 || formatSpec.at(0) == QLatin1Char('c')) {
250 if (presenter()->localizeNumbers())
250 if (presenter()->localizeNumbers())
251 retVal = preStr + presenter()->locale().toString(qint64(value)) + postStr;
251 retVal = preStr + presenter()->locale().toString(qint64(value)) + postStr;
252 else
252 else
253 retVal = QString().sprintf(array, qint64(value));
253 retVal = QString().sprintf(array, qint64(value));
254 } else if (formatSpec.at(0) == QLatin1Char('u')
254 } else if (formatSpec.at(0) == QLatin1Char('u')
255 || formatSpec.at(0) == QLatin1Char('o')
255 || formatSpec.at(0) == QLatin1Char('o')
256 || formatSpec.at(0) == QLatin1Char('x')
256 || formatSpec.at(0) == QLatin1Char('x')
257 || formatSpec.at(0) == QLatin1Char('X')) {
257 || formatSpec.at(0) == QLatin1Char('X')) {
258 // These formats are not supported by localized numbers
258 // These formats are not supported by localized numbers
259 retVal = QString().sprintf(array, quint64(value));
259 retVal = QString().sprintf(array, quint64(value));
260 } else if (formatSpec.at(0) == QLatin1Char('f')
260 } else if (formatSpec.at(0) == QLatin1Char('f')
261 || formatSpec.at(0) == QLatin1Char('F')
261 || formatSpec.at(0) == QLatin1Char('F')
262 || formatSpec.at(0) == QLatin1Char('e')
262 || formatSpec.at(0) == QLatin1Char('e')
263 || formatSpec.at(0) == QLatin1Char('E')
263 || formatSpec.at(0) == QLatin1Char('E')
264 || formatSpec.at(0) == QLatin1Char('g')
264 || formatSpec.at(0) == QLatin1Char('g')
265 || formatSpec.at(0) == QLatin1Char('G')) {
265 || formatSpec.at(0) == QLatin1Char('G')) {
266 if (presenter()->localizeNumbers()) {
266 if (presenter()->localizeNumbers()) {
267 retVal = preStr
267 retVal = preStr
268 + presenter()->locale().toString(value, formatSpec.at(0).toLatin1(),
268 + presenter()->locale().toString(value, formatSpec.at(0).toLatin1(),
269 precision)
269 precision)
270 + postStr;
270 + postStr;
271 } else {
271 } else {
272 retVal = QString().sprintf(array, value);
272 retVal = QString().sprintf(array, value);
273 }
273 }
274 }
274 }
275 }
275 }
276 return retVal;
276 return retVal;
277 }
277 }
278
278
279 QStringList ChartAxisElement::createValueLabels(qreal min, qreal max, int ticks,
279 QStringList ChartAxisElement::createValueLabels(qreal min, qreal max, int ticks,
280 const QString &format) const
280 const QString &format) const
281 {
281 {
282 QStringList labels;
282 QStringList labels;
283
283
284 if (max <= min || ticks < 1)
284 if (max <= min || ticks < 1)
285 return labels;
285 return labels;
286
286
287 if (format.isNull()) {
287 if (format.isNull()) {
288 int n = qMax(int(-qFloor(log10((max - min) / (ticks - 1)))), 0) + 1;
288 int n = qMax(int(-qFloor(log10((max - min) / (ticks - 1)))), 0) + 1;
289 for (int i = 0; i < ticks; i++) {
289 for (int i = 0; i < ticks; i++) {
290 qreal value = min + (i * (max - min) / (ticks - 1));
290 qreal value = min + (i * (max - min) / (ticks - 1));
291 labels << presenter()->numberToString(value, 'f', n);
291 labels << presenter()->numberToString(value, 'f', n);
292 }
292 }
293 } else {
293 } else {
294 QByteArray array = format.toLatin1();
294 QByteArray array = format.toLatin1();
295 QString formatSpec;
295 QString formatSpec;
296 QString preStr;
296 QString preStr;
297 QString postStr;
297 QString postStr;
298 int precision = 0;
298 int precision = 6; // Six is the default precision in Qt API
299 if (presenter()->localizeNumbers()) {
299 if (presenter()->localizeNumbers()) {
300 if (!labelFormatMatcherLocalized)
300 if (!labelFormatMatcherLocalized)
301 labelFormatMatcherLocalized = new QRegExp(labelFormatMatchLocalizedString);
301 labelFormatMatcherLocalized = new QRegExp(labelFormatMatchLocalizedString);
302 if (labelFormatMatcherLocalized->indexIn(format, 0) != -1) {
302 if (labelFormatMatcherLocalized->indexIn(format, 0) != -1) {
303 preStr = labelFormatMatcherLocalized->cap(1);
303 preStr = labelFormatMatcherLocalized->cap(1);
304 precision = labelFormatMatcherLocalized->cap(2).toInt();
304 if (!labelFormatMatcherLocalized->cap(2).isEmpty())
305 precision = labelFormatMatcherLocalized->cap(2).toInt();
305 formatSpec = labelFormatMatcherLocalized->cap(3);
306 formatSpec = labelFormatMatcherLocalized->cap(3);
306 postStr = labelFormatMatcherLocalized->cap(4);
307 postStr = labelFormatMatcherLocalized->cap(4);
307 }
308 }
308 } else {
309 } else {
309 if (!labelFormatMatcher)
310 if (!labelFormatMatcher)
310 labelFormatMatcher = new QRegExp(labelFormatMatchString);
311 labelFormatMatcher = new QRegExp(labelFormatMatchString);
311 if (labelFormatMatcher->indexIn(format, 0) != -1)
312 if (labelFormatMatcher->indexIn(format, 0) != -1)
312 formatSpec = labelFormatMatcher->cap(1);
313 formatSpec = labelFormatMatcher->cap(1);
313 }
314 }
314 for (int i = 0; i < ticks; i++) {
315 for (int i = 0; i < ticks; i++) {
315 qreal value = min + (i * (max - min) / (ticks - 1));
316 qreal value = min + (i * (max - min) / (ticks - 1));
316 labels << formatLabel(formatSpec, array, value, precision, preStr, postStr);
317 labels << formatLabel(formatSpec, array, value, precision, preStr, postStr);
317 }
318 }
318 }
319 }
319
320
320 return labels;
321 return labels;
321 }
322 }
322
323
323 QStringList ChartAxisElement::createLogValueLabels(qreal min, qreal max, qreal base, int ticks,
324 QStringList ChartAxisElement::createLogValueLabels(qreal min, qreal max, qreal base, int ticks,
324 const QString &format) const
325 const QString &format) const
325 {
326 {
326 QStringList labels;
327 QStringList labels;
327
328
328 if (max <= min || ticks < 1)
329 if (max <= min || ticks < 1)
329 return labels;
330 return labels;
330
331
331 int firstTick;
332 int firstTick;
332 if (base > 1)
333 if (base > 1)
333 firstTick = ceil(log10(min) / log10(base));
334 firstTick = ceil(log10(min) / log10(base));
334 else
335 else
335 firstTick = ceil(log10(max) / log10(base));
336 firstTick = ceil(log10(max) / log10(base));
336
337
337 if (format.isNull()) {
338 if (format.isNull()) {
338 int n = 0;
339 int n = 0;
339 if (ticks > 1)
340 if (ticks > 1)
340 n = qMax(int(-qFloor(log10((max - min) / (ticks - 1)))), 0);
341 n = qMax(int(-qFloor(log10((max - min) / (ticks - 1)))), 0);
341 n++;
342 n++;
342 for (int i = firstTick; i < ticks + firstTick; i++) {
343 for (int i = firstTick; i < ticks + firstTick; i++) {
343 qreal value = qPow(base, i);
344 qreal value = qPow(base, i);
344 labels << presenter()->numberToString(value, 'f', n);
345 labels << presenter()->numberToString(value, 'f', n);
345 }
346 }
346 } else {
347 } else {
347 QByteArray array = format.toLatin1();
348 QByteArray array = format.toLatin1();
348 QString formatSpec;
349 QString formatSpec;
349 QString preStr;
350 QString preStr;
350 QString postStr;
351 QString postStr;
351 int precision = 0;
352 int precision = 6; // Six is the default precision in Qt API
352 if (presenter()->localizeNumbers()) {
353 if (presenter()->localizeNumbers()) {
353 if (!labelFormatMatcherLocalized)
354 if (!labelFormatMatcherLocalized)
354 labelFormatMatcherLocalized = new QRegExp(labelFormatMatchLocalizedString);
355 labelFormatMatcherLocalized = new QRegExp(labelFormatMatchLocalizedString);
355 if (labelFormatMatcherLocalized->indexIn(format, 0) != -1) {
356 if (labelFormatMatcherLocalized->indexIn(format, 0) != -1) {
356 preStr = labelFormatMatcherLocalized->cap(1);
357 preStr = labelFormatMatcherLocalized->cap(1);
357 precision = labelFormatMatcherLocalized->cap(2).toInt();
358 if (!labelFormatMatcherLocalized->cap(2).isEmpty())
359 precision = labelFormatMatcherLocalized->cap(2).toInt();
358 formatSpec = labelFormatMatcherLocalized->cap(3);
360 formatSpec = labelFormatMatcherLocalized->cap(3);
359 postStr = labelFormatMatcherLocalized->cap(4);
361 postStr = labelFormatMatcherLocalized->cap(4);
360 }
362 }
361 } else {
363 } else {
362 if (!labelFormatMatcher)
364 if (!labelFormatMatcher)
363 labelFormatMatcher = new QRegExp(labelFormatMatchString);
365 labelFormatMatcher = new QRegExp(labelFormatMatchString);
364 if (labelFormatMatcher->indexIn(format, 0) != -1)
366 if (labelFormatMatcher->indexIn(format, 0) != -1)
365 formatSpec = labelFormatMatcher->cap(1);
367 formatSpec = labelFormatMatcher->cap(1);
366 }
368 }
367 for (int i = firstTick; i < ticks + firstTick; i++) {
369 for (int i = firstTick; i < ticks + firstTick; i++) {
368 qreal value = qPow(base, i);
370 qreal value = qPow(base, i);
369 labels << formatLabel(formatSpec, array, value, precision, preStr, postStr);
371 labels << formatLabel(formatSpec, array, value, precision, preStr, postStr);
370 }
372 }
371 }
373 }
372
374
373 return labels;
375 return labels;
374 }
376 }
375
377
376 QStringList ChartAxisElement::createDateTimeLabels(qreal min, qreal max,int ticks,
378 QStringList ChartAxisElement::createDateTimeLabels(qreal min, qreal max,int ticks,
377 const QString &format) const
379 const QString &format) const
378 {
380 {
379 QStringList labels;
381 QStringList labels;
380
382
381 if (max <= min || ticks < 1)
383 if (max <= min || ticks < 1)
382 return labels;
384 return labels;
383
385
384 int n = qMax(int(-floor(log10((max - min) / (ticks - 1)))), 0);
386 int n = qMax(int(-floor(log10((max - min) / (ticks - 1)))), 0);
385 n++;
387 n++;
386 for (int i = 0; i < ticks; i++) {
388 for (int i = 0; i < ticks; i++) {
387 qreal value = min + (i * (max - min) / (ticks - 1));
389 qreal value = min + (i * (max - min) / (ticks - 1));
388 labels << presenter()->locale().toString(QDateTime::fromMSecsSinceEpoch(value), format);
390 labels << presenter()->locale().toString(QDateTime::fromMSecsSinceEpoch(value), format);
389 }
391 }
390 return labels;
392 return labels;
391 }
393 }
392
394
393 void ChartAxisElement::axisSelected()
395 void ChartAxisElement::axisSelected()
394 {
396 {
395 emit clicked();
397 emit clicked();
396 }
398 }
397
399
398 #include "moc_chartaxiselement_p.cpp"
400 #include "moc_chartaxiselement_p.cpp"
399
401
400 QTCOMMERCIALCHART_END_NAMESPACE
402 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,451 +1,451
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2014 Digia Plc
3 ** Copyright (C) 2014 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Enterprise Charts Add-on.
7 ** This file is part of the Qt Enterprise Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Enterprise licenses may use this file in
10 ** Licensees holding valid Qt Enterprise licenses may use this file in
11 ** accordance with the Qt Enterprise License Agreement provided with the
11 ** accordance with the Qt Enterprise License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "qvalueaxis.h"
21 #include "qvalueaxis.h"
22 #include "qvalueaxis_p.h"
22 #include "qvalueaxis_p.h"
23 #include "chartvalueaxisx_p.h"
23 #include "chartvalueaxisx_p.h"
24 #include "chartvalueaxisy_p.h"
24 #include "chartvalueaxisy_p.h"
25 #include "abstractdomain_p.h"
25 #include "abstractdomain_p.h"
26 #include "polarchartvalueaxisangular_p.h"
26 #include "polarchartvalueaxisangular_p.h"
27 #include "polarchartvalueaxisradial_p.h"
27 #include "polarchartvalueaxisradial_p.h"
28 #include "chartdataset_p.h"
28 #include "chartdataset_p.h"
29 #include "chartpresenter_p.h"
29 #include "chartpresenter_p.h"
30 #include "charttheme_p.h"
30 #include "charttheme_p.h"
31
31
32
32
33 QTCOMMERCIALCHART_BEGIN_NAMESPACE
33 QTCOMMERCIALCHART_BEGIN_NAMESPACE
34 /*!
34 /*!
35 \class QValueAxis
35 \class QValueAxis
36 \inmodule Qt Charts
36 \inmodule Qt Charts
37 \brief The QValueAxis class is used for manipulating chart's axis.
37 \brief The QValueAxis class is used for manipulating chart's axis.
38 \mainclass
38 \mainclass
39
39
40 ValueAxis can be setup to show axis line with tick marks, grid lines and shades.
40 ValueAxis can be setup to show axis line with tick marks, grid lines and shades.
41 Values of axis are drawn to position of ticks.
41 Values of axis are drawn to position of ticks.
42
42
43 Example code on how to use QValueAxis.
43 Example code on how to use QValueAxis.
44 \code
44 \code
45 QChartView *chartView = new QChartView;
45 QChartView *chartView = new QChartView;
46 QLineSeries *series = new QLineSeries;
46 QLineSeries *series = new QLineSeries;
47 // ...
47 // ...
48 chartView->chart()->addSeries(series);
48 chartView->chart()->addSeries(series);
49
49
50 QValueAxis *axisX = new QValueAxis;
50 QValueAxis *axisX = new QValueAxis;
51 axisX->setRange(10, 20.5);
51 axisX->setRange(10, 20.5);
52 axisX->setTickCount(10);
52 axisX->setTickCount(10);
53 axisX->setLabelFormat("%.2f");
53 axisX->setLabelFormat("%.2f");
54 chartView->chart()->setAxisX(axisX, series);
54 chartView->chart()->setAxisX(axisX, series);
55 \endcode
55 \endcode
56 */
56 */
57 #ifdef QDOC_QT5
57 #ifdef QDOC_QT5
58 /*!
58 /*!
59 \qmltype ValueAxis
59 \qmltype ValueAxis
60 \instantiates QValueAxis
60 \instantiates QValueAxis
61 \inqmlmodule QtCommercial.Chart
61 \inqmlmodule QtCommercial.Chart
62
62
63 \include doc/src/valueaxis.qdocinc
63 \include doc/src/valueaxis.qdocinc
64 */
64 */
65 #else
65 #else
66 /*!
66 /*!
67 \qmlclass ValueAxis QValueAxis
67 \qmlclass ValueAxis QValueAxis
68
68
69 \include ../doc/src/valueaxis.qdocinc
69 \include ../doc/src/valueaxis.qdocinc
70 */
70 */
71 #endif
71 #endif
72
72
73 /*!
73 /*!
74 \property QValueAxis::min
74 \property QValueAxis::min
75 Defines the minimum value on the axis.
75 Defines the minimum value on the axis.
76 When setting this property the max is adjusted if necessary, to ensure that the range remains valid.
76 When setting this property the max is adjusted if necessary, to ensure that the range remains valid.
77 */
77 */
78 /*!
78 /*!
79 \qmlproperty real ValueAxis::min
79 \qmlproperty real ValueAxis::min
80 Defines the minimum value on the axis.
80 Defines the minimum value on the axis.
81 When setting this property the max is adjusted if necessary, to ensure that the range remains valid.
81 When setting this property the max is adjusted if necessary, to ensure that the range remains valid.
82 */
82 */
83
83
84 /*!
84 /*!
85 \property QValueAxis::max
85 \property QValueAxis::max
86 Defines the maximum value on the axis.
86 Defines the maximum value on the axis.
87 When setting this property the min is adjusted if necessary, to ensure that the range remains valid.
87 When setting this property the min is adjusted if necessary, to ensure that the range remains valid.
88 */
88 */
89 /*!
89 /*!
90 \qmlproperty real ValueAxis::max
90 \qmlproperty real ValueAxis::max
91 Defines the maximum value on the axis.
91 Defines the maximum value on the axis.
92 When setting this property the min is adjusted if necessary, to ensure that the range remains valid.
92 When setting this property the min is adjusted if necessary, to ensure that the range remains valid.
93 */
93 */
94
94
95 /*!
95 /*!
96 \property QValueAxis::tickCount
96 \property QValueAxis::tickCount
97 Defines the number of ticks on the axis. This indicates how many grid lines are draw on the chart.
97 Defines the number of ticks on the axis. This indicates how many grid lines are draw on the chart.
98 The default value is 5, and it can not be below 2.
98 The default value is 5, and it can not be below 2.
99 */
99 */
100 /*!
100 /*!
101 \qmlproperty real ValueAxis::tickCount
101 \qmlproperty real ValueAxis::tickCount
102 Defines the number of ticks on the axis. This indicates how many grid lines are draw on the chart.
102 Defines the number of ticks on the axis. This indicates how many grid lines are draw on the chart.
103 The default value is 5, and it can not be below 2.
103 The default value is 5, and it can not be below 2.
104 */
104 */
105
105
106 /*!
106 /*!
107 \property QValueAxis::labelFormat
107 \property QValueAxis::labelFormat
108 Defines the label format of the axis.
108 Defines the label format of the axis.
109 Supported specifiers are: d, i, o, x, X, f, F, e, E, g, G, and c.
109 Supported specifiers are: d, i, o, x, X, f, F, e, E, g, G, and c.
110 See QString::sprintf() for additional details.
110 See QString::sprintf() for additional details.
111
111
112 If the QChart::localizeNumbers is \c{true}, the supported specifiers are limited to: d, e, E, f,
112 If the QChart::localizeNumbers is \c{true}, the supported specifiers are limited to: d, e, E, f,
113 g, and G. Also, only the precision modifier is supported. The rest of the formatting comes from
113 g, G, and i. Also, only the precision modifier is supported. The rest of the formatting comes from
114 the default QLocale of the application.
114 the default QLocale of the application.
115 */
115 */
116 /*!
116 /*!
117 \qmlproperty real ValueAxis::labelFormat
117 \qmlproperty real ValueAxis::labelFormat
118 Defines the label format of the axis.
118 Defines the label format of the axis.
119 Supported specifiers are: d, i, o, x, X, f, F, e, E, g, G, and c.
119 Supported specifiers are: d, i, o, x, X, f, F, e, E, g, G, and c.
120 See QString::sprintf() for additional details.
120 See QString::sprintf() for additional details.
121
121
122 If the ChartView::localizeNumbers is \c{true}, the supported specifiers are limited to: d, e, E, f,
122 If the ChartView::localizeNumbers is \c{true}, the supported specifiers are limited to: d, e, E, f,
123 g, and G. Also, only the precision modifier is supported. The rest of the formatting comes from
123 g, G, and i. Also, only the precision modifier is supported. The rest of the formatting comes from
124 the default QLocale of the application.
124 the default QLocale of the application.
125 */
125 */
126
126
127 /*!
127 /*!
128 \fn void QValueAxis::minChanged(qreal min)
128 \fn void QValueAxis::minChanged(qreal min)
129 Axis emits signal when \a min of axis has changed.
129 Axis emits signal when \a min of axis has changed.
130 */
130 */
131 /*!
131 /*!
132 \qmlsignal ValueAxis::onMinChanged(real min)
132 \qmlsignal ValueAxis::onMinChanged(real min)
133 Axis emits signal when \a min of axis has changed.
133 Axis emits signal when \a min of axis has changed.
134 */
134 */
135
135
136 /*!
136 /*!
137 \fn void QValueAxis::maxChanged(qreal max)
137 \fn void QValueAxis::maxChanged(qreal max)
138 Axis emits signal when \a max of axis has changed.
138 Axis emits signal when \a max of axis has changed.
139 */
139 */
140 /*!
140 /*!
141 \qmlsignal ValueAxis::onMaxChanged(real max)
141 \qmlsignal ValueAxis::onMaxChanged(real max)
142 Axis emits signal when \a max of axis has changed.
142 Axis emits signal when \a max of axis has changed.
143 */
143 */
144
144
145 /*!
145 /*!
146 \fn void QValueAxis::tickCountChanged(int tickCount)
146 \fn void QValueAxis::tickCountChanged(int tickCount)
147 Axis emits signal when \a tickCount of axis has changed.
147 Axis emits signal when \a tickCount of axis has changed.
148 */
148 */
149 /*!
149 /*!
150 \qmlsignal ValueAxis::tickCountChanged(int tickCount)
150 \qmlsignal ValueAxis::tickCountChanged(int tickCount)
151 Axis emits signal when \a tickCount of axis has changed.
151 Axis emits signal when \a tickCount of axis has changed.
152 */
152 */
153
153
154 /*!
154 /*!
155 \fn void QValueAxis::rangeChanged(qreal min, qreal max)
155 \fn void QValueAxis::rangeChanged(qreal min, qreal max)
156 Axis emits signal when \a min or \a max of axis has changed.
156 Axis emits signal when \a min or \a max of axis has changed.
157 */
157 */
158
158
159 /*!
159 /*!
160 \fn void QValueAxis::labelFormatChanged(const QString &format)
160 \fn void QValueAxis::labelFormatChanged(const QString &format)
161 Axis emits signal when \a format of axis labels has changed.
161 Axis emits signal when \a format of axis labels has changed.
162 */
162 */
163 /*!
163 /*!
164 \qmlsignal ValueAxis::labelFormatChanged(const QString &format)
164 \qmlsignal ValueAxis::labelFormatChanged(const QString &format)
165 Axis emits signal when \a format of axis labels has changed.
165 Axis emits signal when \a format of axis labels has changed.
166 */
166 */
167
167
168 /*!
168 /*!
169 \property QValueAxis::niceNumbersEnabled
169 \property QValueAxis::niceNumbersEnabled
170 \obsolete
170 \obsolete
171 Using this function can lead to unexpected behavior. Use applyNiceNumbers() instead.
171 Using this function can lead to unexpected behavior. Use applyNiceNumbers() instead.
172 */
172 */
173
173
174 /*!
174 /*!
175 \qmlproperty bool ValueAxis::niceNumbersEnabled
175 \qmlproperty bool ValueAxis::niceNumbersEnabled
176 Deprecated; Using this function can lead to unexpected behavior. Use applyNiceNumbers() instead.
176 Deprecated; Using this function can lead to unexpected behavior. Use applyNiceNumbers() instead.
177 */
177 */
178
178
179 /*!
179 /*!
180 Constructs an axis object which is a child of \a parent.
180 Constructs an axis object which is a child of \a parent.
181 */
181 */
182 QValueAxis::QValueAxis(QObject *parent) :
182 QValueAxis::QValueAxis(QObject *parent) :
183 QAbstractAxis(*new QValueAxisPrivate(this), parent)
183 QAbstractAxis(*new QValueAxisPrivate(this), parent)
184 {
184 {
185
185
186 }
186 }
187
187
188 /*!
188 /*!
189 \internal
189 \internal
190 */
190 */
191 QValueAxis::QValueAxis(QValueAxisPrivate &d, QObject *parent)
191 QValueAxis::QValueAxis(QValueAxisPrivate &d, QObject *parent)
192 : QAbstractAxis(d, parent)
192 : QAbstractAxis(d, parent)
193 {
193 {
194
194
195 }
195 }
196
196
197 /*!
197 /*!
198 Destroys the object
198 Destroys the object
199 */
199 */
200 QValueAxis::~QValueAxis()
200 QValueAxis::~QValueAxis()
201 {
201 {
202 Q_D(QValueAxis);
202 Q_D(QValueAxis);
203 if (d->m_chart)
203 if (d->m_chart)
204 d->m_chart->removeAxis(this);
204 d->m_chart->removeAxis(this);
205 }
205 }
206
206
207 void QValueAxis::setMin(qreal min)
207 void QValueAxis::setMin(qreal min)
208 {
208 {
209 Q_D(QValueAxis);
209 Q_D(QValueAxis);
210 setRange(min, qMax(d->m_max, min));
210 setRange(min, qMax(d->m_max, min));
211 }
211 }
212
212
213 qreal QValueAxis::min() const
213 qreal QValueAxis::min() const
214 {
214 {
215 Q_D(const QValueAxis);
215 Q_D(const QValueAxis);
216 return d->m_min;
216 return d->m_min;
217 }
217 }
218
218
219 void QValueAxis::setMax(qreal max)
219 void QValueAxis::setMax(qreal max)
220 {
220 {
221 Q_D(QValueAxis);
221 Q_D(QValueAxis);
222 setRange(qMin(d->m_min, max), max);
222 setRange(qMin(d->m_min, max), max);
223 }
223 }
224
224
225 qreal QValueAxis::max() const
225 qreal QValueAxis::max() const
226 {
226 {
227 Q_D(const QValueAxis);
227 Q_D(const QValueAxis);
228 return d->m_max;
228 return d->m_max;
229 }
229 }
230
230
231 /*!
231 /*!
232 Sets range from \a min to \a max on the axis.
232 Sets range from \a min to \a max on the axis.
233 If min is greater than max then this function returns without making any changes.
233 If min is greater than max then this function returns without making any changes.
234 */
234 */
235 void QValueAxis::setRange(qreal min, qreal max)
235 void QValueAxis::setRange(qreal min, qreal max)
236 {
236 {
237 Q_D(QValueAxis);
237 Q_D(QValueAxis);
238 d->setRange(min,max);
238 d->setRange(min,max);
239 }
239 }
240
240
241 void QValueAxis::setTickCount(int count)
241 void QValueAxis::setTickCount(int count)
242 {
242 {
243 Q_D(QValueAxis);
243 Q_D(QValueAxis);
244 if (d->m_tickCount != count && count >= 2) {
244 if (d->m_tickCount != count && count >= 2) {
245 d->m_tickCount = count;
245 d->m_tickCount = count;
246 emit tickCountChanged(count);
246 emit tickCountChanged(count);
247 }
247 }
248 }
248 }
249
249
250 int QValueAxis::tickCount() const
250 int QValueAxis::tickCount() const
251 {
251 {
252 Q_D(const QValueAxis);
252 Q_D(const QValueAxis);
253 return d->m_tickCount;
253 return d->m_tickCount;
254 }
254 }
255
255
256 void QValueAxis::setNiceNumbersEnabled(bool enable)
256 void QValueAxis::setNiceNumbersEnabled(bool enable)
257 {
257 {
258 Q_D(QValueAxis);
258 Q_D(QValueAxis);
259 qWarning() << "Deprecated; Using this function can lead to unexpected behavior. " \
259 qWarning() << "Deprecated; Using this function can lead to unexpected behavior. " \
260 "Use applyNiceNumbers() instead.";
260 "Use applyNiceNumbers() instead.";
261 if(enable) {
261 if(enable) {
262 QObject::connect(this,SIGNAL(rangeChanged(qreal,qreal)),this,SLOT(applyNiceNumbers()));
262 QObject::connect(this,SIGNAL(rangeChanged(qreal,qreal)),this,SLOT(applyNiceNumbers()));
263 QObject::connect(this,SIGNAL(tickCountChanged(int)),this,SLOT(applyNiceNumbers()));
263 QObject::connect(this,SIGNAL(tickCountChanged(int)),this,SLOT(applyNiceNumbers()));
264 applyNiceNumbers();
264 applyNiceNumbers();
265 }
265 }
266 else {
266 else {
267 QObject::disconnect(this,SIGNAL(rangeChanged(qreal,qreal)),this,SLOT(applyNiceNumbers()));
267 QObject::disconnect(this,SIGNAL(rangeChanged(qreal,qreal)),this,SLOT(applyNiceNumbers()));
268 QObject::disconnect(this,SIGNAL(tickCountChanged(int)),this,SLOT(applyNiceNumbers()));
268 QObject::disconnect(this,SIGNAL(tickCountChanged(int)),this,SLOT(applyNiceNumbers()));
269 }
269 }
270 d->m_niceNumbersEnabled=enable;
270 d->m_niceNumbersEnabled=enable;
271 }
271 }
272
272
273 bool QValueAxis::niceNumbersEnabled() const
273 bool QValueAxis::niceNumbersEnabled() const
274 {
274 {
275 Q_D(const QValueAxis);
275 Q_D(const QValueAxis);
276 qWarning() << "Deprecated; Using this function can lead to unexpected behavior. " \
276 qWarning() << "Deprecated; Using this function can lead to unexpected behavior. " \
277 "Use applyNiceNumbers() instead.";
277 "Use applyNiceNumbers() instead.";
278 return d->m_niceNumbersEnabled;
278 return d->m_niceNumbersEnabled;
279 }
279 }
280
280
281 void QValueAxis::setLabelFormat(const QString &format)
281 void QValueAxis::setLabelFormat(const QString &format)
282 {
282 {
283 Q_D(QValueAxis);
283 Q_D(QValueAxis);
284 d->m_format = format;
284 d->m_format = format;
285 emit labelFormatChanged(format);
285 emit labelFormatChanged(format);
286 }
286 }
287
287
288 QString QValueAxis::labelFormat() const
288 QString QValueAxis::labelFormat() const
289 {
289 {
290 Q_D(const QValueAxis);
290 Q_D(const QValueAxis);
291 return d->m_format;
291 return d->m_format;
292 }
292 }
293
293
294 /*!
294 /*!
295 Returns the type of the axis
295 Returns the type of the axis
296 */
296 */
297 QAbstractAxis::AxisType QValueAxis::type() const
297 QAbstractAxis::AxisType QValueAxis::type() const
298 {
298 {
299 return AxisTypeValue;
299 return AxisTypeValue;
300 }
300 }
301
301
302 /*!
302 /*!
303 This method modifies range and number of ticks on the axis to look "nice". Algorithm considers numbers that
303 This method modifies range and number of ticks on the axis to look "nice". Algorithm considers numbers that
304 can be expressed as form of 1*10^n, 2* 10^n or 5*10^n as a nice numbers. These numbers are used for spacing the ticks.
304 can be expressed as form of 1*10^n, 2* 10^n or 5*10^n as a nice numbers. These numbers are used for spacing the ticks.
305 This method will modify the current range and number of ticks.
305 This method will modify the current range and number of ticks.
306 \sa setRange(), setTickCount()
306 \sa setRange(), setTickCount()
307 */
307 */
308 void QValueAxis::applyNiceNumbers()
308 void QValueAxis::applyNiceNumbers()
309 {
309 {
310 Q_D(QValueAxis);
310 Q_D(QValueAxis);
311 if(d->m_applying) return;
311 if(d->m_applying) return;
312 qreal min = d->m_min;
312 qreal min = d->m_min;
313 qreal max = d->m_max;
313 qreal max = d->m_max;
314 int ticks = d->m_tickCount;
314 int ticks = d->m_tickCount;
315 AbstractDomain::looseNiceNumbers(min,max,ticks);
315 AbstractDomain::looseNiceNumbers(min,max,ticks);
316 d->m_applying=true;
316 d->m_applying=true;
317 d->setRange(min,max);
317 d->setRange(min,max);
318 setTickCount(ticks);
318 setTickCount(ticks);
319 d->m_applying=false;
319 d->m_applying=false;
320 }
320 }
321
321
322 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
322 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
323
323
324 QValueAxisPrivate::QValueAxisPrivate(QValueAxis *q)
324 QValueAxisPrivate::QValueAxisPrivate(QValueAxis *q)
325 : QAbstractAxisPrivate(q),
325 : QAbstractAxisPrivate(q),
326 m_min(0),
326 m_min(0),
327 m_max(0),
327 m_max(0),
328 m_tickCount(5),
328 m_tickCount(5),
329 m_format(QString::null),
329 m_format(QString::null),
330 m_applying(false),
330 m_applying(false),
331 m_niceNumbersEnabled(false)
331 m_niceNumbersEnabled(false)
332 {
332 {
333
333
334 }
334 }
335
335
336 QValueAxisPrivate::~QValueAxisPrivate()
336 QValueAxisPrivate::~QValueAxisPrivate()
337 {
337 {
338
338
339 }
339 }
340
340
341 void QValueAxisPrivate::setMin(const QVariant &min)
341 void QValueAxisPrivate::setMin(const QVariant &min)
342 {
342 {
343 Q_Q(QValueAxis);
343 Q_Q(QValueAxis);
344 bool ok;
344 bool ok;
345 qreal value = min.toReal(&ok);
345 qreal value = min.toReal(&ok);
346 if (ok)
346 if (ok)
347 q->setMin(value);
347 q->setMin(value);
348 }
348 }
349
349
350 void QValueAxisPrivate::setMax(const QVariant &max)
350 void QValueAxisPrivate::setMax(const QVariant &max)
351 {
351 {
352 Q_Q(QValueAxis);
352 Q_Q(QValueAxis);
353 bool ok;
353 bool ok;
354 qreal value = max.toReal(&ok);
354 qreal value = max.toReal(&ok);
355 if (ok)
355 if (ok)
356 q->setMax(value);
356 q->setMax(value);
357 }
357 }
358
358
359 void QValueAxisPrivate::setRange(const QVariant &min, const QVariant &max)
359 void QValueAxisPrivate::setRange(const QVariant &min, const QVariant &max)
360 {
360 {
361 Q_Q(QValueAxis);
361 Q_Q(QValueAxis);
362 bool ok1;
362 bool ok1;
363 bool ok2;
363 bool ok2;
364 qreal value1 = min.toReal(&ok1);
364 qreal value1 = min.toReal(&ok1);
365 qreal value2 = max.toReal(&ok2);
365 qreal value2 = max.toReal(&ok2);
366 if (ok1 && ok2)
366 if (ok1 && ok2)
367 q->setRange(value1, value2);
367 q->setRange(value1, value2);
368 }
368 }
369
369
370 void QValueAxisPrivate::setRange(qreal min, qreal max)
370 void QValueAxisPrivate::setRange(qreal min, qreal max)
371 {
371 {
372 Q_Q(QValueAxis);
372 Q_Q(QValueAxis);
373 bool changed = false;
373 bool changed = false;
374
374
375 if (min > max)
375 if (min > max)
376 return;
376 return;
377
377
378 bool changeMin = false;
378 bool changeMin = false;
379 if (m_min == 0 || min == 0)
379 if (m_min == 0 || min == 0)
380 changeMin = !qFuzzyCompare(1 + m_min, 1 + min);
380 changeMin = !qFuzzyCompare(1 + m_min, 1 + min);
381 else
381 else
382 changeMin = !qFuzzyCompare(m_min, min);
382 changeMin = !qFuzzyCompare(m_min, min);
383
383
384 bool changeMax = false;
384 bool changeMax = false;
385 if (m_max == 0 || max == 0)
385 if (m_max == 0 || max == 0)
386 changeMax = !qFuzzyCompare(1 + m_max, 1 + max);
386 changeMax = !qFuzzyCompare(1 + m_max, 1 + max);
387 else
387 else
388 changeMax = !qFuzzyCompare(m_max, max);
388 changeMax = !qFuzzyCompare(m_max, max);
389
389
390 if (changeMin) {
390 if (changeMin) {
391 m_min = min;
391 m_min = min;
392 changed = true;
392 changed = true;
393 emit q->minChanged(min);
393 emit q->minChanged(min);
394 }
394 }
395
395
396 if (changeMax) {
396 if (changeMax) {
397 m_max = max;
397 m_max = max;
398 changed = true;
398 changed = true;
399 emit q->maxChanged(max);
399 emit q->maxChanged(max);
400 }
400 }
401
401
402 if (changed) {
402 if (changed) {
403 emit rangeChanged(min,max);
403 emit rangeChanged(min,max);
404 emit q->rangeChanged(min, max);
404 emit q->rangeChanged(min, max);
405 }
405 }
406 }
406 }
407
407
408 void QValueAxisPrivate::initializeGraphics(QGraphicsItem *parent)
408 void QValueAxisPrivate::initializeGraphics(QGraphicsItem *parent)
409 {
409 {
410 Q_Q(QValueAxis);
410 Q_Q(QValueAxis);
411 ChartAxisElement *axis(0);
411 ChartAxisElement *axis(0);
412
412
413 if (m_chart->chartType() == QChart::ChartTypeCartesian) {
413 if (m_chart->chartType() == QChart::ChartTypeCartesian) {
414 if (orientation() == Qt::Vertical)
414 if (orientation() == Qt::Vertical)
415 axis = new ChartValueAxisY(q,parent);
415 axis = new ChartValueAxisY(q,parent);
416 if (orientation() == Qt::Horizontal)
416 if (orientation() == Qt::Horizontal)
417 axis = new ChartValueAxisX(q,parent);
417 axis = new ChartValueAxisX(q,parent);
418 }
418 }
419
419
420 if (m_chart->chartType() == QChart::ChartTypePolar) {
420 if (m_chart->chartType() == QChart::ChartTypePolar) {
421 if (orientation() == Qt::Vertical)
421 if (orientation() == Qt::Vertical)
422 axis = new PolarChartValueAxisRadial(q, parent);
422 axis = new PolarChartValueAxisRadial(q, parent);
423 if (orientation() == Qt::Horizontal)
423 if (orientation() == Qt::Horizontal)
424 axis = new PolarChartValueAxisAngular(q, parent);
424 axis = new PolarChartValueAxisAngular(q, parent);
425 }
425 }
426
426
427 m_item.reset(axis);
427 m_item.reset(axis);
428 QAbstractAxisPrivate::initializeGraphics(parent);
428 QAbstractAxisPrivate::initializeGraphics(parent);
429 }
429 }
430
430
431
431
432 void QValueAxisPrivate::initializeDomain(AbstractDomain *domain)
432 void QValueAxisPrivate::initializeDomain(AbstractDomain *domain)
433 {
433 {
434 if (orientation() == Qt::Vertical) {
434 if (orientation() == Qt::Vertical) {
435 if (!qFuzzyIsNull(m_max - m_min))
435 if (!qFuzzyIsNull(m_max - m_min))
436 domain->setRangeY(m_min, m_max);
436 domain->setRangeY(m_min, m_max);
437 else
437 else
438 setRange(domain->minY(), domain->maxY());
438 setRange(domain->minY(), domain->maxY());
439 }
439 }
440 if (orientation() == Qt::Horizontal) {
440 if (orientation() == Qt::Horizontal) {
441 if (!qFuzzyIsNull(m_max - m_min))
441 if (!qFuzzyIsNull(m_max - m_min))
442 domain->setRangeX(m_min, m_max);
442 domain->setRangeX(m_min, m_max);
443 else
443 else
444 setRange(domain->minX(), domain->maxX());
444 setRange(domain->minX(), domain->maxX());
445 }
445 }
446 }
446 }
447
447
448 #include "moc_qvalueaxis.cpp"
448 #include "moc_qvalueaxis.cpp"
449 #include "moc_qvalueaxis_p.cpp"
449 #include "moc_qvalueaxis_p.cpp"
450
450
451 QTCOMMERCIALCHART_END_NAMESPACE
451 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,1028 +1,1028
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2014 Digia Plc
3 ** Copyright (C) 2014 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Enterprise Charts Add-on.
7 ** This file is part of the Qt Enterprise Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Enterprise licenses may use this file in
10 ** Licensees holding valid Qt Enterprise licenses may use this file in
11 ** accordance with the Qt Enterprise License Agreement provided with the
11 ** accordance with the Qt Enterprise License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "qabstractbarseries.h"
21 #include "qabstractbarseries.h"
22 #include "qabstractbarseries_p.h"
22 #include "qabstractbarseries_p.h"
23 #include "qbarset.h"
23 #include "qbarset.h"
24 #include "qbarset_p.h"
24 #include "qbarset_p.h"
25 #include "abstractdomain_p.h"
25 #include "abstractdomain_p.h"
26 #include "chartdataset_p.h"
26 #include "chartdataset_p.h"
27 #include "charttheme_p.h"
27 #include "charttheme_p.h"
28 #include "qvalueaxis.h"
28 #include "qvalueaxis.h"
29 #include "qbarcategoryaxis.h"
29 #include "qbarcategoryaxis.h"
30 #include "qbarlegendmarker.h"
30 #include "qbarlegendmarker.h"
31 #include "baranimation_p.h"
31 #include "baranimation_p.h"
32 #include "abstractbarchartitem_p.h"
32 #include "abstractbarchartitem_p.h"
33 #include "qchart_p.h"
33 #include "qchart_p.h"
34
34
35 QTCOMMERCIALCHART_BEGIN_NAMESPACE
35 QTCOMMERCIALCHART_BEGIN_NAMESPACE
36
36
37 /*!
37 /*!
38 \class QAbstractBarSeries
38 \class QAbstractBarSeries
39 \inmodule Qt Charts
39 \inmodule Qt Charts
40 \brief Series for creating a bar chart.
40 \brief Series for creating a bar chart.
41 \mainclass
41 \mainclass
42
42
43 QAbstractBarSeries represents a series of data shown as bars. The purpose of this class is to draw bars to
43 QAbstractBarSeries represents a series of data shown as bars. The purpose of this class is to draw bars to
44 the position defined by data. Single bar is defined by QPointF, where x value is the x-coordinate of the bar
44 the position defined by data. Single bar is defined by QPointF, where x value is the x-coordinate of the bar
45 and y-value is the height of the bar. The category names are ignored with this series and x-axis
45 and y-value is the height of the bar. The category names are ignored with this series and x-axis
46 shows the x-values.
46 shows the x-values.
47
47
48 See the \l {BarChart Example} {bar chart example} to learn how to create a simple bar chart.
48 See the \l {BarChart Example} {bar chart example} to learn how to create a simple bar chart.
49 \image examples_barchart.png
49 \image examples_barchart.png
50
50
51 \sa QBarSet, QStackedBarSeries, QPercentBarSeries
51 \sa QBarSet, QStackedBarSeries, QPercentBarSeries
52 */
52 */
53 #ifdef QDOC_QT5
53 #ifdef QDOC_QT5
54 /*!
54 /*!
55 \qmltype AbstractBarSeries
55 \qmltype AbstractBarSeries
56 \instantiates QAbstractBarSeries
56 \instantiates QAbstractBarSeries
57 \inqmlmodule QtCommercial.Chart
57 \inqmlmodule QtCommercial.Chart
58
58
59 \include doc/src/abstractbarseries.qdocinc
59 \include doc/src/abstractbarseries.qdocinc
60 */
60 */
61 #else
61 #else
62 /*!
62 /*!
63 \qmlclass AbstractBarSeries QAbstractBarSeries
63 \qmlclass AbstractBarSeries QAbstractBarSeries
64
64
65 \include ../doc/src/abstractbarseries.qdocinc
65 \include ../doc/src/abstractbarseries.qdocinc
66 */
66 */
67 #endif
67 #endif
68
68
69 /*!
69 /*!
70 \qmlproperty AbstractAxis AbstractBarSeries::axisX
70 \qmlproperty AbstractAxis AbstractBarSeries::axisX
71 The x axis used for the series. If you leave both axisX and axisXTop undefined, a BarCategoriesAxis is created for
71 The x axis used for the series. If you leave both axisX and axisXTop undefined, a BarCategoriesAxis is created for
72 the series.
72 the series.
73 \sa axisXTop
73 \sa axisXTop
74 */
74 */
75
75
76 /*!
76 /*!
77 \qmlproperty AbstractAxis AbstractBarSeries::axisY
77 \qmlproperty AbstractAxis AbstractBarSeries::axisY
78 The y axis used for the series. If you leave both axisY and axisYRight undefined, a ValueAxis is created for
78 The y axis used for the series. If you leave both axisY and axisYRight undefined, a ValueAxis is created for
79 the series.
79 the series.
80 \sa axisYRight
80 \sa axisYRight
81 */
81 */
82
82
83 /*!
83 /*!
84 \qmlproperty AbstractAxis AbstractBarSeries::axisXTop
84 \qmlproperty AbstractAxis AbstractBarSeries::axisXTop
85 The x axis used for the series, drawn on top of the chart view. Note that you can only provide either axisX or
85 The x axis used for the series, drawn on top of the chart view. Note that you can only provide either axisX or
86 axisXTop, but not both.
86 axisXTop, but not both.
87 \sa axisX
87 \sa axisX
88 */
88 */
89
89
90 /*!
90 /*!
91 \qmlproperty AbstractAxis AbstractBarSeries::axisYRight
91 \qmlproperty AbstractAxis AbstractBarSeries::axisYRight
92 The y axis used for the series, drawn to the right on the chart view. Note that you can only provide either axisY
92 The y axis used for the series, drawn to the right on the chart view. Note that you can only provide either axisY
93 or axisYRight, but not both.
93 or axisYRight, but not both.
94 \sa axisY
94 \sa axisY
95 */
95 */
96
96
97 /*!
97 /*!
98 \property QAbstractBarSeries::barWidth
98 \property QAbstractBarSeries::barWidth
99 The width of the bars of the series. The unit of \a width is the unit of x-axis. The minimum width for bars
99 The width of the bars of the series. The unit of \a width is the unit of x-axis. The minimum width for bars
100 is zero and negative values are treated as zero. Setting the width to zero means that width of the bar on screen
100 is zero and negative values are treated as zero. Setting the width to zero means that width of the bar on screen
101 is one pixel no matter what the scale of x-axis is. Bars wider than zero are scaled with x-axis.
101 is one pixel no matter what the scale of x-axis is. Bars wider than zero are scaled with x-axis.
102 Note that with QBarSeries this value means the width of one group of bars instead of just one bar.
102 Note that with QBarSeries this value means the width of one group of bars instead of just one bar.
103 \sa QBarSeries
103 \sa QBarSeries
104 */
104 */
105 /*!
105 /*!
106 \qmlproperty real AbstractBarSeries::barWidth
106 \qmlproperty real AbstractBarSeries::barWidth
107 The width of the bars of the series. The unit of width is the unit of x-axis. The minimum width for bars
107 The width of the bars of the series. The unit of width is the unit of x-axis. The minimum width for bars
108 is zero and negative values are treated as zero. Setting the width to zero means that width of the bar on screen
108 is zero and negative values are treated as zero. Setting the width to zero means that width of the bar on screen
109 is one pixel no matter what the scale of x-axis is. Bars wider than zero are scaled with x-axis.
109 is one pixel no matter what the scale of x-axis is. Bars wider than zero are scaled with x-axis.
110 Note that with QBarSeries this value means the width of one group of bars instead of just one bar.
110 Note that with QBarSeries this value means the width of one group of bars instead of just one bar.
111 */
111 */
112
112
113 /*!
113 /*!
114 \property QAbstractBarSeries::count
114 \property QAbstractBarSeries::count
115 Holds the number of sets in series.
115 Holds the number of sets in series.
116 */
116 */
117 /*!
117 /*!
118 \qmlproperty int AbstractBarSeries::count
118 \qmlproperty int AbstractBarSeries::count
119 Holds the number of sets in series.
119 Holds the number of sets in series.
120 */
120 */
121
121
122 /*!
122 /*!
123 \property QAbstractBarSeries::labelsVisible
123 \property QAbstractBarSeries::labelsVisible
124 Defines the visibility of the labels in series
124 Defines the visibility of the labels in series
125 */
125 */
126 /*!
126 /*!
127 \qmlproperty bool AbstractBarSeries::labelsVisible
127 \qmlproperty bool AbstractBarSeries::labelsVisible
128 Defines the visibility of the labels in series
128 Defines the visibility of the labels in series
129 */
129 */
130
130
131 /*!
131 /*!
132 \property QAbstractBarSeries::labelsFormat
132 \property QAbstractBarSeries::labelsFormat
133 The \a format used for showing labels in series.
133 The \a format used for showing labels in series.
134
134
135 QAbstractBarSeries supports the following format tag:
135 QAbstractBarSeries supports the following format tag:
136 \table
136 \table
137 \row
137 \row
138 \li @value \li The value of the bar
138 \li @value \li The value of the bar
139 \endtable
139 \endtable
140
140
141 For example, the following usage of the format tags would produce labels that show the value
141 For example, the following usage of the format tags would produce labels that show the value
142 followed by unit ('u'):
142 followed by unit ('u'):
143 \code
143 \code
144 series->setLabelsFormat("@value u");
144 series->setLabelsFormat("@value u");
145 \endcode
145 \endcode
146
146
147 By default, the labels shows the value of the bar. For percent bar series '%' is added after
147 By default, the labels shows the value of the bar. For percent bar series '%' is added after
148 the value. The labels are shown on the plot area, labels on the edge of the plot area are cut.
148 the value. The labels are shown on the plot area, labels on the edge of the plot area are cut.
149 If the bars are close to each other the labels may overlap.
149 If the bars are close to each other the labels may overlap.
150
150
151 \sa QAbstractBarSeries::labelsVisible, QAbstractBarSeries::labelsPosition
151 \sa QAbstractBarSeries::labelsVisible, QAbstractBarSeries::labelsPosition
152 */
152 */
153 /*!
153 /*!
154 \qmlproperty string AbstractBarSeries::labelsFormat
154 \qmlproperty string AbstractBarSeries::labelsFormat
155 The format used for showing labels in series.
155 The format used for showing labels in series.
156
156
157 \sa QAbstractBarSeries::labelsFormat, labelsVisible, labelsPosition
157 \sa QAbstractBarSeries::labelsFormat, labelsVisible, labelsPosition
158 */
158 */
159 /*!
159 /*!
160 \fn void QAbstractBarSeries::labelsFormatChanged(const QString &format)
160 \fn void QAbstractBarSeries::labelsFormatChanged(const QString &format)
161 Signal is emitted when the \a format of data value labels is changed.
161 Signal is emitted when the \a format of data value labels is changed.
162 */
162 */
163 /*!
163 /*!
164 \qmlsignal XYSeries::onLabelsFormatChanged(string format)
164 \qmlsignal XYSeries::onLabelsFormatChanged(string format)
165 Signal is emitted when the \a format of data value labels is changed.
165 Signal is emitted when the \a format of data value labels is changed.
166 */
166 */
167
167
168 /*!
168 /*!
169 \enum QAbstractBarSeries::LabelsPosition
169 \enum QAbstractBarSeries::LabelsPosition
170
170
171 This enum describes the position of the data value labels.
171 This enum describes the position of the data value labels.
172
172
173 \value LabelsCenter Label is in the center of the bar.
173 \value LabelsCenter Label is in the center of the bar.
174 \value LabelsInsideEnd Label is inside the bar at the high end of it.
174 \value LabelsInsideEnd Label is inside the bar at the high end of it.
175 \value LabelsInsideBase Label is inside the bar at the low end of it.
175 \value LabelsInsideBase Label is inside the bar at the low end of it.
176 \value LabelsOutsideEnd Label is outside the bar at the high end of it.
176 \value LabelsOutsideEnd Label is outside the bar at the high end of it.
177 */
177 */
178
178
179 /*!
179 /*!
180 \property QAbstractBarSeries::labelsPosition
180 \property QAbstractBarSeries::labelsPosition
181 Defines the \a position of value labels.
181 Defines the \a position of value labels.
182
182
183 \sa QAbstractBarSeries::labelsVisible, QAbstractBarSeries::labelsFormat
183 \sa QAbstractBarSeries::labelsVisible, QAbstractBarSeries::labelsFormat
184 */
184 */
185 /*!
185 /*!
186 \qmlproperty string AbstractBarSeries::labelsPosition
186 \qmlproperty string AbstractBarSeries::labelsPosition
187 Defines the \a position of value labels.
187 Defines the \a position of value labels.
188
188
189 \sa labelsVisible, labelsFormat
189 \sa labelsVisible, labelsFormat
190 */
190 */
191 /*!
191 /*!
192 \fn void QAbstractBarSeries::labelsPositionChanged(QAbstractBarSeries::LabelsPosition position)
192 \fn void QAbstractBarSeries::labelsPositionChanged(QAbstractBarSeries::LabelsPosition position)
193 Signal is emitted when the \a position of value labels is changed.
193 Signal is emitted when the \a position of value labels is changed.
194 */
194 */
195 /*!
195 /*!
196 \qmlsignal AbstractBarSeries::onLabelsPositionChanged(LabelsPosition position)
196 \qmlsignal AbstractBarSeries::onLabelsPositionChanged(LabelsPosition position)
197 Signal is emitted when the \a position of value labels is changed.
197 Signal is emitted when the \a position of value labels is changed.
198 */
198 */
199
199
200 /*!
200 /*!
201 \fn void QAbstractBarSeries::clicked(int index, QBarSet *barset)
201 \fn void QAbstractBarSeries::clicked(int index, QBarSet *barset)
202 The signal is emitted if the user clicks with a mouse on top of QBarSet \a barset.
202 The signal is emitted if the user clicks with a mouse on top of QBarSet \a barset.
203 Clicked bar inside set is indexed by \a index
203 Clicked bar inside set is indexed by \a index
204 */
204 */
205 /*!
205 /*!
206 \qmlsignal AbstractBarSeries::onClicked(int index, BarSet barset)
206 \qmlsignal AbstractBarSeries::onClicked(int index, BarSet barset)
207 The signal is emitted if the user clicks with a mouse on top of BarSet.
207 The signal is emitted if the user clicks with a mouse on top of BarSet.
208 Clicked bar inside set is indexed by \a index
208 Clicked bar inside set is indexed by \a index
209 */
209 */
210
210
211 /*!
211 /*!
212 \fn void QAbstractBarSeries::hovered(bool status, QBarSet* barset)
212 \fn void QAbstractBarSeries::hovered(bool status, QBarSet* barset)
213
213
214 The signal is emitted if mouse is hovered on top of series.
214 The signal is emitted if mouse is hovered on top of series.
215 Parameter \a barset is the pointer of barset, where hover happened.
215 Parameter \a barset is the pointer of barset, where hover happened.
216 Parameter \a status is true, if mouse entered on top of series, false if mouse left from top of series.
216 Parameter \a status is true, if mouse entered on top of series, false if mouse left from top of series.
217 */
217 */
218
218
219 /*!
219 /*!
220 \fn void QAbstractBarSeries::hovered(bool status, int index, QBarSet* barset)
220 \fn void QAbstractBarSeries::hovered(bool status, int index, QBarSet* barset)
221
221
222 The signal is emitted if mouse is hovered on top of series.
222 The signal is emitted if mouse is hovered on top of series.
223 Parameter \a barset is the pointer of barset, where hover happened.
223 Parameter \a barset is the pointer of barset, where hover happened.
224 Parameter \a status is true, if mouse entered on top of series, false if mouse left from top of series.
224 Parameter \a status is true, if mouse entered on top of series, false if mouse left from top of series.
225 Hovered bar inside the set is indexed by \a index.
225 Hovered bar inside the set is indexed by \a index.
226 */
226 */
227 /*!
227 /*!
228 \qmlsignal AbstractBarSeries::onHovered(bool status, int index, BarSet barset)
228 \qmlsignal AbstractBarSeries::onHovered(bool status, int index, BarSet barset)
229
229
230 The signal is emitted if mouse is hovered on top of series.
230 The signal is emitted if mouse is hovered on top of series.
231 Parameter \a barset is the pointer of barset, where hover happened.
231 Parameter \a barset is the pointer of barset, where hover happened.
232 Parameter \a status is true, if mouse entered on top of series, false if mouse left from top of series.
232 Parameter \a status is true, if mouse entered on top of series, false if mouse left from top of series.
233 Hovered bar inside the set is indexed by \a index.
233 Hovered bar inside the set is indexed by \a index.
234 */
234 */
235
235
236 /*!
236 /*!
237 \fn void QAbstractBarSeries::countChanged()
237 \fn void QAbstractBarSeries::countChanged()
238 This signal is emitted when barset count has been changed, for example by append or remove.
238 This signal is emitted when barset count has been changed, for example by append or remove.
239 */
239 */
240 /*!
240 /*!
241 \qmlsignal AbstractBarSeries::onCountChanged()
241 \qmlsignal AbstractBarSeries::onCountChanged()
242 This signal is emitted when barset count has been changed, for example by append or remove.
242 This signal is emitted when barset count has been changed, for example by append or remove.
243 */
243 */
244
244
245 /*!
245 /*!
246 \fn void QAbstractBarSeries::labelsVisibleChanged()
246 \fn void QAbstractBarSeries::labelsVisibleChanged()
247 This signal is emitted when labels visibility have changed.
247 This signal is emitted when labels visibility have changed.
248 \sa isLabelsVisible(), setLabelsVisible()
248 \sa isLabelsVisible(), setLabelsVisible()
249 */
249 */
250
250
251 /*!
251 /*!
252 \fn void QAbstractBarSeries::barsetsAdded(QList<QBarSet*> sets)
252 \fn void QAbstractBarSeries::barsetsAdded(QList<QBarSet*> sets)
253 This signal is emitted when \a sets have been added to the series.
253 This signal is emitted when \a sets have been added to the series.
254 \sa append(), insert()
254 \sa append(), insert()
255 */
255 */
256 /*!
256 /*!
257 \qmlsignal AbstractBarSeries::onBarsetsAdded(BarSet barset)
257 \qmlsignal AbstractBarSeries::onBarsetsAdded(BarSet barset)
258 Emitted when \a barset has been added to the series.
258 Emitted when \a barset has been added to the series.
259 */
259 */
260
260
261 /*!
261 /*!
262 \fn void QAbstractBarSeries::barsetsRemoved(QList<QBarSet*> sets)
262 \fn void QAbstractBarSeries::barsetsRemoved(QList<QBarSet*> sets)
263 This signal is emitted when \a sets have been removed from the series.
263 This signal is emitted when \a sets have been removed from the series.
264 \sa remove()
264 \sa remove()
265 */
265 */
266 /*!
266 /*!
267 \qmlsignal AbstractBarSeries::onBarsetsRemoved(BarSet barset)
267 \qmlsignal AbstractBarSeries::onBarsetsRemoved(BarSet barset)
268 Emitted when \a barset has been removed from the series.
268 Emitted when \a barset has been removed from the series.
269 */
269 */
270
270
271 /*!
271 /*!
272 \qmlmethod BarSet AbstractBarSeries::at(int index)
272 \qmlmethod BarSet AbstractBarSeries::at(int index)
273 Returns bar set at \a index. Returns null if the index is not valid.
273 Returns bar set at \a index. Returns null if the index is not valid.
274 */
274 */
275
275
276 /*!
276 /*!
277 \qmlmethod BarSet AbstractBarSeries::append(string label, VariantList values)
277 \qmlmethod BarSet AbstractBarSeries::append(string label, VariantList values)
278 Adds a new bar set with \a label and \a values to \a index. Values is a list of reals.
278 Adds a new bar set with \a label and \a values to \a index. Values is a list of reals.
279 For example:
279 For example:
280 \code
280 \code
281 myBarSeries.append("set 1", [0, 0.2, 0.2, 0.5, 0.4, 1.5, 0.9]);
281 myBarSeries.append("set 1", [0, 0.2, 0.2, 0.5, 0.4, 1.5, 0.9]);
282 \endcode
282 \endcode
283 */
283 */
284
284
285 /*!
285 /*!
286 \qmlmethod BarSet AbstractBarSeries::insert(int index, string label, VariantList values)
286 \qmlmethod BarSet AbstractBarSeries::insert(int index, string label, VariantList values)
287 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.
287 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.
288 If index is zero or smaller, the new barset is prepended. If the index is count or bigger, the new barset is
288 If index is zero or smaller, the new barset is prepended. If the index is count or bigger, the new barset is
289 appended.
289 appended.
290 \sa AbstractBarSeries::append()
290 \sa AbstractBarSeries::append()
291 */
291 */
292
292
293 /*!
293 /*!
294 \qmlmethod bool AbstractBarSeries::remove(BarSet barset)
294 \qmlmethod bool AbstractBarSeries::remove(BarSet barset)
295 Removes the barset from the series. Returns true if successful, false otherwise.
295 Removes the barset from the series. Returns true if successful, false otherwise.
296 */
296 */
297
297
298 /*!
298 /*!
299 \qmlmethod AbstractBarSeries::clear()
299 \qmlmethod AbstractBarSeries::clear()
300 Removes all barsets from the series.
300 Removes all barsets from the series.
301 */
301 */
302
302
303 /*!
303 /*!
304 Destructs abstractbarseries and owned barsets.
304 Destructs abstractbarseries and owned barsets.
305 */
305 */
306 QAbstractBarSeries::~QAbstractBarSeries()
306 QAbstractBarSeries::~QAbstractBarSeries()
307 {
307 {
308
308
309 }
309 }
310
310
311 /*!
311 /*!
312 \internal
312 \internal
313 */
313 */
314 QAbstractBarSeries::QAbstractBarSeries(QAbstractBarSeriesPrivate &o, QObject *parent)
314 QAbstractBarSeries::QAbstractBarSeries(QAbstractBarSeriesPrivate &o, QObject *parent)
315 : QAbstractSeries(o, parent)
315 : QAbstractSeries(o, parent)
316 {
316 {
317 Q_D(QAbstractSeries);
317 Q_D(QAbstractSeries);
318 QObject::connect(this, SIGNAL(countChanged()), d, SIGNAL(countChanged()));
318 QObject::connect(this, SIGNAL(countChanged()), d, SIGNAL(countChanged()));
319 }
319 }
320
320
321 /*!
321 /*!
322 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
322 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
323 is zero and negative values are treated as zero. Setting the width to zero means that width of the bar on screen
323 is zero and negative values are treated as zero. Setting the width to zero means that width of the bar on screen
324 is one pixel no matter what the scale of x-axis is. Bars wider than zero are scaled with x-axis.
324 is one pixel no matter what the scale of x-axis is. Bars wider than zero are scaled with x-axis.
325 Note that with \link QBarSeries \endlink this value means the width of one group of bars instead of just one bar.
325 Note that with \link QBarSeries \endlink this value means the width of one group of bars instead of just one bar.
326 */
326 */
327 void QAbstractBarSeries::setBarWidth(qreal width)
327 void QAbstractBarSeries::setBarWidth(qreal width)
328 {
328 {
329 Q_D(QAbstractBarSeries);
329 Q_D(QAbstractBarSeries);
330 d->setBarWidth(width);
330 d->setBarWidth(width);
331 }
331 }
332
332
333 /*!
333 /*!
334 Returns the width of the bars of the series.
334 Returns the width of the bars of the series.
335 \sa setBarWidth()
335 \sa setBarWidth()
336 */
336 */
337 qreal QAbstractBarSeries::barWidth() const
337 qreal QAbstractBarSeries::barWidth() const
338 {
338 {
339 Q_D(const QAbstractBarSeries);
339 Q_D(const QAbstractBarSeries);
340 return d->barWidth();
340 return d->barWidth();
341 }
341 }
342
342
343 /*!
343 /*!
344 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.
344 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.
345 Returns true, if appending succeeded.
345 Returns true, if appending succeeded.
346 */
346 */
347 bool QAbstractBarSeries::append(QBarSet *set)
347 bool QAbstractBarSeries::append(QBarSet *set)
348 {
348 {
349 Q_D(QAbstractBarSeries);
349 Q_D(QAbstractBarSeries);
350 bool success = d->append(set);
350 bool success = d->append(set);
351 if (success) {
351 if (success) {
352 QList<QBarSet *> sets;
352 QList<QBarSet *> sets;
353 sets.append(set);
353 sets.append(set);
354 set->setParent(this);
354 set->setParent(this);
355 emit barsetsAdded(sets);
355 emit barsetsAdded(sets);
356 emit countChanged();
356 emit countChanged();
357 }
357 }
358 return success;
358 return success;
359 }
359 }
360
360
361 /*!
361 /*!
362 Removes barset from series. Releases ownership of \a set. Deletes the set, if remove
362 Removes barset from series. Releases ownership of \a set. Deletes the set, if remove
363 was successful.
363 was successful.
364 Returns true, if set was removed.
364 Returns true, if set was removed.
365 */
365 */
366 bool QAbstractBarSeries::remove(QBarSet *set)
366 bool QAbstractBarSeries::remove(QBarSet *set)
367 {
367 {
368 Q_D(QAbstractBarSeries);
368 Q_D(QAbstractBarSeries);
369 bool success = d->remove(set);
369 bool success = d->remove(set);
370 if (success) {
370 if (success) {
371 QList<QBarSet *> sets;
371 QList<QBarSet *> sets;
372 sets.append(set);
372 sets.append(set);
373 set->setParent(0);
373 set->setParent(0);
374 emit barsetsRemoved(sets);
374 emit barsetsRemoved(sets);
375 emit countChanged();
375 emit countChanged();
376 delete set;
376 delete set;
377 set = 0;
377 set = 0;
378 }
378 }
379 return success;
379 return success;
380 }
380 }
381
381
382 /*!
382 /*!
383 Takes a single \a set from the series. Does not delete the barset object.
383 Takes a single \a set from the series. Does not delete the barset object.
384
384
385 NOTE: The series remains as the barset's parent object. You must set the
385 NOTE: The series remains as the barset's parent object. You must set the
386 parent object to take full ownership.
386 parent object to take full ownership.
387
387
388 Returns true if take was successful.
388 Returns true if take was successful.
389 */
389 */
390 bool QAbstractBarSeries::take(QBarSet *set)
390 bool QAbstractBarSeries::take(QBarSet *set)
391 {
391 {
392 Q_D(QAbstractBarSeries);
392 Q_D(QAbstractBarSeries);
393 bool success = d->remove(set);
393 bool success = d->remove(set);
394 if (success) {
394 if (success) {
395 QList<QBarSet *> sets;
395 QList<QBarSet *> sets;
396 sets.append(set);
396 sets.append(set);
397 emit barsetsRemoved(sets);
397 emit barsetsRemoved(sets);
398 emit countChanged();
398 emit countChanged();
399 }
399 }
400 return success;
400 return success;
401 }
401 }
402
402
403 /*!
403 /*!
404 Adds a list of barsets to series. Takes ownership of \a sets.
404 Adds a list of barsets to series. Takes ownership of \a sets.
405 Returns true, if all sets were appended successfully. If any of the sets is null or is already appended to series,
405 Returns true, if all sets were appended successfully. If any of the sets is null or is already appended to series,
406 nothing is appended and function returns false. If any of the sets is in list more than once, nothing is appended
406 nothing is appended and function returns false. If any of the sets is in list more than once, nothing is appended
407 and function returns false.
407 and function returns false.
408 */
408 */
409 bool QAbstractBarSeries::append(QList<QBarSet *> sets)
409 bool QAbstractBarSeries::append(QList<QBarSet *> sets)
410 {
410 {
411 Q_D(QAbstractBarSeries);
411 Q_D(QAbstractBarSeries);
412 bool success = d->append(sets);
412 bool success = d->append(sets);
413 if (success) {
413 if (success) {
414 emit barsetsAdded(sets);
414 emit barsetsAdded(sets);
415 emit countChanged();
415 emit countChanged();
416 }
416 }
417 return success;
417 return success;
418 }
418 }
419
419
420 /*!
420 /*!
421 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.
421 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.
422 Returns true, if inserting succeeded.
422 Returns true, if inserting succeeded.
423
423
424 */
424 */
425 bool QAbstractBarSeries::insert(int index, QBarSet *set)
425 bool QAbstractBarSeries::insert(int index, QBarSet *set)
426 {
426 {
427 Q_D(QAbstractBarSeries);
427 Q_D(QAbstractBarSeries);
428 bool success = d->insert(index, set);
428 bool success = d->insert(index, set);
429 if (success) {
429 if (success) {
430 QList<QBarSet *> sets;
430 QList<QBarSet *> sets;
431 sets.append(set);
431 sets.append(set);
432 emit barsetsAdded(sets);
432 emit barsetsAdded(sets);
433 emit countChanged();
433 emit countChanged();
434 }
434 }
435 return success;
435 return success;
436 }
436 }
437
437
438 /*!
438 /*!
439 Removes all barsets from the series. Deletes removed sets.
439 Removes all barsets from the series. Deletes removed sets.
440 */
440 */
441 void QAbstractBarSeries::clear()
441 void QAbstractBarSeries::clear()
442 {
442 {
443 Q_D(QAbstractBarSeries);
443 Q_D(QAbstractBarSeries);
444 QList<QBarSet *> sets = barSets();
444 QList<QBarSet *> sets = barSets();
445 bool success = d->remove(sets);
445 bool success = d->remove(sets);
446 if (success) {
446 if (success) {
447 emit barsetsRemoved(sets);
447 emit barsetsRemoved(sets);
448 emit countChanged();
448 emit countChanged();
449 foreach (QBarSet *set, sets)
449 foreach (QBarSet *set, sets)
450 delete set;
450 delete set;
451 }
451 }
452 }
452 }
453
453
454 /*!
454 /*!
455 Returns number of sets in series.
455 Returns number of sets in series.
456 */
456 */
457 int QAbstractBarSeries::count() const
457 int QAbstractBarSeries::count() const
458 {
458 {
459 Q_D(const QAbstractBarSeries);
459 Q_D(const QAbstractBarSeries);
460 return d->m_barSets.count();
460 return d->m_barSets.count();
461 }
461 }
462
462
463 /*!
463 /*!
464 Returns a list of sets in series. Keeps ownership of sets.
464 Returns a list of sets in series. Keeps ownership of sets.
465 */
465 */
466 QList<QBarSet *> QAbstractBarSeries::barSets() const
466 QList<QBarSet *> QAbstractBarSeries::barSets() const
467 {
467 {
468 Q_D(const QAbstractBarSeries);
468 Q_D(const QAbstractBarSeries);
469 return d->m_barSets;
469 return d->m_barSets;
470 }
470 }
471
471
472 /*!
472 /*!
473 Sets the visibility of labels in series to \a visible
473 Sets the visibility of labels in series to \a visible
474 */
474 */
475 void QAbstractBarSeries::setLabelsVisible(bool visible)
475 void QAbstractBarSeries::setLabelsVisible(bool visible)
476 {
476 {
477 Q_D(QAbstractBarSeries);
477 Q_D(QAbstractBarSeries);
478 if (d->m_labelsVisible != visible) {
478 if (d->m_labelsVisible != visible) {
479 d->setLabelsVisible(visible);
479 d->setLabelsVisible(visible);
480 emit labelsVisibleChanged();
480 emit labelsVisibleChanged();
481 }
481 }
482 }
482 }
483
483
484 /*!
484 /*!
485 Returns the visibility of labels
485 Returns the visibility of labels
486 */
486 */
487 bool QAbstractBarSeries::isLabelsVisible() const
487 bool QAbstractBarSeries::isLabelsVisible() const
488 {
488 {
489 Q_D(const QAbstractBarSeries);
489 Q_D(const QAbstractBarSeries);
490 return d->m_labelsVisible;
490 return d->m_labelsVisible;
491 }
491 }
492
492
493 void QAbstractBarSeries::setLabelsFormat(const QString &format)
493 void QAbstractBarSeries::setLabelsFormat(const QString &format)
494 {
494 {
495 Q_D(QAbstractBarSeries);
495 Q_D(QAbstractBarSeries);
496 if (d->m_labelsFormat != format) {
496 if (d->m_labelsFormat != format) {
497 d->m_labelsFormat = format;
497 d->m_labelsFormat = format;
498 emit labelsFormatChanged(format);
498 emit labelsFormatChanged(format);
499 }
499 }
500 }
500 }
501
501
502 QString QAbstractBarSeries::labelsFormat() const
502 QString QAbstractBarSeries::labelsFormat() const
503 {
503 {
504 Q_D(const QAbstractBarSeries);
504 Q_D(const QAbstractBarSeries);
505 return d->m_labelsFormat;
505 return d->m_labelsFormat;
506 }
506 }
507
507
508 void QAbstractBarSeries::setLabelsPosition(QAbstractBarSeries::LabelsPosition position)
508 void QAbstractBarSeries::setLabelsPosition(QAbstractBarSeries::LabelsPosition position)
509 {
509 {
510 Q_D(QAbstractBarSeries);
510 Q_D(QAbstractBarSeries);
511 if (d->m_labelsPosition != position) {
511 if (d->m_labelsPosition != position) {
512 d->m_labelsPosition = position;
512 d->m_labelsPosition = position;
513 emit labelsPositionChanged(position);
513 emit labelsPositionChanged(position);
514 }
514 }
515 }
515 }
516
516
517 QAbstractBarSeries::LabelsPosition QAbstractBarSeries::labelsPosition() const
517 QAbstractBarSeries::LabelsPosition QAbstractBarSeries::labelsPosition() const
518 {
518 {
519 Q_D(const QAbstractBarSeries);
519 Q_D(const QAbstractBarSeries);
520 return d->m_labelsPosition;
520 return d->m_labelsPosition;
521 }
521 }
522
522
523 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
523 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
524
524
525 QAbstractBarSeriesPrivate::QAbstractBarSeriesPrivate(QAbstractBarSeries *q) :
525 QAbstractBarSeriesPrivate::QAbstractBarSeriesPrivate(QAbstractBarSeries *q) :
526 QAbstractSeriesPrivate(q),
526 QAbstractSeriesPrivate(q),
527 m_barWidth(0.5), // Default value is 50% of category width
527 m_barWidth(0.5), // Default value is 50% of category width
528 m_labelsVisible(false),
528 m_labelsVisible(false),
529 m_visible(true),
529 m_visible(true),
530 m_blockBarUpdate(false),
530 m_blockBarUpdate(false),
531 m_labelsFormat(),
531 m_labelsFormat(),
532 m_labelsPosition(QAbstractBarSeries::LabelsCenter)
532 m_labelsPosition(QAbstractBarSeries::LabelsCenter)
533 {
533 {
534 }
534 }
535
535
536 int QAbstractBarSeriesPrivate::categoryCount() const
536 int QAbstractBarSeriesPrivate::categoryCount() const
537 {
537 {
538 // No categories defined. return count of longest set.
538 // No categories defined. return count of longest set.
539 int count = 0;
539 int count = 0;
540 for (int i = 0; i < m_barSets.count(); i++) {
540 for (int i = 0; i < m_barSets.count(); i++) {
541 if (m_barSets.at(i)->count() > count)
541 if (m_barSets.at(i)->count() > count)
542 count = m_barSets.at(i)->count();
542 count = m_barSets.at(i)->count();
543 }
543 }
544
544
545 return count;
545 return count;
546 }
546 }
547
547
548 void QAbstractBarSeriesPrivate::setBarWidth(qreal width)
548 void QAbstractBarSeriesPrivate::setBarWidth(qreal width)
549 {
549 {
550 if (width < 0.0)
550 if (width < 0.0)
551 width = 0.0;
551 width = 0.0;
552 m_barWidth = width;
552 m_barWidth = width;
553 emit updatedLayout();
553 emit updatedLayout();
554 }
554 }
555
555
556 qreal QAbstractBarSeriesPrivate::barWidth() const
556 qreal QAbstractBarSeriesPrivate::barWidth() const
557 {
557 {
558 return m_barWidth;
558 return m_barWidth;
559 }
559 }
560
560
561 QBarSet *QAbstractBarSeriesPrivate::barsetAt(int index)
561 QBarSet *QAbstractBarSeriesPrivate::barsetAt(int index)
562 {
562 {
563 return m_barSets.at(index);
563 return m_barSets.at(index);
564 }
564 }
565
565
566 void QAbstractBarSeriesPrivate::setVisible(bool visible)
566 void QAbstractBarSeriesPrivate::setVisible(bool visible)
567 {
567 {
568 m_visible = visible;
568 m_visible = visible;
569 emit visibleChanged();
569 emit visibleChanged();
570 }
570 }
571
571
572 void QAbstractBarSeriesPrivate::setLabelsVisible(bool visible)
572 void QAbstractBarSeriesPrivate::setLabelsVisible(bool visible)
573 {
573 {
574 m_labelsVisible = visible;
574 m_labelsVisible = visible;
575 emit labelsVisibleChanged(visible);
575 emit labelsVisibleChanged(visible);
576 }
576 }
577
577
578 qreal QAbstractBarSeriesPrivate::min()
578 qreal QAbstractBarSeriesPrivate::min()
579 {
579 {
580 if (m_barSets.count() <= 0)
580 if (m_barSets.count() <= 0)
581 return 0;
581 return 0;
582
582
583 qreal min = INT_MAX;
583 qreal min = INT_MAX;
584
584
585 for (int i = 0; i < m_barSets.count(); i++) {
585 for (int i = 0; i < m_barSets.count(); i++) {
586 int categoryCount = m_barSets.at(i)->count();
586 int categoryCount = m_barSets.at(i)->count();
587 for (int j = 0; j < categoryCount; j++) {
587 for (int j = 0; j < categoryCount; j++) {
588 qreal temp = m_barSets.at(i)->at(j);
588 qreal temp = m_barSets.at(i)->at(j);
589 if (temp < min)
589 if (temp < min)
590 min = temp;
590 min = temp;
591 }
591 }
592 }
592 }
593 return min;
593 return min;
594 }
594 }
595
595
596 qreal QAbstractBarSeriesPrivate::max()
596 qreal QAbstractBarSeriesPrivate::max()
597 {
597 {
598 if (m_barSets.count() <= 0)
598 if (m_barSets.count() <= 0)
599 return 0;
599 return 0;
600
600
601 qreal max = INT_MIN;
601 qreal max = INT_MIN;
602
602
603 for (int i = 0; i < m_barSets.count(); i++) {
603 for (int i = 0; i < m_barSets.count(); i++) {
604 int categoryCount = m_barSets.at(i)->count();
604 int categoryCount = m_barSets.at(i)->count();
605 for (int j = 0; j < categoryCount; j++) {
605 for (int j = 0; j < categoryCount; j++) {
606 qreal temp = m_barSets.at(i)->at(j);
606 qreal temp = m_barSets.at(i)->at(j);
607 if (temp > max)
607 if (temp > max)
608 max = temp;
608 max = temp;
609 }
609 }
610 }
610 }
611
611
612 return max;
612 return max;
613 }
613 }
614
614
615 qreal QAbstractBarSeriesPrivate::valueAt(int set, int category)
615 qreal QAbstractBarSeriesPrivate::valueAt(int set, int category)
616 {
616 {
617 if ((set < 0) || (set >= m_barSets.count()))
617 if ((set < 0) || (set >= m_barSets.count()))
618 return 0; // No set, no value.
618 return 0; // No set, no value.
619 else if ((category < 0) || (category >= m_barSets.at(set)->count()))
619 else if ((category < 0) || (category >= m_barSets.at(set)->count()))
620 return 0; // No category, no value.
620 return 0; // No category, no value.
621
621
622 return m_barSets.at(set)->at(category);
622 return m_barSets.at(set)->at(category);
623 }
623 }
624
624
625 qreal QAbstractBarSeriesPrivate::percentageAt(int set, int category)
625 qreal QAbstractBarSeriesPrivate::percentageAt(int set, int category)
626 {
626 {
627 if ((set < 0) || (set >= m_barSets.count()))
627 if ((set < 0) || (set >= m_barSets.count()))
628 return 0; // No set, no value.
628 return 0; // No set, no value.
629 else if ((category < 0) || (category >= m_barSets.at(set)->count()))
629 else if ((category < 0) || (category >= m_barSets.at(set)->count()))
630 return 0; // No category, no value.
630 return 0; // No category, no value.
631
631
632 qreal value = m_barSets.at(set)->at(category);
632 qreal value = m_barSets.at(set)->at(category);
633 qreal sum = categorySum(category);
633 qreal sum = categorySum(category);
634 if (qFuzzyCompare(sum, 0))
634 if (qFuzzyCompare(sum, 0))
635 return 0;
635 return 0;
636
636
637 return value / sum;
637 return value / sum;
638 }
638 }
639
639
640 qreal QAbstractBarSeriesPrivate::categorySum(int category)
640 qreal QAbstractBarSeriesPrivate::categorySum(int category)
641 {
641 {
642 qreal sum(0);
642 qreal sum(0);
643 int count = m_barSets.count(); // Count sets
643 int count = m_barSets.count(); // Count sets
644 for (int set = 0; set < count; set++) {
644 for (int set = 0; set < count; set++) {
645 if (category < m_barSets.at(set)->count())
645 if (category < m_barSets.at(set)->count())
646 sum += m_barSets.at(set)->at(category);
646 sum += m_barSets.at(set)->at(category);
647 }
647 }
648 return sum;
648 return sum;
649 }
649 }
650
650
651 qreal QAbstractBarSeriesPrivate::absoluteCategorySum(int category)
651 qreal QAbstractBarSeriesPrivate::absoluteCategorySum(int category)
652 {
652 {
653 qreal sum(0);
653 qreal sum(0);
654 int count = m_barSets.count(); // Count sets
654 int count = m_barSets.count(); // Count sets
655 for (int set = 0; set < count; set++) {
655 for (int set = 0; set < count; set++) {
656 if (category < m_barSets.at(set)->count())
656 if (category < m_barSets.at(set)->count())
657 sum += qAbs(m_barSets.at(set)->at(category));
657 sum += qAbs(m_barSets.at(set)->at(category));
658 }
658 }
659 return sum;
659 return sum;
660 }
660 }
661
661
662 qreal QAbstractBarSeriesPrivate::maxCategorySum()
662 qreal QAbstractBarSeriesPrivate::maxCategorySum()
663 {
663 {
664 qreal max = INT_MIN;
664 qreal max = INT_MIN;
665 int count = categoryCount();
665 int count = categoryCount();
666 for (int i = 0; i < count; i++) {
666 for (int i = 0; i < count; i++) {
667 qreal sum = categorySum(i);
667 qreal sum = categorySum(i);
668 if (sum > max)
668 if (sum > max)
669 max = sum;
669 max = sum;
670 }
670 }
671 return max;
671 return max;
672 }
672 }
673
673
674 qreal QAbstractBarSeriesPrivate::minX()
674 qreal QAbstractBarSeriesPrivate::minX()
675 {
675 {
676 if (m_barSets.count() <= 0)
676 if (m_barSets.count() <= 0)
677 return 0;
677 return 0;
678
678
679 qreal min = INT_MAX;
679 qreal min = INT_MAX;
680
680
681 for (int i = 0; i < m_barSets.count(); i++) {
681 for (int i = 0; i < m_barSets.count(); i++) {
682 int categoryCount = m_barSets.at(i)->count();
682 int categoryCount = m_barSets.at(i)->count();
683 for (int j = 0; j < categoryCount; j++) {
683 for (int j = 0; j < categoryCount; j++) {
684 qreal temp = m_barSets.at(i)->d_ptr.data()->m_values.at(j).x();
684 qreal temp = m_barSets.at(i)->d_ptr.data()->m_values.at(j).x();
685 if (temp < min)
685 if (temp < min)
686 min = temp;
686 min = temp;
687 }
687 }
688 }
688 }
689 return min;
689 return min;
690 }
690 }
691
691
692 qreal QAbstractBarSeriesPrivate::maxX()
692 qreal QAbstractBarSeriesPrivate::maxX()
693 {
693 {
694 if (m_barSets.count() <= 0)
694 if (m_barSets.count() <= 0)
695 return 0;
695 return 0;
696
696
697 qreal max = INT_MIN;
697 qreal max = INT_MIN;
698
698
699 for (int i = 0; i < m_barSets.count(); i++) {
699 for (int i = 0; i < m_barSets.count(); i++) {
700 int categoryCount = m_barSets.at(i)->count();
700 int categoryCount = m_barSets.at(i)->count();
701 for (int j = 0; j < categoryCount; j++) {
701 for (int j = 0; j < categoryCount; j++) {
702 qreal temp = m_barSets.at(i)->d_ptr.data()->m_values.at(j).x();
702 qreal temp = m_barSets.at(i)->d_ptr.data()->m_values.at(j).x();
703 if (temp > max)
703 if (temp > max)
704 max = temp;
704 max = temp;
705 }
705 }
706 }
706 }
707
707
708 return max;
708 return max;
709 }
709 }
710
710
711 qreal QAbstractBarSeriesPrivate::categoryTop(int category)
711 qreal QAbstractBarSeriesPrivate::categoryTop(int category)
712 {
712 {
713 // Returns top (sum of all positive values) of category.
713 // Returns top (sum of all positive values) of category.
714 // Returns 0, if all values are negative
714 // Returns 0, if all values are negative
715 qreal top(0);
715 qreal top(0);
716 int count = m_barSets.count();
716 int count = m_barSets.count();
717 for (int set = 0; set < count; set++) {
717 for (int set = 0; set < count; set++) {
718 if (category < m_barSets.at(set)->count()) {
718 if (category < m_barSets.at(set)->count()) {
719 qreal temp = m_barSets.at(set)->at(category);
719 qreal temp = m_barSets.at(set)->at(category);
720 if (temp > 0) {
720 if (temp > 0) {
721 top += temp;
721 top += temp;
722 }
722 }
723 }
723 }
724 }
724 }
725 return top;
725 return top;
726 }
726 }
727
727
728 qreal QAbstractBarSeriesPrivate::categoryBottom(int category)
728 qreal QAbstractBarSeriesPrivate::categoryBottom(int category)
729 {
729 {
730 // Returns bottom (sum of all negative values) of category
730 // Returns bottom (sum of all negative values) of category
731 // Returns 0, if all values are positive
731 // Returns 0, if all values are positive
732 qreal bottom(0);
732 qreal bottom(0);
733 int count = m_barSets.count();
733 int count = m_barSets.count();
734 for (int set = 0; set < count; set++) {
734 for (int set = 0; set < count; set++) {
735 if (category < m_barSets.at(set)->count()) {
735 if (category < m_barSets.at(set)->count()) {
736 qreal temp = m_barSets.at(set)->at(category);
736 qreal temp = m_barSets.at(set)->at(category);
737 if (temp < 0) {
737 if (temp < 0) {
738 bottom += temp;
738 bottom += temp;
739 }
739 }
740 }
740 }
741 }
741 }
742 return bottom;
742 return bottom;
743 }
743 }
744
744
745 qreal QAbstractBarSeriesPrivate::top()
745 qreal QAbstractBarSeriesPrivate::top()
746 {
746 {
747 // Returns top of all categories
747 // Returns top of all categories
748 qreal top(0);
748 qreal top(0);
749 int count = categoryCount();
749 int count = categoryCount();
750 for (int i = 0; i < count; i++) {
750 for (int i = 0; i < count; i++) {
751 qreal temp = categoryTop(i);
751 qreal temp = categoryTop(i);
752 if (temp > top)
752 if (temp > top)
753 top = temp;
753 top = temp;
754 }
754 }
755 return top;
755 return top;
756 }
756 }
757
757
758 qreal QAbstractBarSeriesPrivate::bottom()
758 qreal QAbstractBarSeriesPrivate::bottom()
759 {
759 {
760 // Returns bottom of all categories
760 // Returns bottom of all categories
761 qreal bottom(0);
761 qreal bottom(0);
762 int count = categoryCount();
762 int count = categoryCount();
763 for (int i = 0; i < count; i++) {
763 for (int i = 0; i < count; i++) {
764 qreal temp = categoryBottom(i);
764 qreal temp = categoryBottom(i);
765 if (temp < bottom)
765 if (temp < bottom)
766 bottom = temp;
766 bottom = temp;
767 }
767 }
768 return bottom;
768 return bottom;
769 }
769 }
770
770
771 bool QAbstractBarSeriesPrivate::blockBarUpdate()
771 bool QAbstractBarSeriesPrivate::blockBarUpdate()
772 {
772 {
773 return m_blockBarUpdate;
773 return m_blockBarUpdate;
774 }
774 }
775
775
776 void QAbstractBarSeriesPrivate::initializeDomain()
776 void QAbstractBarSeriesPrivate::initializeDomain()
777 {
777 {
778 qreal minX(domain()->minX());
778 qreal minX(domain()->minX());
779 qreal minY(domain()->minY());
779 qreal minY(domain()->minY());
780 qreal maxX(domain()->maxX());
780 qreal maxX(domain()->maxX());
781 qreal maxY(domain()->maxY());
781 qreal maxY(domain()->maxY());
782
782
783 qreal seriesMinX = this->minX();
783 qreal seriesMinX = this->minX();
784 qreal seriesMaxX = this->maxX();
784 qreal seriesMaxX = this->maxX();
785 qreal y = max();
785 qreal y = max();
786 minX = qMin(minX, seriesMinX - (qreal)0.5);
786 minX = qMin(minX, seriesMinX - (qreal)0.5);
787 minY = qMin(minY, y);
787 minY = qMin(minY, y);
788 maxX = qMax(maxX, seriesMaxX + (qreal)0.5);
788 maxX = qMax(maxX, seriesMaxX + (qreal)0.5);
789 maxY = qMax(maxY, y);
789 maxY = qMax(maxY, y);
790
790
791 domain()->setRange(minX, maxX, minY, maxY);
791 domain()->setRange(minX, maxX, minY, maxY);
792 }
792 }
793
793
794 QList<QLegendMarker*> QAbstractBarSeriesPrivate::createLegendMarkers(QLegend* legend)
794 QList<QLegendMarker*> QAbstractBarSeriesPrivate::createLegendMarkers(QLegend* legend)
795 {
795 {
796 Q_Q(QAbstractBarSeries);
796 Q_Q(QAbstractBarSeries);
797 QList<QLegendMarker*> markers;
797 QList<QLegendMarker*> markers;
798
798
799 foreach(QBarSet* set, q->barSets()) {
799 foreach(QBarSet* set, q->barSets()) {
800 QBarLegendMarker* marker = new QBarLegendMarker(q,set,legend);
800 QBarLegendMarker* marker = new QBarLegendMarker(q,set,legend);
801 markers << marker;
801 markers << marker;
802 }
802 }
803 return markers;
803 return markers;
804 }
804 }
805
805
806
806
807 bool QAbstractBarSeriesPrivate::append(QBarSet *set)
807 bool QAbstractBarSeriesPrivate::append(QBarSet *set)
808 {
808 {
809 if ((m_barSets.contains(set)) || (set == 0))
809 if ((m_barSets.contains(set)) || (set == 0))
810 return false; // Fail if set is already in list or set is null.
810 return false; // Fail if set is already in list or set is null.
811
811
812 m_barSets.append(set);
812 m_barSets.append(set);
813 QObject::connect(set->d_ptr.data(), SIGNAL(updatedLayout()), this, SIGNAL(updatedLayout()));
813 QObject::connect(set->d_ptr.data(), SIGNAL(updatedLayout()), this, SIGNAL(updatedLayout()));
814 QObject::connect(set->d_ptr.data(), SIGNAL(updatedBars()), this, SIGNAL(updatedBars()));
814 QObject::connect(set->d_ptr.data(), SIGNAL(updatedBars()), this, SIGNAL(updatedBars()));
815 QObject::connect(set->d_ptr.data(), SIGNAL(restructuredBars()), this, SIGNAL(restructuredBars()));
815 QObject::connect(set->d_ptr.data(), SIGNAL(restructuredBars()), this, SIGNAL(restructuredBars()));
816
816
817 emit restructuredBars(); // this notifies barchartitem
817 emit restructuredBars(); // this notifies barchartitem
818 return true;
818 return true;
819 }
819 }
820
820
821 bool QAbstractBarSeriesPrivate::remove(QBarSet *set)
821 bool QAbstractBarSeriesPrivate::remove(QBarSet *set)
822 {
822 {
823 if (!m_barSets.contains(set))
823 if (!m_barSets.contains(set))
824 return false; // Fail if set is not in list
824 return false; // Fail if set is not in list
825
825
826 m_barSets.removeOne(set);
826 m_barSets.removeOne(set);
827 QObject::disconnect(set->d_ptr.data(), SIGNAL(updatedLayout()), this, SIGNAL(updatedLayout()));
827 QObject::disconnect(set->d_ptr.data(), SIGNAL(updatedLayout()), this, SIGNAL(updatedLayout()));
828 QObject::disconnect(set->d_ptr.data(), SIGNAL(updatedBars()), this, SIGNAL(updatedBars()));
828 QObject::disconnect(set->d_ptr.data(), SIGNAL(updatedBars()), this, SIGNAL(updatedBars()));
829 QObject::disconnect(set->d_ptr.data(), SIGNAL(restructuredBars()), this, SIGNAL(restructuredBars()));
829 QObject::disconnect(set->d_ptr.data(), SIGNAL(restructuredBars()), this, SIGNAL(restructuredBars()));
830
830
831 emit restructuredBars(); // this notifies barchartitem
831 emit restructuredBars(); // this notifies barchartitem
832 return true;
832 return true;
833 }
833 }
834
834
835 bool QAbstractBarSeriesPrivate::append(QList<QBarSet * > sets)
835 bool QAbstractBarSeriesPrivate::append(QList<QBarSet * > sets)
836 {
836 {
837 foreach (QBarSet *set, sets) {
837 foreach (QBarSet *set, sets) {
838 if ((set == 0) || (m_barSets.contains(set)))
838 if ((set == 0) || (m_barSets.contains(set)))
839 return false; // Fail if any of the sets is null or is already appended.
839 return false; // Fail if any of the sets is null or is already appended.
840 if (sets.count(set) != 1)
840 if (sets.count(set) != 1)
841 return false; // Also fail if same set is more than once in given list.
841 return false; // Also fail if same set is more than once in given list.
842 }
842 }
843
843
844 foreach (QBarSet *set, sets) {
844 foreach (QBarSet *set, sets) {
845 m_barSets.append(set);
845 m_barSets.append(set);
846 QObject::connect(set->d_ptr.data(), SIGNAL(updatedLayout()), this, SIGNAL(updatedLayout()));
846 QObject::connect(set->d_ptr.data(), SIGNAL(updatedLayout()), this, SIGNAL(updatedLayout()));
847 QObject::connect(set->d_ptr.data(), SIGNAL(updatedBars()), this, SIGNAL(updatedBars()));
847 QObject::connect(set->d_ptr.data(), SIGNAL(updatedBars()), this, SIGNAL(updatedBars()));
848 QObject::connect(set->d_ptr.data(), SIGNAL(restructuredBars()), this, SIGNAL(restructuredBars()));
848 QObject::connect(set->d_ptr.data(), SIGNAL(restructuredBars()), this, SIGNAL(restructuredBars()));
849 }
849 }
850
850
851 emit restructuredBars(); // this notifies barchartitem
851 emit restructuredBars(); // this notifies barchartitem
852 return true;
852 return true;
853 }
853 }
854
854
855 bool QAbstractBarSeriesPrivate::remove(QList<QBarSet * > sets)
855 bool QAbstractBarSeriesPrivate::remove(QList<QBarSet * > sets)
856 {
856 {
857 if (sets.count() == 0)
857 if (sets.count() == 0)
858 return false;
858 return false;
859
859
860 foreach (QBarSet *set, sets) {
860 foreach (QBarSet *set, sets) {
861 if ((set == 0) || (!m_barSets.contains(set)))
861 if ((set == 0) || (!m_barSets.contains(set)))
862 return false; // Fail if any of the sets is null or is not in series
862 return false; // Fail if any of the sets is null or is not in series
863 if (sets.count(set) != 1)
863 if (sets.count(set) != 1)
864 return false; // Also fail if same set is more than once in given list.
864 return false; // Also fail if same set is more than once in given list.
865 }
865 }
866
866
867 foreach (QBarSet *set, sets) {
867 foreach (QBarSet *set, sets) {
868 m_barSets.removeOne(set);
868 m_barSets.removeOne(set);
869 QObject::disconnect(set->d_ptr.data(), SIGNAL(updatedLayout()), this, SIGNAL(updatedLayout()));
869 QObject::disconnect(set->d_ptr.data(), SIGNAL(updatedLayout()), this, SIGNAL(updatedLayout()));
870 QObject::disconnect(set->d_ptr.data(), SIGNAL(updatedBars()), this, SIGNAL(updatedBars()));
870 QObject::disconnect(set->d_ptr.data(), SIGNAL(updatedBars()), this, SIGNAL(updatedBars()));
871 QObject::disconnect(set->d_ptr.data(), SIGNAL(restructuredBars()), this, SIGNAL(restructuredBars()));
871 QObject::disconnect(set->d_ptr.data(), SIGNAL(restructuredBars()), this, SIGNAL(restructuredBars()));
872 }
872 }
873
873
874 emit restructuredBars(); // this notifies barchartitem
874 emit restructuredBars(); // this notifies barchartitem
875
875
876 return true;
876 return true;
877 }
877 }
878
878
879 bool QAbstractBarSeriesPrivate::insert(int index, QBarSet *set)
879 bool QAbstractBarSeriesPrivate::insert(int index, QBarSet *set)
880 {
880 {
881 if ((m_barSets.contains(set)) || (set == 0))
881 if ((m_barSets.contains(set)) || (set == 0))
882 return false; // Fail if set is already in list or set is null.
882 return false; // Fail if set is already in list or set is null.
883
883
884 m_barSets.insert(index, set);
884 m_barSets.insert(index, set);
885 QObject::connect(set->d_ptr.data(), SIGNAL(updatedLayout()), this, SIGNAL(updatedLayout()));
885 QObject::connect(set->d_ptr.data(), SIGNAL(updatedLayout()), this, SIGNAL(updatedLayout()));
886 QObject::connect(set->d_ptr.data(), SIGNAL(updatedBars()), this, SIGNAL(updatedBars()));
886 QObject::connect(set->d_ptr.data(), SIGNAL(updatedBars()), this, SIGNAL(updatedBars()));
887 QObject::connect(set->d_ptr.data(), SIGNAL(restructuredBars()), this, SIGNAL(restructuredBars()));
887 QObject::connect(set->d_ptr.data(), SIGNAL(restructuredBars()), this, SIGNAL(restructuredBars()));
888
888
889 emit restructuredBars(); // this notifies barchartitem
889 emit restructuredBars(); // this notifies barchartitem
890 return true;
890 return true;
891 }
891 }
892
892
893 void QAbstractBarSeriesPrivate::initializeAxes()
893 void QAbstractBarSeriesPrivate::initializeAxes()
894 {
894 {
895 Q_Q(QAbstractBarSeries);
895 Q_Q(QAbstractBarSeries);
896
896
897 foreach(QAbstractAxis* axis, m_axes) {
897 foreach(QAbstractAxis* axis, m_axes) {
898
898
899 if (axis->type() == QAbstractAxis::AxisTypeBarCategory) {
899 if (axis->type() == QAbstractAxis::AxisTypeBarCategory) {
900 switch (q->type()) {
900 switch (q->type()) {
901 case QAbstractSeries::SeriesTypeHorizontalBar:
901 case QAbstractSeries::SeriesTypeHorizontalBar:
902 case QAbstractSeries::SeriesTypeHorizontalPercentBar:
902 case QAbstractSeries::SeriesTypeHorizontalPercentBar:
903 case QAbstractSeries::SeriesTypeHorizontalStackedBar:
903 case QAbstractSeries::SeriesTypeHorizontalStackedBar:
904 if (axis->orientation() == Qt::Vertical)
904 if (axis->orientation() == Qt::Vertical)
905 populateCategories(qobject_cast<QBarCategoryAxis *>(axis));
905 populateCategories(qobject_cast<QBarCategoryAxis *>(axis));
906 break;
906 break;
907 case QAbstractSeries::SeriesTypeBar:
907 case QAbstractSeries::SeriesTypeBar:
908 case QAbstractSeries::SeriesTypePercentBar:
908 case QAbstractSeries::SeriesTypePercentBar:
909 case QAbstractSeries::SeriesTypeStackedBar:
909 case QAbstractSeries::SeriesTypeStackedBar:
910 case QAbstractSeries::SeriesTypeBoxPlot:
910 case QAbstractSeries::SeriesTypeBoxPlot:
911 if (axis->orientation() == Qt::Horizontal)
911 if (axis->orientation() == Qt::Horizontal)
912 populateCategories(qobject_cast<QBarCategoryAxis *>(axis));
912 populateCategories(qobject_cast<QBarCategoryAxis *>(axis));
913 break;
913 break;
914 default:
914 default:
915 qWarning() << "Unexpected series type";
915 qWarning() << "Unexpected series type";
916 break;
916 break;
917 }
917 }
918 }
918 }
919 }
919 }
920 }
920 }
921
921
922 QAbstractAxis::AxisType QAbstractBarSeriesPrivate::defaultAxisType(Qt::Orientation orientation) const
922 QAbstractAxis::AxisType QAbstractBarSeriesPrivate::defaultAxisType(Qt::Orientation orientation) const
923 {
923 {
924 Q_Q(const QAbstractBarSeries);
924 Q_Q(const QAbstractBarSeries);
925
925
926 switch (q->type()) {
926 switch (q->type()) {
927 case QAbstractSeries::SeriesTypeHorizontalBar:
927 case QAbstractSeries::SeriesTypeHorizontalBar:
928 case QAbstractSeries::SeriesTypeHorizontalPercentBar:
928 case QAbstractSeries::SeriesTypeHorizontalPercentBar:
929 case QAbstractSeries::SeriesTypeHorizontalStackedBar:
929 case QAbstractSeries::SeriesTypeHorizontalStackedBar:
930 if (orientation == Qt::Vertical)
930 if (orientation == Qt::Vertical)
931 return QAbstractAxis::AxisTypeBarCategory;
931 return QAbstractAxis::AxisTypeBarCategory;
932 break;
932 break;
933 case QAbstractSeries::SeriesTypeBar:
933 case QAbstractSeries::SeriesTypeBar:
934 case QAbstractSeries::SeriesTypePercentBar:
934 case QAbstractSeries::SeriesTypePercentBar:
935 case QAbstractSeries::SeriesTypeStackedBar:
935 case QAbstractSeries::SeriesTypeStackedBar:
936 case QAbstractSeries::SeriesTypeBoxPlot:
936 case QAbstractSeries::SeriesTypeBoxPlot:
937 if (orientation == Qt::Horizontal)
937 if (orientation == Qt::Horizontal)
938 return QAbstractAxis::AxisTypeBarCategory;
938 return QAbstractAxis::AxisTypeBarCategory;
939 break;
939 break;
940 default:
940 default:
941 qWarning() << "Unexpected series type";
941 qWarning() << "Unexpected series type";
942 break;
942 break;
943 }
943 }
944 return QAbstractAxis::AxisTypeValue;
944 return QAbstractAxis::AxisTypeValue;
945
945
946 }
946 }
947
947
948 void QAbstractBarSeriesPrivate::populateCategories(QBarCategoryAxis *axis)
948 void QAbstractBarSeriesPrivate::populateCategories(QBarCategoryAxis *axis)
949 {
949 {
950 QStringList categories;
950 QStringList categories;
951 if (axis->categories().isEmpty()) {
951 if (axis->categories().isEmpty()) {
952 for (int i(1); i < categoryCount() + 1; i++)
952 for (int i(1); i < categoryCount() + 1; i++)
953 categories << QString::number(i);
953 categories << presenter()->numberToString(i);
954 axis->append(categories);
954 axis->append(categories);
955 }
955 }
956 }
956 }
957
957
958 QAbstractAxis* QAbstractBarSeriesPrivate::createDefaultAxis(Qt::Orientation orientation) const
958 QAbstractAxis* QAbstractBarSeriesPrivate::createDefaultAxis(Qt::Orientation orientation) const
959 {
959 {
960 if (defaultAxisType(orientation) == QAbstractAxis::AxisTypeBarCategory)
960 if (defaultAxisType(orientation) == QAbstractAxis::AxisTypeBarCategory)
961 return new QBarCategoryAxis;
961 return new QBarCategoryAxis;
962 else
962 else
963 return new QValueAxis;
963 return new QValueAxis;
964 }
964 }
965
965
966 void QAbstractBarSeriesPrivate::initializeTheme(int index, ChartTheme* theme, bool forced)
966 void QAbstractBarSeriesPrivate::initializeTheme(int index, ChartTheme* theme, bool forced)
967 {
967 {
968 m_blockBarUpdate = true; // Ensures that the bars are not updated before the theme is ready
968 m_blockBarUpdate = true; // Ensures that the bars are not updated before the theme is ready
969
969
970 const QList<QGradient> gradients = theme->seriesGradients();
970 const QList<QGradient> gradients = theme->seriesGradients();
971
971
972 qreal takeAtPos = 0.5;
972 qreal takeAtPos = 0.5;
973 qreal step = 0.2;
973 qreal step = 0.2;
974 if (m_barSets.count() > 1) {
974 if (m_barSets.count() > 1) {
975 step = 1.0 / (qreal) m_barSets.count();
975 step = 1.0 / (qreal) m_barSets.count();
976 if (m_barSets.count() % gradients.count())
976 if (m_barSets.count() % gradients.count())
977 step *= gradients.count();
977 step *= gradients.count();
978 else
978 else
979 step *= (gradients.count() - 1);
979 step *= (gradients.count() - 1);
980 }
980 }
981
981
982 for (int i(0); i < m_barSets.count(); i++) {
982 for (int i(0); i < m_barSets.count(); i++) {
983 int colorIndex = (index + i) % gradients.count();
983 int colorIndex = (index + i) % gradients.count();
984 if (i > 0 && i %gradients.count() == 0) {
984 if (i > 0 && i %gradients.count() == 0) {
985 // There is no dedicated base color for each sets, generate more colors
985 // There is no dedicated base color for each sets, generate more colors
986 takeAtPos += step;
986 takeAtPos += step;
987 if (takeAtPos == 1.0)
987 if (takeAtPos == 1.0)
988 takeAtPos += step;
988 takeAtPos += step;
989 takeAtPos -= (int) takeAtPos;
989 takeAtPos -= (int) takeAtPos;
990 }
990 }
991 if (forced || QChartPrivate::defaultBrush() == m_barSets.at(i)->d_ptr->m_brush)
991 if (forced || QChartPrivate::defaultBrush() == m_barSets.at(i)->d_ptr->m_brush)
992 m_barSets.at(i)->setBrush(ChartThemeManager::colorAt(gradients.at(colorIndex), takeAtPos));
992 m_barSets.at(i)->setBrush(ChartThemeManager::colorAt(gradients.at(colorIndex), takeAtPos));
993
993
994 // Pick label color from the opposite end of the gradient.
994 // Pick label color from the opposite end of the gradient.
995 // 0.3 as a boundary seems to work well.
995 // 0.3 as a boundary seems to work well.
996 if (forced || QChartPrivate::defaultBrush() == m_barSets.at(i)->d_ptr->m_labelBrush) {
996 if (forced || QChartPrivate::defaultBrush() == m_barSets.at(i)->d_ptr->m_labelBrush) {
997 if (takeAtPos < 0.3)
997 if (takeAtPos < 0.3)
998 m_barSets.at(i)->setLabelBrush(ChartThemeManager::colorAt(gradients.at(index % gradients.size()), 1));
998 m_barSets.at(i)->setLabelBrush(ChartThemeManager::colorAt(gradients.at(index % gradients.size()), 1));
999 else
999 else
1000 m_barSets.at(i)->setLabelBrush(ChartThemeManager::colorAt(gradients.at(index % gradients.size()), 0));
1000 m_barSets.at(i)->setLabelBrush(ChartThemeManager::colorAt(gradients.at(index % gradients.size()), 0));
1001 }
1001 }
1002 if (forced || QChartPrivate::defaultPen() == m_barSets.at(i)->d_ptr->m_pen) {
1002 if (forced || QChartPrivate::defaultPen() == m_barSets.at(i)->d_ptr->m_pen) {
1003 QColor c = ChartThemeManager::colorAt(gradients.at(index % gradients.size()), 0.0);
1003 QColor c = ChartThemeManager::colorAt(gradients.at(index % gradients.size()), 0.0);
1004 m_barSets.at(i)->setPen(c);
1004 m_barSets.at(i)->setPen(c);
1005 }
1005 }
1006 }
1006 }
1007 m_blockBarUpdate = false;
1007 m_blockBarUpdate = false;
1008 emit updatedBars();
1008 emit updatedBars();
1009 }
1009 }
1010
1010
1011 void QAbstractBarSeriesPrivate::initializeAnimations(QChart::AnimationOptions options)
1011 void QAbstractBarSeriesPrivate::initializeAnimations(QChart::AnimationOptions options)
1012 {
1012 {
1013 AbstractBarChartItem *bar = static_cast<AbstractBarChartItem *>(m_item.data());
1013 AbstractBarChartItem *bar = static_cast<AbstractBarChartItem *>(m_item.data());
1014 Q_ASSERT(bar);
1014 Q_ASSERT(bar);
1015 if (bar->animation())
1015 if (bar->animation())
1016 bar->animation()->stopAndDestroyLater();
1016 bar->animation()->stopAndDestroyLater();
1017
1017
1018 if (options.testFlag(QChart::SeriesAnimations))
1018 if (options.testFlag(QChart::SeriesAnimations))
1019 bar->setAnimation(new BarAnimation(bar));
1019 bar->setAnimation(new BarAnimation(bar));
1020 else
1020 else
1021 bar->setAnimation(0);
1021 bar->setAnimation(0);
1022 QAbstractSeriesPrivate::initializeAnimations(options);
1022 QAbstractSeriesPrivate::initializeAnimations(options);
1023 }
1023 }
1024
1024
1025 #include "moc_qabstractbarseries.cpp"
1025 #include "moc_qabstractbarseries.cpp"
1026 #include "moc_qabstractbarseries_p.cpp"
1026 #include "moc_qabstractbarseries_p.cpp"
1027
1027
1028 QTCOMMERCIALCHART_END_NAMESPACE
1028 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,690 +1,690
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2014 Digia Plc
3 ** Copyright (C) 2014 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Enterprise Charts Add-on.
7 ** This file is part of the Qt Enterprise Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Enterprise licenses may use this file in
10 ** Licensees holding valid Qt Enterprise licenses may use this file in
11 ** accordance with the Qt Enterprise License Agreement provided with the
11 ** accordance with the Qt Enterprise License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "qboxplotseries.h"
21 #include "qboxplotseries.h"
22 #include "qboxplotseries_p.h"
22 #include "qboxplotseries_p.h"
23 #include "qboxplotlegendmarker.h"
23 #include "qboxplotlegendmarker.h"
24 #include "qbarcategoryaxis.h"
24 #include "qbarcategoryaxis.h"
25 #include "boxplotchartitem_p.h"
25 #include "boxplotchartitem_p.h"
26 #include "chartdataset_p.h"
26 #include "chartdataset_p.h"
27 #include "charttheme_p.h"
27 #include "charttheme_p.h"
28 #include "qvalueaxis.h"
28 #include "qvalueaxis.h"
29 #include "charttheme_p.h"
29 #include "charttheme_p.h"
30 #include "boxplotanimation_p.h"
30 #include "boxplotanimation_p.h"
31 #include "qchart_p.h"
31 #include "qchart_p.h"
32 #include "qboxset.h"
32 #include "qboxset.h"
33 #include "qboxset_p.h"
33 #include "qboxset_p.h"
34
34
35 QTCOMMERCIALCHART_BEGIN_NAMESPACE
35 QTCOMMERCIALCHART_BEGIN_NAMESPACE
36
36
37 /*!
37 /*!
38 \class QBoxPlotSeries
38 \class QBoxPlotSeries
39 \inmodule Qt Charts
39 \inmodule Qt Charts
40 \brief Series for creating box-and-whiskers chart
40 \brief Series for creating box-and-whiskers chart
41 \mainclass
41 \mainclass
42
42
43 QBoxPlotSeries represents a series of data shown as box-and-whisker bars. The purpose of this class is to act as
43 QBoxPlotSeries represents a series of data shown as box-and-whisker bars. The purpose of this class is to act as
44 a container for single box-and-whisker items. Each item is drawn to own slot. If chart includes multiple instances of
44 a container for single box-and-whisker items. Each item is drawn to own slot. If chart includes multiple instances of
45 QBoxPlotSeries then box-and-whiskers items with the same index are drawn to same slot.
45 QBoxPlotSeries then box-and-whiskers items with the same index are drawn to same slot.
46
46
47 See the \l {Box and Whiskers Example} {box-and-whiskers chart example} to learn how to create a box-and-whiskers chart.
47 See the \l {Box and Whiskers Example} {box-and-whiskers chart example} to learn how to create a box-and-whiskers chart.
48 \image examples_boxplotchart.png
48 \image examples_boxplotchart.png
49
49
50 \sa QBoxSet
50 \sa QBoxSet
51 */
51 */
52 /*!
52 /*!
53 \fn QBoxPlotSeries::boxsetsAdded(QList<QBoxSet *> sets)
53 \fn QBoxPlotSeries::boxsetsAdded(QList<QBoxSet *> sets)
54 \brief Signal is emitted when a new \a sets of box-and-whiskers data is added to the series.
54 \brief Signal is emitted when a new \a sets of box-and-whiskers data is added to the series.
55 */
55 */
56 /*!
56 /*!
57 \fn QBoxPlotSeries::boxsetsRemoved(QList<QBoxSet *> sets)
57 \fn QBoxPlotSeries::boxsetsRemoved(QList<QBoxSet *> sets)
58 \brief Signal is emitted when \a sets of box-and-whiskers data is removed from the series.
58 \brief Signal is emitted when \a sets of box-and-whiskers data is removed from the series.
59 */
59 */
60 /*!
60 /*!
61 \fn QBoxPlotSeries::clicked(QBoxSet *boxset)
61 \fn QBoxPlotSeries::clicked(QBoxSet *boxset)
62 \brief Signal is emitted when the user clicks the \a boxset on the chart.
62 \brief Signal is emitted when the user clicks the \a boxset on the chart.
63 */
63 */
64 /*!
64 /*!
65 \fn QBoxPlotSeries::hovered(bool status, QBoxSet *boxset)
65 \fn QBoxPlotSeries::hovered(bool status, QBoxSet *boxset)
66 \brief Signal is emitted when there is change in hover \a status over \a boxset.
66 \brief Signal is emitted when there is change in hover \a status over \a boxset.
67 */
67 */
68 /*!
68 /*!
69 \fn QBoxPlotSeries::countChanged()
69 \fn QBoxPlotSeries::countChanged()
70 \brief Signal is emitted when there is change in count of box-and-whiskers items in the series.
70 \brief Signal is emitted when there is change in count of box-and-whiskers items in the series.
71 */
71 */
72 /*!
72 /*!
73 \property QBoxPlotSeries::boxOutlineVisible
73 \property QBoxPlotSeries::boxOutlineVisible
74 \brief This property configures the visibility of the middle box outline.
74 \brief This property configures the visibility of the middle box outline.
75 */
75 */
76 /*!
76 /*!
77 \property QBoxPlotSeries::boxWidth
77 \property QBoxPlotSeries::boxWidth
78 \brief This property configures the width of the box-and-whiskers item. The value signifies the relative
78 \brief This property configures the width of the box-and-whiskers item. The value signifies the relative
79 width of the box-and-whiskers item inside its own slot. The value can between 0.0 and 1.0. Negative values
79 width of the box-and-whiskers item inside its own slot. The value can between 0.0 and 1.0. Negative values
80 are clamped to 0.0 and values over 1.0 are clamped to 1.0.
80 are clamped to 0.0 and values over 1.0 are clamped to 1.0.
81 */
81 */
82 /*!
82 /*!
83 \property QBoxPlotSeries::pen
83 \property QBoxPlotSeries::pen
84 \brief This property configures the pen of the box-and-whiskers items.
84 \brief This property configures the pen of the box-and-whiskers items.
85 */
85 */
86 /*!
86 /*!
87 \property QBoxPlotSeries::brush
87 \property QBoxPlotSeries::brush
88 \brief This property configures the brush of the box-and-whiskers items.
88 \brief This property configures the brush of the box-and-whiskers items.
89 */
89 */
90 /*!
90 /*!
91 \property QBoxPlotSeries::count
91 \property QBoxPlotSeries::count
92 \brief The count of sets in series.
92 \brief The count of sets in series.
93 */
93 */
94
94
95 /*!
95 /*!
96 \qmlproperty QString BoxPlotSeries::brushFilename
96 \qmlproperty QString BoxPlotSeries::brushFilename
97 The name of the file used as a brush for the series.
97 The name of the file used as a brush for the series.
98 */
98 */
99
99
100 /*!
100 /*!
101 \fn void QBoxPlotSeries::boxOutlineVisibilityChanged()
101 \fn void QBoxPlotSeries::boxOutlineVisibilityChanged()
102 Signal is emitted when the middle box outline visibility is changed.
102 Signal is emitted when the middle box outline visibility is changed.
103 */
103 */
104 /*!
104 /*!
105 \fn void QBoxPlotSeries::boxWidthChanged()
105 \fn void QBoxPlotSeries::boxWidthChanged()
106 Signal is emitted when the width of the box-and-whiskers item is changed.
106 Signal is emitted when the width of the box-and-whiskers item is changed.
107 */
107 */
108 /*!
108 /*!
109 \fn void QBoxPlotSeries::penChanged()
109 \fn void QBoxPlotSeries::penChanged()
110 This signal is emitted when the pen of the box-and-whiskers has changed.
110 This signal is emitted when the pen of the box-and-whiskers has changed.
111 \sa brush
111 \sa brush
112 */
112 */
113 /*!
113 /*!
114 \fn void QBoxPlotSeries::brushChanged()
114 \fn void QBoxPlotSeries::brushChanged()
115 This signal is emitted when the brush of the box-and-whiskers has changed.
115 This signal is emitted when the brush of the box-and-whiskers has changed.
116 \sa brush
116 \sa brush
117 */
117 */
118 /*!
118 /*!
119 \fn virtual SeriesType QBoxPlotSeries::type() const
119 \fn virtual SeriesType QBoxPlotSeries::type() const
120 \brief Returns type of series.
120 \brief Returns type of series.
121 \sa QAbstractSeries, SeriesType
121 \sa QAbstractSeries, SeriesType
122 */
122 */
123
123
124 /*!
124 /*!
125 Constructs empty QBoxPlotSeries.
125 Constructs empty QBoxPlotSeries.
126 QBoxPlotSeries is QObject which is a child of a \a parent.
126 QBoxPlotSeries is QObject which is a child of a \a parent.
127 */
127 */
128 QBoxPlotSeries::QBoxPlotSeries(QObject *parent)
128 QBoxPlotSeries::QBoxPlotSeries(QObject *parent)
129 : QAbstractSeries(*new QBoxPlotSeriesPrivate(this), parent)
129 : QAbstractSeries(*new QBoxPlotSeriesPrivate(this), parent)
130 {
130 {
131 }
131 }
132
132
133 /*!
133 /*!
134 Destructor. Removes series from chart.
134 Destructor. Removes series from chart.
135 */
135 */
136 QBoxPlotSeries::~QBoxPlotSeries()
136 QBoxPlotSeries::~QBoxPlotSeries()
137 {
137 {
138 Q_D(QBoxPlotSeries);
138 Q_D(QBoxPlotSeries);
139 if (d->m_chart)
139 if (d->m_chart)
140 d->m_chart->removeSeries(this);
140 d->m_chart->removeSeries(this);
141 }
141 }
142
142
143 /*!
143 /*!
144 Adds a single box and whiskers set to series. Takes ownership of the \a set. If the set is null or is already in series, it won't be appended.
144 Adds a single box and whiskers set to series. Takes ownership of the \a set. If the set is null or is already in series, it won't be appended.
145 Returns true, if appending succeeded.
145 Returns true, if appending succeeded.
146 */
146 */
147 bool QBoxPlotSeries::append(QBoxSet *set)
147 bool QBoxPlotSeries::append(QBoxSet *set)
148 {
148 {
149 Q_D(QBoxPlotSeries);
149 Q_D(QBoxPlotSeries);
150
150
151 bool success = d->append(set);
151 bool success = d->append(set);
152 if (success) {
152 if (success) {
153 QList<QBoxSet *> sets;
153 QList<QBoxSet *> sets;
154 sets.append(set);
154 sets.append(set);
155 set->setParent(this);
155 set->setParent(this);
156 emit boxsetsAdded(sets);
156 emit boxsetsAdded(sets);
157 emit countChanged();
157 emit countChanged();
158 }
158 }
159 return success;
159 return success;
160 }
160 }
161
161
162 /*!
162 /*!
163 Removes boxset from the series. Deletes the \a set and returns true if successful.
163 Removes boxset from the series. Deletes the \a set and returns true if successful.
164 */
164 */
165 bool QBoxPlotSeries::remove(QBoxSet *set)
165 bool QBoxPlotSeries::remove(QBoxSet *set)
166 {
166 {
167 Q_D(QBoxPlotSeries);
167 Q_D(QBoxPlotSeries);
168 bool success = d->remove(set);
168 bool success = d->remove(set);
169 if (success) {
169 if (success) {
170 QList<QBoxSet *> sets;
170 QList<QBoxSet *> sets;
171 sets.append(set);
171 sets.append(set);
172 set->setParent(0);
172 set->setParent(0);
173 emit boxsetsRemoved(sets);
173 emit boxsetsRemoved(sets);
174 emit countChanged();
174 emit countChanged();
175 delete set;
175 delete set;
176 set = 0;
176 set = 0;
177 }
177 }
178 return success;
178 return success;
179 }
179 }
180
180
181 /*!
181 /*!
182 Takes a single \a set from the series. Does not delete the boxset object.
182 Takes a single \a set from the series. Does not delete the boxset object.
183
183
184 NOTE: The series remains as the boxset's parent object. You must set the
184 NOTE: The series remains as the boxset's parent object. You must set the
185 parent object to take full ownership.
185 parent object to take full ownership.
186
186
187 Returns true if take was successful.
187 Returns true if take was successful.
188 */
188 */
189 bool QBoxPlotSeries::take(QBoxSet *set)
189 bool QBoxPlotSeries::take(QBoxSet *set)
190 {
190 {
191 Q_D(QBoxPlotSeries);
191 Q_D(QBoxPlotSeries);
192
192
193 bool success = d->remove(set);
193 bool success = d->remove(set);
194 if (success) {
194 if (success) {
195 QList<QBoxSet *> sets;
195 QList<QBoxSet *> sets;
196 sets.append(set);
196 sets.append(set);
197 emit boxsetsRemoved(sets);
197 emit boxsetsRemoved(sets);
198 emit countChanged();
198 emit countChanged();
199 }
199 }
200 return success;
200 return success;
201 }
201 }
202
202
203 /*!
203 /*!
204 Adds a list of boxsets to series. Takes ownership of the \a sets.
204 Adds a list of boxsets to series. Takes ownership of the \a sets.
205 Returns true, if all sets were appended successfully. If any of the sets is null or is already appended to series,
205 Returns true, if all sets were appended successfully. If any of the sets is null or is already appended to series,
206 nothing is appended and function returns false. If any of the sets is in list more than once, nothing is appended
206 nothing is appended and function returns false. If any of the sets is in list more than once, nothing is appended
207 and function returns false.
207 and function returns false.
208 */
208 */
209 bool QBoxPlotSeries::append(QList<QBoxSet *> sets)
209 bool QBoxPlotSeries::append(QList<QBoxSet *> sets)
210 {
210 {
211 Q_D(QBoxPlotSeries);
211 Q_D(QBoxPlotSeries);
212 bool success = d->append(sets);
212 bool success = d->append(sets);
213 if (success) {
213 if (success) {
214 emit boxsetsAdded(sets);
214 emit boxsetsAdded(sets);
215 emit countChanged();
215 emit countChanged();
216 }
216 }
217 return success;
217 return success;
218 }
218 }
219
219
220 /*!
220 /*!
221 Insert a box-and-whiskers set to the series at \a index postion. Takes ownership of the \a set. If the set is null or
221 Insert a box-and-whiskers set to the series at \a index postion. Takes ownership of the \a set. If the set is null or
222 is already in series, it won't be appended. Returns true, if inserting succeeded.
222 is already in series, it won't be appended. Returns true, if inserting succeeded.
223
223
224 */
224 */
225 bool QBoxPlotSeries::insert(int index, QBoxSet *set)
225 bool QBoxPlotSeries::insert(int index, QBoxSet *set)
226 {
226 {
227 Q_D(QBoxPlotSeries);
227 Q_D(QBoxPlotSeries);
228 bool success = d->insert(index, set);
228 bool success = d->insert(index, set);
229 if (success) {
229 if (success) {
230 QList<QBoxSet *> sets;
230 QList<QBoxSet *> sets;
231 sets.append(set);
231 sets.append(set);
232 emit boxsetsAdded(sets);
232 emit boxsetsAdded(sets);
233 emit countChanged();
233 emit countChanged();
234 }
234 }
235 return success;
235 return success;
236 }
236 }
237
237
238 /*!
238 /*!
239 Removes all boxsets from the series. Deletes removed sets.
239 Removes all boxsets from the series. Deletes removed sets.
240 */
240 */
241 void QBoxPlotSeries::clear()
241 void QBoxPlotSeries::clear()
242 {
242 {
243 Q_D(QBoxPlotSeries);
243 Q_D(QBoxPlotSeries);
244 QList<QBoxSet *> sets = boxSets();
244 QList<QBoxSet *> sets = boxSets();
245 bool success = d->remove(sets);
245 bool success = d->remove(sets);
246 if (success) {
246 if (success) {
247 emit boxsetsRemoved(sets);
247 emit boxsetsRemoved(sets);
248 emit countChanged();
248 emit countChanged();
249 foreach (QBoxSet *set, sets)
249 foreach (QBoxSet *set, sets)
250 delete set;
250 delete set;
251 }
251 }
252 }
252 }
253
253
254 /*!
254 /*!
255 Returns number of sets in series.
255 Returns number of sets in series.
256 */
256 */
257 int QBoxPlotSeries::count() const
257 int QBoxPlotSeries::count() const
258 {
258 {
259 Q_D(const QBoxPlotSeries);
259 Q_D(const QBoxPlotSeries);
260 return d->m_boxSets.count();
260 return d->m_boxSets.count();
261 }
261 }
262
262
263 /*!
263 /*!
264 Returns a list of sets in series. Keeps ownership of sets.
264 Returns a list of sets in series. Keeps ownership of sets.
265 */
265 */
266 QList<QBoxSet *> QBoxPlotSeries::boxSets() const
266 QList<QBoxSet *> QBoxPlotSeries::boxSets() const
267 {
267 {
268 Q_D(const QBoxPlotSeries);
268 Q_D(const QBoxPlotSeries);
269 return d->m_boxSets;
269 return d->m_boxSets;
270 }
270 }
271
271
272 /*
272 /*
273 Returns QAbstractSeries::SeriesTypeBoxPlot.
273 Returns QAbstractSeries::SeriesTypeBoxPlot.
274 */
274 */
275 QAbstractSeries::SeriesType QBoxPlotSeries::type() const
275 QAbstractSeries::SeriesType QBoxPlotSeries::type() const
276 {
276 {
277 return QAbstractSeries::SeriesTypeBoxPlot;
277 return QAbstractSeries::SeriesTypeBoxPlot;
278 }
278 }
279
279
280 void QBoxPlotSeries::setBoxOutlineVisible(bool visible)
280 void QBoxPlotSeries::setBoxOutlineVisible(bool visible)
281 {
281 {
282 Q_D(QBoxPlotSeries);
282 Q_D(QBoxPlotSeries);
283
283
284 if (d->m_boxOutlineVisible != visible) {
284 if (d->m_boxOutlineVisible != visible) {
285 d->m_boxOutlineVisible = visible;
285 d->m_boxOutlineVisible = visible;
286 emit d->updated();
286 emit d->updated();
287 emit boxOutlineVisibilityChanged();
287 emit boxOutlineVisibilityChanged();
288 }
288 }
289 }
289 }
290
290
291 bool QBoxPlotSeries::boxOutlineVisible()
291 bool QBoxPlotSeries::boxOutlineVisible()
292 {
292 {
293 Q_D(QBoxPlotSeries);
293 Q_D(QBoxPlotSeries);
294
294
295 return d->m_boxOutlineVisible;
295 return d->m_boxOutlineVisible;
296 }
296 }
297
297
298 void QBoxPlotSeries::setBoxWidth(qreal width)
298 void QBoxPlotSeries::setBoxWidth(qreal width)
299 {
299 {
300 Q_D(QBoxPlotSeries);
300 Q_D(QBoxPlotSeries);
301
301
302 if (width != d->m_boxWidth) {
302 if (width != d->m_boxWidth) {
303 if (width < 0.0)
303 if (width < 0.0)
304 width = 0.0;
304 width = 0.0;
305 if (width > 1.0)
305 if (width > 1.0)
306 width = 1.0;
306 width = 1.0;
307 d->m_boxWidth = width;
307 d->m_boxWidth = width;
308 emit d->updatedLayout();
308 emit d->updatedLayout();
309 emit boxWidthChanged();
309 emit boxWidthChanged();
310 }
310 }
311 }
311 }
312
312
313 qreal QBoxPlotSeries::boxWidth()
313 qreal QBoxPlotSeries::boxWidth()
314 {
314 {
315 Q_D(QBoxPlotSeries);
315 Q_D(QBoxPlotSeries);
316
316
317 return d->m_boxWidth;
317 return d->m_boxWidth;
318 }
318 }
319
319
320 void QBoxPlotSeries::setBrush(const QBrush &brush)
320 void QBoxPlotSeries::setBrush(const QBrush &brush)
321 {
321 {
322 Q_D(QBoxPlotSeries);
322 Q_D(QBoxPlotSeries);
323
323
324 if (d->m_brush != brush) {
324 if (d->m_brush != brush) {
325 d->m_brush = brush;
325 d->m_brush = brush;
326 emit d->updated();
326 emit d->updated();
327 emit brushChanged();
327 emit brushChanged();
328 }
328 }
329 }
329 }
330
330
331 QBrush QBoxPlotSeries::brush() const
331 QBrush QBoxPlotSeries::brush() const
332 {
332 {
333 Q_D(const QBoxPlotSeries);
333 Q_D(const QBoxPlotSeries);
334
334
335 return d->m_brush;
335 return d->m_brush;
336 }
336 }
337
337
338 void QBoxPlotSeries::setPen(const QPen &pen)
338 void QBoxPlotSeries::setPen(const QPen &pen)
339 {
339 {
340 Q_D(QBoxPlotSeries);
340 Q_D(QBoxPlotSeries);
341
341
342 if (d->m_pen != pen) {
342 if (d->m_pen != pen) {
343 d->m_pen = pen;
343 d->m_pen = pen;
344 emit d->updated();
344 emit d->updated();
345 emit penChanged();
345 emit penChanged();
346 }
346 }
347 }
347 }
348
348
349 QPen QBoxPlotSeries::pen() const
349 QPen QBoxPlotSeries::pen() const
350 {
350 {
351 Q_D(const QBoxPlotSeries);
351 Q_D(const QBoxPlotSeries);
352
352
353 return d->m_pen;
353 return d->m_pen;
354 }
354 }
355
355
356 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
356 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
357
357
358 QBoxPlotSeriesPrivate::QBoxPlotSeriesPrivate(QBoxPlotSeries *q)
358 QBoxPlotSeriesPrivate::QBoxPlotSeriesPrivate(QBoxPlotSeries *q)
359 : QAbstractSeriesPrivate(q),
359 : QAbstractSeriesPrivate(q),
360 m_pen(QChartPrivate::defaultPen()),
360 m_pen(QChartPrivate::defaultPen()),
361 m_brush(QChartPrivate::defaultBrush()),
361 m_brush(QChartPrivate::defaultBrush()),
362 m_boxOutlineVisible(true),
362 m_boxOutlineVisible(true),
363 m_boxWidth(0.5)
363 m_boxWidth(0.5)
364 {
364 {
365 }
365 }
366
366
367 QBoxPlotSeriesPrivate::~QBoxPlotSeriesPrivate()
367 QBoxPlotSeriesPrivate::~QBoxPlotSeriesPrivate()
368 {
368 {
369 disconnect(this, 0, 0, 0);
369 disconnect(this, 0, 0, 0);
370 }
370 }
371
371
372 void QBoxPlotSeriesPrivate::initializeDomain()
372 void QBoxPlotSeriesPrivate::initializeDomain()
373 {
373 {
374 qreal minX(domain()->minX());
374 qreal minX(domain()->minX());
375 qreal minY(domain()->minY());
375 qreal minY(domain()->minY());
376 qreal maxX(domain()->maxX());
376 qreal maxX(domain()->maxX());
377 qreal maxY(domain()->maxY());
377 qreal maxY(domain()->maxY());
378
378
379 qreal x = m_boxSets.count();
379 qreal x = m_boxSets.count();
380 minX = qMin(minX, qreal(-0.5));
380 minX = qMin(minX, qreal(-0.5));
381 minY = qMin(minY, min());
381 minY = qMin(minY, min());
382 maxX = qMax(maxX, x - qreal(0.5));
382 maxX = qMax(maxX, x - qreal(0.5));
383 maxY = qMax(maxY, max());
383 maxY = qMax(maxY, max());
384
384
385 domain()->setRange(minX, maxX, minY, maxY);
385 domain()->setRange(minX, maxX, minY, maxY);
386 }
386 }
387
387
388 void QBoxPlotSeriesPrivate::initializeAxes()
388 void QBoxPlotSeriesPrivate::initializeAxes()
389 {
389 {
390 foreach (QAbstractAxis* axis, m_axes) {
390 foreach (QAbstractAxis* axis, m_axes) {
391 if (axis->type() == QAbstractAxis::AxisTypeBarCategory) {
391 if (axis->type() == QAbstractAxis::AxisTypeBarCategory) {
392 if (axis->orientation() == Qt::Horizontal)
392 if (axis->orientation() == Qt::Horizontal)
393 populateCategories(qobject_cast<QBarCategoryAxis *>(axis));
393 populateCategories(qobject_cast<QBarCategoryAxis *>(axis));
394 }
394 }
395 }
395 }
396 }
396 }
397
397
398 QAbstractAxis::AxisType QBoxPlotSeriesPrivate::defaultAxisType(Qt::Orientation orientation) const
398 QAbstractAxis::AxisType QBoxPlotSeriesPrivate::defaultAxisType(Qt::Orientation orientation) const
399 {
399 {
400 if (orientation == Qt::Horizontal)
400 if (orientation == Qt::Horizontal)
401 return QAbstractAxis::AxisTypeBarCategory;
401 return QAbstractAxis::AxisTypeBarCategory;
402
402
403 return QAbstractAxis::AxisTypeValue;
403 return QAbstractAxis::AxisTypeValue;
404 }
404 }
405
405
406 QAbstractAxis* QBoxPlotSeriesPrivate::createDefaultAxis(Qt::Orientation orientation) const
406 QAbstractAxis* QBoxPlotSeriesPrivate::createDefaultAxis(Qt::Orientation orientation) const
407 {
407 {
408 if (defaultAxisType(orientation) == QAbstractAxis::AxisTypeBarCategory)
408 if (defaultAxisType(orientation) == QAbstractAxis::AxisTypeBarCategory)
409 return new QBarCategoryAxis;
409 return new QBarCategoryAxis;
410 else
410 else
411 return new QValueAxis;
411 return new QValueAxis;
412 }
412 }
413
413
414 void QBoxPlotSeriesPrivate::populateCategories(QBarCategoryAxis *axis)
414 void QBoxPlotSeriesPrivate::populateCategories(QBarCategoryAxis *axis)
415 {
415 {
416 QStringList categories;
416 QStringList categories;
417 if (axis->categories().isEmpty()) {
417 if (axis->categories().isEmpty()) {
418 for (int i(1); i < m_boxSets.count() + 1; i++) {
418 for (int i(1); i < m_boxSets.count() + 1; i++) {
419 QBoxSet *set = m_boxSets.at(i - 1);
419 QBoxSet *set = m_boxSets.at(i - 1);
420 if (set->label().isEmpty())
420 if (set->label().isEmpty())
421 categories << QString::number(i);
421 categories << presenter()->numberToString(i);
422 else
422 else
423 categories << set->label();
423 categories << set->label();
424 }
424 }
425 axis->append(categories);
425 axis->append(categories);
426 }
426 }
427 }
427 }
428
428
429 void QBoxPlotSeriesPrivate::initializeGraphics(QGraphicsItem *parent)
429 void QBoxPlotSeriesPrivate::initializeGraphics(QGraphicsItem *parent)
430 {
430 {
431 Q_Q(QBoxPlotSeries);
431 Q_Q(QBoxPlotSeries);
432
432
433 BoxPlotChartItem *boxPlot = new BoxPlotChartItem(q, parent);
433 BoxPlotChartItem *boxPlot = new BoxPlotChartItem(q, parent);
434 m_item.reset(boxPlot);
434 m_item.reset(boxPlot);
435 QAbstractSeriesPrivate::initializeGraphics(parent);
435 QAbstractSeriesPrivate::initializeGraphics(parent);
436
436
437 if (m_chart) {
437 if (m_chart) {
438 connect(m_chart->d_ptr->m_dataset, SIGNAL(seriesAdded(QAbstractSeries*)), this, SLOT(handleSeriesChange(QAbstractSeries*)) );
438 connect(m_chart->d_ptr->m_dataset, SIGNAL(seriesAdded(QAbstractSeries*)), this, SLOT(handleSeriesChange(QAbstractSeries*)) );
439 connect(m_chart->d_ptr->m_dataset, SIGNAL(seriesRemoved(QAbstractSeries*)), this, SLOT(handleSeriesRemove(QAbstractSeries*)) );
439 connect(m_chart->d_ptr->m_dataset, SIGNAL(seriesRemoved(QAbstractSeries*)), this, SLOT(handleSeriesRemove(QAbstractSeries*)) );
440
440
441 QList<QAbstractSeries *> serieses = m_chart->series();
441 QList<QAbstractSeries *> serieses = m_chart->series();
442
442
443 // Tries to find this series from the Chart's list of series and deduce the index
443 // Tries to find this series from the Chart's list of series and deduce the index
444 int index = 0;
444 int index = 0;
445 foreach (QAbstractSeries *s, serieses) {
445 foreach (QAbstractSeries *s, serieses) {
446 if (s->type() == QAbstractSeries::SeriesTypeBoxPlot) {
446 if (s->type() == QAbstractSeries::SeriesTypeBoxPlot) {
447 if (q == static_cast<QBoxPlotSeries *>(s)) {
447 if (q == static_cast<QBoxPlotSeries *>(s)) {
448 boxPlot->m_seriesIndex = index;
448 boxPlot->m_seriesIndex = index;
449 m_index = index;
449 m_index = index;
450 }
450 }
451 index++;
451 index++;
452 }
452 }
453 }
453 }
454 boxPlot->m_seriesCount = index;
454 boxPlot->m_seriesCount = index;
455 }
455 }
456
456
457 // Make BoxPlotChartItem to instantiate box & whisker items
457 // Make BoxPlotChartItem to instantiate box & whisker items
458 boxPlot->handleDataStructureChanged();
458 boxPlot->handleDataStructureChanged();
459 }
459 }
460
460
461 void QBoxPlotSeriesPrivate::initializeTheme(int index, ChartTheme* theme, bool forced)
461 void QBoxPlotSeriesPrivate::initializeTheme(int index, ChartTheme* theme, bool forced)
462 {
462 {
463 Q_Q(QBoxPlotSeries);
463 Q_Q(QBoxPlotSeries);
464
464
465 const QList<QGradient> gradients = theme->seriesGradients();
465 const QList<QGradient> gradients = theme->seriesGradients();
466
466
467 if (forced || QChartPrivate::defaultBrush() == m_brush) {
467 if (forced || QChartPrivate::defaultBrush() == m_brush) {
468 QColor brushColor = ChartThemeManager::colorAt(gradients.at(index % gradients.size()), 0.5);
468 QColor brushColor = ChartThemeManager::colorAt(gradients.at(index % gradients.size()), 0.5);
469 q->setBrush(brushColor);
469 q->setBrush(brushColor);
470 }
470 }
471
471
472 if (forced || QChartPrivate::defaultPen() == m_pen) {
472 if (forced || QChartPrivate::defaultPen() == m_pen) {
473 QPen pen = theme->outlinePen();
473 QPen pen = theme->outlinePen();
474 pen.setCosmetic(true);
474 pen.setCosmetic(true);
475 q->setPen(pen);
475 q->setPen(pen);
476 }
476 }
477 }
477 }
478
478
479 void QBoxPlotSeriesPrivate::initializeAnimations(QChart::AnimationOptions options)
479 void QBoxPlotSeriesPrivate::initializeAnimations(QChart::AnimationOptions options)
480 {
480 {
481 BoxPlotChartItem *item = static_cast<BoxPlotChartItem *>(m_item.data());
481 BoxPlotChartItem *item = static_cast<BoxPlotChartItem *>(m_item.data());
482 Q_ASSERT(item);
482 Q_ASSERT(item);
483 if (item->animation())
483 if (item->animation())
484 item->animation()->stopAndDestroyLater();
484 item->animation()->stopAndDestroyLater();
485
485
486 if (options.testFlag(QChart::SeriesAnimations))
486 if (options.testFlag(QChart::SeriesAnimations))
487 m_animation = new BoxPlotAnimation(item);
487 m_animation = new BoxPlotAnimation(item);
488 else
488 else
489 m_animation = 0;
489 m_animation = 0;
490 item->setAnimation(m_animation);
490 item->setAnimation(m_animation);
491
491
492 QAbstractSeriesPrivate::initializeAnimations(options);
492 QAbstractSeriesPrivate::initializeAnimations(options);
493 }
493 }
494
494
495 QList<QLegendMarker*> QBoxPlotSeriesPrivate::createLegendMarkers(QLegend *legend)
495 QList<QLegendMarker*> QBoxPlotSeriesPrivate::createLegendMarkers(QLegend *legend)
496 {
496 {
497 Q_Q(QBoxPlotSeries);
497 Q_Q(QBoxPlotSeries);
498 QList<QLegendMarker *> list;
498 QList<QLegendMarker *> list;
499 return list << new QBoxPlotLegendMarker(q, legend);
499 return list << new QBoxPlotLegendMarker(q, legend);
500 }
500 }
501
501
502 void QBoxPlotSeriesPrivate::handleSeriesRemove(QAbstractSeries *series)
502 void QBoxPlotSeriesPrivate::handleSeriesRemove(QAbstractSeries *series)
503 {
503 {
504 Q_Q(QBoxPlotSeries);
504 Q_Q(QBoxPlotSeries);
505
505
506 QBoxPlotSeries *removedSeries = static_cast<QBoxPlotSeries *>(series);
506 QBoxPlotSeries *removedSeries = static_cast<QBoxPlotSeries *>(series);
507
507
508 if (q == removedSeries && m_animation) {
508 if (q == removedSeries && m_animation) {
509 m_animation->stopAll();
509 m_animation->stopAll();
510 QObject::disconnect(m_chart->d_ptr->m_dataset, 0, removedSeries->d_func(), 0);
510 QObject::disconnect(m_chart->d_ptr->m_dataset, 0, removedSeries->d_func(), 0);
511 }
511 }
512
512
513 // Test if series removed is me, then don't do anything
513 // Test if series removed is me, then don't do anything
514 if (q != removedSeries) {
514 if (q != removedSeries) {
515 BoxPlotChartItem *item = static_cast<BoxPlotChartItem *>(m_item.data());
515 BoxPlotChartItem *item = static_cast<BoxPlotChartItem *>(m_item.data());
516 if (item) {
516 if (item) {
517 item->m_seriesCount = item->m_seriesCount - 1;
517 item->m_seriesCount = item->m_seriesCount - 1;
518 if (removedSeries->d_func()->m_index < m_index) {
518 if (removedSeries->d_func()->m_index < m_index) {
519 m_index--;
519 m_index--;
520 item->m_seriesIndex = m_index;
520 item->m_seriesIndex = m_index;
521 }
521 }
522
522
523 item->handleDataStructureChanged();
523 item->handleDataStructureChanged();
524 }
524 }
525 }
525 }
526 }
526 }
527
527
528 void QBoxPlotSeriesPrivate::handleSeriesChange(QAbstractSeries *series)
528 void QBoxPlotSeriesPrivate::handleSeriesChange(QAbstractSeries *series)
529 {
529 {
530 Q_UNUSED(series);
530 Q_UNUSED(series);
531
531
532 Q_Q(QBoxPlotSeries);
532 Q_Q(QBoxPlotSeries);
533
533
534 BoxPlotChartItem *boxPlot = static_cast<BoxPlotChartItem *>(m_item.data());
534 BoxPlotChartItem *boxPlot = static_cast<BoxPlotChartItem *>(m_item.data());
535
535
536 if (m_chart) {
536 if (m_chart) {
537 QList<QAbstractSeries *> serieses = m_chart->series();
537 QList<QAbstractSeries *> serieses = m_chart->series();
538
538
539 // Tries to find this series from the Chart's list of series and deduce the index
539 // Tries to find this series from the Chart's list of series and deduce the index
540 int index = 0;
540 int index = 0;
541 foreach (QAbstractSeries *s, serieses) {
541 foreach (QAbstractSeries *s, serieses) {
542 if (s->type() == QAbstractSeries::SeriesTypeBoxPlot) {
542 if (s->type() == QAbstractSeries::SeriesTypeBoxPlot) {
543 if (q == static_cast<QBoxPlotSeries *>(s)) {
543 if (q == static_cast<QBoxPlotSeries *>(s)) {
544 boxPlot->m_seriesIndex = index;
544 boxPlot->m_seriesIndex = index;
545 m_index = index;
545 m_index = index;
546 }
546 }
547 index++;
547 index++;
548 }
548 }
549 }
549 }
550 boxPlot->m_seriesCount = index;
550 boxPlot->m_seriesCount = index;
551 }
551 }
552
552
553 boxPlot->handleDataStructureChanged();
553 boxPlot->handleDataStructureChanged();
554 }
554 }
555
555
556 bool QBoxPlotSeriesPrivate::append(QBoxSet *set)
556 bool QBoxPlotSeriesPrivate::append(QBoxSet *set)
557 {
557 {
558 if (m_boxSets.contains(set) || (set == 0) || set->d_ptr->m_series)
558 if (m_boxSets.contains(set) || (set == 0) || set->d_ptr->m_series)
559 return false; // Fail if set is already in list or set is null.
559 return false; // Fail if set is already in list or set is null.
560
560
561 m_boxSets.append(set);
561 m_boxSets.append(set);
562 QObject::connect(set->d_ptr.data(), SIGNAL(updatedLayout()), this, SIGNAL(updatedLayout()));
562 QObject::connect(set->d_ptr.data(), SIGNAL(updatedLayout()), this, SIGNAL(updatedLayout()));
563 QObject::connect(set->d_ptr.data(), SIGNAL(updatedBox()), this, SIGNAL(updatedBoxes()));
563 QObject::connect(set->d_ptr.data(), SIGNAL(updatedBox()), this, SIGNAL(updatedBoxes()));
564 QObject::connect(set->d_ptr.data(), SIGNAL(restructuredBox()), this, SIGNAL(restructuredBoxes()));
564 QObject::connect(set->d_ptr.data(), SIGNAL(restructuredBox()), this, SIGNAL(restructuredBoxes()));
565 set->d_ptr->m_series = this;
565 set->d_ptr->m_series = this;
566
566
567 emit restructuredBoxes(); // this notifies boxplotchartitem
567 emit restructuredBoxes(); // this notifies boxplotchartitem
568 return true;
568 return true;
569 }
569 }
570
570
571 bool QBoxPlotSeriesPrivate::remove(QBoxSet *set)
571 bool QBoxPlotSeriesPrivate::remove(QBoxSet *set)
572 {
572 {
573 if (!m_boxSets.contains(set))
573 if (!m_boxSets.contains(set))
574 return false; // Fail if set is not in list
574 return false; // Fail if set is not in list
575
575
576 set->d_ptr->m_series = 0;
576 set->d_ptr->m_series = 0;
577 m_boxSets.removeOne(set);
577 m_boxSets.removeOne(set);
578 QObject::disconnect(set->d_ptr.data(), SIGNAL(updatedLayout()), this, SIGNAL(updatedLayout()));
578 QObject::disconnect(set->d_ptr.data(), SIGNAL(updatedLayout()), this, SIGNAL(updatedLayout()));
579 QObject::disconnect(set->d_ptr.data(), SIGNAL(updatedBox()), this, SIGNAL(updatedBoxes()));
579 QObject::disconnect(set->d_ptr.data(), SIGNAL(updatedBox()), this, SIGNAL(updatedBoxes()));
580 QObject::disconnect(set->d_ptr.data(), SIGNAL(restructuredBox()), this, SIGNAL(restructuredBoxes()));
580 QObject::disconnect(set->d_ptr.data(), SIGNAL(restructuredBox()), this, SIGNAL(restructuredBoxes()));
581
581
582 emit restructuredBoxes(); // this notifies boxplotchartitem
582 emit restructuredBoxes(); // this notifies boxplotchartitem
583 return true;
583 return true;
584 }
584 }
585
585
586 bool QBoxPlotSeriesPrivate::append(QList<QBoxSet *> sets)
586 bool QBoxPlotSeriesPrivate::append(QList<QBoxSet *> sets)
587 {
587 {
588 foreach (QBoxSet *set, sets) {
588 foreach (QBoxSet *set, sets) {
589 if ((set == 0) || m_boxSets.contains(set) || set->d_ptr->m_series)
589 if ((set == 0) || m_boxSets.contains(set) || set->d_ptr->m_series)
590 return false; // Fail if any of the sets is null or is already appended.
590 return false; // Fail if any of the sets is null or is already appended.
591 if (sets.count(set) != 1)
591 if (sets.count(set) != 1)
592 return false; // Also fail if same set is more than once in given list.
592 return false; // Also fail if same set is more than once in given list.
593 }
593 }
594
594
595 foreach (QBoxSet *set, sets) {
595 foreach (QBoxSet *set, sets) {
596 m_boxSets.append(set);
596 m_boxSets.append(set);
597 QObject::connect(set->d_ptr.data(), SIGNAL(updatedLayout()), this, SIGNAL(updatedLayout()));
597 QObject::connect(set->d_ptr.data(), SIGNAL(updatedLayout()), this, SIGNAL(updatedLayout()));
598 QObject::connect(set->d_ptr.data(), SIGNAL(updatedBox()), this, SIGNAL(updatedBoxes()));
598 QObject::connect(set->d_ptr.data(), SIGNAL(updatedBox()), this, SIGNAL(updatedBoxes()));
599 QObject::connect(set->d_ptr.data(), SIGNAL(restructuredBox()), this, SIGNAL(restructuredBoxes()));
599 QObject::connect(set->d_ptr.data(), SIGNAL(restructuredBox()), this, SIGNAL(restructuredBoxes()));
600 set->d_ptr->m_series = this;
600 set->d_ptr->m_series = this;
601 }
601 }
602
602
603 emit restructuredBoxes(); // this notifies boxplotchartitem
603 emit restructuredBoxes(); // this notifies boxplotchartitem
604 return true;
604 return true;
605 }
605 }
606
606
607 bool QBoxPlotSeriesPrivate::remove(QList<QBoxSet *> sets)
607 bool QBoxPlotSeriesPrivate::remove(QList<QBoxSet *> sets)
608 {
608 {
609 if (sets.count() == 0)
609 if (sets.count() == 0)
610 return false;
610 return false;
611
611
612 foreach (QBoxSet *set, sets) {
612 foreach (QBoxSet *set, sets) {
613 if ((set == 0) || (!m_boxSets.contains(set)))
613 if ((set == 0) || (!m_boxSets.contains(set)))
614 return false; // Fail if any of the sets is null or is not in series
614 return false; // Fail if any of the sets is null or is not in series
615 if (sets.count(set) != 1)
615 if (sets.count(set) != 1)
616 return false; // Also fail if same set is more than once in given list.
616 return false; // Also fail if same set is more than once in given list.
617 }
617 }
618
618
619 foreach (QBoxSet *set, sets) {
619 foreach (QBoxSet *set, sets) {
620 set->d_ptr->m_series = 0;
620 set->d_ptr->m_series = 0;
621 m_boxSets.removeOne(set);
621 m_boxSets.removeOne(set);
622 QObject::disconnect(set->d_ptr.data(), SIGNAL(updatedLayout()), this, SIGNAL(updatedLayout()));
622 QObject::disconnect(set->d_ptr.data(), SIGNAL(updatedLayout()), this, SIGNAL(updatedLayout()));
623 QObject::disconnect(set->d_ptr.data(), SIGNAL(updatedBox()), this, SIGNAL(updatedBoxes()));
623 QObject::disconnect(set->d_ptr.data(), SIGNAL(updatedBox()), this, SIGNAL(updatedBoxes()));
624 QObject::disconnect(set->d_ptr.data(), SIGNAL(restructuredBox()), this, SIGNAL(restructuredBoxes()));
624 QObject::disconnect(set->d_ptr.data(), SIGNAL(restructuredBox()), this, SIGNAL(restructuredBoxes()));
625 }
625 }
626
626
627 emit restructuredBoxes(); // this notifies boxplotchartitem
627 emit restructuredBoxes(); // this notifies boxplotchartitem
628
628
629 return true;
629 return true;
630 }
630 }
631
631
632 bool QBoxPlotSeriesPrivate::insert(int index, QBoxSet *set)
632 bool QBoxPlotSeriesPrivate::insert(int index, QBoxSet *set)
633 {
633 {
634 if ((m_boxSets.contains(set)) || (set == 0) || set->d_ptr->m_series)
634 if ((m_boxSets.contains(set)) || (set == 0) || set->d_ptr->m_series)
635 return false; // Fail if set is already in list or set is null.
635 return false; // Fail if set is already in list or set is null.
636
636
637 m_boxSets.insert(index, set);
637 m_boxSets.insert(index, set);
638 set->d_ptr->m_series = this;
638 set->d_ptr->m_series = this;
639 QObject::connect(set->d_ptr.data(), SIGNAL(updatedLayout()), this, SIGNAL(updatedLayout()));
639 QObject::connect(set->d_ptr.data(), SIGNAL(updatedLayout()), this, SIGNAL(updatedLayout()));
640 QObject::connect(set->d_ptr.data(), SIGNAL(updatedBox()), this, SIGNAL(updatedBoxes()));
640 QObject::connect(set->d_ptr.data(), SIGNAL(updatedBox()), this, SIGNAL(updatedBoxes()));
641 QObject::connect(set->d_ptr.data(), SIGNAL(restructuredBox()), this, SIGNAL(restructuredBoxes()));
641 QObject::connect(set->d_ptr.data(), SIGNAL(restructuredBox()), this, SIGNAL(restructuredBoxes()));
642
642
643 emit restructuredBoxes(); // this notifies boxplotchartitem
643 emit restructuredBoxes(); // this notifies boxplotchartitem
644 return true;
644 return true;
645 }
645 }
646
646
647 QBoxSet *QBoxPlotSeriesPrivate::boxSetAt(int index)
647 QBoxSet *QBoxPlotSeriesPrivate::boxSetAt(int index)
648 {
648 {
649 return m_boxSets.at(index);
649 return m_boxSets.at(index);
650 }
650 }
651
651
652 qreal QBoxPlotSeriesPrivate::min()
652 qreal QBoxPlotSeriesPrivate::min()
653 {
653 {
654 if (m_boxSets.count() <= 0)
654 if (m_boxSets.count() <= 0)
655 return 0;
655 return 0;
656
656
657 qreal min = m_boxSets.at(0)->at(0);
657 qreal min = m_boxSets.at(0)->at(0);
658
658
659 foreach (QBoxSet *set, m_boxSets) {
659 foreach (QBoxSet *set, m_boxSets) {
660 for (int i = 0; i < 5; i++) {
660 for (int i = 0; i < 5; i++) {
661 if (set->at(i) < min)
661 if (set->at(i) < min)
662 min = set->at(i);
662 min = set->at(i);
663 }
663 }
664 }
664 }
665
665
666 return min;
666 return min;
667 }
667 }
668
668
669 qreal QBoxPlotSeriesPrivate::max()
669 qreal QBoxPlotSeriesPrivate::max()
670 {
670 {
671 if (m_boxSets.count() <= 0)
671 if (m_boxSets.count() <= 0)
672 return 0;
672 return 0;
673
673
674 qreal max = m_boxSets.at(0)->at(0);
674 qreal max = m_boxSets.at(0)->at(0);
675
675
676 foreach (QBoxSet *set, m_boxSets) {
676 foreach (QBoxSet *set, m_boxSets) {
677 for (int i = 0; i < 5; i++) {
677 for (int i = 0; i < 5; i++) {
678 if (set->at(i) > max)
678 if (set->at(i) > max)
679 max = set->at(i);
679 max = set->at(i);
680 }
680 }
681 }
681 }
682
682
683 return max;
683 return max;
684 }
684 }
685
685
686 #include "moc_qboxplotseries.cpp"
686 #include "moc_qboxplotseries.cpp"
687 #include "moc_qboxplotseries_p.cpp"
687 #include "moc_qboxplotseries_p.cpp"
688
688
689 QTCOMMERCIALCHART_END_NAMESPACE
689 QTCOMMERCIALCHART_END_NAMESPACE
690
690
@@ -1,501 +1,509
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2014 Digia Plc
3 ** Copyright (C) 2014 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Enterprise Charts Add-on.
7 ** This file is part of the Qt Enterprise Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Enterprise licenses may use this file in
10 ** Licensees holding valid Qt Enterprise licenses may use this file in
11 ** accordance with the Qt Enterprise License Agreement provided with the
11 ** accordance with the Qt Enterprise License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20 #include "chartpresenter_p.h"
20 #include "chartpresenter_p.h"
21 #include "qchart.h"
21 #include "qchart.h"
22 #include "chartitem_p.h"
22 #include "chartitem_p.h"
23 #include "qchart_p.h"
23 #include "qchart_p.h"
24 #include "qabstractaxis.h"
24 #include "qabstractaxis.h"
25 #include "qabstractaxis_p.h"
25 #include "qabstractaxis_p.h"
26 #include "chartdataset_p.h"
26 #include "chartdataset_p.h"
27 #include "chartanimation_p.h"
27 #include "chartanimation_p.h"
28 #include "qabstractseries_p.h"
28 #include "qabstractseries_p.h"
29 #include "qareaseries.h"
29 #include "qareaseries.h"
30 #include "chartaxiselement_p.h"
30 #include "chartaxiselement_p.h"
31 #include "chartbackground_p.h"
31 #include "chartbackground_p.h"
32 #include "cartesianchartlayout_p.h"
32 #include "cartesianchartlayout_p.h"
33 #include "polarchartlayout_p.h"
33 #include "polarchartlayout_p.h"
34 #include "charttitle_p.h"
34 #include "charttitle_p.h"
35 #include <QTimer>
35 #include <QTimer>
36 #include <QTextDocument>
36 #include <QTextDocument>
37
37
38 QTCOMMERCIALCHART_BEGIN_NAMESPACE
38 QTCOMMERCIALCHART_BEGIN_NAMESPACE
39
39
40 ChartPresenter::ChartPresenter(QChart *chart, QChart::ChartType type)
40 ChartPresenter::ChartPresenter(QChart *chart, QChart::ChartType type)
41 : QObject(chart),
41 : QObject(chart),
42 m_chart(chart),
42 m_chart(chart),
43 m_options(QChart::NoAnimation),
43 m_options(QChart::NoAnimation),
44 m_state(ShowState),
44 m_state(ShowState),
45 m_background(0),
45 m_background(0),
46 m_plotAreaBackground(0),
46 m_plotAreaBackground(0),
47 m_title(0),
47 m_title(0),
48 m_localizeNumbers(true)
48 m_localizeNumbers(true)
49 {
49 {
50 if (type == QChart::ChartTypeCartesian)
50 if (type == QChart::ChartTypeCartesian)
51 m_layout = new CartesianChartLayout(this);
51 m_layout = new CartesianChartLayout(this);
52 else if (type == QChart::ChartTypePolar)
52 else if (type == QChart::ChartTypePolar)
53 m_layout = new PolarChartLayout(this);
53 m_layout = new PolarChartLayout(this);
54 Q_ASSERT(m_layout);
54 Q_ASSERT(m_layout);
55 }
55 }
56
56
57 ChartPresenter::~ChartPresenter()
57 ChartPresenter::~ChartPresenter()
58 {
58 {
59
59
60 }
60 }
61
61
62 void ChartPresenter::setGeometry(const QRectF rect)
62 void ChartPresenter::setGeometry(const QRectF rect)
63 {
63 {
64 if (m_rect != rect) {
64 if (m_rect != rect) {
65 m_rect = rect;
65 m_rect = rect;
66 foreach (ChartItem *chart, m_chartItems) {
66 foreach (ChartItem *chart, m_chartItems) {
67 chart->domain()->setSize(rect.size());
67 chart->domain()->setSize(rect.size());
68 chart->setPos(rect.topLeft());
68 chart->setPos(rect.topLeft());
69 }
69 }
70 }
70 }
71 }
71 }
72
72
73 QRectF ChartPresenter::geometry() const
73 QRectF ChartPresenter::geometry() const
74 {
74 {
75 return m_rect;
75 return m_rect;
76 }
76 }
77
77
78 void ChartPresenter::handleAxisAdded(QAbstractAxis *axis)
78 void ChartPresenter::handleAxisAdded(QAbstractAxis *axis)
79 {
79 {
80 axis->d_ptr->initializeGraphics(rootItem());
80 axis->d_ptr->initializeGraphics(rootItem());
81 axis->d_ptr->initializeAnimations(m_options);
81 axis->d_ptr->initializeAnimations(m_options);
82 ChartAxisElement *item = axis->d_ptr->axisItem();
82 ChartAxisElement *item = axis->d_ptr->axisItem();
83 item->setPresenter(this);
83 item->setPresenter(this);
84 item->setThemeManager(m_chart->d_ptr->m_themeManager);
84 item->setThemeManager(m_chart->d_ptr->m_themeManager);
85 m_axisItems<<item;
85 m_axisItems<<item;
86 m_axes<<axis;
86 m_axes<<axis;
87 m_layout->invalidate();
87 m_layout->invalidate();
88 }
88 }
89
89
90 void ChartPresenter::handleAxisRemoved(QAbstractAxis *axis)
90 void ChartPresenter::handleAxisRemoved(QAbstractAxis *axis)
91 {
91 {
92 ChartAxisElement *item = axis->d_ptr->m_item.take();
92 ChartAxisElement *item = axis->d_ptr->m_item.take();
93 item->hide();
93 item->hide();
94 item->disconnect();
94 item->disconnect();
95 item->deleteLater();
95 item->deleteLater();
96 m_axisItems.removeAll(item);
96 m_axisItems.removeAll(item);
97 m_axes.removeAll(axis);
97 m_axes.removeAll(axis);
98 m_layout->invalidate();
98 m_layout->invalidate();
99 }
99 }
100
100
101
101
102 void ChartPresenter::handleSeriesAdded(QAbstractSeries *series)
102 void ChartPresenter::handleSeriesAdded(QAbstractSeries *series)
103 {
103 {
104 series->d_ptr->initializeGraphics(rootItem());
104 series->d_ptr->initializeGraphics(rootItem());
105 series->d_ptr->initializeAnimations(m_options);
105 series->d_ptr->initializeAnimations(m_options);
106 series->d_ptr->setPresenter(this);
106 series->d_ptr->setPresenter(this);
107 ChartItem *chart = series->d_ptr->chartItem();
107 ChartItem *chart = series->d_ptr->chartItem();
108 chart->setPresenter(this);
108 chart->setPresenter(this);
109 chart->setThemeManager(m_chart->d_ptr->m_themeManager);
109 chart->setThemeManager(m_chart->d_ptr->m_themeManager);
110 chart->domain()->setSize(m_rect.size());
110 chart->domain()->setSize(m_rect.size());
111 chart->setPos(m_rect.topLeft());
111 chart->setPos(m_rect.topLeft());
112 chart->handleDomainUpdated(); //this could be moved to intializeGraphics when animator is refactored
112 chart->handleDomainUpdated(); //this could be moved to intializeGraphics when animator is refactored
113 m_chartItems<<chart;
113 m_chartItems<<chart;
114 m_series<<series;
114 m_series<<series;
115 m_layout->invalidate();
115 m_layout->invalidate();
116 }
116 }
117
117
118 void ChartPresenter::handleSeriesRemoved(QAbstractSeries *series)
118 void ChartPresenter::handleSeriesRemoved(QAbstractSeries *series)
119 {
119 {
120 ChartItem *chart = series->d_ptr->m_item.take();
120 ChartItem *chart = series->d_ptr->m_item.take();
121 chart->hide();
121 chart->hide();
122 chart->disconnect();
122 chart->disconnect();
123 chart->deleteLater();
123 chart->deleteLater();
124 m_chartItems.removeAll(chart);
124 m_chartItems.removeAll(chart);
125 m_series.removeAll(series);
125 m_series.removeAll(series);
126 m_layout->invalidate();
126 m_layout->invalidate();
127 }
127 }
128
128
129 void ChartPresenter::setAnimationOptions(QChart::AnimationOptions options)
129 void ChartPresenter::setAnimationOptions(QChart::AnimationOptions options)
130 {
130 {
131 if (m_options != options) {
131 if (m_options != options) {
132 QChart::AnimationOptions oldOptions = m_options;
132 QChart::AnimationOptions oldOptions = m_options;
133 m_options = options;
133 m_options = options;
134 if (options.testFlag(QChart::SeriesAnimations) != oldOptions.testFlag(QChart::SeriesAnimations)) {
134 if (options.testFlag(QChart::SeriesAnimations) != oldOptions.testFlag(QChart::SeriesAnimations)) {
135 foreach (QAbstractSeries *series, m_series)
135 foreach (QAbstractSeries *series, m_series)
136 series->d_ptr->initializeAnimations(m_options);
136 series->d_ptr->initializeAnimations(m_options);
137 }
137 }
138 if (options.testFlag(QChart::GridAxisAnimations) != oldOptions.testFlag(QChart::GridAxisAnimations)) {
138 if (options.testFlag(QChart::GridAxisAnimations) != oldOptions.testFlag(QChart::GridAxisAnimations)) {
139 foreach (QAbstractAxis *axis, m_axes)
139 foreach (QAbstractAxis *axis, m_axes)
140 axis->d_ptr->initializeAnimations(m_options);
140 axis->d_ptr->initializeAnimations(m_options);
141 }
141 }
142 m_layout->invalidate(); // So that existing animations don't just stop halfway
142 m_layout->invalidate(); // So that existing animations don't just stop halfway
143 }
143 }
144 }
144 }
145
145
146 void ChartPresenter::setState(State state,QPointF point)
146 void ChartPresenter::setState(State state,QPointF point)
147 {
147 {
148 m_state=state;
148 m_state=state;
149 m_statePoint=point;
149 m_statePoint=point;
150 }
150 }
151
151
152 QChart::AnimationOptions ChartPresenter::animationOptions() const
152 QChart::AnimationOptions ChartPresenter::animationOptions() const
153 {
153 {
154 return m_options;
154 return m_options;
155 }
155 }
156
156
157 void ChartPresenter::createBackgroundItem()
157 void ChartPresenter::createBackgroundItem()
158 {
158 {
159 if (!m_background) {
159 if (!m_background) {
160 m_background = new ChartBackground(rootItem());
160 m_background = new ChartBackground(rootItem());
161 m_background->setPen(Qt::NoPen); // Theme doesn't touch pen so don't use default
161 m_background->setPen(Qt::NoPen); // Theme doesn't touch pen so don't use default
162 m_background->setBrush(QChartPrivate::defaultBrush());
162 m_background->setBrush(QChartPrivate::defaultBrush());
163 m_background->setZValue(ChartPresenter::BackgroundZValue);
163 m_background->setZValue(ChartPresenter::BackgroundZValue);
164 }
164 }
165 }
165 }
166
166
167 void ChartPresenter::createPlotAreaBackgroundItem()
167 void ChartPresenter::createPlotAreaBackgroundItem()
168 {
168 {
169 if (!m_plotAreaBackground) {
169 if (!m_plotAreaBackground) {
170 if (m_chart->chartType() == QChart::ChartTypeCartesian)
170 if (m_chart->chartType() == QChart::ChartTypeCartesian)
171 m_plotAreaBackground = new QGraphicsRectItem(rootItem());
171 m_plotAreaBackground = new QGraphicsRectItem(rootItem());
172 else
172 else
173 m_plotAreaBackground = new QGraphicsEllipseItem(rootItem());
173 m_plotAreaBackground = new QGraphicsEllipseItem(rootItem());
174 // Use transparent pen instead of Qt::NoPen, as Qt::NoPen causes
174 // Use transparent pen instead of Qt::NoPen, as Qt::NoPen causes
175 // antialising artifacts with axis lines for some reason.
175 // antialising artifacts with axis lines for some reason.
176 m_plotAreaBackground->setPen(QPen(Qt::transparent));
176 m_plotAreaBackground->setPen(QPen(Qt::transparent));
177 m_plotAreaBackground->setBrush(Qt::NoBrush);
177 m_plotAreaBackground->setBrush(Qt::NoBrush);
178 m_plotAreaBackground->setZValue(ChartPresenter::PlotAreaZValue);
178 m_plotAreaBackground->setZValue(ChartPresenter::PlotAreaZValue);
179 m_plotAreaBackground->setVisible(false);
179 m_plotAreaBackground->setVisible(false);
180 }
180 }
181 }
181 }
182
182
183 void ChartPresenter::createTitleItem()
183 void ChartPresenter::createTitleItem()
184 {
184 {
185 if (!m_title) {
185 if (!m_title) {
186 m_title = new ChartTitle(rootItem());
186 m_title = new ChartTitle(rootItem());
187 m_title->setZValue(ChartPresenter::BackgroundZValue);
187 m_title->setZValue(ChartPresenter::BackgroundZValue);
188 }
188 }
189 }
189 }
190
190
191 void ChartPresenter::startAnimation(ChartAnimation *animation)
191 void ChartPresenter::startAnimation(ChartAnimation *animation)
192 {
192 {
193 animation->stop();
193 animation->stop();
194 QTimer::singleShot(0, animation, SLOT(startChartAnimation()));
194 QTimer::singleShot(0, animation, SLOT(startChartAnimation()));
195 }
195 }
196
196
197 void ChartPresenter::setBackgroundBrush(const QBrush &brush)
197 void ChartPresenter::setBackgroundBrush(const QBrush &brush)
198 {
198 {
199 createBackgroundItem();
199 createBackgroundItem();
200 m_background->setBrush(brush);
200 m_background->setBrush(brush);
201 m_layout->invalidate();
201 m_layout->invalidate();
202 }
202 }
203
203
204 QBrush ChartPresenter::backgroundBrush() const
204 QBrush ChartPresenter::backgroundBrush() const
205 {
205 {
206 if (!m_background)
206 if (!m_background)
207 return QBrush();
207 return QBrush();
208 return m_background->brush();
208 return m_background->brush();
209 }
209 }
210
210
211 void ChartPresenter::setBackgroundPen(const QPen &pen)
211 void ChartPresenter::setBackgroundPen(const QPen &pen)
212 {
212 {
213 createBackgroundItem();
213 createBackgroundItem();
214 m_background->setPen(pen);
214 m_background->setPen(pen);
215 m_layout->invalidate();
215 m_layout->invalidate();
216 }
216 }
217
217
218 QPen ChartPresenter::backgroundPen() const
218 QPen ChartPresenter::backgroundPen() const
219 {
219 {
220 if (!m_background)
220 if (!m_background)
221 return QPen();
221 return QPen();
222 return m_background->pen();
222 return m_background->pen();
223 }
223 }
224
224
225 void ChartPresenter::setBackgroundRoundness(qreal diameter)
225 void ChartPresenter::setBackgroundRoundness(qreal diameter)
226 {
226 {
227 createBackgroundItem();
227 createBackgroundItem();
228 m_background->setDiameter(diameter);
228 m_background->setDiameter(diameter);
229 m_layout->invalidate();
229 m_layout->invalidate();
230 }
230 }
231
231
232 qreal ChartPresenter::backgroundRoundness() const
232 qreal ChartPresenter::backgroundRoundness() const
233 {
233 {
234 if (!m_background)
234 if (!m_background)
235 return 0;
235 return 0;
236 return m_background->diameter();
236 return m_background->diameter();
237 }
237 }
238
238
239 void ChartPresenter::setPlotAreaBackgroundBrush(const QBrush &brush)
239 void ChartPresenter::setPlotAreaBackgroundBrush(const QBrush &brush)
240 {
240 {
241 createPlotAreaBackgroundItem();
241 createPlotAreaBackgroundItem();
242 m_plotAreaBackground->setBrush(brush);
242 m_plotAreaBackground->setBrush(brush);
243 m_layout->invalidate();
243 m_layout->invalidate();
244 }
244 }
245
245
246 QBrush ChartPresenter::plotAreaBackgroundBrush() const
246 QBrush ChartPresenter::plotAreaBackgroundBrush() const
247 {
247 {
248 if (!m_plotAreaBackground)
248 if (!m_plotAreaBackground)
249 return QBrush();
249 return QBrush();
250 return m_plotAreaBackground->brush();
250 return m_plotAreaBackground->brush();
251 }
251 }
252
252
253 void ChartPresenter::setPlotAreaBackgroundPen(const QPen &pen)
253 void ChartPresenter::setPlotAreaBackgroundPen(const QPen &pen)
254 {
254 {
255 createPlotAreaBackgroundItem();
255 createPlotAreaBackgroundItem();
256 m_plotAreaBackground->setPen(pen);
256 m_plotAreaBackground->setPen(pen);
257 m_layout->invalidate();
257 m_layout->invalidate();
258 }
258 }
259
259
260 QPen ChartPresenter::plotAreaBackgroundPen() const
260 QPen ChartPresenter::plotAreaBackgroundPen() const
261 {
261 {
262 if (!m_plotAreaBackground)
262 if (!m_plotAreaBackground)
263 return QPen();
263 return QPen();
264 return m_plotAreaBackground->pen();
264 return m_plotAreaBackground->pen();
265 }
265 }
266
266
267 void ChartPresenter::setTitle(const QString &title)
267 void ChartPresenter::setTitle(const QString &title)
268 {
268 {
269 createTitleItem();
269 createTitleItem();
270 m_title->setText(title);
270 m_title->setText(title);
271 m_layout->invalidate();
271 m_layout->invalidate();
272 }
272 }
273
273
274 QString ChartPresenter::title() const
274 QString ChartPresenter::title() const
275 {
275 {
276 if (!m_title)
276 if (!m_title)
277 return QString();
277 return QString();
278 return m_title->text();
278 return m_title->text();
279 }
279 }
280
280
281 void ChartPresenter::setTitleFont(const QFont &font)
281 void ChartPresenter::setTitleFont(const QFont &font)
282 {
282 {
283 createTitleItem();
283 createTitleItem();
284 m_title->setFont(font);
284 m_title->setFont(font);
285 m_layout->invalidate();
285 m_layout->invalidate();
286 }
286 }
287
287
288 QFont ChartPresenter::titleFont() const
288 QFont ChartPresenter::titleFont() const
289 {
289 {
290 if (!m_title)
290 if (!m_title)
291 return QFont();
291 return QFont();
292 return m_title->font();
292 return m_title->font();
293 }
293 }
294
294
295 void ChartPresenter::setTitleBrush(const QBrush &brush)
295 void ChartPresenter::setTitleBrush(const QBrush &brush)
296 {
296 {
297 createTitleItem();
297 createTitleItem();
298 m_title->setDefaultTextColor(brush.color());
298 m_title->setDefaultTextColor(brush.color());
299 m_layout->invalidate();
299 m_layout->invalidate();
300 }
300 }
301
301
302 QBrush ChartPresenter::titleBrush() const
302 QBrush ChartPresenter::titleBrush() const
303 {
303 {
304 if (!m_title)
304 if (!m_title)
305 return QBrush();
305 return QBrush();
306 return QBrush(m_title->defaultTextColor());
306 return QBrush(m_title->defaultTextColor());
307 }
307 }
308
308
309 void ChartPresenter::setBackgroundVisible(bool visible)
309 void ChartPresenter::setBackgroundVisible(bool visible)
310 {
310 {
311 createBackgroundItem();
311 createBackgroundItem();
312 m_background->setVisible(visible);
312 m_background->setVisible(visible);
313 }
313 }
314
314
315
315
316 bool ChartPresenter::isBackgroundVisible() const
316 bool ChartPresenter::isBackgroundVisible() const
317 {
317 {
318 if (!m_background)
318 if (!m_background)
319 return false;
319 return false;
320 return m_background->isVisible();
320 return m_background->isVisible();
321 }
321 }
322
322
323 void ChartPresenter::setPlotAreaBackgroundVisible(bool visible)
323 void ChartPresenter::setPlotAreaBackgroundVisible(bool visible)
324 {
324 {
325 createPlotAreaBackgroundItem();
325 createPlotAreaBackgroundItem();
326 m_plotAreaBackground->setVisible(visible);
326 m_plotAreaBackground->setVisible(visible);
327 }
327 }
328
328
329 bool ChartPresenter::isPlotAreaBackgroundVisible() const
329 bool ChartPresenter::isPlotAreaBackgroundVisible() const
330 {
330 {
331 if (!m_plotAreaBackground)
331 if (!m_plotAreaBackground)
332 return false;
332 return false;
333 return m_plotAreaBackground->isVisible();
333 return m_plotAreaBackground->isVisible();
334 }
334 }
335
335
336 void ChartPresenter::setBackgroundDropShadowEnabled(bool enabled)
336 void ChartPresenter::setBackgroundDropShadowEnabled(bool enabled)
337 {
337 {
338 createBackgroundItem();
338 createBackgroundItem();
339 m_background->setDropShadowEnabled(enabled);
339 m_background->setDropShadowEnabled(enabled);
340 }
340 }
341
341
342 bool ChartPresenter::isBackgroundDropShadowEnabled() const
342 bool ChartPresenter::isBackgroundDropShadowEnabled() const
343 {
343 {
344 if (!m_background)
344 if (!m_background)
345 return false;
345 return false;
346 return m_background->isDropShadowEnabled();
346 return m_background->isDropShadowEnabled();
347 }
347 }
348
348
349 void ChartPresenter::setLocalizeNumbers(bool localize)
349 void ChartPresenter::setLocalizeNumbers(bool localize)
350 {
350 {
351 m_localizeNumbers = localize;
351 m_localizeNumbers = localize;
352 m_layout->invalidate();
352 m_layout->invalidate();
353 }
353 }
354
354
355 void ChartPresenter::setLocale(const QLocale &locale)
355 void ChartPresenter::setLocale(const QLocale &locale)
356 {
356 {
357 m_locale = locale;
357 m_locale = locale;
358 m_layout->invalidate();
358 m_layout->invalidate();
359 }
359 }
360
360
361 AbstractChartLayout *ChartPresenter::layout()
361 AbstractChartLayout *ChartPresenter::layout()
362 {
362 {
363 return m_layout;
363 return m_layout;
364 }
364 }
365
365
366 QLegend *ChartPresenter::legend()
366 QLegend *ChartPresenter::legend()
367 {
367 {
368 return m_chart->legend();
368 return m_chart->legend();
369 }
369 }
370
370
371 void ChartPresenter::setVisible(bool visible)
371 void ChartPresenter::setVisible(bool visible)
372 {
372 {
373 m_chart->setVisible(visible);
373 m_chart->setVisible(visible);
374 }
374 }
375
375
376 ChartBackground *ChartPresenter::backgroundElement()
376 ChartBackground *ChartPresenter::backgroundElement()
377 {
377 {
378 return m_background;
378 return m_background;
379 }
379 }
380
380
381 QAbstractGraphicsShapeItem *ChartPresenter::plotAreaElement()
381 QAbstractGraphicsShapeItem *ChartPresenter::plotAreaElement()
382 {
382 {
383 return m_plotAreaBackground;
383 return m_plotAreaBackground;
384 }
384 }
385
385
386 QList<ChartAxisElement *> ChartPresenter::axisItems() const
386 QList<ChartAxisElement *> ChartPresenter::axisItems() const
387 {
387 {
388 return m_axisItems;
388 return m_axisItems;
389 }
389 }
390
390
391 QList<ChartItem *> ChartPresenter::chartItems() const
391 QList<ChartItem *> ChartPresenter::chartItems() const
392 {
392 {
393 return m_chartItems;
393 return m_chartItems;
394 }
394 }
395
395
396 ChartTitle *ChartPresenter::titleElement()
396 ChartTitle *ChartPresenter::titleElement()
397 {
397 {
398 return m_title;
398 return m_title;
399 }
399 }
400
400
401 QRectF ChartPresenter::textBoundingRect(const QFont &font, const QString &text, qreal angle)
401 QRectF ChartPresenter::textBoundingRect(const QFont &font, const QString &text, qreal angle)
402 {
402 {
403 static QGraphicsTextItem dummyTextItem;
403 static QGraphicsTextItem dummyTextItem;
404 static bool initMargin = true;
404 static bool initMargin = true;
405 if (initMargin) {
405 if (initMargin) {
406 dummyTextItem.document()->setDocumentMargin(textMargin());
406 dummyTextItem.document()->setDocumentMargin(textMargin());
407 initMargin = false;
407 initMargin = false;
408 }
408 }
409
409
410 dummyTextItem.setFont(font);
410 dummyTextItem.setFont(font);
411 dummyTextItem.setHtml(text);
411 dummyTextItem.setHtml(text);
412 QRectF boundingRect = dummyTextItem.boundingRect();
412 QRectF boundingRect = dummyTextItem.boundingRect();
413
413
414 // Take rotation into account
414 // Take rotation into account
415 if (angle) {
415 if (angle) {
416 QTransform transform;
416 QTransform transform;
417 transform.rotate(angle);
417 transform.rotate(angle);
418 boundingRect = transform.mapRect(boundingRect);
418 boundingRect = transform.mapRect(boundingRect);
419 }
419 }
420
420
421 return boundingRect;
421 return boundingRect;
422 }
422 }
423
423
424 // boundingRect parameter returns the rotated bounding rect of the text
424 // boundingRect parameter returns the rotated bounding rect of the text
425 QString ChartPresenter::truncatedText(const QFont &font, const QString &text, qreal angle,
425 QString ChartPresenter::truncatedText(const QFont &font, const QString &text, qreal angle,
426 qreal maxWidth, qreal maxHeight, QRectF &boundingRect)
426 qreal maxWidth, qreal maxHeight, QRectF &boundingRect)
427 {
427 {
428 QString truncatedString(text);
428 QString truncatedString(text);
429 boundingRect = textBoundingRect(font, truncatedString, angle);
429 boundingRect = textBoundingRect(font, truncatedString, angle);
430 if (boundingRect.width() > maxWidth || boundingRect.height() > maxHeight) {
430 if (boundingRect.width() > maxWidth || boundingRect.height() > maxHeight) {
431 // It can be assumed that almost any amount of string manipulation is faster
431 // It can be assumed that almost any amount of string manipulation is faster
432 // than calculating one bounding rectangle, so first prepare a list of truncated strings
432 // than calculating one bounding rectangle, so first prepare a list of truncated strings
433 // to try.
433 // to try.
434 static const char *truncateMatchString = "&#?[0-9a-zA-Z]*;$";
434 static const char *truncateMatchString = "&#?[0-9a-zA-Z]*;$";
435 static QRegExp truncateMatcher(truncateMatchString);
435 static QRegExp truncateMatcher(truncateMatchString);
436
436
437 QVector<QString> testStrings(text.length());
437 QVector<QString> testStrings(text.length());
438 int count(0);
438 int count(0);
439 static QLatin1Char closeTag('>');
439 static QLatin1Char closeTag('>');
440 static QLatin1Char openTag('<');
440 static QLatin1Char openTag('<');
441 static QLatin1Char semiColon(';');
441 static QLatin1Char semiColon(';');
442 static QLatin1String ellipsis("...");
442 static QLatin1String ellipsis("...");
443 while (truncatedString.length() > 1) {
443 while (truncatedString.length() > 1) {
444 int chopIndex(-1);
444 int chopIndex(-1);
445 int chopCount(1);
445 int chopCount(1);
446 QChar lastChar(truncatedString.at(truncatedString.length() - 1));
446 QChar lastChar(truncatedString.at(truncatedString.length() - 1));
447
447
448 if (lastChar == closeTag)
448 if (lastChar == closeTag)
449 chopIndex = truncatedString.lastIndexOf(openTag);
449 chopIndex = truncatedString.lastIndexOf(openTag);
450 else if (lastChar == semiColon)
450 else if (lastChar == semiColon)
451 chopIndex = truncateMatcher.indexIn(truncatedString, 0);
451 chopIndex = truncateMatcher.indexIn(truncatedString, 0);
452
452
453 if (chopIndex != -1)
453 if (chopIndex != -1)
454 chopCount = truncatedString.length() - chopIndex;
454 chopCount = truncatedString.length() - chopIndex;
455 truncatedString.chop(chopCount);
455 truncatedString.chop(chopCount);
456 testStrings[count] = truncatedString + ellipsis;
456 testStrings[count] = truncatedString + ellipsis;
457 count++;
457 count++;
458 }
458 }
459
459
460 // Binary search for best fit
460 // Binary search for best fit
461 int minIndex(0);
461 int minIndex(0);
462 int maxIndex(count - 1);
462 int maxIndex(count - 1);
463 int bestIndex(count);
463 int bestIndex(count);
464 QRectF checkRect;
464 QRectF checkRect;
465
465
466 while (maxIndex >= minIndex) {
466 while (maxIndex >= minIndex) {
467 int mid = (maxIndex + minIndex) / 2;
467 int mid = (maxIndex + minIndex) / 2;
468 checkRect = textBoundingRect(font, testStrings.at(mid), angle);
468 checkRect = textBoundingRect(font, testStrings.at(mid), angle);
469 if (checkRect.width() > maxWidth || checkRect.height() > maxHeight) {
469 if (checkRect.width() > maxWidth || checkRect.height() > maxHeight) {
470 // Checked index too large, all under this are also too large
470 // Checked index too large, all under this are also too large
471 minIndex = mid + 1;
471 minIndex = mid + 1;
472 } else {
472 } else {
473 // Checked index fits, all over this also fit
473 // Checked index fits, all over this also fit
474 maxIndex = mid - 1;
474 maxIndex = mid - 1;
475 bestIndex = mid;
475 bestIndex = mid;
476 boundingRect = checkRect;
476 boundingRect = checkRect;
477 }
477 }
478 }
478 }
479 // Default to "..." if nothing fits
479 // Default to "..." if nothing fits
480 if (bestIndex == count) {
480 if (bestIndex == count) {
481 boundingRect = textBoundingRect(font, ellipsis, angle);
481 boundingRect = textBoundingRect(font, ellipsis, angle);
482 truncatedString = ellipsis;
482 truncatedString = ellipsis;
483 } else {
483 } else {
484 truncatedString = testStrings.at(bestIndex);
484 truncatedString = testStrings.at(bestIndex);
485 }
485 }
486 }
486 }
487
487
488 return truncatedString;
488 return truncatedString;
489 }
489 }
490
490
491 QString ChartPresenter::numberToString(double value, char f, int prec)
491 QString ChartPresenter::numberToString(double value, char f, int prec)
492 {
492 {
493 if (m_localizeNumbers)
493 if (m_localizeNumbers)
494 return m_locale.toString(value, f, prec);
494 return m_locale.toString(value, f, prec);
495 else
495 else
496 return QString::number(value, f, prec);
496 return QString::number(value, f, prec);
497 }
497 }
498
498
499 QString ChartPresenter::numberToString(int value)
500 {
501 if (m_localizeNumbers)
502 return m_locale.toString(value);
503 else
504 return QString::number(value);
505 }
506
499 #include "moc_chartpresenter_p.cpp"
507 #include "moc_chartpresenter_p.cpp"
500
508
501 QTCOMMERCIALCHART_END_NAMESPACE
509 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,191 +1,192
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2014 Digia Plc
3 ** Copyright (C) 2014 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Enterprise Charts Add-on.
7 ** This file is part of the Qt Enterprise Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Enterprise licenses may use this file in
10 ** Licensees holding valid Qt Enterprise licenses may use this file in
11 ** accordance with the Qt Enterprise License Agreement provided with the
11 ** accordance with the Qt Enterprise License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 // W A R N I N G
21 // W A R N I N G
22 // -------------
22 // -------------
23 //
23 //
24 // This file is not part of the Qt Enterprise Chart API. It exists purely as an
24 // This file is not part of the Qt Enterprise Chart API. It exists purely as an
25 // implementation detail. This header file may change from version to
25 // implementation detail. This header file may change from version to
26 // version without notice, or even be removed.
26 // version without notice, or even be removed.
27 //
27 //
28 // We mean it.
28 // We mean it.
29
29
30 #ifndef CHARTPRESENTER_H
30 #ifndef CHARTPRESENTER_H
31 #define CHARTPRESENTER_H
31 #define CHARTPRESENTER_H
32
32
33 #include "qchartglobal.h"
33 #include "qchartglobal.h"
34 #include "qchart.h" //because of QChart::ChartThemeId
34 #include "qchart.h" //because of QChart::ChartThemeId
35 #include <QRectF>
35 #include <QRectF>
36 #include <QMargins>
36 #include <QMargins>
37 #include <QLocale>
37 #include <QLocale>
38
38
39 QTCOMMERCIALCHART_BEGIN_NAMESPACE
39 QTCOMMERCIALCHART_BEGIN_NAMESPACE
40
40
41 class ChartItem;
41 class ChartItem;
42 class AxisItem;
42 class AxisItem;
43 class QAbstractSeries;
43 class QAbstractSeries;
44 class ChartDataSet;
44 class ChartDataSet;
45 class AbstractDomain;
45 class AbstractDomain;
46 class ChartAxisElement;
46 class ChartAxisElement;
47 class ChartAnimator;
47 class ChartAnimator;
48 class ChartBackground;
48 class ChartBackground;
49 class ChartTitle;
49 class ChartTitle;
50 class ChartAnimation;
50 class ChartAnimation;
51 class AbstractChartLayout;
51 class AbstractChartLayout;
52
52
53 class ChartPresenter: public QObject
53 class ChartPresenter: public QObject
54 {
54 {
55 Q_OBJECT
55 Q_OBJECT
56 public:
56 public:
57 enum ZValues {
57 enum ZValues {
58 BackgroundZValue = -1,
58 BackgroundZValue = -1,
59 PlotAreaZValue,
59 PlotAreaZValue,
60 ShadesZValue,
60 ShadesZValue,
61 GridZValue,
61 GridZValue,
62 AxisZValue,
62 AxisZValue,
63 SeriesZValue,
63 SeriesZValue,
64 LineChartZValue = SeriesZValue,
64 LineChartZValue = SeriesZValue,
65 SplineChartZValue = SeriesZValue,
65 SplineChartZValue = SeriesZValue,
66 BarSeriesZValue = SeriesZValue,
66 BarSeriesZValue = SeriesZValue,
67 ScatterSeriesZValue = SeriesZValue,
67 ScatterSeriesZValue = SeriesZValue,
68 PieSeriesZValue = SeriesZValue,
68 PieSeriesZValue = SeriesZValue,
69 BoxPlotSeriesZValue = SeriesZValue,
69 BoxPlotSeriesZValue = SeriesZValue,
70 LegendZValue,
70 LegendZValue,
71 TopMostZValue
71 TopMostZValue
72 };
72 };
73
73
74 enum State {
74 enum State {
75 ShowState,
75 ShowState,
76 ScrollUpState,
76 ScrollUpState,
77 ScrollDownState,
77 ScrollDownState,
78 ScrollLeftState,
78 ScrollLeftState,
79 ScrollRightState,
79 ScrollRightState,
80 ZoomInState,
80 ZoomInState,
81 ZoomOutState
81 ZoomOutState
82 };
82 };
83
83
84 ChartPresenter(QChart *chart, QChart::ChartType type);
84 ChartPresenter(QChart *chart, QChart::ChartType type);
85 virtual ~ChartPresenter();
85 virtual ~ChartPresenter();
86
86
87
87
88 void setGeometry(QRectF rect);
88 void setGeometry(QRectF rect);
89 QRectF geometry() const;
89 QRectF geometry() const;
90
90
91 QGraphicsItem *rootItem(){ return m_chart; }
91 QGraphicsItem *rootItem(){ return m_chart; }
92 ChartBackground *backgroundElement();
92 ChartBackground *backgroundElement();
93 QAbstractGraphicsShapeItem *plotAreaElement();
93 QAbstractGraphicsShapeItem *plotAreaElement();
94 ChartTitle *titleElement();
94 ChartTitle *titleElement();
95 QList<ChartAxisElement *> axisItems() const;
95 QList<ChartAxisElement *> axisItems() const;
96 QList<ChartItem *> chartItems() const;
96 QList<ChartItem *> chartItems() const;
97
97
98 QLegend *legend();
98 QLegend *legend();
99
99
100 void setBackgroundBrush(const QBrush &brush);
100 void setBackgroundBrush(const QBrush &brush);
101 QBrush backgroundBrush() const;
101 QBrush backgroundBrush() const;
102
102
103 void setBackgroundPen(const QPen &pen);
103 void setBackgroundPen(const QPen &pen);
104 QPen backgroundPen() const;
104 QPen backgroundPen() const;
105
105
106 void setBackgroundRoundness(qreal diameter);
106 void setBackgroundRoundness(qreal diameter);
107 qreal backgroundRoundness() const;
107 qreal backgroundRoundness() const;
108
108
109 void setPlotAreaBackgroundBrush(const QBrush &brush);
109 void setPlotAreaBackgroundBrush(const QBrush &brush);
110 QBrush plotAreaBackgroundBrush() const;
110 QBrush plotAreaBackgroundBrush() const;
111
111
112 void setPlotAreaBackgroundPen(const QPen &pen);
112 void setPlotAreaBackgroundPen(const QPen &pen);
113 QPen plotAreaBackgroundPen() const;
113 QPen plotAreaBackgroundPen() const;
114
114
115 void setTitle(const QString &title);
115 void setTitle(const QString &title);
116 QString title() const;
116 QString title() const;
117
117
118 void setTitleFont(const QFont &font);
118 void setTitleFont(const QFont &font);
119 QFont titleFont() const;
119 QFont titleFont() const;
120
120
121 void setTitleBrush(const QBrush &brush);
121 void setTitleBrush(const QBrush &brush);
122 QBrush titleBrush() const;
122 QBrush titleBrush() const;
123
123
124 void setBackgroundVisible(bool visible);
124 void setBackgroundVisible(bool visible);
125 bool isBackgroundVisible() const;
125 bool isBackgroundVisible() const;
126
126
127 void setPlotAreaBackgroundVisible(bool visible);
127 void setPlotAreaBackgroundVisible(bool visible);
128 bool isPlotAreaBackgroundVisible() const;
128 bool isPlotAreaBackgroundVisible() const;
129
129
130 void setBackgroundDropShadowEnabled(bool enabled);
130 void setBackgroundDropShadowEnabled(bool enabled);
131 bool isBackgroundDropShadowEnabled() const;
131 bool isBackgroundDropShadowEnabled() const;
132
132
133 void setLocalizeNumbers(bool localize);
133 void setLocalizeNumbers(bool localize);
134 inline bool localizeNumbers() const { return m_localizeNumbers; }
134 inline bool localizeNumbers() const { return m_localizeNumbers; }
135 void setLocale(const QLocale &locale);
135 void setLocale(const QLocale &locale);
136 inline const QLocale &locale() const { return m_locale; }
136 inline const QLocale &locale() const { return m_locale; }
137
137
138 void setVisible(bool visible);
138 void setVisible(bool visible);
139
139
140 void setAnimationOptions(QChart::AnimationOptions options);
140 void setAnimationOptions(QChart::AnimationOptions options);
141 QChart::AnimationOptions animationOptions() const;
141 QChart::AnimationOptions animationOptions() const;
142
142
143 void startAnimation(ChartAnimation *animation);
143 void startAnimation(ChartAnimation *animation);
144
144
145 void setState(State state,QPointF point);
145 void setState(State state,QPointF point);
146 State state() const { return m_state; }
146 State state() const { return m_state; }
147 QPointF statePoint() const { return m_statePoint; }
147 QPointF statePoint() const { return m_statePoint; }
148 AbstractChartLayout *layout();
148 AbstractChartLayout *layout();
149
149
150 QChart::ChartType chartType() const { return m_chart->chartType(); }
150 QChart::ChartType chartType() const { return m_chart->chartType(); }
151 QChart *chart() { return m_chart; }
151 QChart *chart() { return m_chart; }
152
152
153 static QRectF textBoundingRect(const QFont &font, const QString &text, qreal angle = 0.0);
153 static QRectF textBoundingRect(const QFont &font, const QString &text, qreal angle = 0.0);
154 static QString truncatedText(const QFont &font, const QString &text, qreal angle,
154 static QString truncatedText(const QFont &font, const QString &text, qreal angle,
155 qreal maxWidth, qreal maxHeight, QRectF &boundingRect);
155 qreal maxWidth, qreal maxHeight, QRectF &boundingRect);
156 inline static qreal textMargin() { return qreal(0.5); }
156 inline static qreal textMargin() { return qreal(0.5); }
157
157
158 QString numberToString(double value, char f = 'g', int prec = 6);
158 QString numberToString(double value, char f = 'g', int prec = 6);
159 QString numberToString(int value);
159
160
160 private:
161 private:
161 void createBackgroundItem();
162 void createBackgroundItem();
162 void createPlotAreaBackgroundItem();
163 void createPlotAreaBackgroundItem();
163 void createTitleItem();
164 void createTitleItem();
164
165
165 public Q_SLOTS:
166 public Q_SLOTS:
166 void handleSeriesAdded(QAbstractSeries *series);
167 void handleSeriesAdded(QAbstractSeries *series);
167 void handleSeriesRemoved(QAbstractSeries *series);
168 void handleSeriesRemoved(QAbstractSeries *series);
168 void handleAxisAdded(QAbstractAxis *axis);
169 void handleAxisAdded(QAbstractAxis *axis);
169 void handleAxisRemoved(QAbstractAxis *axis);
170 void handleAxisRemoved(QAbstractAxis *axis);
170
171
171 private:
172 private:
172 QChart *m_chart;
173 QChart *m_chart;
173 QList<ChartItem *> m_chartItems;
174 QList<ChartItem *> m_chartItems;
174 QList<ChartAxisElement *> m_axisItems;
175 QList<ChartAxisElement *> m_axisItems;
175 QList<QAbstractSeries *> m_series;
176 QList<QAbstractSeries *> m_series;
176 QList<QAbstractAxis *> m_axes;
177 QList<QAbstractAxis *> m_axes;
177 QChart::AnimationOptions m_options;
178 QChart::AnimationOptions m_options;
178 State m_state;
179 State m_state;
179 QPointF m_statePoint;
180 QPointF m_statePoint;
180 AbstractChartLayout *m_layout;
181 AbstractChartLayout *m_layout;
181 ChartBackground *m_background;
182 ChartBackground *m_background;
182 QAbstractGraphicsShapeItem *m_plotAreaBackground;
183 QAbstractGraphicsShapeItem *m_plotAreaBackground;
183 ChartTitle *m_title;
184 ChartTitle *m_title;
184 QRectF m_rect;
185 QRectF m_rect;
185 bool m_localizeNumbers;
186 bool m_localizeNumbers;
186 QLocale m_locale;
187 QLocale m_locale;
187 };
188 };
188
189
189 QTCOMMERCIALCHART_END_NAMESPACE
190 QTCOMMERCIALCHART_END_NAMESPACE
190
191
191 #endif /* CHARTPRESENTER_H */
192 #endif /* CHARTPRESENTER_H */
General Comments 0
You need to be logged in to leave comments. Login now