##// END OF EJS Templates
remove todo comments for release
Jani Honkonen -
r2015:b5f96ea8740c
parent child
Show More
@@ -1,88 +1,88
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "qchartsplugin.h"
22 22 #include "qchartview.h"
23 23 #include <QtPlugin>
24 24
25 25 QTCOMMERCIALCHART_USE_NAMESPACE
26 26
27 27 QChartsPlugin::QChartsPlugin(QObject *parent) :
28 28 QObject(parent)
29 29 {
30 // TODO Auto-generated constructor stub
30
31 31 }
32 32
33 33 QChartsPlugin::~QChartsPlugin()
34 34 {
35 // TODO Auto-generated destructor stub
35
36 36 }
37 37
38 38 QString QChartsPlugin::name() const
39 39 {
40 40 return "QChartView";
41 41 }
42 42
43 43 QString QChartsPlugin::includeFile() const
44 44 {
45 45 #ifdef linux
46 46 QString myNewLine = "\n";
47 47 #endif
48 48 #ifdef WIN32
49 49 QString myNewLine = "\n\r";
50 50 #endif
51 51 #ifdef __APPLE__
52 52 QString myNewLine = "\n";
53 53 #endif
54 54
55 55 return "<qchartview.h>" + myNewLine + "#include <chartsnamespace.h>";
56 56 }
57 57
58 58 QString QChartsPlugin::group() const
59 59 {
60 60 return tr("QCharts Widgets");
61 61 }
62 62
63 63 QIcon QChartsPlugin::icon() const
64 64 {
65 65 return QIcon(":/images/qcharts.png");
66 66 }
67 67
68 68 QString QChartsPlugin::toolTip() const
69 69 {
70 70 return tr("An qcharts view widget");
71 71 }
72 72
73 73 QString QChartsPlugin::whatsThis() const
74 74 {
75 75 return tr("This widget is presents QChartView widget");
76 76 }
77 77
78 78 bool QChartsPlugin::isContainer() const
79 79 {
80 80 return false;
81 81 }
82 82
83 83 QWidget* QChartsPlugin::createWidget(QWidget *parent)
84 84 {
85 85 return new QChartView(new QChart(), parent);
86 86 }
87 87
88 88 Q_EXPORT_PLUGIN2(qtcommercialchart, QChartsPlugin)
@@ -1,151 +1,150
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "areachartitem_p.h"
22 22 #include "qareaseries.h"
23 23 #include "qareaseries_p.h"
24 24 #include "qlineseries.h"
25 25 #include "chartpresenter_p.h"
26 26 #include "domain_p.h"
27 27 #include <QPainter>
28 28 #include <QGraphicsSceneMouseEvent>
29 29 #include <QDebug>
30 30
31 31
32 32 QTCOMMERCIALCHART_BEGIN_NAMESPACE
33 33
34 //TODO: optimize : remove points which are not visible
35 34
36 35 AreaChartItem::AreaChartItem(QAreaSeries *areaSeries, ChartPresenter *presenter)
37 36 : ChartItem(presenter),
38 37 m_series(areaSeries),
39 38 m_upper(0),
40 39 m_lower(0),
41 40 m_pointsVisible(false)
42 41 {
43 42 setZValue(ChartPresenter::LineChartZValue);
44 43 m_upper = new AreaBoundItem(this,m_series->upperSeries(),presenter);
45 44 if (m_series->lowerSeries()){
46 45 m_lower = new AreaBoundItem(this,m_series->lowerSeries(),presenter);
47 46 }
48 47
49 48 QObject::connect(m_series->d_func(),SIGNAL(updated()),this,SLOT(handleUpdated()));
50 49 QObject::connect(m_series, SIGNAL(visibleChanged()), this, SLOT(handleUpdated()));
51 50 QObject::connect(this,SIGNAL(clicked(QPointF)),areaSeries,SIGNAL(clicked(QPointF)));
52 51
53 52 handleUpdated();
54 53 }
55 54
56 55 AreaChartItem::~AreaChartItem()
57 56 {
58 57 delete m_upper;
59 58 delete m_lower;
60 59 }
61 60
62 61 QRectF AreaChartItem::boundingRect() const
63 62 {
64 63 return m_rect;
65 64 }
66 65
67 66 QPainterPath AreaChartItem::shape() const
68 67 {
69 68 return m_path;
70 69 }
71 70
72 71 void AreaChartItem::updatePath()
73 72 {
74 73 QPainterPath path;
75 74
76 75 path = m_upper->path();
77 76
78 77 if (m_lower) {
79 78 path.connectPath(m_lower->path().toReversed());
80 79 } else {
81 80 QPointF first = path.pointAtPercent(0);
82 81 QPointF last = path.pointAtPercent(1);
83 82 path.lineTo(last.x(),m_clipRect.bottom());
84 83 path.lineTo(first.x(),m_clipRect.bottom());
85 84 }
86 85 path.closeSubpath();
87 86 prepareGeometryChange();
88 87 m_path = path;
89 88 m_rect = path.boundingRect();
90 89 update();
91 90 }
92 91
93 92 void AreaChartItem::handleUpdated()
94 93 {
95 94 setVisible(m_series->isVisible());
96 95 m_pointsVisible = m_series->pointsVisible();
97 96 m_linePen = m_series->pen();
98 97 m_brush = m_series->brush();
99 98 m_pointPen = m_series->pen();
100 99 m_pointPen.setWidthF(2 * m_pointPen.width());
101 100
102 101 update();
103 102 }
104 103
105 104 void AreaChartItem::handleDomainUpdated()
106 105 {
107 106 m_upper->setDomain(domain());
108 107 m_upper->handleDomainUpdated();
109 108 if (m_lower){
110 109 m_lower->setDomain(domain());
111 110 m_lower->handleDomainUpdated();
112 111 }
113 112 }
114 113
115 114 void AreaChartItem::handleGeometryChanged(const QRectF &rect)
116 115 {
117 116 m_clipRect=rect.translated(-rect.topLeft());
118 117 setPos(rect.topLeft());
119 118 m_upper->handleGeometryChanged(rect);
120 119 if (m_lower)
121 120 m_lower->handleGeometryChanged(rect);
122 121 }
123 122
124 123 void AreaChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
125 124 {
126 125 Q_UNUSED(widget)
127 126 Q_UNUSED(option)
128 127
129 128 painter->save();
130 129 painter->setPen(m_linePen);
131 130 painter->setBrush(m_brush);
132 131 painter->setClipRect(m_clipRect);
133 132 painter->drawPath(m_path);
134 133 if (m_pointsVisible) {
135 134 painter->setPen(m_pointPen);
136 135 painter->drawPoints(m_upper->geometryPoints());
137 136 if (m_lower)
138 137 painter->drawPoints(m_lower->geometryPoints());
139 138 }
140 139 painter->restore();
141 140 }
142 141
143 142 void AreaChartItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
144 143 {
145 144 emit clicked(m_upper->calculateDomainPoint(event->pos()));
146 145 ChartItem::mousePressEvent(event);
147 146 }
148 147
149 148 #include "moc_areachartitem_p.cpp"
150 149
151 150 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,399 +1,399
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "chartaxis_p.h"
22 22 #include "qabstractaxis.h"
23 23 #include "qabstractaxis_p.h"
24 24 #include "chartpresenter_p.h"
25 25 #include "domain_p.h"
26 26 #include <qmath.h>
27 27 #include <QDateTime>
28 28 #include <QValueAxis>
29 29 #include <QGraphicsLayout>
30 30
31 31 QTCOMMERCIALCHART_BEGIN_NAMESPACE
32 32
33 33 ChartAxis::ChartAxis(QAbstractAxis *axis,ChartPresenter *presenter) : ChartElement(presenter),
34 34 m_chartAxis(axis),
35 35 m_labelsAngle(0),
36 36 m_grid(new QGraphicsItemGroup(presenter->rootItem())),
37 37 m_shades(new QGraphicsItemGroup(presenter->rootItem())),
38 38 m_labels(new QGraphicsItemGroup(presenter->rootItem())),
39 39 m_arrow(new QGraphicsItemGroup(presenter->rootItem())),
40 40 m_min(0),
41 41 m_max(0),
42 42 m_animation(0),
43 43 m_minWidth(0),
44 44 m_minHeight(0)
45 45 {
46 46 //initial initialization
47 47 m_arrow->setZValue(ChartPresenter::AxisZValue);
48 48 m_arrow->setHandlesChildEvents(false);
49 49 m_labels->setZValue(ChartPresenter::AxisZValue);
50 50 m_shades->setZValue(ChartPresenter::ShadesZValue);
51 51 m_grid->setZValue(ChartPresenter::GridZValue);
52 52
53 53 QObject::connect(m_chartAxis->d_ptr.data(),SIGNAL(updated()),this,SLOT(handleAxisUpdated()));
54 54
55 55 QGraphicsSimpleTextItem item;
56 56 m_font = item.font();
57 57
58 58 }
59 59
60 60 ChartAxis::~ChartAxis()
61 61 {
62 62 }
63 63
64 64 void ChartAxis::setAnimation(AxisAnimation* animation)
65 65 {
66 66 m_animation=animation;
67 67 }
68 68
69 69 void ChartAxis::setLayout(QVector<qreal> &layout)
70 70 {
71 71 m_layoutVector=layout;
72 72 }
73 73
74 74 void ChartAxis::createItems(int count)
75 75 {
76 76 if (m_arrow->children().size() == 0)
77 77 m_arrow->addToGroup(new AxisItem(this,presenter()->rootItem()));
78 78 for (int i = 0; i < count; ++i) {
79 79 m_grid->addToGroup(new QGraphicsLineItem(presenter()->rootItem()));
80 80 m_labels->addToGroup(new QGraphicsSimpleTextItem(presenter()->rootItem()));
81 81 m_arrow->addToGroup(new QGraphicsLineItem(presenter()->rootItem()));
82 82 if ((m_grid->childItems().size())%2 && m_grid->childItems().size()>2) m_shades->addToGroup(new QGraphicsRectItem(presenter()->rootItem()));
83 83 }
84 84 }
85 85
86 86 void ChartAxis::deleteItems(int count)
87 87 {
88 88 QList<QGraphicsItem *> lines = m_grid->childItems();
89 89 QList<QGraphicsItem *> labels = m_labels->childItems();
90 90 QList<QGraphicsItem *> shades = m_shades->childItems();
91 91 QList<QGraphicsItem *> axis = m_arrow->childItems();
92 92
93 93 for (int i = 0; i < count; ++i) {
94 94 if (lines.size()%2 && lines.size() > 1) delete(shades.takeLast());
95 95 delete(lines.takeLast());
96 96 delete(labels.takeLast());
97 97 delete(axis.takeLast());
98 98 }
99 99 }
100 100
101 101 void ChartAxis::updateLayout(QVector<qreal> &layout)
102 102 {
103 103 int diff = m_layoutVector.size() - layout.size();
104 104
105 105 if (diff>0) {
106 106 deleteItems(diff);
107 107 }
108 108 else if (diff<0) {
109 109 createItems(-diff);
110 110 }
111 111
112 112 if(diff<0) handleAxisUpdated();
113 113
114 114 if (m_animation) {
115 115 switch(presenter()->state()){
116 116 case ChartPresenter::ZoomInState:
117 117 m_animation->setAnimationType(AxisAnimation::ZoomInAnimation);
118 118 m_animation->setAnimationPoint(presenter()->statePoint());
119 119 break;
120 120 case ChartPresenter::ZoomOutState:
121 121 m_animation->setAnimationType(AxisAnimation::ZoomOutAnimation);
122 122 m_animation->setAnimationPoint(presenter()->statePoint());
123 123 break;
124 124 case ChartPresenter::ScrollUpState:
125 125 case ChartPresenter::ScrollLeftState:
126 126 m_animation->setAnimationType(AxisAnimation::MoveBackwordAnimation);
127 127 break;
128 128 case ChartPresenter::ScrollDownState:
129 129 case ChartPresenter::ScrollRightState:
130 130 m_animation->setAnimationType(AxisAnimation::MoveForwardAnimation);
131 131 break;
132 132 case ChartPresenter::ShowState:
133 133 m_animation->setAnimationType(AxisAnimation::DefaultAnimation);
134 134 break;
135 135 }
136 136 m_animation->setValues(m_layoutVector,layout);
137 137 presenter()->startAnimation(m_animation);
138 138 }
139 139 else {
140 140 setLayout(layout);
141 141 updateGeometry();
142 142 checkLayout();
143 143 }
144 144 }
145 145
146 146 void ChartAxis::setArrowOpacity(qreal opacity)
147 147 {
148 148 m_arrow->setOpacity(opacity);
149 149 }
150 150
151 151 qreal ChartAxis::arrowOpacity() const
152 152 {
153 153 return m_arrow->opacity();
154 154 }
155 155
156 156 void ChartAxis::setArrowVisibility(bool visible)
157 157 {
158 158 m_arrow->setOpacity(visible);
159 159 }
160 160
161 161 void ChartAxis::setGridOpacity(qreal opacity)
162 162 {
163 163 m_grid->setOpacity(opacity);
164 164 }
165 165
166 166 qreal ChartAxis::gridOpacity() const
167 167 {
168 168 return m_grid->opacity();
169 169 }
170 170
171 171 void ChartAxis::setGridVisibility(bool visible)
172 172 {
173 173 m_grid->setOpacity(visible);
174 174 }
175 175
176 176 void ChartAxis::setLabelsOpacity(qreal opacity)
177 177 {
178 178 m_labels->setOpacity(opacity);
179 179 }
180 180
181 181 qreal ChartAxis::labelsOpacity() const
182 182 {
183 183 return m_labels->opacity();
184 184 }
185 185
186 186 void ChartAxis::setLabelsVisibility(bool visible)
187 187 {
188 188 m_labels->setOpacity(visible);
189 189 }
190 190
191 191 void ChartAxis::setShadesOpacity(qreal opacity)
192 192 {
193 193 m_shades->setOpacity(opacity);
194 194 }
195 195
196 196 qreal ChartAxis::shadesOpacity() const
197 197 {
198 198 return m_shades->opacity();
199 199 }
200 200
201 201 void ChartAxis::setShadesVisibility(bool visible)
202 202 {
203 203 m_shades->setVisible(visible);
204 204 }
205 205
206 206 void ChartAxis::setLabelsAngle(int angle)
207 207 {
208 208 foreach(QGraphicsItem* item , m_labels->childItems()) {
209 209 item->setRotation(angle);
210 210 }
211 211
212 212 m_labelsAngle=angle;
213 213 }
214 214
215 215 void ChartAxis::setLabelsPen(const QPen &pen)
216 216 {
217 217 foreach(QGraphicsItem* item , m_labels->childItems()) {
218 218 static_cast<QGraphicsSimpleTextItem*>(item)->setPen(pen);
219 219 }
220 220 }
221 221
222 222 void ChartAxis::setLabelsBrush(const QBrush &brush)
223 223 {
224 224 foreach(QGraphicsItem* item , m_labels->childItems()) {
225 225 static_cast<QGraphicsSimpleTextItem*>(item)->setBrush(brush);
226 226 }
227 227 }
228 228
229 229 void ChartAxis::setLabelsFont(const QFont &font)
230 230 {
231 231 foreach(QGraphicsItem* item , m_labels->childItems()) {
232 232 static_cast<QGraphicsSimpleTextItem*>(item)->setFont(font);
233 233 }
234 234 m_font = font;
235 235 }
236 236
237 237 void ChartAxis::setShadesBrush(const QBrush &brush)
238 238 {
239 239 foreach(QGraphicsItem* item , m_shades->childItems()) {
240 240 static_cast<QGraphicsRectItem*>(item)->setBrush(brush);
241 241 }
242 242 }
243 243
244 244 void ChartAxis::setShadesPen(const QPen &pen)
245 245 {
246 246 foreach(QGraphicsItem* item , m_shades->childItems()) {
247 247 static_cast<QGraphicsRectItem*>(item)->setPen(pen);
248 248 }
249 249 }
250 250
251 251 void ChartAxis::setArrowPen(const QPen &pen)
252 252 {
253 253 foreach(QGraphicsItem* item , m_arrow->childItems()) {
254 254 static_cast<QGraphicsLineItem*>(item)->setPen(pen);
255 255 }
256 256 }
257 257
258 258 void ChartAxis::setGridPen(const QPen &pen)
259 259 {
260 260 foreach(QGraphicsItem* item , m_grid->childItems()) {
261 261 static_cast<QGraphicsLineItem*>(item)->setPen(pen);
262 262 }
263 263 }
264 264
265 265 bool ChartAxis::isEmpty()
266 266 {
267 267 return m_rect.isEmpty() || qFuzzyIsNull(m_min - m_max);
268 268 }
269 269
270 270 void ChartAxis::handleDomainUpdated()
271 271 {
272 272 Domain* domain = qobject_cast<Domain*>(sender());
273 273 qreal min(0);
274 274 qreal max(0);
275 275
276 276 if(m_chartAxis->orientation()==Qt::Horizontal) {
277 277 min = domain->minX();
278 278 max = domain->maxX();
279 279 }
280 280 else if (m_chartAxis->orientation()==Qt::Vertical)
281 281 {
282 282 min = domain->minY();
283 283 max = domain->maxY();
284 284 }
285 285
286 286 if (!qFuzzyIsNull(m_min - min) || !qFuzzyIsNull(m_max - max))
287 287 {
288 288 m_min = min;
289 289 m_max = max;
290 290
291 291 if (!isEmpty()) {
292 292 QVector<qreal> layout = calculateLayout();
293 293 updateLayout(layout);
294 294 }
295 295 }
296 296 }
297 297
298 298 void ChartAxis::handleAxisUpdated()
299 299 {
300 300 if(isEmpty()) return;
301 301
302 302
303 303 bool visible = m_chartAxis->isVisible();
304 304
305 305 setArrowVisibility(visible && m_chartAxis->isLineVisible());
306 306 setGridVisibility(visible && m_chartAxis->isGridLineVisible());
307 307 setLabelsVisibility(visible && m_chartAxis->labelsVisible());
308 308 setShadesVisibility(visible && m_chartAxis->shadesVisible());
309 309 setLabelsAngle(m_chartAxis->labelsAngle());
310 310 setArrowPen(m_chartAxis->linePen());
311 311 setLabelsPen(m_chartAxis->labelsPen());
312 312 setLabelsBrush(m_chartAxis->labelsBrush());
313 313 setLabelsFont(m_chartAxis->labelsFont());
314 314 setGridPen(m_chartAxis->gridLinePen());
315 315 setShadesPen(m_chartAxis->shadesPen());
316 316 setShadesBrush(m_chartAxis->shadesBrush());
317 317
318 318 }
319 319
320 320 void ChartAxis::hide()
321 321 {
322 322 setArrowVisibility(false);
323 323 setGridVisibility(false);
324 324 setLabelsVisibility(false);
325 325 setShadesVisibility(false);
326 326 }
327 327
328 328 void ChartAxis::handleGeometryChanged(const QRectF &rect)
329 329 {
330 330 if(m_rect != rect)
331 331 {
332 332 m_rect = rect;
333 333 if (isEmpty()) return;
334 334 QVector<qreal> layout = calculateLayout();
335 335 updateLayout(layout);
336 336 }
337 337 }
338 338
339 339
340 340 qreal ChartAxis::minimumWidth()
341 341 {
342 342 if(m_minWidth == 0) updateGeometry();
343 343 return m_minWidth;
344 344 }
345 345
346 346 qreal ChartAxis::minimumHeight()
347 347 {
348 348 if(m_minHeight == 0) updateGeometry();
349 349 return m_minHeight;
350 350 }
351 351
352 352
353 353 void ChartAxis::axisSelected()
354 354 {
355 qDebug()<<"TODO: axis clicked";
355
356 356 }
357 357
358 358
359 359 void ChartAxis::createNumberLabels(QStringList &labels,qreal min, qreal max, int ticks) const
360 360 {
361 361 Q_ASSERT(max>min);
362 362 Q_ASSERT(ticks>1);
363 363
364 364 int n = qMax(int(-qFloor(log10((max-min)/(ticks-1)))),0);
365 365 n++;
366 366
367 367 QValueAxis *axis = qobject_cast<QValueAxis *>(m_chartAxis);
368 368
369 369 QString format = axis->labelFormat();
370 370
371 371 if(format.isNull()) {
372 372 for (int i=0; i< ticks; i++) {
373 373 qreal value = min + (i * (max - min)/ (ticks-1));
374 374 labels << QString::number(value,'f',n);
375 375 }
376 376 }
377 377 else {
378 378 QByteArray array = format.toAscii();
379 379 for (int i=0; i< ticks; i++) {
380 380 qreal value = min + (i * (max - min)/ (ticks-1));
381 381 labels << QString().sprintf(array, value);
382 382 }
383 383 }
384 384 }
385 385
386 386 void ChartAxis::checkLayout()
387 387 {
388 388 if(m_minWidth > m_rect.width()) {
389 389 presenter()->layout()->invalidate();
390 390 }
391 391
392 392 if(m_minHeight > m_rect.height()) {
393 393 presenter()->layout()->invalidate();
394 394 }
395 395 }
396 396
397 397 #include "moc_chartaxis_p.cpp"
398 398
399 399 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,136 +1,135
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "chartdatetimeaxisx_p.h"
22 22 #include "chartpresenter_p.h"
23 23 #include "qdatetimeaxis.h"
24 24 #include <QGraphicsLayout>
25 25 #include <QDateTime>
26 26 #include <QFontMetrics>
27 27 #include <qmath.h>
28 28
29 29
30 30 static int label_padding = 5;
31 31
32 32 QTCOMMERCIALCHART_BEGIN_NAMESPACE
33 33
34 34 ChartDateTimeAxisX::ChartDateTimeAxisX(QAbstractAxis *axis,ChartPresenter *presenter) : ChartAxis(axis,presenter),
35 35 m_tickCount(0)
36 36 {
37 37 }
38 38
39 39 ChartDateTimeAxisX::~ChartDateTimeAxisX()
40 40 {
41 41 }
42 42
43 43 void ChartDateTimeAxisX::createLabels(QStringList &labels,qreal min, qreal max, int ticks)
44 44 {
45 45 Q_ASSERT(max>min);
46 46 Q_ASSERT(ticks>1);
47 47
48 48 QDateTimeAxis *axis = qobject_cast<QDateTimeAxis *>(m_chartAxis);
49 49
50 50 int n = qMax(int(-floor(log10((max-min)/(ticks-1)))),0);
51 51 n++;
52 52 for (int i=0; i< ticks; i++) {
53 53 qreal value = min + (i * (max - min)/ (ticks-1));
54 54 labels << QDateTime::fromMSecsSinceEpoch(value).toString(axis->format());
55 55 }
56 56 }
57 57
58 58 QVector<qreal> ChartDateTimeAxisX::calculateLayout() const
59 59 {
60 60 Q_ASSERT(m_tickCount>=2);
61 61
62 62 QVector<qreal> points;
63 63 points.resize(m_tickCount);
64 64
65 65 const qreal deltaX = m_rect.width()/(m_tickCount-1);
66 66 for (int i = 0; i < m_tickCount; ++i) {
67 67 int x = i * deltaX + m_rect.left();
68 68 points[i] = x;
69 69 }
70 70 return points;
71 71 }
72 72
73 73 void ChartDateTimeAxisX::updateGeometry()
74 74 {
75 75 const QVector<qreal>& layout = ChartAxis::layout();
76 76
77 77 m_minWidth = 0;
78 78 m_minHeight = 0;
79 79
80 80 if(layout.isEmpty()) return;
81 81
82 82 QStringList ticksList;
83 83
84 84 createLabels(ticksList,m_min,m_max,layout.size());
85 85
86 86 QList<QGraphicsItem *> lines = m_grid->childItems();
87 87 QList<QGraphicsItem *> labels = m_labels->childItems();
88 88 QList<QGraphicsItem *> shades = m_shades->childItems();
89 89 QList<QGraphicsItem *> axis = m_arrow->childItems();
90 90
91 91 Q_ASSERT(labels.size() == ticksList.size());
92 92 Q_ASSERT(layout.size() == ticksList.size());
93 93
94 94 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(axis.at(0));
95 95 lineItem->setLine(m_rect.left(), m_rect.bottom(), m_rect.right(), m_rect.bottom());
96 96
97 97 qreal width = 0;
98 98 for (int i = 0; i < layout.size(); ++i) {
99 99 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(lines.at(i));
100 100 lineItem->setLine(layout[i], m_rect.top(), layout[i], m_rect.bottom());
101 101 QGraphicsSimpleTextItem *labelItem = static_cast<QGraphicsSimpleTextItem*>(labels.at(i));
102 102 labelItem->setText(ticksList.at(i));
103 103 const QRectF& rect = labelItem->boundingRect();
104 104 QPointF center = rect.center();
105 105 labelItem->setTransformOriginPoint(center.x(), center.y());
106 106 labelItem->setPos(layout[i] - center.x(), m_rect.bottom() + label_padding);
107 107
108 108 if(labelItem->pos().x()<=width){
109 109 labelItem->setVisible(false);
110 110 lineItem->setVisible(false);
111 111 }else{
112 112 labelItem->setVisible(true);
113 113 lineItem->setVisible(true);
114 114 width=rect.width()+labelItem->pos().x();
115 115 }
116 116 m_minWidth+=rect.width();
117 117 m_minHeight=qMax(rect.height(),m_minHeight);
118 118
119 119 if ((i+1)%2 && i>1) {
120 120 QGraphicsRectItem *rectItem = static_cast<QGraphicsRectItem*>(shades.at(i/2-1));
121 121 rectItem->setRect(layout[i-1],m_rect.top(),layout[i]-layout[i-1],m_rect.height());
122 122 }
123 123 lineItem = static_cast<QGraphicsLineItem*>(axis.at(i+1));
124 124 lineItem->setLine(layout[i],m_rect.bottom(),layout[i],m_rect.bottom()+5);
125 125 }
126 126 }
127 127
128 128 void ChartDateTimeAxisX::handleAxisUpdated()
129 129 {
130 //TODO:: fix this
131 130 QDateTimeAxis* axis = qobject_cast<QDateTimeAxis*>(m_chartAxis);
132 131 m_tickCount = axis->tickCount();
133 132 ChartAxis::handleAxisUpdated();
134 133 }
135 134
136 135 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,142 +1,141
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "chartdatetimeaxisy_p.h"
22 22 #include "chartpresenter_p.h"
23 23 #include "qdatetimeaxis.h"
24 24 #include <QGraphicsLayout>
25 25 #include <QFontMetrics>
26 26 #include <QDateTime>
27 27 #include <qmath.h>
28 28
29 29
30 30 static int label_padding = 5;
31 31
32 32 QTCOMMERCIALCHART_BEGIN_NAMESPACE
33 33
34 34 ChartDateTimeAxisY::ChartDateTimeAxisY(QAbstractAxis *axis,ChartPresenter *presenter) : ChartAxis(axis,presenter),
35 35 m_tickCount(0)
36 36 {
37 37 }
38 38
39 39 ChartDateTimeAxisY::~ChartDateTimeAxisY()
40 40 {
41 41 }
42 42
43 43 void ChartDateTimeAxisY::createLabels(QStringList &labels,qreal min, qreal max, int ticks)
44 44 {
45 45 Q_ASSERT(max>min);
46 46 Q_ASSERT(ticks>1);
47 47
48 48 QDateTimeAxis *axis = qobject_cast<QDateTimeAxis *>(m_chartAxis);
49 49
50 50 int n = qMax(int(-floor(log10((max-min)/(ticks-1)))),0);
51 51 n++;
52 52 for (int i=0; i< ticks; i++) {
53 53 qreal value = min + (i * (max - min)/ (ticks-1));
54 54 labels << QDateTime::fromMSecsSinceEpoch(value).toString(axis->format());
55 55 }
56 56 }
57 57
58 58 QVector<qreal> ChartDateTimeAxisY::calculateLayout() const
59 59 {
60 60 Q_ASSERT(m_tickCount>=2);
61 61
62 62 QVector<qreal> points;
63 63 points.resize(m_tickCount);
64 64
65 65 const qreal deltaY = m_rect.height()/(m_tickCount-1);
66 66 for (int i = 0; i < m_tickCount; ++i) {
67 67 int y = i * -deltaY + m_rect.bottom();
68 68 points[i] = y;
69 69 }
70 70
71 71 return points;
72 72 }
73 73
74 74 void ChartDateTimeAxisY::updateGeometry()
75 75 {
76 76 const QVector<qreal> &layout = ChartAxis::layout();
77 77 m_minWidth = 0;
78 78 m_minHeight = 0;
79 79
80 80 if(layout.isEmpty()) return;
81 81
82 82 QStringList ticksList;
83 83
84 84 createLabels(ticksList,m_min,m_max,layout.size());
85 85
86 86 QList<QGraphicsItem *> lines = m_grid->childItems();
87 87 QList<QGraphicsItem *> labels = m_labels->childItems();
88 88 QList<QGraphicsItem *> shades = m_shades->childItems();
89 89 QList<QGraphicsItem *> axis = m_arrow->childItems();
90 90
91 91 Q_ASSERT(labels.size() == ticksList.size());
92 92 Q_ASSERT(layout.size() == ticksList.size());
93 93
94 94 qreal height = 2*m_rect.bottom();
95 95
96 96 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(axis.at(0));
97 97 lineItem->setLine(m_rect.left() , m_rect.top(), m_rect.left(), m_rect.bottom());
98 98
99 99 for (int i = 0; i < layout.size(); ++i) {
100 100 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(lines.at(i));
101 101 lineItem->setLine(m_rect.left() , layout[i], m_rect.right(), layout[i]);
102 102 QGraphicsSimpleTextItem *labelItem = static_cast<QGraphicsSimpleTextItem*>(labels.at(i));
103 103
104 104 labelItem->setText(ticksList.at(i));
105 105 const QRectF& rect = labelItem->boundingRect();
106 106
107 107 QPointF center = rect.center();
108 108 labelItem->setTransformOriginPoint(center.x(), center.y());
109 109 labelItem->setPos(m_rect.left() - rect.width() - label_padding , layout[i]-center.y());
110 110
111 111 if(labelItem->pos().y()+rect.height()>height) {
112 112 labelItem->setVisible(false);
113 113 lineItem->setVisible(false);
114 114 }
115 115 else {
116 116 labelItem->setVisible(true);
117 117 lineItem->setVisible(true);
118 118 height=labelItem->pos().y();
119 119 }
120 120
121 121 m_minWidth=qMax(rect.width()+label_padding,m_minWidth);
122 122 m_minHeight+=rect.height();
123 123
124 124 if ((i+1)%2 && i>1) {
125 125 QGraphicsRectItem *rectItem = static_cast<QGraphicsRectItem*>(shades.at(i/2-1));
126 126 rectItem->setRect(m_rect.left(),layout[i],m_rect.width(),layout[i-1]-layout[i]);
127 127 }
128 128 lineItem = static_cast<QGraphicsLineItem*>(axis.at(i+1));
129 129 lineItem->setLine(m_rect.left()-5,layout[i],m_rect.left(),layout[i]);
130 130 }
131 131 }
132 132
133 133 void ChartDateTimeAxisY::handleAxisUpdated()
134 134 {
135 //TODO:: fix this
136 135 QDateTimeAxis* axis = qobject_cast<QDateTimeAxis*>(m_chartAxis);
137 136 m_tickCount = axis->tickCount();
138 137 ChartAxis::handleAxisUpdated();
139 138 }
140 139
141 140
142 141 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,70 +1,70
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 // W A R N I N G
22 22 // -------------
23 23 //
24 24 // This file is not part of the QtCommercial Chart API. It exists purely as an
25 25 // implementation detail. This header file may change from version to
26 26 // version without notice, or even be removed.
27 27 //
28 28 // We mean it.
29 29
30 30 #ifndef QDATETIMEAXIS_P_H
31 31 #define QDATETIMEAXIS_P_H
32 32
33 33 #include "qdatetimeaxis.h"
34 34 #include "qabstractaxis_p.h"
35 35 #include <QDateTime>
36 36
37 37 QTCOMMERCIALCHART_BEGIN_NAMESPACE
38 38
39 39 class QDateTimeAxisPrivate : public QAbstractAxisPrivate
40 40 {
41 41 Q_OBJECT
42 42 public:
43 43 QDateTimeAxisPrivate(QDateTimeAxis *q);
44 44 ~QDateTimeAxisPrivate();
45 45
46 46 public:
47 47 ChartAxis* createGraphics(ChartPresenter* presenter);
48 48 void intializeDomain(Domain* domain);
49 49 void handleDomainUpdated();
50 50 qreal min(){ return m_min.toMSecsSinceEpoch(); }
51 51 qreal max(){ return m_max.toMSecsSinceEpoch(); }
52 int count() const { /*TODO:*/ return 0;}
52 int count() const { return 0;}
53 53
54 54 protected:
55 55 void setMin(const QVariant &min);
56 56 void setMax(const QVariant &max);
57 57 void setRange(const QVariant &min, const QVariant &max);
58 58 int tickCount() const;
59 59
60 60 protected:
61 61 QDateTime m_min;
62 62 QDateTime m_max;
63 63 int m_tickCount;
64 64 QString m_format;
65 65 Q_DECLARE_PUBLIC(QDateTimeAxis)
66 66 };
67 67
68 68 QTCOMMERCIALCHART_END_NAMESPACE
69 69
70 70 #endif // QDATETIMEAXIS_P_H
@@ -1,121 +1,120
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "chartvalueaxisx_p.h"
22 22 #include "qabstractaxis.h"
23 23 #include "chartpresenter_p.h"
24 24 #include "qvalueaxis.h"
25 25 #include <QGraphicsLayout>
26 26 #include <QFontMetrics>
27 27 #include <qmath.h>
28 28
29 29 static int label_padding = 5;
30 30
31 31 QTCOMMERCIALCHART_BEGIN_NAMESPACE
32 32
33 33 ChartValueAxisX::ChartValueAxisX(QAbstractAxis *axis,ChartPresenter *presenter) : ChartAxis(axis,presenter),
34 34 m_tickCount(0)
35 35 {
36 36 }
37 37
38 38 ChartValueAxisX::~ChartValueAxisX()
39 39 {
40 40 }
41 41
42 42 QVector<qreal> ChartValueAxisX::calculateLayout() const
43 43 {
44 44 Q_ASSERT(m_tickCount>=2);
45 45
46 46 QVector<qreal> points;
47 47 points.resize(m_tickCount);
48 48
49 49 const qreal deltaX = m_rect.width()/(m_tickCount-1);
50 50 for (int i = 0; i < m_tickCount; ++i) {
51 51 int x = i * deltaX + m_rect.left();
52 52 points[i] = x;
53 53 }
54 54 return points;
55 55 }
56 56
57 57 void ChartValueAxisX::updateGeometry()
58 58 {
59 59 const QVector<qreal>& layout = ChartAxis::layout();
60 60
61 61 m_minWidth = 0;
62 62 m_minHeight = 0;
63 63
64 64 if(layout.isEmpty()) return;
65 65
66 66 QStringList ticksList;
67 67
68 68 createNumberLabels(ticksList,m_min,m_max,layout.size());
69 69
70 70 QList<QGraphicsItem *> lines = m_grid->childItems();
71 71 QList<QGraphicsItem *> labels = m_labels->childItems();
72 72 QList<QGraphicsItem *> shades = m_shades->childItems();
73 73 QList<QGraphicsItem *> axis = m_arrow->childItems();
74 74
75 75 Q_ASSERT(labels.size() == ticksList.size());
76 76 Q_ASSERT(layout.size() == ticksList.size());
77 77
78 78 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(axis.at(0));
79 79 lineItem->setLine(m_rect.left(), m_rect.bottom(), m_rect.right(), m_rect.bottom());
80 80
81 81 qreal width = 0;
82 82 for (int i = 0; i < layout.size(); ++i) {
83 83 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(lines.at(i));
84 84 lineItem->setLine(layout[i], m_rect.top(), layout[i], m_rect.bottom());
85 85 QGraphicsSimpleTextItem *labelItem = static_cast<QGraphicsSimpleTextItem*>(labels.at(i));
86 86 labelItem->setText(ticksList.at(i));
87 87 const QRectF& rect = labelItem->boundingRect();
88 88 QPointF center = rect.center();
89 89 labelItem->setTransformOriginPoint(center.x(), center.y());
90 90 labelItem->setPos(layout[i] - center.x(), m_rect.bottom() + label_padding);
91 91
92 92 if(labelItem->pos().x()<=width){
93 93 labelItem->setVisible(false);
94 94 lineItem->setVisible(false);
95 95 }else{
96 96 labelItem->setVisible(true);
97 97 lineItem->setVisible(true);
98 98 width=rect.width()+labelItem->pos().x();
99 99 }
100 100 m_minWidth+=rect.width();
101 101 m_minHeight=qMax(rect.height(),m_minHeight);
102 102
103 103 if ((i+1)%2 && i>1) {
104 104 QGraphicsRectItem *rectItem = static_cast<QGraphicsRectItem*>(shades.at(i/2-1));
105 105 rectItem->setRect(layout[i-1],m_rect.top(),layout[i]-layout[i-1],m_rect.height());
106 106 }
107 107 lineItem = static_cast<QGraphicsLineItem*>(axis.at(i+1));
108 108 lineItem->setLine(layout[i],m_rect.bottom(),layout[i],m_rect.bottom()+5);
109 109 }
110 110
111 111 }
112 112
113 113 void ChartValueAxisX::handleAxisUpdated()
114 114 {
115 //TODO:: fix this
116 115 QValueAxis* axis = qobject_cast<QValueAxis*>(m_chartAxis);
117 116 m_tickCount = axis->tickCount();
118 117 ChartAxis::handleAxisUpdated();
119 118 }
120 119
121 120 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,127 +1,126
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "chartvalueaxisy_p.h"
22 22 #include "qabstractaxis.h"
23 23 #include "chartpresenter_p.h"
24 24 #include "qvalueaxis.h"
25 25 #include <QGraphicsLayout>
26 26 #include <QFontMetrics>
27 27 #include <qmath.h>
28 28
29 29 static int label_padding = 5;
30 30
31 31 QTCOMMERCIALCHART_BEGIN_NAMESPACE
32 32
33 33 ChartValueAxisY::ChartValueAxisY(QAbstractAxis *axis,ChartPresenter *presenter) : ChartAxis(axis,presenter),
34 34 m_tickCount(0)
35 35 {
36 36 }
37 37
38 38 ChartValueAxisY::~ChartValueAxisY()
39 39 {
40 40 }
41 41
42 42 QVector<qreal> ChartValueAxisY::calculateLayout() const
43 43 {
44 44 Q_ASSERT(m_tickCount>=2);
45 45
46 46 QVector<qreal> points;
47 47 points.resize(m_tickCount);
48 48
49 49 const qreal deltaY = m_rect.height()/(m_tickCount-1);
50 50 for (int i = 0; i < m_tickCount; ++i) {
51 51 int y = i * -deltaY + m_rect.bottom();
52 52 points[i] = y;
53 53 }
54 54
55 55 return points;
56 56 }
57 57
58 58 void ChartValueAxisY::updateGeometry()
59 59 {
60 60 const QVector<qreal> &layout = ChartAxis::layout();
61 61 m_minWidth = 0;
62 62 m_minHeight = 0;
63 63
64 64 if(layout.isEmpty()) return;
65 65
66 66 QStringList ticksList;
67 67
68 68 createNumberLabels(ticksList,m_min,m_max,layout.size());
69 69
70 70 QList<QGraphicsItem *> lines = m_grid->childItems();
71 71 QList<QGraphicsItem *> labels = m_labels->childItems();
72 72 QList<QGraphicsItem *> shades = m_shades->childItems();
73 73 QList<QGraphicsItem *> axis = m_arrow->childItems();
74 74
75 75 Q_ASSERT(labels.size() == ticksList.size());
76 76 Q_ASSERT(layout.size() == ticksList.size());
77 77
78 78 qreal height = 2*m_rect.bottom();
79 79
80 80 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(axis.at(0));
81 81 lineItem->setLine(m_rect.left() , m_rect.top(), m_rect.left(), m_rect.bottom());
82 82
83 83 for (int i = 0; i < layout.size(); ++i) {
84 84 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(lines.at(i));
85 85 lineItem->setLine(m_rect.left() , layout[i], m_rect.right(), layout[i]);
86 86 QGraphicsSimpleTextItem *labelItem = static_cast<QGraphicsSimpleTextItem*>(labels.at(i));
87 87
88 88 labelItem->setText(ticksList.at(i));
89 89 const QRectF& rect = labelItem->boundingRect();
90 90
91 91 QPointF center = rect.center();
92 92 labelItem->setTransformOriginPoint(center.x(), center.y());
93 93 labelItem->setPos(m_rect.left() - rect.width() - label_padding , layout[i]-center.y());
94 94
95 95 if(labelItem->pos().y()+rect.height()>height) {
96 96 labelItem->setVisible(false);
97 97 lineItem->setVisible(false);
98 98 }
99 99 else {
100 100 labelItem->setVisible(true);
101 101 lineItem->setVisible(true);
102 102 height=labelItem->pos().y();
103 103 }
104 104
105 105 m_minWidth=qMax(rect.width()+label_padding,m_minWidth);
106 106 m_minHeight+=rect.height();
107 107
108 108 if ((i+1)%2 && i>1) {
109 109 QGraphicsRectItem *rectItem = static_cast<QGraphicsRectItem*>(shades.at(i/2-1));
110 110 rectItem->setRect(m_rect.left(),layout[i],m_rect.width(),layout[i-1]-layout[i]);
111 111 }
112 112 lineItem = static_cast<QGraphicsLineItem*>(axis.at(i+1));
113 113 lineItem->setLine(m_rect.left()-5,layout[i],m_rect.left(),layout[i]);
114 114 }
115 115
116 116 }
117 117
118 118 void ChartValueAxisY::handleAxisUpdated()
119 119 {
120 //TODO:: fix this
121 120 QValueAxis* axis = qobject_cast<QValueAxis*>(m_chartAxis);
122 121 m_tickCount = axis->tickCount();
123 122 ChartAxis::handleAxisUpdated();
124 123 }
125 124
126 125
127 126 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,496 +1,495
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "chartdataset_p.h"
22 22 #include "qchart.h"
23 23 #include "qvalueaxis.h"
24 24 #include "qbarcategoryaxis.h"
25 25 #include "qvalueaxis_p.h"
26 26 #include "qcategoryaxis.h"
27 27 #include "qabstractseries_p.h"
28 28 #include "qabstractbarseries.h"
29 29 #include "qstackedbarseries.h"
30 30 #include "qpercentbarseries.h"
31 31 #include "qpieseries.h"
32 32
33 33 #ifndef QT_ON_ARM
34 34 #include "qdatetimeaxis.h"
35 35 #endif
36 36
37 37 QTCOMMERCIALCHART_BEGIN_NAMESPACE
38 38
39 39 ChartDataSet::ChartDataSet(QChart *parent):QObject(parent)
40 40 {
41 41
42 42 }
43 43
44 44 ChartDataSet::~ChartDataSet()
45 45 {
46 46 removeAllSeries();
47 47 }
48 48
49 49 void ChartDataSet::addSeries(QAbstractSeries* series)
50 50 {
51 51 Domain* domain = m_seriesDomainMap.value(series);
52 52
53 53 if(domain) {
54 54 qWarning() << "Can not add series. Series already on the chart";
55 55 return;
56 56 }
57 57
58 58 domain = new Domain(series);
59 59 m_seriesDomainMap.insert(series,domain);
60 60 series->d_ptr->scaleDomain(*domain);
61 61
62 62 createSeriesIndex(series);
63 63
64 64 series->setParent(this); // take ownership
65 65 series->d_ptr->m_chart = qobject_cast<QChart*>(parent());
66 66 series->d_ptr->m_dataset = this;
67 67
68 68 emit seriesAdded(series,domain);
69 69
70 70 }
71 71
72 72 void ChartDataSet::removeSeries(QAbstractSeries* series)
73 73 {
74 74
75 75 if(!m_seriesDomainMap.contains(series)) {
76 76 qWarning()<<"Can not remove series. Series not found on the chart.";
77 77 return;
78 78 }
79 79
80 80 emit seriesRemoved(series);
81 81
82 82 Domain* domain = m_seriesDomainMap.take(series);
83 83 delete domain;
84 84 domain = 0;
85 85
86 86 removeSeriesIndex(series);
87 87
88 88 series->setParent(0);
89 89 series->d_ptr->m_chart = 0;
90 90 series->d_ptr->m_dataset = 0;
91 91
92 92 removeAxes(series);
93 93 }
94 94
95 95
96 96
97 97 void ChartDataSet::createSeriesIndex(QAbstractSeries* series)
98 98 {
99 99 QMapIterator<int, QAbstractSeries*> i(m_indexSeriesMap);
100 100
101 101 int key=0;
102 102 while (i.hasNext()) {
103 103 i.next();
104 104 if(i.key()!=key) {
105 105 break;
106 106 }
107 107 key++;
108 108 }
109 109
110 110 m_indexSeriesMap.insert(key,series);
111 111 }
112 112
113 113 void ChartDataSet::removeSeriesIndex(QAbstractSeries* series)
114 114 {
115 115 int key = seriesIndex(series);
116 116 Q_ASSERT(key!=-1);
117 117 m_indexSeriesMap.remove(key);
118 118 }
119 119
120 120 void ChartDataSet::createDefaultAxes()
121 121 {
122 122 if (m_seriesDomainMap.isEmpty())
123 123 return;
124 124
125 125 QAbstractAxis::AxisTypes typeX(0);
126 126 QAbstractAxis::AxisTypes typeY(0);
127 127
128 128 // Remove possibly existing axes
129 129 QMapIterator<QAbstractSeries*, Domain*> i(m_seriesDomainMap);
130 130 while (i.hasNext()) {
131 131 i.next();
132 132 removeAxes(i.key());
133 133 }
134 134
135 135 i.toFront();
136 136
137 137 // Select the required axis x and axis y types based on the types of the current series
138 138 while (i.hasNext()) {
139 139 i.next();
140 140
141 141 QAbstractAxis* axisX = m_seriesAxisXMap.value(i.key());
142 142 QAbstractAxis* axisY = m_seriesAxisYMap.value(i.key());
143 143 if(axisX) typeX&=axisX->type();
144 144 else typeX|=i.key()->d_ptr->defaultAxisType(Qt::Horizontal);
145 145 if(axisY) typeY&=axisY->type();
146 146 else typeY|=i.key()->d_ptr->defaultAxisType(Qt::Vertical);
147 147 }
148 148
149 149 // Create the axes of the types selected
150 150 createAxes(typeX, Qt::Horizontal);
151 151 createAxes(typeY, Qt::Vertical);
152 152 }
153 153
154 154 void ChartDataSet::createAxes(QAbstractAxis::AxisTypes type, Qt::Orientation orientation)
155 155 {
156 156 QMapIterator<QAbstractSeries*, Domain*> i(m_seriesDomainMap);
157 157
158 // TODO: Add a descriptive comment of what happens here
159 158 if (type.testFlag(QAbstractAxis::AxisTypeValue) && type.testFlag(QAbstractAxis::AxisTypeBarCategory)) {
160 159 while (i.hasNext()) {
161 160 i.next();
162 161 QAbstractAxis* axis = createAxis(i.key()->d_ptr->defaultAxisType(orientation), orientation);
163 162 if (axis) {
164 163 initializeAxis(axis, i.key());
165 164 emit axisAdded(axis, i.value());
166 165 }
167 166 }
168 167 } else if (!type.testFlag(QAbstractAxis::AxisTypeNoAxis)) {
169 168 QAbstractAxis* axis = createAxis(QAbstractAxis::AxisType(int(type)), orientation);
170 169 i.toFront();
171 170 while (i.hasNext()) {
172 171 i.next();
173 172 initializeAxis(axis,i.key());
174 173 }
175 174 emit axisAdded(axis,i.value());
176 175 }
177 176 }
178 177
179 178 QAbstractAxis* ChartDataSet::createAxis(QAbstractAxis::AxisType type, Qt::Orientation orientation)
180 179 {
181 180 QAbstractAxis* axis = 0;
182 181
183 182 switch(type) {
184 183 case QAbstractAxis::AxisTypeValue:
185 184 axis = new QValueAxis(this);
186 185 break;
187 186 case QAbstractAxis::AxisTypeBarCategory:
188 187 axis = new QBarCategoryAxis(this);
189 188 break;
190 189 case QAbstractAxis::AxisTypeCategory:
191 190 axis = new QCategoryAxis(this);
192 191 break;
193 192 #ifndef Q_WS_QWS
194 193 case QAbstractAxis::AxisTypeDateTime:
195 194 axis = new QDateTimeAxis(this);
196 195 break;
197 196 #endif
198 197 default:
199 198 axis = 0;
200 199 break;
201 200 }
202 201
203 202 if(axis)
204 203 axis->d_ptr->setOrientation(orientation);
205 204
206 205 return axis;
207 206 }
208 207
209 208 void ChartDataSet::initializeAxis(QAbstractAxis* axis,QAbstractSeries* series)
210 209 {
211 210 Domain* domain = m_seriesDomainMap.value(series);
212 211 axis->d_ptr->m_dataset = this;
213 212 series->d_ptr->initializeAxis(axis);
214 213 axis->d_ptr->intializeDomain(domain);
215 214 if(axis->orientation()==Qt::Horizontal) {
216 215 QObject::connect(axis->d_ptr.data(),SIGNAL(updated()),domain,SLOT(handleAxisUpdated()));
217 216 QObject::connect(domain,SIGNAL(updated()),axis->d_ptr.data(),SLOT(handleDomainUpdated()));
218 217 m_seriesAxisXMap.insert(series,axis);
219 218 }
220 219 else {
221 220 QObject::connect(axis->d_ptr.data(),SIGNAL(updated()),domain,SLOT(handleAxisUpdated()));
222 221 QObject::connect(domain,SIGNAL(updated()),axis->d_ptr.data(),SLOT(handleDomainUpdated()));
223 222 m_seriesAxisYMap.insert(series,axis);
224 223 }
225 224 axis->d_ptr->emitUpdated();
226 225 }
227 226
228 227 void ChartDataSet::removeAxes(QAbstractSeries* series)
229 228 {
230 229 QAbstractAxis* axisX = m_seriesAxisXMap.take(series);
231 230
232 231 if(axisX) {
233 232 QList<QAbstractAxis*> axesX = m_seriesAxisXMap.values();
234 233 int x = axesX.indexOf(axisX);
235 234
236 235 if(x==-1) {
237 236 emit axisRemoved(axisX);
238 237 axisX->d_ptr->m_dataset=0;
239 238 axisX->deleteLater();
240 239 }
241 240 }
242 241
243 242 QAbstractAxis* axisY = m_seriesAxisYMap.take(series);
244 243
245 244 if(axisY) {
246 245 QList<QAbstractAxis*> axesY = m_seriesAxisYMap.values();
247 246
248 247 int y = axesY.indexOf(axisY);
249 248
250 249 if(y==-1) {
251 250 emit axisRemoved(axisY);
252 251 axisY->d_ptr->m_dataset=0;
253 252 axisY->deleteLater();
254 253 }
255 254 }
256 255 }
257 256
258 257 void ChartDataSet::removeAxis(QAbstractAxis* axis)
259 258 {
260 259 if(!axis->d_ptr->m_dataset) {
261 260 qWarning()<<"UnBound axis found !";
262 261 return;
263 262 }
264 263
265 264 QMap<QAbstractSeries*, QAbstractAxis*> *seriesAxisMap;
266 265
267 266 if(axis->orientation()==Qt::Vertical) {
268 267 seriesAxisMap= &m_seriesAxisYMap;
269 268 }
270 269 else {
271 270 seriesAxisMap= &m_seriesAxisXMap;
272 271 }
273 272
274 273 QMapIterator<QAbstractSeries*, QAbstractAxis*> i(*seriesAxisMap);
275 274
276 275 while (i.hasNext()) {
277 276 i.next();
278 277 if(i.value()==axis) {
279 278 removeSeries(i.key());
280 279 }
281 280 }
282 281 }
283 282
284 283 void ChartDataSet::removeAllSeries()
285 284 {
286 285 QList<QAbstractSeries*> series = m_seriesDomainMap.keys();
287 286 foreach(QAbstractSeries *s , series) {
288 287 removeSeries(s);
289 288 }
290 289
291 290 Q_ASSERT(m_seriesAxisXMap.count()==0);
292 291 Q_ASSERT(m_seriesAxisXMap.count()==0);
293 292 Q_ASSERT(m_seriesDomainMap.count()==0);
294 293
295 294 qDeleteAll(series);
296 295 }
297 296
298 297 void ChartDataSet::zoomInDomain(const QRectF& rect, const QSizeF& size)
299 298 {
300 299 //for performance reasons block, signals and scale "full" domain one by one. Gives twice less screen updates
301 300
302 301
303 302 blockAxisSignals(true);
304 303
305 304 QMapIterator<QAbstractSeries*, Domain*> i(m_seriesDomainMap);
306 305
307 306 while (i.hasNext()) {
308 307 i.next();
309 308 i.value()->zoomIn(rect,size);
310 309 }
311 310
312 311 blockAxisSignals(false);
313 312
314 313 }
315 314
316 315 void ChartDataSet::zoomOutDomain(const QRectF& rect, const QSizeF& size)
317 316 {
318 317 //for performance reasons block, signals and scale "full" domain one by one. Gives twice less screen updates
319 318
320 319 blockAxisSignals(true);
321 320
322 321 QMapIterator<QAbstractSeries*, Domain*> i(m_seriesDomainMap);
323 322
324 323 while (i.hasNext()) {
325 324 i.next();
326 325 i.value()->zoomOut(rect,size);
327 326 }
328 327
329 328 blockAxisSignals(false);
330 329 }
331 330
332 331 void ChartDataSet::blockAxisSignals(bool enabled)
333 332 {
334 333 QMapIterator<QAbstractSeries*, Domain*> i(m_seriesDomainMap);
335 334 while (i.hasNext()) {
336 335 i.next();
337 336 QAbstractAxis* axisX = m_seriesAxisXMap.value(i.key());
338 337 QAbstractAxis* axisY = m_seriesAxisYMap.value(i.key());
339 338 if(axisX) {
340 339 axisX->d_ptr->blockSignals(enabled);
341 340 if(!enabled) {
342 341 axisX->d_ptr->setDirty(false);
343 342 axisX->d_ptr->emitUpdated();
344 343 }
345 344 }
346 345 if(axisY) {
347 346 axisY->d_ptr->blockSignals(enabled);
348 347 if(!enabled) {
349 348 axisY->d_ptr->setDirty(false);
350 349 axisY->d_ptr->emitUpdated();
351 350 }
352 351 }
353 352 }
354 353 }
355 354
356 355 int ChartDataSet::seriesCount(QAbstractSeries::SeriesType type)
357 356 {
358 357 int count=0;
359 358 QMapIterator<QAbstractSeries*, Domain*> i(m_seriesDomainMap);
360 359 while (i.hasNext()) {
361 360 i.next();
362 361 if(i.key()->type()==type) count++;
363 362 }
364 363 return count;
365 364 }
366 365
367 366 int ChartDataSet::seriesIndex(QAbstractSeries *series)
368 367 {
369 368 QMapIterator<int, QAbstractSeries*> i(m_indexSeriesMap);
370 369 while (i.hasNext()) {
371 370 i.next();
372 371 if (i.value() == series)
373 372 return i.key();
374 373 }
375 374 return -1;
376 375 }
377 376
378 377 QAbstractAxis* ChartDataSet::axisX(QAbstractSeries *series) const
379 378 {
380 379 if(series == 0) {
381 380
382 381 QMapIterator<QAbstractSeries*, QAbstractAxis *> i(m_seriesAxisXMap);
383 382
384 383 while (i.hasNext()) {
385 384 i.next();
386 385 if(i.value()->isVisible()) return i.value();
387 386 }
388 387 return 0;
389 388 }
390 389 return m_seriesAxisXMap.value(series);
391 390 }
392 391
393 392 QAbstractAxis* ChartDataSet::axisY(QAbstractSeries *series) const
394 393 {
395 394 if(series == 0) {
396 395 QMapIterator<QAbstractSeries*, QAbstractAxis *> i(m_seriesAxisYMap);
397 396
398 397 while (i.hasNext()) {
399 398 i.next();
400 399 if(i.value()->isVisible()) return i.value();
401 400 }
402 401 return 0;
403 402 }
404 403 return m_seriesAxisYMap.value(series);
405 404 }
406 405
407 406 void ChartDataSet::setAxis(QAbstractSeries *series, QAbstractAxis *axis, Qt::Orientation orientation)
408 407 {
409 408 Q_ASSERT(axis);
410 409
411 410 if(!series) {
412 411 qWarning() << "Series not found on the chart.";
413 412 return;
414 413 }
415 414
416 415 Domain* domain = m_seriesDomainMap.value(series);
417 416
418 417 if(!domain) {
419 418 qWarning() << "Series not found on the chart.";
420 419 return;
421 420 }
422 421
423 422 if(orientation==Qt::Horizontal && axis->orientation()==Qt::Vertical) {
424 423 qWarning()<<"Axis already defined as axis Y";
425 424 return;
426 425 }
427 426
428 427 if(orientation==Qt::Vertical && axis->orientation()==Qt::Horizontal) {
429 428 qWarning()<<"Axis already defined as axis X";
430 429 return;
431 430 }
432 431
433 432 axis->d_ptr->setOrientation(orientation);
434 433
435 434 QMap<QAbstractSeries*, QAbstractAxis*> *seriesAxisMap;
436 435
437 436 if(orientation==Qt::Vertical) {
438 437 seriesAxisMap= &m_seriesAxisYMap;
439 438 }else{
440 439 seriesAxisMap= &m_seriesAxisXMap;
441 440 }
442 441
443 442 if (seriesAxisMap->value(series) == axis) {
444 443 qWarning() << "The axis already set for the series";
445 444 return;
446 445 }
447 446
448 447 QAbstractAxis *oldAxis = seriesAxisMap->take(series);
449 448 QList<QAbstractAxis*> axes = seriesAxisMap->values();
450 449 if(oldAxis) {
451 450 if(axes.indexOf(oldAxis)==-1) {
452 451 emit axisRemoved(oldAxis);
453 452 oldAxis->disconnect();
454 453 QObject::disconnect(domain,0,oldAxis,0);
455 454 oldAxis->d_ptr->m_dataset=0;
456 455 oldAxis->deleteLater();
457 456 }
458 457 }
459 458
460 459 if(axes.indexOf(axis)==-1) {
461 460 initializeAxis(axis,series);
462 461 emit axisAdded(axis,domain);
463 462 }else{
464 463 initializeAxis(axis,series);
465 464 }
466 465 }
467 466
468 467 Domain* ChartDataSet::domain(QAbstractSeries *series) const
469 468 {
470 469 return m_seriesDomainMap.value(series);
471 470 }
472 471
473 472 void ChartDataSet::scrollDomain(qreal dx,qreal dy,const QSizeF& size)
474 473 {
475 474 blockAxisSignals(true);
476 475 QMapIterator<QAbstractSeries*, Domain*> i(m_seriesDomainMap);
477 476 while (i.hasNext()) {
478 477 i.next();
479 478 i.value()->move(dx,dy,size);
480 479 }
481 480 blockAxisSignals(false);
482 481 }
483 482
484 483 QList<QAbstractSeries*> ChartDataSet::series() const
485 484 {
486 485 return m_seriesDomainMap.keys();
487 486 }
488 487
489 488 void ChartDataSet::updateSeries(QAbstractSeries *series)
490 489 {
491 490 emit seriesUpdated(series);
492 491 }
493 492
494 493 #include "moc_chartdataset_p.cpp"
495 494
496 495 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,180 +1,179
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "chartlayout_p.h"
22 22 #include "chartpresenter_p.h"
23 23 #include "qlegend_p.h"
24 24 #include "chartaxis_p.h"
25 25 #include <QDebug>
26 26
27 27 QTCOMMERCIALCHART_BEGIN_NAMESPACE
28 28
29 29 ChartLayout::ChartLayout(ChartPresenter* presenter):
30 30 m_presenter(presenter),
31 31 m_marginBig(60),
32 32 m_marginSmall(20),
33 33 m_marginTiny(10),
34 34 m_chartMargins(m_marginBig,m_marginBig,m_marginBig,m_marginBig),
35 35 m_intialized(false)
36 36 {
37 37
38 38 }
39 39
40 40 ChartLayout::~ChartLayout()
41 41 {
42 42
43 43 }
44 44
45 45 void ChartLayout::setGeometry(const QRectF& rect)
46 46 {
47 47
48 48 if (!rect.isValid()) return;
49 49
50 50 QGraphicsLayout::setGeometry(rect);
51 51
52 52 if(!m_intialized){
53 53 m_presenter->setGeometry(rect);
54 54 m_intialized=true;
55 55 }
56 56
57 57 // check title size
58 58
59 59 QSize titleSize = QSize(0,0);
60 60
61 61 if (m_presenter->titleItem()) {
62 62 titleSize= m_presenter->titleItem()->boundingRect().size().toSize();
63 63 }
64 64
65 65 qreal axisHeight = 0;
66 66 qreal axisWidth = 0;
67 67
68 68 // check axis size
69 69
70 70 foreach (ChartAxis* axis,m_presenter->axisItems()){
71 71 if(axis->axisType() == ChartAxis::X_AXIS)
72 72 axisHeight = qMax(axis->minimumHeight(),axisHeight);
73 73 else
74 74 axisWidth = qMax(axis->minimumWidth(),axisWidth);
75 75 }
76 76
77 77 QLegend* legend = m_presenter->legend();
78 78 Q_ASSERT(legend);
79 79
80 80 qreal titlePadding = m_chartMargins.top()/2;
81 81
82 82 QMargins chartMargins = m_chartMargins;
83 83
84 //TODO multiple axis handling;
85 84 chartMargins.setLeft(qMax(m_chartMargins.left(),int(axisWidth + 2*m_marginTiny)));
86 85 chartMargins.setBottom(qMax(m_chartMargins.bottom(),int(axisHeight + 2* m_marginTiny)));
87 86
88 87
89 88 // recalculate legend position
90 89 if ((legend->isAttachedToChart() && legend->isVisible())) {
91 90
92 91 // Reserve some space for legend
93 92 switch (legend->alignment()) {
94 93
95 94 case Qt::AlignTop: {
96 95
97 96 QSizeF legendSize = legend->effectiveSizeHint(Qt::PreferredSize,QSizeF(rect.width(),-1));
98 97 int topMargin = qMax(2*m_marginTiny + titleSize.height() + legendSize.height() + m_marginTiny,qreal(chartMargins.top()));
99 98 chartMargins = QMargins(chartMargins.left(),topMargin,chartMargins.right(),chartMargins.bottom());
100 99 m_legendMargins = QMargins(chartMargins.left(),topMargin - (legendSize.height() + m_marginTiny),chartMargins.right(),rect.height()-topMargin + m_marginTiny);
101 100 titlePadding = m_marginTiny + m_marginTiny;
102 101 break;
103 102 }
104 103 case Qt::AlignBottom: {
105 104 QSizeF legendSize = legend->effectiveSizeHint(Qt::PreferredSize,QSizeF(rect.width(),-1));
106 105 int bottomMargin = qMax(m_marginTiny + legendSize.height() + m_marginTiny + axisHeight,qreal(chartMargins.bottom()));
107 106 chartMargins = QMargins(chartMargins.left(),chartMargins.top(),chartMargins.right(),bottomMargin);
108 107 m_legendMargins = QMargins(chartMargins.left(),rect.height()-bottomMargin + m_marginTiny + axisHeight,chartMargins.right(),m_marginTiny + m_marginSmall);
109 108 titlePadding = chartMargins.top()/2;
110 109 break;
111 110 }
112 111 case Qt::AlignLeft: {
113 112 QSizeF legendSize = legend->effectiveSizeHint(Qt::PreferredSize,QSizeF(-1,rect.height()));
114 113 int leftPadding = qMax(m_marginTiny + legendSize.width() + m_marginTiny + axisWidth,qreal(chartMargins.left()));
115 114 chartMargins = QMargins(leftPadding,chartMargins.top(),chartMargins.right(),chartMargins.bottom());
116 115 m_legendMargins = QMargins(m_marginTiny + m_marginSmall,chartMargins.top(),rect.width()-leftPadding + m_marginTiny + axisWidth,chartMargins.bottom());
117 116 titlePadding = chartMargins.top()/2;
118 117 break;
119 118 }
120 119 case Qt::AlignRight: {
121 120 QSizeF legendSize = legend->effectiveSizeHint(Qt::PreferredSize,QSizeF(-1,rect.height()));
122 121 int rightPadding = qMax(m_marginTiny + legendSize.width() + m_marginTiny,qreal(chartMargins.right()));
123 122 chartMargins = QMargins(chartMargins.left(),chartMargins.top(),rightPadding,chartMargins.bottom());
124 123 m_legendMargins = QMargins(rect.width()- rightPadding+ m_marginTiny ,chartMargins.top(),m_marginTiny + m_marginSmall,chartMargins.bottom());
125 124 titlePadding = chartMargins.top()/2;
126 125 break;
127 126 }
128 127 default: {
129 128 break;
130 129 }
131 130 }
132 131
133 132 legend->setGeometry(rect.adjusted(m_legendMargins.left(),m_legendMargins.top(),-m_legendMargins.right(),-m_legendMargins.bottom()));
134 133 }
135 134
136 135 // recalculate title position
137 136 if (m_presenter->titleItem()) {
138 137 QPointF center = rect.center() - m_presenter->titleItem()->boundingRect().center();
139 138 m_presenter->titleItem()->setPos(center.x(),titlePadding);
140 139 }
141 140
142 141 //recalculate background gradient
143 142 if (m_presenter->backgroundItem()) {
144 143 m_presenter->backgroundItem()->setRect(rect.adjusted(m_marginTiny,m_marginTiny, -m_marginTiny, -m_marginTiny));
145 144 }
146 145
147 146 QRectF chartRect = rect.adjusted(chartMargins.left(),chartMargins.top(),-chartMargins.right(),-chartMargins.bottom());
148 147
149 148 if(m_presenter->geometry()!=chartRect && chartRect.isValid()){
150 149 m_presenter->setGeometry(chartRect);
151 150 }else if(chartRect.size().isEmpty()){
152 151 m_presenter->setGeometry(QRect(rect.width()/2,rect.height()/2,1,1));
153 152 }
154 153 }
155 154
156 155
157 156 QSizeF ChartLayout::sizeHint ( Qt::SizeHint which, const QSizeF & constraint) const
158 157 {
159 158 Q_UNUSED(constraint);
160 159 if(which == Qt::MinimumSize)
161 160 return QSize(2*(m_chartMargins.top()+m_chartMargins.bottom()),2*(m_chartMargins.top() + m_chartMargins.bottom()));
162 161 else
163 162 return QSize(-1,-1);
164 163 }
165 164
166 165 void ChartLayout::setMinimumMargins(const QMargins& margins)
167 166 {
168 167
169 168 if(m_chartMargins != margins){
170 169 m_chartMargins = margins;
171 170 updateGeometry();
172 171 }
173 172 }
174 173
175 174 QMargins ChartLayout::minimumMargins() const
176 175 {
177 176 return m_chartMargins;
178 177 }
179 178
180 179 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,177 +1,177
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 // W A R N I N G
22 22 // -------------
23 23 //
24 24 // This file is not part of the QtCommercial Chart API. It exists purely as an
25 25 // implementation detail. This header file may change from version to
26 26 // version without notice, or even be removed.
27 27 //
28 28 // We mean it.
29 29
30 30 #ifndef CHARTPRESENTER_H
31 31 #define CHARTPRESENTER_H
32 32
33 33 #include "qchartglobal.h"
34 #include "qchart.h" //becouse of QChart::ChartThemeId //TODO
34 #include "qchart.h"
35 35 #include <QRectF>
36 36 #include <QMargins>
37 37
38 38 QTCOMMERCIALCHART_BEGIN_NAMESPACE
39 39
40 40 class ChartElement;
41 41 class QAbstractSeries;
42 42 class ChartDataSet;
43 43 class Domain;
44 44 class ChartAxis;
45 45 class ChartTheme;
46 46 class ChartAnimator;
47 47 class ChartBackground;
48 48 class ChartAnimation;
49 49 class ChartLayout;
50 50
51 51 class ChartPresenter: public QObject
52 52 {
53 53 Q_OBJECT
54 54 public:
55 55 enum ZValues {
56 56 BackgroundZValue = -1,
57 57 ShadesZValue ,
58 58 GridZValue,
59 59 AxisZValue,
60 60 SeriesZValue,
61 61 LineChartZValue = SeriesZValue,
62 62 SplineChartZValue = SeriesZValue,
63 63 BarSeriesZValue = SeriesZValue,
64 64 ScatterSeriesZValue = SeriesZValue,
65 65 PieSeriesZValue = SeriesZValue,
66 66 LegendZValue,
67 67 TopMostZValue
68 68 };
69 69
70 70 enum State {
71 71 ShowState,
72 72 ScrollUpState,
73 73 ScrollDownState,
74 74 ScrollLeftState,
75 75 ScrollRightState,
76 76 ZoomInState,
77 77 ZoomOutState
78 78 };
79 79
80 80 ChartPresenter(QChart* chart,ChartDataSet *dataset);
81 81 virtual ~ChartPresenter();
82 82
83 83 ChartTheme *chartTheme() const { return m_chartTheme; }
84 84 ChartDataSet *dataSet() const { return m_dataset; }
85 85 QGraphicsItem* rootItem() const { return m_chart; }
86 86 QGraphicsRectItem* backgroundItem();
87 87 QGraphicsItem* titleItem();
88 88 QList<ChartAxis*> axisItems() const;
89 89
90 90 QLegend* legend();
91 91
92 92 void setBackgroundBrush(const QBrush& brush);
93 93 QBrush backgroundBrush() const;
94 94
95 95 void setBackgroundPen(const QPen& pen);
96 96 QPen backgroundPen() const;
97 97
98 98 void setTitle(const QString& title);
99 99 QString title() const;
100 100
101 101 void setTitleFont(const QFont& font);
102 102 QFont titleFont() const;
103 103
104 104 void setTitleBrush(const QBrush &brush);
105 105 QBrush titleBrush() const;
106 106
107 107 void setBackgroundVisible(bool visible);
108 108 bool isBackgroundVisible() const;
109 109
110 110 void setBackgroundDropShadowEnabled(bool enabled);
111 111 bool isBackgroundDropShadowEnabled() const;
112 112
113 113 void setVisible(bool visible);
114 114
115 115 void setTheme(QChart::ChartTheme theme,bool force = true);
116 116 QChart::ChartTheme theme();
117 117
118 118 void setAnimationOptions(QChart::AnimationOptions options);
119 119 QChart::AnimationOptions animationOptions() const;
120 120
121 121 void zoomIn(qreal factor);
122 122 void zoomIn(const QRectF& rect);
123 123 void zoomOut(qreal factor);
124 124 void scroll(qreal dx,qreal dy);
125 125
126 126 void setGeometry(const QRectF& rect);
127 127 QRectF geometry() { return m_rect; }
128 128
129 129 void startAnimation(ChartAnimation* animation);
130 130 State state() const { return m_state; }
131 131 QPointF statePoint() const { return m_statePoint; }
132 132
133 133 void resetAllElements();
134 134
135 135 void setMinimumMargins(const QMargins& margins);
136 136 QMargins minimumMargins() const;
137 137 QGraphicsLayout* layout();
138 138
139 139 private:
140 140 void createBackgroundItem();
141 141 void createTitleItem();
142 142 void selectVisibleAxis();
143 143
144 144 public Q_SLOTS:
145 145 void handleSeriesAdded(QAbstractSeries* series,Domain* domain);
146 146 void handleSeriesRemoved(QAbstractSeries* series);
147 147 void handleAxisAdded(QAbstractAxis* axis,Domain* domain);
148 148 void handleAxisRemoved(QAbstractAxis* axis);
149 149 void handleAxisVisibleChanged(bool visible);
150 150
151 151 private Q_SLOTS:
152 152 void handleAnimationFinished();
153 153
154 154 Q_SIGNALS:
155 155 void geometryChanged(const QRectF& rect);
156 156 void animationsFinished();
157 157 void marginsChanged(QRectF margins);
158 158
159 159 private:
160 160 QChart* m_chart;
161 161 ChartDataSet* m_dataset;
162 162 ChartTheme *m_chartTheme;
163 163 QMap<QAbstractSeries*, ChartElement*> m_chartItems;
164 164 QMap<QAbstractAxis*, ChartAxis*> m_axisItems;
165 165 QRectF m_rect;
166 166 QChart::AnimationOptions m_options;
167 167 State m_state;
168 168 QPointF m_statePoint;
169 169 QList<ChartAnimation*> m_animations;
170 170 ChartLayout* m_layout;
171 171 ChartBackground* m_backgroundItem;
172 172 QGraphicsSimpleTextItem* m_titleItem;
173 173 };
174 174
175 175 QTCOMMERCIALCHART_END_NAMESPACE
176 176
177 177 #endif /* CHARTPRESENTER_H */
@@ -1,393 +1,390
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "charttheme_p.h"
22 22 #include "qchart.h"
23 23 #include "qchart_p.h"
24 24 #include "qchartview.h"
25 25 #include "qlegend.h"
26 26 #include "qabstractaxis.h"
27 27 #include <QTime>
28 28
29 29 //series
30 30 #include "qbarset.h"
31 31 #include "qabstractbarseries.h"
32 32 #include "qstackedbarseries.h"
33 33 #include "qpercentbarseries.h"
34 34 #include "qlineseries.h"
35 35 #include "qareaseries.h"
36 36 #include "qscatterseries.h"
37 37 #include "qpieseries.h"
38 38 #include "qpieslice.h"
39 39 #include "qpieslice_p.h"
40 40 #include "qsplineseries.h"
41 41
42 42 //items
43 43 #include "chartaxis_p.h"
44 44 #include "abstractbarchartitem_p.h"
45 45 #include "stackedbarchartitem_p.h"
46 46 #include "percentbarchartitem_p.h"
47 47 #include "linechartitem_p.h"
48 48 #include "areachartitem_p.h"
49 49 #include "scatterchartitem_p.h"
50 50 #include "piechartitem_p.h"
51 51 #include "splinechartitem_p.h"
52 52
53 53 //themes
54 54 #include "chartthemesystem_p.h"
55 55 #include "chartthemelight_p.h"
56 56 #include "chartthemebluecerulean_p.h"
57 57 #include "chartthemedark_p.h"
58 58 #include "chartthemebrownsand_p.h"
59 59 #include "chartthemebluencs_p.h"
60 60 #include "chartthemehighcontrast_p.h"
61 61 #include "chartthemeblueicy_p.h"
62 62
63 63 QTCOMMERCIALCHART_BEGIN_NAMESPACE
64 64
65 65 ChartTheme::ChartTheme(QChart::ChartTheme id) :
66 66 m_id(id),
67 67 m_masterFont(QFont("arial", 14)),
68 68 m_labelFont(QFont("arial", 10)),
69 69 m_labelBrush(QColor(QRgb(0x000000))),
70 70 m_axisLinePen(QPen(QRgb(0x000000))),
71 71 m_backgroundShadesPen(Qt::NoPen),
72 72 m_backgroundShadesBrush(Qt::NoBrush),
73 73 m_backgroundShades(BackgroundShadesNone),
74 74 m_backgroundDropShadowEnabled(false),
75 75 m_gridLinePen(QPen(QRgb(0x000000))),
76 76 m_force(false)
77 77 {
78 78 qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
79 79 }
80 80
81 81
82 82 ChartTheme* ChartTheme::createTheme(QChart::ChartTheme theme)
83 83 {
84 84 switch(theme) {
85 85 case QChart::ChartThemeLight:
86 86 return new ChartThemeLight();
87 87 case QChart::ChartThemeBlueCerulean:
88 88 return new ChartThemeBlueCerulean();
89 89 case QChart::ChartThemeDark:
90 90 return new ChartThemeDark();
91 91 case QChart::ChartThemeBrownSand:
92 92 return new ChartThemeBrownSand();
93 93 case QChart::ChartThemeBlueNcs:
94 94 return new ChartThemeBlueNcs();
95 95 case QChart::ChartThemeHighContrast:
96 96 return new ChartThemeHighContrast();
97 97 case QChart::ChartThemeBlueIcy:
98 98 return new ChartThemeBlueIcy();
99 99 default:
100 100 return new ChartThemeSystem();
101 101 }
102 102 }
103 103
104 104 void ChartTheme::decorate(QChart *chart)
105 105 {
106 106 QBrush brush;
107 107
108 108 if(m_force || brush == chart->backgroundBrush())
109 109 chart->setBackgroundBrush(m_chartBackgroundGradient);
110 110 chart->setTitleFont(m_masterFont);
111 111 chart->setTitleBrush(m_labelBrush);
112 112 chart->setDropShadowEnabled(m_backgroundDropShadowEnabled);
113 113 }
114 114
115 115 void ChartTheme::decorate(QLegend *legend)
116 116 {
117 117 QPen pen;
118 118 QBrush brush;
119 119 QFont font;
120 120
121 121 if (m_force || pen == legend->pen())
122 122 legend->setPen(m_axisLinePen);
123 123
124 124 if (m_force || brush == legend->brush())
125 125 legend->setBrush(m_chartBackgroundGradient);
126 126
127 127 if (m_force || font == legend->font())
128 128 legend->setFont(m_labelFont);
129 129
130 130 if (m_force || brush == legend->labelBrush())
131 131 legend->setLabelBrush(m_labelBrush);
132 132 }
133 133
134 134 void ChartTheme::decorate(QAreaSeries *series, int index)
135 135 {
136 136 QPen pen;
137 137 QBrush brush;
138 138
139 139 if (m_force || pen == series->pen()){
140 140 pen.setColor(colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 0.0));
141 141 pen.setWidthF(2);
142 142 series->setPen(pen);
143 143 }
144 144
145 145 if (m_force || brush == series->brush()) {
146 146 QBrush brush(m_seriesColors.at(index % m_seriesColors.size()));
147 147 series->setBrush(brush);
148 148 }
149 149 }
150 150
151 151
152 152 void ChartTheme::decorate(QLineSeries *series,int index)
153 153 {
154 154 QPen pen;
155 155 if(m_force || pen == series->pen()){
156 156 pen.setColor(m_seriesColors.at(index%m_seriesColors.size()));
157 157 pen.setWidthF(2);
158 158 series->setPen(pen);
159 159 }
160 160 }
161 161
162 162 void ChartTheme::decorate(QAbstractBarSeries *series, int index)
163 163 {
164 164 QBrush brush;
165 165 QPen pen;
166 166 QList<QBarSet *> sets = series->barSets();
167 167
168 168 qreal takeAtPos = 0.5;
169 169 qreal step = 0.2;
170 170 if (sets.count() > 1 ) {
171 171 step = 1.0 / (qreal) sets.count();
172 172 if (sets.count() % m_seriesGradients.count())
173 173 step *= m_seriesGradients.count();
174 174 else
175 175 step *= (m_seriesGradients.count() - 1);
176 176 }
177 177
178 178 for (int i(0); i < sets.count(); i++) {
179 179 int colorIndex = (index + i) % m_seriesGradients.count();
180 180 if (i > 0 && i % m_seriesGradients.count() == 0) {
181 181 // There is no dedicated base color for each sets, generate more colors
182 182 takeAtPos += step;
183 183 if (takeAtPos == 1.0)
184 184 takeAtPos += step;
185 185 takeAtPos -= (int) takeAtPos;
186 186 }
187 187 if (m_force || brush == sets.at(i)->brush())
188 188 sets.at(i)->setBrush(colorAt(m_seriesGradients.at(colorIndex), takeAtPos));
189 189
190 190 // Pick label color from the opposite end of the gradient.
191 191 // 0.3 as a boundary seems to work well.
192 192 if (m_force || brush == sets.at(i)->labelBrush()) {
193 193 if (takeAtPos < 0.3)
194 194 sets.at(i)->setLabelBrush(colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 1));
195 195 else
196 196 sets.at(i)->setLabelBrush(colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 0));
197 197 }
198 198
199 199 if (m_force || pen == sets.at(i)->pen()) {
200 200 QColor c = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 0.0);
201 201 sets.at(i)->setPen(c);
202 202 }
203 203 }
204 204 }
205 205
206 206 void ChartTheme::decorate(QScatterSeries *series, int index)
207 207 {
208 208 QPen pen;
209 209 QBrush brush;
210 210
211 211 if (m_force || pen == series->pen()) {
212 212 pen.setColor(colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 0.0));
213 213 pen.setWidthF(2);
214 214 series->setPen(pen);
215 215 }
216 216
217 217 if (m_force || brush == series->brush()) {
218 218 QBrush brush(m_seriesColors.at(index % m_seriesColors.size()));
219 219 series->setBrush(brush);
220 220 }
221 221 }
222 222
223 223 void ChartTheme::decorate(QPieSeries *series, int index)
224 224 {
225 225
226 226 for (int i(0); i < series->slices().count(); i++) {
227 227
228 228 QColor penColor = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 0.0);
229 229
230 230 // Get color for a slice from a gradient linearly, beginning from the start of the gradient
231 231 qreal pos = (qreal) (i + 1) / (qreal) series->count();
232 232 QColor brushColor = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), pos);
233 233
234 234 QPieSlice *s = series->slices().at(i);
235 235 QPieSlicePrivate *d = QPieSlicePrivate::fromSlice(s);
236 236
237 237 if (m_force || d->m_data.m_slicePen.isThemed())
238 238 d->setPen(penColor, true);
239 239
240 240 if (m_force || d->m_data.m_sliceBrush.isThemed())
241 241 d->setBrush(brushColor, true);
242 242
243 243 if (m_force || d->m_data.m_labelBrush.isThemed())
244 244 d->setLabelBrush(m_labelBrush.color(), true);
245 245
246 246 if (m_force || d->m_data.m_labelFont.isThemed())
247 247 d->setLabelFont(m_labelFont, true);
248 248 }
249 249 }
250 250
251 251 void ChartTheme::decorate(QSplineSeries *series, int index)
252 252 {
253 253 QPen pen;
254 254 if(m_force || pen == series->pen()){
255 255 pen.setColor(m_seriesColors.at(index%m_seriesColors.size()));
256 256 pen.setWidthF(2);
257 257 series->setPen(pen);
258 258 }
259 259 }
260 260
261 261 void ChartTheme::decorate(QAbstractAxis *axis)
262 262 {
263 263 QPen pen;
264 264 QBrush brush;
265 265 QFont font;
266 266
267 267 bool axisX = axis->orientation()== Qt::Horizontal;
268 268
269 269 if (axis->isLineVisible()) {
270 270
271 271 if(m_force || brush == axis->labelsBrush()){
272 272 axis->setLabelsBrush(m_labelBrush);
273 273 }
274 274 if(m_force || pen == axis->labelsPen()){
275 275 axis->setLabelsPen(Qt::NoPen); // NoPen for performance reasons
276 276 }
277 277
278 278
279 279 if (m_force || axis->shadesVisible()) {
280 280
281 281 if(m_force || brush == axis->shadesBrush()){
282 282 axis->setShadesBrush(m_backgroundShadesBrush);
283 283 }
284 284
285 285 if(m_force || pen == axis->shadesPen()){
286 286 axis->setShadesPen(m_backgroundShadesPen);
287 287 }
288 288
289 289 if( m_force && (m_backgroundShades == BackgroundShadesBoth
290 290 || (m_backgroundShades == BackgroundShadesVertical && axisX)
291 291 || (m_backgroundShades == BackgroundShadesHorizontal && !axisX))){
292 292 axis->setShadesVisible(true);
293 293
294 294 }
295 295 }
296 296
297 297 if(m_force || pen == axis->linePen()){
298 298 axis->setLinePen(m_axisLinePen);
299 299 }
300 300
301 301 if(m_force || pen == axis->gridLinePen()){
302 302 axis->setGridLinePen(m_gridLinePen);
303 303 }
304 304
305 305 if(m_force || font == axis->labelsFont()){
306 306 axis->setLabelsFont(m_labelFont);
307 307 }
308 308 }
309 309 }
310 310
311 311 void ChartTheme::generateSeriesGradients()
312 312 {
313 313 // Generate gradients in HSV color space
314 314 foreach (const QColor& color, m_seriesColors) {
315 315 QLinearGradient g;
316 316 qreal h = color.hsvHueF();
317 317 qreal s = color.hsvSaturationF();
318 318
319 // TODO: tune the algorithm to give nice results with most base colors defined in
320 // most themes. The rest of the gradients we can define manually in theme specific
321 // implementation.
322 319 QColor start = color;
323 320 start.setHsvF(h, 0.0, 1.0);
324 321 g.setColorAt(0.0, start);
325 322
326 323 g.setColorAt(0.5, color);
327 324
328 325 QColor end = color;
329 326 end.setHsvF(h, s, 0.25);
330 327 g.setColorAt(1.0, end);
331 328
332 329 m_seriesGradients << g;
333 330 }
334 331 }
335 332
336 333
337 334 QColor ChartTheme::colorAt(const QColor &start, const QColor &end, qreal pos)
338 335 {
339 336 Q_ASSERT(pos >= 0.0 && pos <= 1.0);
340 337 qreal r = start.redF() + ((end.redF() - start.redF()) * pos);
341 338 qreal g = start.greenF() + ((end.greenF() - start.greenF()) * pos);
342 339 qreal b = start.blueF() + ((end.blueF() - start.blueF()) * pos);
343 340 QColor c;
344 341 c.setRgbF(r, g, b);
345 342 return c;
346 343 }
347 344
348 345 QColor ChartTheme::colorAt(const QGradient &gradient, qreal pos)
349 346 {
350 347 Q_ASSERT(pos >= 0 && pos <= 1.0);
351 348
352 349 QGradientStops stops = gradient.stops();
353 350 int count = stops.count();
354 351
355 352 // find previous stop relative to position
356 353 QGradientStop prev = stops.first();
357 354 for (int i = 0; i < count; i++) {
358 355 QGradientStop stop = stops.at(i);
359 356 if (pos > stop.first)
360 357 prev = stop;
361 358
362 359 // given position is actually a stop position?
363 360 if (pos == stop.first) {
364 361 //qDebug() << "stop color" << pos;
365 362 return stop.second;
366 363 }
367 364 }
368 365
369 366 // find next stop relative to position
370 367 QGradientStop next = stops.last();
371 368 for (int i = count - 1; i >= 0; i--) {
372 369 QGradientStop stop = stops.at(i);
373 370 if (pos < stop.first)
374 371 next = stop;
375 372 }
376 373
377 374 //qDebug() << "prev" << prev.first << "pos" << pos << "next" << next.first;
378 375
379 376 qreal range = next.first - prev.first;
380 377 qreal posDelta = pos - prev.first;
381 378 qreal relativePos = posDelta / range;
382 379
383 380 //qDebug() << "range" << range << "posDelta" << posDelta << "relativePos" << relativePos;
384 381
385 382 return colorAt(prev.second, next.second, relativePos);
386 383 }
387 384
388 385 void ChartTheme::setForced(bool enabled)
389 386 {
390 387 m_force = enabled;
391 388 }
392 389
393 390 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,236 +1,236
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "legendmarker_p.h"
22 22 #include "qxyseries.h"
23 23 #include "qxyseries_p.h"
24 24 #include "qlegend.h"
25 25 #include "qabstractbarseries.h"
26 26 #include "qpieseries.h"
27 27 #include "qpieslice.h"
28 28 #include "qbarset.h"
29 29 #include "qbarset_p.h"
30 30 #include "qareaseries.h"
31 31 #include "qareaseries_p.h"
32 32 #include <QPainter>
33 33 #include <QGraphicsSceneEvent>
34 34 #include <QGraphicsSimpleTextItem>
35 35 #include <QDebug>
36 36
37 37 QTCOMMERCIALCHART_BEGIN_NAMESPACE
38 38
39 39 LegendMarker::LegendMarker(QAbstractSeries *series, QLegend *legend) :
40 40 QGraphicsObject(legend),
41 41 m_series(series),
42 42 m_markerRect(0,0,10.0,10.0),
43 43 m_boundingRect(0,0,0,0),
44 44 m_legend(legend),
45 45 m_textItem(new QGraphicsSimpleTextItem(this)),
46 46 m_rectItem(new QGraphicsRectItem(this)),
47 47 m_margin(2),
48 48 m_space(4)
49 49 {
50 50 //setAcceptedMouseButtons(Qt::LeftButton|Qt::RightButton);
51 51 m_rectItem->setRect(m_markerRect);
52 52 }
53 53
54 54 void LegendMarker::setPen(const QPen &pen)
55 55 {
56 56 m_rectItem->setPen(pen);
57 57 }
58 58
59 59 QPen LegendMarker::pen() const
60 60 {
61 61 return m_rectItem->pen();
62 62 }
63 63
64 64 void LegendMarker::setBrush(const QBrush &brush)
65 65 {
66 66 m_rectItem->setBrush(brush);
67 67 }
68 68
69 69 QBrush LegendMarker::brush() const
70 70 {
71 71 return m_rectItem->brush();
72 72 }
73 73
74 74 void LegendMarker::setFont(const QFont &font)
75 75 {
76 76 m_textItem->setFont(font);
77 77 QFontMetrics fn(font);
78 78 m_markerRect = QRectF(0,0,fn.height()/2,fn.height()/2);
79 79 updateGeometry();
80 80 }
81 81
82 82 QFont LegendMarker::font() const
83 83 {
84 84 return m_textItem->font();
85 85 }
86 86
87 87 void LegendMarker::setLabel(const QString label)
88 88 {
89 89 m_textItem->setText(label);
90 90 }
91 91
92 92 QString LegendMarker::label() const
93 93 {
94 94 return m_textItem->text();
95 95 }
96 96
97 97 QRectF LegendMarker::boundingRect() const
98 98 {
99 99 return m_boundingRect;
100 100 }
101 101
102 102 void LegendMarker::setLabelBrush(const QBrush &brush)
103 103 {
104 104 m_textItem->setBrush(brush);
105 105 }
106 106
107 107 QBrush LegendMarker::labelBrush() const
108 108 {
109 109 return m_textItem->brush();
110 110 }
111 111
112 112
113 113 void LegendMarker::setGeometry(const QRectF& rect)
114 114 {
115 115 const QRectF& textRect = m_textItem->boundingRect();
116 116
117 117 m_textItem->setPos(m_markerRect.width() + m_space + m_margin,rect.height()/2 - textRect.height()/2);
118 118 m_rectItem->setRect(m_markerRect);
119 119 m_rectItem->setPos(m_margin,rect.height()/2 - m_markerRect.height()/2);
120 120
121 121 prepareGeometryChange();
122 122 m_boundingRect = rect;
123 123 }
124 124
125 125 void LegendMarker::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
126 126 {
127 127 Q_UNUSED(option)
128 128 Q_UNUSED(widget)
129 129 Q_UNUSED(painter)
130 130 }
131 131
132 132
133 133 QSizeF LegendMarker::sizeHint(Qt::SizeHint which, const QSizeF& constraint) const
134 134 {
135 135 Q_UNUSED(constraint)
136 136
137 137 QFontMetrics fn(m_textItem->font());
138 138 QSizeF sh;
139 139
140 140 switch (which) {
141 141 case Qt::MinimumSize:
142 142 sh = QSizeF(fn.boundingRect("...").width(),fn.height());
143 143 break;
144 144 case Qt::PreferredSize:
145 145 sh = QSizeF(fn.boundingRect(m_textItem->text()).width() + 2*m_margin + m_space +m_markerRect.width(),qMax(m_markerRect.height()+2*m_margin,fn.height()+2*m_margin));
146 146 break;
147 147 default:
148 148 break;
149 149 }
150 150
151 151 return sh;
152 152 }
153 153
154 154 void LegendMarker::mousePressEvent(QGraphicsSceneMouseEvent *event)
155 155 {
156 156 QGraphicsObject::mousePressEvent(event);
157 qDebug()<<"Not implemented"; //TODO: selected signal removed for now
157 qDebug()<<"Not implemented";
158 158 }
159 159
160 160 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
161 161
162 162 AreaLegendMarker::AreaLegendMarker(QAreaSeries *series,QLegend *legend) : LegendMarker(series,legend),
163 163 m_series(series)
164 164 {
165 165 //QObject::connect(this, SIGNAL(selected()), series, SIGNAL(selected()));
166 166 QObject::connect(series->d_func(),SIGNAL(updated()), this, SLOT(updated()));
167 167 QObject::connect(series, SIGNAL(nameChanged()), this, SLOT(updated()));
168 168 updated();
169 169 }
170 170
171 171 void AreaLegendMarker::updated()
172 172 {
173 173 setBrush(m_series->brush());
174 174 setLabel(m_series->name());
175 175 }
176 176
177 177 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
178 178
179 179 BarLegendMarker::BarLegendMarker(QAbstractBarSeries *barseries,QBarSet *barset, QLegend *legend) : LegendMarker(barseries,legend),
180 180 m_barset(barset)
181 181 {
182 182 //QObject::connect(this, SIGNAL(selected()),barset->d_ptr.data(), SIGNAL(selected()));
183 183 QObject::connect(barset->d_ptr.data(), SIGNAL(updatedBars()), this, SLOT(updated()));
184 184 updated();
185 185 }
186 186
187 187 void BarLegendMarker::updated()
188 188 {
189 189 setBrush(m_barset->brush());
190 190 setLabel(m_barset->label());
191 191 }
192 192
193 193 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
194 194
195 195 PieLegendMarker::PieLegendMarker(QPieSeries* series,QPieSlice *pieslice, QLegend *legend) : LegendMarker(series,legend),
196 196 m_pieslice(pieslice)
197 197 {
198 198 QObject::connect(pieslice, SIGNAL(labelChanged()), this, SLOT(updated()));
199 199 QObject::connect(pieslice, SIGNAL(brushChanged()), this, SLOT(updated()));
200 200 updated();
201 201 }
202 202
203 203 void PieLegendMarker::updated()
204 204 {
205 205 setBrush(m_pieslice->brush());
206 206 setLabel(m_pieslice->label());
207 207 }
208 208
209 209 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
210 210
211 211 XYLegendMarker::XYLegendMarker(QXYSeries *series, QLegend *legend) : LegendMarker(series,legend),
212 212 m_series(series)
213 213 {
214 214 //QObject::connect(this, SIGNAL(selected()), series, SIGNAL(selected()));
215 215 QObject::connect(series->d_func(),SIGNAL(updated()), this, SLOT(updated()));
216 216 QObject::connect(series, SIGNAL(nameChanged()), this, SLOT(updated()));
217 217 updated();
218 218 }
219 219
220 220 void XYLegendMarker::updated()
221 221 {
222 222 setLabel(m_series->name());
223 223
224 224 if(m_series->type()== QAbstractSeries::SeriesTypeScatter)
225 225 {
226 226 setBrush(m_series->brush());
227 227
228 228 }
229 229 else {
230 230 setBrush(QBrush(m_series->pen().color()));
231 231 }
232 232 }
233 233
234 234 #include "moc_legendmarker_p.cpp"
235 235
236 236 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,537 +1,534
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "qlegend.h"
22 22 #include "qlegend_p.h"
23 23 #include "qabstractseries.h"
24 24 #include "qabstractseries_p.h"
25 25 #include "qchart_p.h"
26 26 #include "legendlayout_p.h"
27 27 #include "legendmarker_p.h"
28 28 #include "qxyseries.h"
29 29 #include "qlineseries.h"
30 30 #include "qareaseries.h"
31 31 #include "qscatterseries.h"
32 32 #include "qsplineseries.h"
33 33 #include "qabstractbarseries.h"
34 34 #include "qstackedbarseries.h"
35 35 #include "qpercentbarseries.h"
36 36 #include "qbarset.h"
37 37 #include "qpieseries.h"
38 38 #include "qpieseries_p.h"
39 39 #include "qpieslice.h"
40 40 #include "chartpresenter_p.h"
41 41 #include <QPainter>
42 42 #include <QPen>
43 43 #include <QTimer>
44 44 #include <QGraphicsLayout>
45 45 #include <QGraphicsSceneEvent>
46 46
47 47 QTCOMMERCIALCHART_BEGIN_NAMESPACE
48 48
49 49 /*!
50 50 \class QLegend
51 51 \brief Legend object
52 52 \mainclass
53 53
54 54 QLegend is a graphical object, whics displays legend of the chart. Legend state is updated by QChart, when
55 55 series have been changed. By default, legend is drawn by QChart, but user can set a new parent to legend and
56 56 handle the drawing manually.
57 57 User isn't supposed to create or delete legend objects, but can reference it via QChart class.
58 58
59 59 \image examples_percentbarchart_legend.png
60 60
61 61 \sa QChart
62 62 */
63 63 /*!
64 64 \qmlclass Legend QLegend
65 65 \brief Legend is part of QtCommercial Chart QML API.
66 66
67 67 Legend is a graphical object, whics displays legend of the chart. Legend state is updated by ChartView, when
68 68 series have been changed. Legend is used via ChartView class. For example:
69 69 \code
70 70 ChartView {
71 71 legend.visible: true
72 72 legend.alignment: Qt.AlignBottom
73 73 // Add a few series...
74 74 }
75 75 \endcode
76 76
77 77 \image examples_percentbarchart_legend.png
78 78 */
79 79
80 80 /*!
81 81 \property QLegend::alignment
82 82 \brief The alignment of the legend.
83 83
84 84 Legend paints on the defined position in the chart. The following alignments are supported:
85 85 Qt::AlignTop, Qt::AlignBottom, Qt::AlignLeft, Qt::AlignRight. If you set more than one flag the result is undefined.
86 86 */
87 87 /*!
88 88 \qmlproperty Qt.Alignment Legend::alignment
89 89 \brief The alignment of the legend.
90 90
91 91 Legend paints on the defined position in the chart. The following alignments are supported:
92 92 Qt.AlignTop, Qt.AlignBottom, Qt.AlignLeft, Qt.AlignRight. If you set more than one flag the result is undefined.
93 93 */
94 94
95 95 /*!
96 96 \property QLegend::backgroundVisible
97 97 Whether the legend background is visible or not.
98 98 */
99 99 /*!
100 100 \qmlproperty bool Legend::backgroundVisible
101 101 Whether the legend background is visible or not.
102 102 */
103 103
104 104 /*!
105 105 \property QLegend::color
106 106 The color of the legend, i.e. the background (brush) color. Note that if you change the color
107 107 of the legend, the style of the legend brush is set to Qt::SolidPattern.
108 108 */
109 109 /*!
110 110 \qmlproperty color Legend::color
111 111 The color of the legend, i.e. the background (brush) color.
112 112 */
113 113
114 114 /*!
115 115 \property QLegend::borderColor
116 116 The border color of the legend, i.e. the line color.
117 117 */
118 118 /*!
119 119 \qmlproperty color Legend::borderColor
120 120 The border color of the legend, i.e. the line color.
121 121 */
122 122
123 123 /*!
124 124 \property QLegend::font
125 125 The font of markers used by legend
126 126 */
127 127 /*!
128 128 \qmlproperty color Legend::font
129 129 The font of markers used by legend
130 130 */
131 131
132 132 /*!
133 133 \property QLegend::labelColor
134 134 The color of brush used to draw labels.
135 135 */
136 136 /*!
137 137 \qmlproperty color QLegend::labelColor
138 138 The color of brush used to draw labels.
139 139 */
140 140
141 141 /*!
142 142 \fn void QLegend::backgroundVisibleChanged(bool)
143 143 The visibility of the legend background changed to \a visible.
144 144 */
145 145
146 146 /*!
147 147 \fn void QLegend::colorChanged(QColor)
148 148 The color of the legend background changed to \a color.
149 149 */
150 150
151 151 /*!
152 152 \fn void QLegend::borderColorChanged(QColor)
153 153 The border color of the legend background changed to \a color.
154 154 */
155 155
156 156 /*!
157 157 \fn void QLegend::fontChanged(QFont)
158 158 The font of markers of the legend changed to \a font.
159 159 */
160 160
161 161 /*!
162 162 \fn void QLegend::labelColorChanged(QColor color)
163 163 This signal is emitted when the color of brush used to draw labels has changed to \a color.
164 164 */
165 165
166 166 /*!
167 167 Constructs the legend object and sets the parent to \a parent
168 168 */
169 169
170 170 QLegend::QLegend(QChart *chart):QGraphicsWidget(chart),
171 171 d_ptr(new QLegendPrivate(chart->d_ptr->m_presenter,chart,this))
172 172 {
173 173 setZValue(ChartPresenter::LegendZValue);
174 174 setFlags(QGraphicsItem::ItemClipsChildrenToShape);
175 175 QObject::connect(chart->d_ptr->m_dataset,SIGNAL(seriesAdded(QAbstractSeries*,Domain*)),d_ptr.data(),SLOT(handleSeriesAdded(QAbstractSeries*,Domain*)));
176 176 QObject::connect(chart->d_ptr->m_dataset,SIGNAL(seriesRemoved(QAbstractSeries*)),d_ptr.data(),SLOT(handleSeriesRemoved(QAbstractSeries*)));
177 177 QObject::connect(chart->d_ptr->m_dataset,SIGNAL(seriesUpdated(QAbstractSeries*)),d_ptr.data(),SLOT(handleSeriesUpdated(QAbstractSeries*)));
178 178 setLayout(d_ptr->m_layout);
179 179 }
180 180
181 181 /*!
182 182 Destroys the legend object. Legend is always owned by a QChart, so an application should never call this.
183 183 */
184 184 QLegend::~QLegend()
185 185 {
186 186 }
187 187
188 188 /*!
189 189 \internal
190 190 */
191 191 void QLegend::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
192 192 {
193 193 Q_UNUSED(option)
194 194 Q_UNUSED(widget)
195 195 if(!d_ptr->m_backgroundVisible) return;
196 196
197 197 painter->setOpacity(opacity());
198 198 painter->setPen(d_ptr->m_pen);
199 199 painter->setBrush(d_ptr->m_brush);
200 200 painter->drawRoundRect(rect(),d_ptr->roundness(rect().width()),d_ptr->roundness(rect().height()));
201 201
202 202 }
203 203
204 204
205 205 /*!
206 206 Sets the \a brush of legend. Brush affects the background of legend.
207 207 */
208 208 void QLegend::setBrush(const QBrush &brush)
209 209 {
210 210 if (d_ptr->m_brush != brush) {
211 211 d_ptr->m_brush = brush;
212 212 update();
213 213 emit colorChanged(brush.color());
214 214 }
215 215 }
216 216
217 217 /*!
218 218 Returns the brush used by legend.
219 219 */
220 220 QBrush QLegend::brush() const
221 221 {
222 222 return d_ptr->m_brush;
223 223 }
224 224
225 225 void QLegend::setColor(QColor color)
226 226 {
227 227 QBrush b = d_ptr->m_brush;
228 228 if (b.style() != Qt::SolidPattern || b.color() != color) {
229 229 b.setStyle(Qt::SolidPattern);
230 230 b.setColor(color);
231 231 setBrush(b);
232 232 }
233 233 }
234 234
235 235 QColor QLegend::color()
236 236 {
237 237 return d_ptr->m_brush.color();
238 238 }
239 239
240 240 /*!
241 241 Sets the \a pen of legend. Pen affects the legend borders.
242 242 */
243 243 void QLegend::setPen(const QPen &pen)
244 244 {
245 245 if (d_ptr->m_pen != pen) {
246 246 d_ptr->m_pen = pen;
247 247 update();
248 248 emit borderColorChanged(pen.color());
249 249 }
250 250 }
251 251
252 252 /*!
253 253 Returns the pen used by legend
254 254 */
255 255
256 256 QPen QLegend::pen() const
257 257 {
258 258 return d_ptr->m_pen;
259 259 }
260 260
261 261 void QLegend::setFont(const QFont &font)
262 262 {
263 263 if (d_ptr->m_font != font) {
264 264 d_ptr->m_font = font;
265 265
266 266 foreach (LegendMarker *marker, d_ptr->markers()) {
267 267 marker->setFont(d_ptr->m_font);
268 268 }
269 269 layout()->invalidate();
270 270 emit fontChanged(font);
271 271 }
272 272 }
273 273
274 274 QFont QLegend::font() const
275 275 {
276 276 return d_ptr->m_font;
277 277 }
278 278
279 279 void QLegend::setBorderColor(QColor color)
280 280 {
281 281 QPen p = d_ptr->m_pen;
282 282 if (p.color() != color) {
283 283 p.setColor(color);
284 284 setPen(p);
285 285 }
286 286 }
287 287
288 288 QColor QLegend::borderColor()
289 289 {
290 290 return d_ptr->m_pen.color();
291 291 }
292 292
293 293 /*!
294 294 Set brush used to draw labels to \a brush.
295 295 */
296 296 void QLegend::setLabelBrush(const QBrush &brush)
297 297 {
298 298 if (d_ptr->m_labelBrush != brush) {
299 299 d_ptr->m_labelBrush = brush;
300 300 foreach (LegendMarker *marker, d_ptr->markers()) {
301 301 marker->setLabelBrush(d_ptr->m_labelBrush);
302 302 // Note: The pen of the marker rectangle could be exposed in the public QLegend API
303 303 // instead of mapping it from label brush color
304 304 marker->setPen(brush.color());
305 305 }
306 306 emit labelColorChanged(brush.color());
307 307 }
308 308 }
309 309
310 310 /*!
311 311 Brush used to draw labels.
312 312 */
313 313 QBrush QLegend::labelBrush() const
314 314 {
315 315 return d_ptr->m_labelBrush;
316 316 }
317 317
318 318 void QLegend::setLabelColor(QColor color)
319 319 {
320 320 QBrush b = d_ptr->m_labelBrush;
321 321 if (b.style() != Qt::SolidPattern || b.color() != color) {
322 322 b.setStyle(Qt::SolidPattern);
323 323 b.setColor(color);
324 324 setLabelBrush(b);
325 325 }
326 326 }
327 327
328 328 QColor QLegend::labelColor() const
329 329 {
330 330 return d_ptr->m_labelBrush.color();
331 331 }
332 332
333 333
334 334 void QLegend::setAlignment(Qt::Alignment alignment)
335 335 {
336 336 if(d_ptr->m_alignment!=alignment) {
337 337 d_ptr->m_alignment = alignment;
338 338 updateGeometry();
339 339 if(isAttachedToChart()){
340 340 d_ptr->m_presenter->layout()->invalidate();
341 341 }else{
342 342 layout()->invalidate();
343 343 }
344 344 }
345 345 }
346 346
347 347 Qt::Alignment QLegend::alignment() const
348 348 {
349 349 return d_ptr->m_alignment;
350 350 }
351 351
352 352 /*!
353 353 Detaches the legend from chart. Chart won't change layout of the legend.
354 354 */
355 355 void QLegend::detachFromChart()
356 356 {
357 357 d_ptr->m_attachedToChart = false;
358 358 d_ptr->m_layout->invalidate();
359 359 setParent(0);
360 360
361 361 }
362 362
363 363 /*!
364 364 Attaches the legend to chart. Chart may change layout of the legend.
365 365 */
366 366 void QLegend::attachToChart()
367 367 {
368 368 d_ptr->m_attachedToChart = true;
369 369 d_ptr->m_presenter->layout()->invalidate();
370 370 setParent(d_ptr->m_chart);
371 371 }
372 372
373 373 /*!
374 374 Returns true, if legend is attached to chart.
375 375 */
376 376 bool QLegend::isAttachedToChart()
377 377 {
378 378 return d_ptr->m_attachedToChart;
379 379 }
380 380
381 381 /*!
382 382 Sets the visibility of legend background to \a visible
383 383 */
384 384 void QLegend::setBackgroundVisible(bool visible)
385 385 {
386 386 if(d_ptr->m_backgroundVisible != visible) {
387 387 d_ptr->m_backgroundVisible = visible;
388 388 update();
389 389 emit backgroundVisibleChanged(visible);
390 390 }
391 391 }
392 392
393 393 /*!
394 394 Returns the visibility of legend background
395 395 */
396 396 bool QLegend::isBackgroundVisible() const
397 397 {
398 398 return d_ptr->m_backgroundVisible;
399 399 }
400 400
401 401 /*!
402 402 \internal \a event see QGraphicsWidget for details
403 403 */
404 404 void QLegend::hideEvent(QHideEvent *event)
405 405 {
406 406 d_ptr->m_presenter->layout()->invalidate();
407 407 QGraphicsWidget::hideEvent(event);
408 408 }
409 409
410 410 /*!
411 411 \internal \a event see QGraphicsWidget for details
412 412 */
413 413 void QLegend::showEvent(QShowEvent *event)
414 414 {
415 415 d_ptr->m_presenter->layout()->invalidate();
416 416 QGraphicsWidget::showEvent(event);
417 417 }
418 418
419 419 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
420 420
421 421 QLegendPrivate::QLegendPrivate(ChartPresenter* presenter, QChart *chart, QLegend *q):
422 422 q_ptr(q),
423 423 m_presenter(presenter),
424 424 m_layout(new LegendLayout(q)),
425 425 m_chart(chart),
426 426 m_items(new QGraphicsItemGroup(q)),
427 427 m_alignment(Qt::AlignTop),
428 428 m_brush(QBrush()),
429 429 m_pen(QPen()),
430 430 m_labelBrush(QBrush()),
431 431 m_diameter(5),
432 432 m_attachedToChart(true),
433 433 m_backgroundVisible(false)
434 434 {
435 435
436 436 }
437 437
438 438 QLegendPrivate::~QLegendPrivate()
439 439 {
440 440
441 441 }
442 442
443 443 void QLegendPrivate::setOffset(qreal x, qreal y)
444 444 {
445 445 m_layout->setOffset(x,y);
446 446 }
447 447
448 448 QPointF QLegendPrivate::offset() const
449 449 {
450 450 return m_layout->offset();
451 451 }
452 452
453 453 int QLegendPrivate::roundness(qreal size)
454 454 {
455 455 return 100*m_diameter/int(size);
456 456 }
457 457
458 458 void QLegendPrivate::handleSeriesAdded(QAbstractSeries *series, Domain *domain)
459 459 {
460 460 Q_UNUSED(domain)
461 461
462 462 QList<LegendMarker*> markers = series->d_ptr->createLegendMarker(q_ptr);
463 463
464 464 foreach(LegendMarker* marker, markers) {
465 465 marker->setFont(m_font);
466 466 marker->setLabelBrush(m_labelBrush);
467 467 marker->setVisible(series->isVisible());
468 468 m_items->addToGroup(marker);
469 469 m_markers<<marker;
470 470 }
471 471
472 472 QObject::connect(series, SIGNAL(visibleChanged()), this, SLOT(handleSeriesVisibleChanged()));
473 473
474 474 if(series->type() == QAbstractSeries::SeriesTypePie) {
475 475 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
476 476 QObject::connect(pieSeries, SIGNAL(added(QList<QPieSlice*>)), this, SLOT(handleUpdatePieSeries()));
477 477 QObject::connect(pieSeries, SIGNAL(removed(QList<QPieSlice*>)), this, SLOT(handleUpdatePieSeries()));
478 478 }
479 479
480 480 q_ptr->layout()->invalidate();
481 481 q_ptr->layout()->activate();
482 482 }
483 483
484 484 void QLegendPrivate::handleSeriesRemoved(QAbstractSeries *series)
485 485 {
486 486 foreach (LegendMarker *marker, m_markers) {
487 487 if (marker->series() == series) {
488 488 delete marker;
489 489 m_markers.removeAll(marker);
490 490 }
491 491 }
492 492
493 493 if(series->type() == QAbstractSeries::SeriesTypePie)
494 494 {
495 495 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
496 496 QObject::disconnect(pieSeries, SIGNAL(added(QList<QPieSlice*>)), this, SLOT(handleUpdatePieSeries()));
497 497 QObject::disconnect(pieSeries, SIGNAL(removed(QList<QPieSlice*>)), this, SLOT(handleUpdatePieSeries()));
498 498 }
499 499
500 500 q_ptr->layout()->invalidate();
501 501 }
502 502
503 503 void QLegendPrivate::handleSeriesUpdated(QAbstractSeries *series)
504 504 {
505 // TODO: find out which markers are are added or removed. Update them
506 // TODO: better implementation
507 505 handleSeriesRemoved(series);
508 506 Domain domain;
509 507 handleSeriesAdded(series, &domain);
510 508 }
511 509
512 510 void QLegendPrivate::handleUpdatePieSeries()
513 511 {
514 //TODO: reimplement to be optimal
515 512 QPieSeries* series = qobject_cast<QPieSeries *> (sender());
516 513 Q_ASSERT(series);
517 514 handleSeriesRemoved(series);
518 515 handleSeriesAdded(series, 0);
519 516 }
520 517
521 518 void QLegendPrivate::handleSeriesVisibleChanged()
522 519 {
523 520 QAbstractSeries* series = qobject_cast<QAbstractSeries *> (sender());
524 521
525 522 foreach (LegendMarker* marker, m_markers) {
526 523 if (marker->series() == series) {
527 524 marker->setVisible(series->isVisible());
528 525 }
529 526 }
530 527
531 528 q_ptr->layout()->invalidate();
532 529 }
533 530
534 531 #include "moc_qlegend.cpp"
535 532 #include "moc_qlegend_p.cpp"
536 533
537 534 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,88 +1,88
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 // W A R N I N G
22 22 // -------------
23 23 //
24 24 // This file is not part of the QtCommercial Chart API. It exists purely as an
25 25 // implementation detail. This header file may change from version to
26 26 // version without notice, or even be removed.
27 27 //
28 28 // We mean it.
29 29
30 30 #ifndef QLEGEND_P_H
31 31 #define QLEGEND_P_H
32 32
33 33 #include "qlegend.h"
34 34
35 35 QTCOMMERCIALCHART_BEGIN_NAMESPACE
36 36
37 37 class QChart;
38 38 class ChartPresenter;
39 39 class QAbstractSeries;
40 40 class LegendLayout;
41 41 class LegendMarker;
42 42 class Domain;
43 43
44 44 class QLegendPrivate : public QObject
45 45 {
46 46 Q_OBJECT
47 47 public:
48 48 QLegendPrivate(ChartPresenter *presenter, QChart *chart, QLegend *q);
49 49 ~QLegendPrivate();
50 50
51 51 void setOffset(qreal x, qreal y);
52 52 QPointF offset() const;
53 53 int roundness(qreal size);
54 54
55 55 QList<LegendMarker*> markers() { return m_markers; }
56 56 QGraphicsItemGroup* items() { return m_items; }
57 57
58 58 public Q_SLOTS:
59 59 void handleSeriesAdded(QAbstractSeries *series, Domain *domain);
60 60 void handleSeriesRemoved(QAbstractSeries *series);
61 61 void handleSeriesUpdated(QAbstractSeries *series);
62 void handleUpdatePieSeries(); //TODO remove this function
62 void handleUpdatePieSeries();
63 63 void handleSeriesVisibleChanged();
64 64
65 65 private:
66 66 QLegend *q_ptr;
67 67 ChartPresenter *m_presenter;
68 68 LegendLayout *m_layout;
69 69 QChart* m_chart;
70 70 QGraphicsItemGroup* m_items;
71 71 QList<LegendMarker*> m_markers;
72 72 Qt::Alignment m_alignment;
73 73 QBrush m_brush;
74 74 QPen m_pen;
75 75 QFont m_font;
76 76 QBrush m_labelBrush;
77 77
78 78 qreal m_diameter;
79 79 bool m_attachedToChart;
80 80 bool m_backgroundVisible;
81 81
82 82 friend class QLegend;
83 83
84 84 };
85 85
86 86 QTCOMMERCIALCHART_END_NAMESPACE
87 87
88 88 #endif
@@ -1,209 +1,204
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "qabstractseries.h"
22 22 #include "qabstractseries_p.h"
23 23 #include "chartdataset_p.h"
24 24
25 25 QTCOMMERCIALCHART_BEGIN_NAMESPACE
26 26
27 27 /*!
28 28 \class QAbstractSeries
29 29 \brief Base class for all QtCommercial Chart series.
30 30 \mainclass
31 31
32 32 Usually you use the series type specific inherited classes instead of the base class.
33 33 \sa QXYSeries, QLineSeries, QSplineSeries, QScatterSeries, QAreaSeries, QAbstractBarSeries, QStackedBarSeries,
34 34 QPercentBarSeries, QPieSeries
35 35 */
36 36 /*!
37 37 \qmlclass AbstractSeries
38 38 AbstractSeries is the base class for all series.
39 39 The class cannot be instantiated by the user.
40 40 */
41 41
42 42 /*!
43 43 \enum QAbstractSeries::SeriesType
44 44
45 45 The type of the series object.
46 46
47 47 \value SeriesTypeLine
48 48 \value SeriesTypeArea
49 49 \value SeriesTypeBar
50 50 \value SeriesTypeStackedBar
51 51 \value SeriesTypePercentBar
52 52 \value SeriesTypePie
53 53 \value SeriesTypeScatter
54 54 \value SeriesTypeSpline
55 55 \value SeriesTypeHorizontalBar
56 56 \value SeriesTypeHorizontalStackedBar
57 57 \value SeriesTypeHorizontalPercentBar
58 58 */
59 59
60 60 /*!
61 61 \property QAbstractSeries::type
62 62 The type of the series.
63 63 */
64 64 /*!
65 65 \qmlproperty ChartView.SeriesType AbstractSeries::type
66 66 The type of the series.
67 67 */
68 68
69 69 /*!
70 70 \property QAbstractSeries::name
71 71 \brief name of the series property. The name is shown in legend for QXYSeries.
72 72 */
73 73 /*!
74 74 \qmlproperty string AbstractSeries::name
75 75 Name of the series. The name is shown in legend for QXYSeries.
76 76 */
77 77
78 78 /*!
79 79 \fn void QAbstractSeries::nameChanged()
80 80 This signal is emitted when the series name changes.
81 81 */
82 82 /*!
83 83 \qmlsignal AbstractSeries::onNameChanged()
84 84 This signal is emitted when the series name changes.
85 85 */
86 86
87 87 /*!
88 88 \property QAbstractSeries::visible
89 89 \brief whether the series is visible or not; true by default.
90 90 */
91 91 /*!
92 92 \qmlproperty void AbstractSeries::visible
93 93 Visibility of the series. True by default.
94 94 */
95 95
96 96 /*!
97 97 \fn void QAbstractSeries::visibleChanged()
98 98 Emitted when the series visibility changes.
99 99 */
100 100 /*!
101 101 \qmlsignal AbstractSeries::onVisibleChanged()
102 102 Emitted when the series visibility changes.
103 103 */
104 104 /*!
105 105 \internal
106 106 \brief Constructs ChartSeries object with \a parent.
107 107 */
108 108 QAbstractSeries::QAbstractSeries(QAbstractSeriesPrivate &d, QObject *parent) :
109 109 QObject(parent),
110 110 d_ptr(&d)
111 111 {
112 112 }
113 113
114 114 /*!
115 115 \brief Virtual destructor for the chart series.
116 116 */
117 117 QAbstractSeries::~QAbstractSeries()
118 118 {
119 119 if(d_ptr->m_dataset) qFatal("Still binded series detected !");
120 120 }
121 121
122 122 void QAbstractSeries::setName(const QString& name)
123 123 {
124 124 if (name != d_ptr->m_name) {
125 125 d_ptr->m_name = name;
126 126 emit nameChanged();
127 127 }
128 128 }
129 129
130 130 QString QAbstractSeries::name() const
131 131 {
132 132 return d_ptr->m_name;
133 133 }
134 134
135 135 /*!
136 136 Sets the visibility of series to \a visible
137 137 */
138 138 void QAbstractSeries::setVisible(bool visible)
139 139 {
140 140 if (visible != d_ptr->m_visible) {
141 141 d_ptr->m_visible = visible;
142 142 emit visibleChanged();
143 143 }
144 144 }
145 145
146 146 /*!
147 147 Returns the visibility of series
148 148 */
149 149 bool QAbstractSeries::isVisible() const
150 150 {
151 151 return d_ptr->m_visible;
152 152 }
153 153
154 154 /*!
155 155 \brief Returns the chart where series belongs to.
156 156
157 157 Set automatically when the series is added to the chart
158 158 and unset when the series is removed from the chart.
159 159 */
160 160 QChart* QAbstractSeries::chart() const
161 161 {
162 162 return d_ptr->m_chart;
163 163 }
164 164
165 //void QAbstractSeries::adjustView()
166 //{
167 // //TODO:
168 //}
169
170 165 /*!
171 166 \brief Sets the visibility of the series to true
172 167
173 168 \sa setVisible(), isVisible()
174 169 */
175 170 void QAbstractSeries::show()
176 171 {
177 172 setVisible(true);
178 173 }
179 174
180 175 /*!
181 176 \brief Sets the visibility of the series to false
182 177
183 178 \sa setVisible(), isVisible()
184 179 */
185 180 void QAbstractSeries::hide()
186 181 {
187 182 setVisible(false);
188 183 }
189 184
190 185 ///////////////////////////////////////////////////////////////////////////////////////////////////
191 186
192 187 QAbstractSeriesPrivate::QAbstractSeriesPrivate(QAbstractSeries* q):
193 188 q_ptr(q),
194 189 m_chart(0),
195 190 m_dataset(0),
196 191 m_visible(true)
197 192 {
198 193 }
199 194
200 195 QAbstractSeriesPrivate::~QAbstractSeriesPrivate()
201 196 {
202 197 }
203 198
204 199 #include "moc_qabstractseries.cpp"
205 200 #include "moc_qabstractseries_p.cpp"
206 201
207 202 QTCOMMERCIALCHART_END_NAMESPACE
208 203
209 204
@@ -1,499 +1,490
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "qchart.h"
22 22 #include "qchart_p.h"
23 23 #include "legendscroller_p.h"
24 24 #include "qlegend_p.h"
25 25 #include "chartbackground_p.h"
26 26 #include "qabstractaxis.h"
27 27 #include <QGraphicsScene>
28 28 #include <QGraphicsSceneResizeEvent>
29 29 #include <QGraphicsLayout>
30 30
31 31 QTCOMMERCIALCHART_BEGIN_NAMESPACE
32 32
33 33 /*!
34 34 \enum QChart::ChartTheme
35 35
36 36 This enum describes the theme used by the chart.
37 37
38 38 \value ChartThemeLight The default theme
39 39 \value ChartThemeBlueCerulean
40 40 \value ChartThemeDark
41 41 \value ChartThemeBrownSand
42 42 \value ChartThemeBlueNcs
43 43 \value ChartThemeHighContrast
44 44 \value ChartThemeBlueIcy
45 45 */
46 46
47 47 /*!
48 48 \enum QChart::AnimationOption
49 49
50 50 For enabling/disabling animations. Defaults to NoAnimation.
51 51
52 52 \value NoAnimation
53 53 \value GridAxisAnimations
54 54 \value SeriesAnimations
55 55 \value AllAnimations
56 56 */
57 57
58 58 /*!
59 59 \class QChart
60 60 \brief QtCommercial chart API.
61 61
62 62 QChart is a QGraphicsWidget that you can show in a QGraphicsScene. It manages the graphical
63 63 representation of different types of series and other chart related objects like
64 64 QAxis and QLegend. If you simply want to show a chart in a layout, you can use the
65 65 convenience class QChartView instead of QChart.
66 66 \sa QChartView
67 67 */
68 68
69 69 /*!
70 70 \property QChart::animationOptions
71 71 The animation \a options for the chart. Animations are enabled/disabled based on this setting.
72 72 */
73 73
74 74 /*!
75 75 \property QChart::backgroundVisible
76 76 Whether the chart background is visible or not.
77 77 \sa setBackgroundBrush(), setBackgroundPen()
78 78 */
79 79
80 80 /*!
81 81 \property QChart::dropShadowEnabled
82 82 If set to true, the background drop shadow effect is enabled. If set to false, it is disabled. Note that the drop
83 83 shadow effect depends on theme, which means the setting may be changed if you switch to another theme.
84 84 */
85 85
86 86 /*!
87 87 \property QChart::minimumMargins
88 88 Minimum margins between the plot area (axes) and the edge of the chart widget.
89 89 */
90 90
91 91 /*!
92 92 \property QChart::theme
93 93 Theme is a built-in collection of UI style related settings applied for all visual elements of a chart, like colors,
94 94 pens, brushes and fonts of series, axes, title and legend. \l {Chart themes demo} shows an example with a few
95 95 different themes.
96 96 Note: changing the theme will overwrite all customizations previously applied to the series.
97 97 */
98 98
99 99 /*!
100 100 \property QChart::title
101 101 Title is the name (label) of a chart. It is shown as a headline on top of the chart.
102 102 */
103 103
104 104 /*!
105 105 Constructs a chart object which is a child of a\a parent. Parameter \a wFlags is passed to the QGraphicsWidget constructor.
106 106 */
107 107 QChart::QChart(QGraphicsItem *parent, Qt::WindowFlags wFlags) : QGraphicsWidget(parent,wFlags),
108 108 d_ptr(new QChartPrivate())
109 109 {
110 110 d_ptr->m_dataset = new ChartDataSet(this);
111 111 d_ptr->m_presenter = new ChartPresenter(this,d_ptr->m_dataset);
112 112 d_ptr->createConnections();
113 113 d_ptr->m_legend = new LegendScroller(this);
114 114 d_ptr->m_presenter->setTheme(QChart::ChartThemeLight, false);
115 115 //connect(d_ptr->m_presenter, SIGNAL(marginsChanged(QRectF)), this, SIGNAL(marginsChanged(QRectF)));
116 116 setLayout(d_ptr->m_presenter->layout());
117 117 }
118 118
119 119 /*!
120 120 Destroys the object and it's children, like series and axis objects added to it.
121 121 */
122 122 QChart::~QChart()
123 123 {
124 124 //delete first presenter , since this is a root of all the graphical items
125 125 setLayout(0);
126 126 delete d_ptr->m_presenter;
127 127 d_ptr->m_presenter=0;
128 128 }
129 129
130 130 /*!
131 131 Adds the \a series onto the chart and takes the ownership of the object.
132 132 If auto scaling is enabled, re-scales the axes the series is bound to (both the x axis and
133 133 the y axis).
134 134
135 135 \sa removeSeries(), removeAllSeries()
136 136 */
137 137 void QChart::addSeries(QAbstractSeries *series)
138 138 {
139 139 Q_ASSERT(series);
140 140 d_ptr->m_dataset->addSeries(series);
141 141 }
142 142
143 143 /*!
144 144 Removes the \a series specified in a perameter from the QChartView.
145 145 It releses its ownership of the specified QChartSeries object.
146 146 It does not delete the pointed QChartSeries data object
147 147 \sa addSeries(), removeAllSeries()
148 148 */
149 149 void QChart::removeSeries(QAbstractSeries *series)
150 150 {
151 151 Q_ASSERT(series);
152 152 d_ptr->m_dataset->removeSeries(series);
153 153 }
154 154
155 155 /*!
156 156 Removes all the QChartSeries that have been added to the QChartView
157 157 It also deletes the pointed QChartSeries data objects
158 158 \sa addSeries(), removeSeries()
159 159 */
160 160 void QChart::removeAllSeries()
161 161 {
162 162 d_ptr->m_dataset->removeAllSeries();
163 163 }
164 164
165 165 /*!
166 166 Sets the \a brush that is used for painting the background of the chart area.
167 167 */
168 168 void QChart::setBackgroundBrush(const QBrush& brush)
169 169 {
170 170 d_ptr->m_presenter->setBackgroundBrush(brush);
171 171 }
172 172
173 173 /*!
174 174 Gets the brush that is used for painting the background of the chart area.
175 175 */
176 176 QBrush QChart::backgroundBrush() const
177 177 {
178 178 return d_ptr->m_presenter->backgroundBrush();
179 179 }
180 180
181 181 /*!
182 182 Sets the \a pen that is used for painting the background of the chart area.
183 183 */
184 184 void QChart::setBackgroundPen(const QPen& pen)
185 185 {
186 186 d_ptr->m_presenter->setBackgroundPen(pen);
187 187 }
188 188
189 189 /*!
190 190 Gets the pen that is used for painting the background of the chart area.
191 191 */
192 192 QPen QChart::backgroundPen() const
193 193 {
194 194 return d_ptr->m_presenter->backgroundPen();
195 195 }
196 196
197 197 /*!
198 198 Sets the chart \a title. The description text that is drawn above the chart.
199 199 */
200 200 void QChart::setTitle(const QString& title)
201 201 {
202 202 d_ptr->m_presenter->setTitle(title);
203 203 }
204 204
205 205 /*!
206 206 Returns the chart title. The description text that is drawn above the chart.
207 207 */
208 208 QString QChart::title() const
209 209 {
210 210 return d_ptr->m_presenter->title();
211 211 }
212 212
213 213 /*!
214 214 Sets the \a font that is used for drawing the chart description text that is rendered above the chart.
215 215 */
216 216 void QChart::setTitleFont(const QFont& font)
217 217 {
218 218 d_ptr->m_presenter->setTitleFont(font);
219 219 }
220 220
221 221 /*!
222 222 Gets the font that is used for drawing the chart description text that is rendered above the chart.
223 223 */
224 224 QFont QChart::titleFont() const
225 225 {
226 226 return d_ptr->m_presenter->titleFont();
227 227 }
228 228
229 229 /*!
230 230 Sets the \a brush used for rendering the title text.
231 231 */
232 232 void QChart::setTitleBrush(const QBrush &brush)
233 233 {
234 234 d_ptr->m_presenter->setTitleBrush(brush);
235 235 }
236 236
237 237 /*!
238 238 Returns the brush used for rendering the title text.
239 239 */
240 240 QBrush QChart::titleBrush() const
241 241 {
242 242 return d_ptr->m_presenter->titleBrush();
243 243 }
244 244
245 245 void QChart::setTheme(QChart::ChartTheme theme)
246 246 {
247 247 d_ptr->m_presenter->setTheme(theme);
248 248 }
249 249
250 250 QChart::ChartTheme QChart::theme() const
251 251 {
252 252 return d_ptr->m_presenter->theme();
253 253 }
254 254
255 255 /*!
256 256 Zooms in the view by a factor of 2
257 257 */
258 258 void QChart::zoomIn()
259 259 {
260 260 d_ptr->m_presenter->zoomIn(2.0);
261 261 }
262 262
263 263 /*!
264 264 Zooms in the view to a maximum level at which \a rect is still fully visible.
265 265 */
266 266 void QChart::zoomIn(const QRectF& rect)
267 267 {
268 268 if (!rect.isValid()) return;
269 269 d_ptr->m_presenter->zoomIn(rect);
270 270 }
271 271
272 272 /*!
273 273 Restores the view zoom level to the previous one.
274 274 */
275 275 void QChart::zoomOut()
276 276 {
277 277 d_ptr->m_presenter->zoomOut(2.0);
278 278 }
279 279
280 280 /*!
281 281 Zooms in the view by a \a factor.
282 282
283 283 A factor over 1.0 zooms the view in and factor between 0.0 and 1.0 zooms out.
284 284 */
285 285 void QChart::zoom(qreal factor)
286 286 {
287 287 if (qFuzzyIsNull(factor))
288 288 return;
289 289
290 290 if (qFuzzyCompare(factor, (qreal)1.0))
291 291 return;
292 292
293 293 if (factor < 0)
294 294 return;
295 295
296 296 if (factor > 1.0)
297 297 d_ptr->m_presenter->zoomIn(factor);
298 298 else
299 299 d_ptr->m_presenter->zoomOut(1.0 / factor);
300 300 }
301 301
302 302 /*!
303 303 Returns the pointer to the x axis object of the chart asociated with the specified \a series
304 304 If no series is provided then pointer to currently visible axis is provided
305 305 */
306 306 QAbstractAxis* QChart::axisX(QAbstractSeries* series) const
307 307 {
308 308 return d_ptr->m_dataset->axisX(series);
309 309 }
310 310
311 311 /*!
312 312 Returns the pointer to the y axis object of the chart asociated with the specified \a series
313 313 If no series is provided then pointer to currently visible axis is provided
314 314 */
315 315 QAbstractAxis* QChart::axisY(QAbstractSeries *series) const
316 316 {
317 317 return d_ptr->m_dataset->axisY(series);
318 318 }
319 319
320 320 /*!
321 321 NOTICE: This function has to be called after series has been added to the chart if no customized axes are set to the chart. Otherwise axisX(), axisY() calls return NULL.
322 322
323 323 Creates the axes for the chart based on the series that has already been added to the chart.
324 324
325 325 \table
326 326 \header
327 327 \o Series type
328 328 \o X-axis
329 329 \o Y-axis
330 330 \row
331 331 \o QXYSeries
332 332 \o QValueAxis
333 333 \o QValueAxis
334 334 \row
335 335 \o QBarSeries
336 336 \o QBarCategoryAxis
337 337 \o QValueAxis
338 338 \row
339 339 \o QPieSeries
340 340 \o None
341 341 \o None
342 342 \endtable
343 343
344 344 If there are several QXYSeries derived series added to the chart and no other series type has been added then only one pair of axes is created.
345 345 If there are sevaral series added of different types then each series gets its own axes pair.
346 346
347 347 NOTICE: if there is more than one x and y axes created then no axis is drawn by default and one needs to choose explicitly which axis should be shown.
348 348
349 349 Axis specifix to the series can be later obtained from the chart by providing the series as the parameter of axisX(), axisY() function calls.
350 350 QPieSeries does not create any axes.
351 351
352 352 \sa axisX(), axisY(), setAxisX(), setAxisY()
353 353 */
354 354 void QChart::createDefaultAxes()
355 355 {
356 356 d_ptr->m_dataset->createDefaultAxes();
357 357 }
358 358
359 359 /*!
360 360 Returns the legend object of the chart. Ownership stays in chart.
361 361 */
362 362 QLegend* QChart::legend() const
363 363 {
364 364 return d_ptr->m_legend;
365 365 }
366 366
367 367 /*!
368 368 Sets the minimum \a margins between the plot area (axes) and the edge of the chart widget.
369 369 */
370 370 void QChart::setMinimumMargins(const QMargins& margins)
371 371 {
372 372 d_ptr->m_presenter->setMinimumMargins(margins);
373 373 }
374 374
375 375 /*!
376 376 Returns the rect that contains information about margins (distance between chart widget edge and axes).
377 377 Individual margins can be obtained by calling left, top, right, bottom on the returned rect.
378 378 */
379 379 QMargins QChart::minimumMargins() const
380 380 {
381 381 return d_ptr->m_presenter->minimumMargins();
382 382 }
383 383
384 384 /*!
385 385 Returns the the rect within which the drawing of the chart is done.
386 386 It does not include the area defines by margins.
387 387 */
388 388 QRectF QChart::plotArea() const
389 389 {
390 390 return d_ptr->m_presenter->geometry();
391 391 }
392 392
393 ///*!
394 // TODO: Dummy.
395 // Adjest the ranges of the axes so that all the data of the specified \a series is visible
396 // */
397 //void QChart::adjustViewToSeries(QAbstractSeries* series)
398 //{
399 // //
400 //}
401
402 393 /*!
403 394 Sets animation \a options for the chart
404 395 */
405 396 void QChart::setAnimationOptions(AnimationOptions options)
406 397 {
407 398 d_ptr->m_presenter->setAnimationOptions(options);
408 399 }
409 400
410 401 QChart::AnimationOptions QChart::animationOptions() const
411 402 {
412 403 return d_ptr->m_presenter->animationOptions();
413 404 }
414 405
415 406 /*!
416 407 Scrolls the visible area of the chart by the distance defined in the \a dx and \a dy.
417 408 */
418 409 void QChart::scroll(qreal dx, qreal dy)
419 410 {
420 411 d_ptr->m_presenter->scroll(dx, dy);
421 412 }
422 413
423 414 void QChart::setBackgroundVisible(bool visible)
424 415 {
425 416 d_ptr->m_presenter->setBackgroundVisible(visible);
426 417 }
427 418
428 419 bool QChart::isBackgroundVisible() const
429 420 {
430 421 return d_ptr->m_presenter->isBackgroundVisible();
431 422 }
432 423
433 424 void QChart::setDropShadowEnabled(bool enabled)
434 425 {
435 426 d_ptr->m_presenter->setBackgroundDropShadowEnabled(enabled);
436 427 }
437 428
438 429 bool QChart::isDropShadowEnabled() const
439 430 {
440 431 return d_ptr->m_presenter->isBackgroundDropShadowEnabled();
441 432 }
442 433
443 434 /*!
444 435 Returns all the series that are added to the chart.
445 436
446 437 \sa addSeries(), removeSeries(), removeAllSeries()
447 438 */
448 439 QList<QAbstractSeries*> QChart::series() const
449 440 {
450 441 return d_ptr->m_dataset->series();
451 442 }
452 443
453 444 /*!
454 445 Sets \a axis to the chart, which will control the presentation of the \a series
455 446
456 447 \sa axisX(), axisY(), setAxisY(), createDefaultAxes()
457 448 */
458 449 void QChart::setAxisX(QAbstractAxis* axis , QAbstractSeries *series)
459 450 {
460 451 d_ptr->m_dataset->setAxis(series,axis,Qt::Horizontal);
461 452 }
462 453
463 454 /*!
464 455 Sets \a axis to the chart, which will control the presentation of the \a series
465 456
466 457 \sa axisX(), axisY(), setAxisX(), createDefaultAxes()
467 458 */
468 459 void QChart::setAxisY( QAbstractAxis* axis , QAbstractSeries *series)
469 460 {
470 461 d_ptr->m_dataset->setAxis(series,axis,Qt::Vertical);
471 462 }
472 463
473 464 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
474 465
475 466 QChartPrivate::QChartPrivate():
476 467 m_legend(0),
477 468 m_dataset(0),
478 469 m_presenter(0)
479 470 {
480 471
481 472 }
482 473
483 474 QChartPrivate::~QChartPrivate()
484 475 {
485 476
486 477 }
487 478
488 479 void QChartPrivate::createConnections()
489 480 {
490 481 QObject::connect(m_dataset,SIGNAL(seriesAdded(QAbstractSeries*,Domain*)),m_presenter,SLOT(handleSeriesAdded(QAbstractSeries*,Domain*)));
491 482 QObject::connect(m_dataset,SIGNAL(seriesRemoved(QAbstractSeries*)),m_presenter,SLOT(handleSeriesRemoved(QAbstractSeries*)));
492 483 QObject::connect(m_dataset,SIGNAL(axisAdded(QAbstractAxis*,Domain*)),m_presenter,SLOT(handleAxisAdded(QAbstractAxis*,Domain*)));
493 484 QObject::connect(m_dataset,SIGNAL(axisRemoved(QAbstractAxis*)),m_presenter,SLOT(handleAxisRemoved(QAbstractAxis*)));
494 485 //QObject::connect(m_presenter, SIGNAL(marginsChanged(QRectF)), q_ptr, SIGNAL(marginsChanged(QRectF)));
495 486 }
496 487
497 488 #include "moc_qchart.cpp"
498 489
499 490 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,194 +1,193
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "scatterchartitem_p.h"
22 22 #include "qscatterseries.h"
23 23 #include "qscatterseries_p.h"
24 24 #include "chartpresenter_p.h"
25 25 #include <QPainter>
26 26 #include <QGraphicsScene>
27 27 #include <QDebug>
28 28 #include <QGraphicsSceneMouseEvent>
29 29
30 30 QTCOMMERCIALCHART_BEGIN_NAMESPACE
31 31
32 32 ScatterChartItem::ScatterChartItem(QScatterSeries *series, ChartPresenter *presenter) :
33 33 XYChart(series,presenter),
34 34 QGraphicsItem(presenter ? presenter->rootItem() : 0),
35 35 m_series(series),
36 36 m_items(this),
37 37 m_visible(true),
38 38 m_shape(QScatterSeries::MarkerShapeRectangle),
39 39 m_size(15)
40 40 {
41 41 QObject::connect(m_series->d_func(),SIGNAL(updated()), this, SLOT(handleUpdated()));
42 42 QObject::connect(m_series, SIGNAL(visibleChanged()), this, SLOT(handleUpdated()));
43 43
44 44 setZValue(ChartPresenter::ScatterSeriesZValue);
45 45 setFlags(QGraphicsItem::ItemClipsChildrenToShape);
46 46
47 47 handleUpdated();
48 48
49 49 m_items.setHandlesChildEvents(false);
50 50 }
51 51
52 52 QRectF ScatterChartItem::boundingRect() const
53 53 {
54 54 return m_rect;
55 55 }
56 56
57 57 void ScatterChartItem::createPoints(int count)
58 58 {
59 59 for (int i = 0; i < count; ++i) {
60 60
61 61 QGraphicsItem *item = 0;
62 62
63 63 switch (m_shape) {
64 64 case QScatterSeries::MarkerShapeCircle: {
65 65 item = new CircleMarker(0,0,m_size,m_size,this);
66 66 const QRectF& rect = item->boundingRect();
67 67 item->setPos(-rect.width()/2,-rect.height()/2);
68 68 break;
69 69 }
70 70 case QScatterSeries::MarkerShapeRectangle: {
71 71 item = new RectangleMarker(0,0,m_size,m_size,this);
72 72 item->setPos(-m_size/2,-m_size/2);
73 73 break;
74 74 }
75 75 default:
76 76 qWarning()<<"Unsupported marker type";
77 77 break;
78 78
79 79 }
80 80 m_items.addToGroup(item);
81 81 }
82 82 }
83 83
84 84 void ScatterChartItem::deletePoints(int count)
85 85 {
86 86 QList<QGraphicsItem *> items = m_items.childItems();
87 87
88 88 for (int i = 0; i < count; ++i) {
89 89 QGraphicsItem * item = items.takeLast();
90 90 m_markerMap.remove(item);
91 91 delete(item);
92 92 }
93 93 }
94 94
95 95 void ScatterChartItem::markerSelected(QGraphicsItem *marker)
96 96 {
97 97 emit XYChart::clicked(calculateDomainPoint(m_markerMap[marker]));
98 98 }
99 99
100 100 void ScatterChartItem::updateGeometry()
101 101 {
102 102
103 103 const QVector<QPointF>& points = geometryPoints();
104 104
105 105 if(points.size()==0)
106 106 {
107 107 deletePoints(m_items.childItems().count());
108 108 return;
109 109 }
110 110
111 111 int diff = m_items.childItems().size() - points.size();
112 112
113 113 if(diff>0) {
114 114 deletePoints(diff);
115 115 }
116 116 else if(diff<0) {
117 117 createPoints(-diff);
118 118 }
119 119
120 120 if(diff!=0) handleUpdated();
121 121
122 122 QList<QGraphicsItem*> items = m_items.childItems();
123 123
124 124 for (int i = 0; i < points.size(); i++) {
125 125 QGraphicsItem* item = items.at(i);
126 126 const QPointF& point = points.at(i);
127 127 const QRectF& rect = item->boundingRect();
128 128 m_markerMap[item]=point;
129 129 item->setPos(point.x()-rect.width()/2,point.y()-rect.height()/2);
130 130 if(!m_visible || !clipRect().contains(point)) {
131 131 item->setVisible(false);
132 132 }
133 133 else {
134 134 item->setVisible(true);
135 135 }
136 136 }
137 137
138 138 prepareGeometryChange();
139 139 m_rect = clipRect();
140 140 setPos(origin());
141 141 }
142 142
143 143 void ScatterChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
144 144 {
145 145 Q_UNUSED(painter)
146 146 Q_UNUSED(option)
147 147 Q_UNUSED(widget)
148 148 }
149 149
150 150 void ScatterChartItem::setPen(const QPen& pen)
151 151 {
152 152 foreach(QGraphicsItem* item , m_items.childItems()) {
153 153 static_cast<QAbstractGraphicsShapeItem*>(item)->setPen(pen);
154 154 }
155 155 }
156 156
157 157 void ScatterChartItem::setBrush(const QBrush& brush)
158 158 {
159 159 foreach(QGraphicsItem* item , m_items.childItems()) {
160 160 static_cast<QAbstractGraphicsShapeItem*>(item)->setBrush(brush);
161 161 }
162 162 }
163 163
164 164 void ScatterChartItem::handleUpdated()
165 165 {
166 166 int count = m_items.childItems().count();
167 167
168 168 if(count==0) return;
169 169
170 170 bool recreate = m_visible != m_series->isVisible()
171 171 || m_size != m_series->markerSize()
172 172 || m_shape != m_series->markerShape();
173 173
174 174 m_visible = m_series->isVisible();
175 175 m_size = m_series->markerSize();
176 176 m_shape = m_series->markerShape();
177 177
178 178 if(recreate) {
179 // TODO: optimize handleUpdate to recreate points only in case shape changed
180 179 deletePoints(count);
181 180 createPoints(count);
182 181
183 182 // Updating geometry is now safe, because it won't call handleUpdated unless it creates/deletes points
184 183 updateGeometry();
185 184 }
186 185
187 186 setPen(m_series->pen());
188 187 setBrush(m_series->brush());
189 188 update();
190 189 }
191 190
192 191 #include "moc_scatterchartitem_p.cpp"
193 192
194 193 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,227 +1,225
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "xychart_p.h"
22 22 #include "qxyseries.h"
23 23 #include "qxyseries_p.h"
24 24 #include "chartpresenter_p.h"
25 25 #include "domain_p.h"
26 26 #include "qxymodelmapper.h"
27 27 #include <QPainter>
28 28 #include <QAbstractItemModel>
29 29
30 30
31 31 QTCOMMERCIALCHART_BEGIN_NAMESPACE
32 32
33 //TODO: optimize : remove points which are not visible
34
35 33 XYChart::XYChart(QXYSeries *series, ChartPresenter *presenter):ChartElement(presenter),
36 34 m_minX(0),
37 35 m_maxX(0),
38 36 m_minY(0),
39 37 m_maxY(0),
40 38 m_series(series),
41 39 m_animation(0),
42 40 m_dirty(true)
43 41 {
44 42 QObject::connect(series, SIGNAL(pointReplaced(int)), this, SLOT(handlePointReplaced(int)));
45 43 QObject::connect(series, SIGNAL(pointsReplaced()), this, SLOT(handlePointsReplaced()));
46 44 QObject::connect(series, SIGNAL(pointAdded(int)), this, SLOT(handlePointAdded(int)));
47 45 QObject::connect(series, SIGNAL(pointRemoved(int)), this, SLOT(handlePointRemoved(int)));
48 46 QObject::connect(this, SIGNAL(clicked(QPointF)), series, SIGNAL(clicked(QPointF)));
49 47 }
50 48
51 49 void XYChart::setGeometryPoints(const QVector<QPointF>& points)
52 50 {
53 51 m_points = points;
54 52 }
55 53
56 54 void XYChart::setClipRect(const QRectF &rect)
57 55 {
58 56 m_clipRect = rect;
59 57 }
60 58
61 59 void XYChart::setAnimation(XYAnimation* animation)
62 60 {
63 61 m_animation=animation;
64 62 }
65 63
66 64 void XYChart::setDirty(bool dirty)
67 65 {
68 66 m_dirty=dirty;
69 67 }
70 68
71 69 QPointF XYChart::calculateGeometryPoint(const QPointF &point) const
72 70 {
73 71 const qreal deltaX = m_size.width()/(m_maxX-m_minX);
74 72 const qreal deltaY = m_size.height()/(m_maxY-m_minY);
75 73 qreal x = (point.x() - m_minX)* deltaX;
76 74 qreal y = (point.y() - m_minY)*-deltaY + m_size.height();
77 75 return QPointF(x,y);
78 76 }
79 77
80 78 QPointF XYChart::calculateGeometryPoint(int index) const
81 79 {
82 80 const qreal deltaX = m_size.width()/(m_maxX-m_minX);
83 81 const qreal deltaY = m_size.height()/(m_maxY-m_minY);
84 82 const QList<QPointF>& vector = m_series->points();
85 83 qreal x = (vector[index].x() - m_minX)* deltaX;
86 84 qreal y = (vector[index].y() - m_minY)*-deltaY + m_size.height();
87 85 return QPointF(x,y);
88 86 }
89 87
90 88 QVector<QPointF> XYChart::calculateGeometryPoints() const
91 89 {
92 90 const qreal deltaX = m_size.width()/(m_maxX-m_minX);
93 91 const qreal deltaY = m_size.height()/(m_maxY-m_minY);
94 92
95 93 QVector<QPointF> result;
96 94 result.resize(m_series->count());
97 95 const QList<QPointF>& vector = m_series->points();
98 96 for (int i = 0; i < m_series->count(); ++i) {
99 97 qreal x = (vector[i].x() - m_minX)* deltaX;
100 98 qreal y = (vector[i].y() - m_minY)*-deltaY + m_size.height();
101 99 result[i].setX(x);
102 100 result[i].setY(y);
103 101 }
104 102 return result;
105 103 }
106 104
107 105 QPointF XYChart::calculateDomainPoint(const QPointF &point) const
108 106 {
109 107 const qreal deltaX = m_size.width()/(m_maxX-m_minX);
110 108 const qreal deltaY = m_size.height()/(m_maxY-m_minY);
111 109 qreal x = point.x()/deltaX +m_minX;
112 110 qreal y = (point.y()-m_size.height())/(-deltaY)+ m_minY;
113 111 return QPointF(x,y);
114 112 }
115 113
116 114 void XYChart::updateChart(QVector<QPointF> &oldPoints, QVector<QPointF> &newPoints,int index)
117 115 {
118 116
119 117 if (m_animation) {
120 118 m_animation->setup(oldPoints, newPoints, index);
121 119 m_points = newPoints;
122 120 setDirty(false);
123 121 presenter()->startAnimation(m_animation);
124 122 }
125 123 else {
126 124 m_points = newPoints;
127 125 updateGeometry();
128 126 }
129 127 }
130 128
131 129 //handlers
132 130
133 131 void XYChart::handlePointAdded(int index)
134 132 {
135 133 Q_ASSERT(index<m_series->count());
136 134 Q_ASSERT(index>=0);
137 135
138 136 QVector<QPointF> points;
139 137
140 138 if(m_dirty) {
141 139 points = calculateGeometryPoints();
142 140 } else {
143 141 points = m_points;
144 142 QPointF point = calculateGeometryPoint(index);
145 143 points.insert(index, point);
146 144 }
147 145
148 146 updateChart(m_points,points,index);
149 147 }
150 148
151 149 void XYChart::handlePointRemoved(int index)
152 150 {
153 151 Q_ASSERT(index<=m_series->count());
154 152 Q_ASSERT(index>=0);
155 153
156 154 QVector<QPointF> points;
157 155
158 156 if(m_dirty) {
159 157 points = calculateGeometryPoints();
160 158 } else {
161 159 points = m_points;
162 160 points.remove(index);
163 161 }
164 162
165 163 updateChart(m_points,points,index);
166 164 }
167 165
168 166 void XYChart::handlePointReplaced(int index)
169 167 {
170 168 Q_ASSERT(index<m_series->count());
171 169 Q_ASSERT(index>=0);
172 170
173 171 QVector<QPointF> points;
174 172
175 173 if(m_dirty) {
176 174 points = calculateGeometryPoints();
177 175 } else {
178 176 QPointF point = calculateGeometryPoint(index);
179 177 points = m_points;
180 178 points.replace(index,point);
181 179 }
182 180
183 181 updateChart(m_points,points,index);
184 182 }
185 183
186 184 void XYChart::handlePointsReplaced()
187 185 {
188 186 // All the points were replaced -> recalculate
189 187 QVector<QPointF> points = calculateGeometryPoints();
190 188 updateChart(m_points, points, -1);
191 189 }
192 190
193 191 void XYChart::handleDomainUpdated()
194 192 {
195 193 m_minX=domain()->minX();
196 194 m_maxX=domain()->maxX();
197 195 m_minY=domain()->minY();
198 196 m_maxY=domain()->maxY();
199 197 if (isEmpty()) return;
200 198
201 199 QVector<QPointF> points = calculateGeometryPoints();
202 200
203 201 updateChart(m_points,points);
204 202 }
205 203
206 204 void XYChart::handleGeometryChanged(const QRectF &rect)
207 205 {
208 206 Q_ASSERT(rect.isValid());
209 207 m_size=rect.size();
210 208 m_clipRect=rect.translated(-rect.topLeft());
211 209 m_origin=rect.topLeft();
212 210
213 211 if (isEmpty()) return;
214 212
215 213 QVector<QPointF> points = calculateGeometryPoints();
216 214
217 215 updateChart(m_points,points);
218 216 }
219 217
220 218 bool XYChart::isEmpty()
221 219 {
222 220 return !m_clipRect.isValid() || qFuzzyIsNull(m_maxX - m_minX) || qFuzzyIsNull(m_maxY - m_minY) || m_series->points().isEmpty();
223 221 }
224 222
225 223 #include "moc_xychart_p.cpp"
226 224
227 225 QTCOMMERCIALCHART_END_NAMESPACE
General Comments 0
You need to be logged in to leave comments. Login now