##// END OF EJS Templates
Squashed bunch of warnings
Tero Ahola -
r611:e622b3a8d8a0
parent child
Show More
@@ -1,120 +1,121
1 1 #include "areachartitem_p.h"
2 2 #include "qareaseries.h"
3 3 #include "qlineseries.h"
4 4 #include "chartpresenter_p.h"
5 5 #include <QPainter>
6 6 #include <QGraphicsSceneMouseEvent>
7 7
8 8
9 9 QTCOMMERCIALCHART_BEGIN_NAMESPACE
10 10
11 11 //TODO: optimize : remove points which are not visible
12 12
13 13 AreaChartItem::AreaChartItem(QAreaSeries* areaSeries,QGraphicsItem *parent):ChartItem(parent),
14 14 m_series(areaSeries),
15 15 m_upper(0),
16 16 m_lower(0),
17 17 m_pointsVisible(false)
18 18 {
19 19 setZValue(ChartPresenter::LineChartZValue);
20 20 m_upper = new AreaBoundItem(this,m_series->upperSeries());
21 21 if(m_series->lowerSeries()){
22 22 m_lower = new AreaBoundItem(this,m_series->lowerSeries());
23 23 }
24 24
25 25 QObject::connect(areaSeries,SIGNAL(updated()),this,SLOT(handleUpdated()));
26 26 QObject::connect(this,SIGNAL(clicked(const QPointF&)),areaSeries,SIGNAL(clicked(const QPointF&)));
27 27
28 28 handleUpdated();
29 29 }
30 30
31 31 AreaChartItem::~AreaChartItem()
32 32 {
33 33 delete m_upper;
34 34 delete m_lower;
35 35 };
36 36
37 37 QRectF AreaChartItem::boundingRect() const
38 38 {
39 39 return m_rect;
40 40 }
41 41
42 42 QPainterPath AreaChartItem::shape() const
43 43 {
44 44 return m_path;
45 45 }
46 46
47 47 void AreaChartItem::updatePath()
48 48 {
49 49 QPainterPath path;
50 50
51 51 path.connectPath(m_upper->shape());
52 52 if(m_lower){
53 53 path.connectPath(m_lower->shape().toReversed());
54 54 }
55 55 else{
56 56 QPointF first = path.pointAtPercent(0);
57 57 QPointF last = path.pointAtPercent(1);
58 58 path.lineTo(last.x(),m_clipRect.bottom());
59 59 path.lineTo(first.x(),m_clipRect.bottom());
60 60 }
61 61 path.closeSubpath();
62 62 prepareGeometryChange();
63 63 m_path=path;
64 64 m_rect=path.boundingRect();
65 65 update();
66 66 }
67 67
68 68 void AreaChartItem::handleUpdated()
69 69 {
70 70 m_pointsVisible = m_series->pointsVisible();
71 71 m_linePen = m_series->pen();
72 72 m_brush = m_series->brush();
73 73 m_pointPen = m_series->pen();
74 74 m_pointPen.setWidthF(2*m_pointPen.width());
75 75
76 76 update();
77 77 }
78 78
79 79 void AreaChartItem::handleDomainChanged(qreal minX, qreal maxX, qreal minY, qreal maxY)
80 80 {
81 81 m_upper->handleDomainChanged(minX,maxX,minY,maxY);
82 82 if(m_lower)
83 83 m_lower->handleDomainChanged(minX,maxX,minY,maxY);
84 84 }
85 85
86 86 void AreaChartItem::handleGeometryChanged(const QRectF& rect)
87 87 {
88 88 m_clipRect=rect.translated(-rect.topLeft());
89 89 setPos(rect.topLeft());
90 90 m_upper->handleGeometryChanged(rect);
91 91 if(m_lower)
92 92 m_lower->handleGeometryChanged(rect);
93 93 }
94 94 //painter
95 95
96 96 void AreaChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
97 97 {
98 Q_UNUSED(widget);
99 Q_UNUSED(option);
98 Q_UNUSED(widget)
99 Q_UNUSED(option)
100
100 101 painter->save();
101 102 painter->setPen(m_linePen);
102 103 painter->setBrush(m_brush);
103 104 painter->setClipRect(m_clipRect);
104 105 painter->drawPath(m_path);
105 106 if(m_pointsVisible){
106 107 painter->setPen(m_pointPen);
107 108 painter->drawPoints(m_upper->points());
108 109 if(m_lower) painter->drawPoints(m_lower->points());
109 110 }
110 111 painter->restore();
111 112 }
112 113
113 114 void AreaChartItem::mousePressEvent( QGraphicsSceneMouseEvent * event )
114 115 {
115 116 emit clicked(m_upper->calculateDomainPoint(event->pos()));
116 117 }
117 118
118 119 #include "moc_areachartitem_p.cpp"
119 120
120 121 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,406 +1,406
1 1 #include "axisitem_p.h"
2 2 #include "qchartaxis.h"
3 3 #include "chartpresenter_p.h"
4 4 #include "chartanimator_p.h"
5 5 #include <QPainter>
6 6 #include <QDebug>
7 7
8 8 static int label_padding = 5;
9 9
10 10 QTCOMMERCIALCHART_BEGIN_NAMESPACE
11 11
12 12 AxisItem::AxisItem(QChartAxis* axis,ChartPresenter* presenter,AxisType type,QGraphicsItem* parent) :
13 13 ChartItem(parent),
14 14 m_presenter(presenter),
15 15 m_chartAxis(axis),
16 16 m_type(type),
17 17 m_labelsAngle(0),
18 18 m_grid(parent),
19 19 m_shades(parent),
20 20 m_labels(parent),
21 21 m_axis(parent),
22 22 m_min(0),
23 23 m_max(0),
24 24 m_ticksCount(0)
25 25 {
26 26 //initial initialization
27 27 m_axis.setZValue(ChartPresenter::AxisZValue);
28 28 m_shades.setZValue(ChartPresenter::ShadesZValue);
29 29 m_grid.setZValue(ChartPresenter::GridZValue);
30 30 setFlags(QGraphicsItem::ItemHasNoContents);
31 31
32 32 QObject::connect(m_chartAxis,SIGNAL(updated()),this,SLOT(handleAxisUpdated()));
33 33 QObject::connect(m_chartAxis->categories(),SIGNAL(updated()),this,SLOT(handleAxisCategoriesUpdated()));
34 34
35 35 handleAxisUpdated();
36 36 }
37 37
38 38 AxisItem::~AxisItem()
39 39 {
40 40 }
41 41
42 42 QRectF AxisItem::boundingRect() const
43 43 {
44 44 return QRectF();
45 45 }
46 46
47 47 void AxisItem::createItems(int count)
48 48 {
49 49
50 50 if(m_axis.children().size()==0)
51 51 m_axis.addToGroup(new QGraphicsLineItem());
52 52 for (int i = 0; i < count; ++i) {
53 53 m_grid.addToGroup(new QGraphicsLineItem());
54 54 m_labels.addToGroup(new QGraphicsSimpleTextItem());
55 55 m_axis.addToGroup(new QGraphicsLineItem());
56 56 if((m_grid.childItems().size())%2 && m_grid.childItems().size()>2) m_shades.addToGroup(new QGraphicsRectItem());
57 57 }
58 58 }
59 59
60 60 void AxisItem::deleteItems(int count)
61 61 {
62 62 QList<QGraphicsItem *> lines = m_grid.childItems();
63 63 QList<QGraphicsItem *> labels = m_labels.childItems();
64 64 QList<QGraphicsItem *> shades = m_shades.childItems();
65 65 QList<QGraphicsItem *> axis = m_axis.childItems();
66 66
67 67 for (int i = 0; i < count; ++i) {
68 68 if(lines.size()%2 && lines.size()>1) delete(shades.takeLast());
69 69 delete(lines.takeLast());
70 70 delete(labels.takeLast());
71 71 delete(axis.takeLast());
72 72 }
73 73 }
74 74
75 75 void AxisItem::updateLayout(QVector<qreal>& layout)
76 76 {
77 77 if(m_animator){
78 78 m_animator->applyLayout(this,layout);
79 79 }
80 80 else setLayout(layout);
81 81 }
82 82
83 83 QStringList AxisItem::createLabels(int ticks, qreal min, qreal max) const
84 84 {
85 85 Q_ASSERT(max>=min);
86 86 Q_ASSERT(ticks>0);
87 87
88 88 QStringList labels;
89 89
90 90 QChartAxisCategories* categories = m_chartAxis->categories();
91 91
92 92 for(int i=0; i< ticks; i++) {
93 93 qreal value = min + (i * (max - min)/ (ticks-1));
94 94 if(categories->count()==0) {
95 95 labels << QString::number(value);
96 96 }
97 97 else {
98 98
99 99 QString label = categories->label(value);
100 100 labels << label;
101 101 }
102 102 }
103 103 return labels;
104 104 }
105 105
106 106 void AxisItem::setAxisOpacity(qreal opacity)
107 107 {
108 108 m_axis.setOpacity(opacity);
109 109 }
110 110
111 111 qreal AxisItem::axisOpacity() const
112 112 {
113 113 return m_axis.opacity();
114 114 }
115 115
116 116 void AxisItem::setGridOpacity(qreal opacity)
117 117 {
118 118 m_grid.setOpacity(opacity);
119 119 }
120 120
121 121 qreal AxisItem::gridOpacity() const
122 122 {
123 123 return m_grid.opacity();
124 124 }
125 125
126 126 void AxisItem::setLabelsOpacity(qreal opacity)
127 127 {
128 128 m_labels.setOpacity(opacity);
129 129 }
130 130
131 131 qreal AxisItem::labelsOpacity() const
132 132 {
133 133 return m_labels.opacity();
134 134 }
135 135
136 136 void AxisItem::setShadesOpacity(qreal opacity)
137 137 {
138 138 m_shades.setOpacity(opacity);
139 139 }
140 140
141 141 qreal AxisItem::shadesOpacity() const
142 142 {
143 143 return m_shades.opacity();
144 144 }
145 145
146 146 void AxisItem::setLabelsAngle(int angle)
147 147 {
148 148 foreach(QGraphicsItem* item , m_labels.childItems()) {
149 149 QPointF center = item->boundingRect().center();
150 150 item->setRotation(angle);
151 151 }
152 152
153 153 m_labelsAngle=angle;
154 154 }
155 155
156 156 void AxisItem::setLabelsPen(const QPen& pen)
157 157 {
158 158 foreach(QGraphicsItem* item , m_labels.childItems()) {
159 159 static_cast<QGraphicsSimpleTextItem*>(item)->setPen(pen);
160 160 }
161 161 }
162 162
163 163 void AxisItem::setLabelsBrush(const QBrush& brush)
164 164 {
165 165 foreach(QGraphicsItem* item , m_labels.childItems()) {
166 166 static_cast<QGraphicsSimpleTextItem*>(item)->setBrush(brush);
167 167 }
168 168 }
169 169
170 170 void AxisItem::setLabelsFont(const QFont& font)
171 171 {
172 172 foreach(QGraphicsItem* item , m_labels.childItems()) {
173 173 static_cast<QGraphicsSimpleTextItem*>(item)->setFont(font);
174 174 }
175 175 }
176 176
177 177 void AxisItem::setShadesBrush(const QBrush& brush)
178 178 {
179 179 foreach(QGraphicsItem* item , m_shades.childItems()) {
180 180 static_cast<QGraphicsRectItem*>(item)->setBrush(brush);
181 181 }
182 182 }
183 183
184 184 void AxisItem::setShadesPen(const QPen& pen)
185 185 {
186 186 foreach(QGraphicsItem* item , m_shades.childItems()) {
187 187 static_cast<QGraphicsRectItem*>(item)->setPen(pen);
188 188 }
189 189 }
190 190
191 191 void AxisItem::setAxisPen(const QPen& pen)
192 192 {
193 193 foreach(QGraphicsItem* item , m_axis.childItems()) {
194 194 static_cast<QGraphicsLineItem*>(item)->setPen(pen);
195 195 }
196 196 }
197 197
198 198 void AxisItem::setGridPen(const QPen& pen)
199 199 {
200 200 foreach(QGraphicsItem* item , m_grid.childItems()) {
201 201 static_cast<QGraphicsLineItem*>(item)->setPen(pen);
202 202 }
203 203 }
204 204
205 205 QVector<qreal> AxisItem::calculateLayout() const
206 206 {
207 207 Q_ASSERT(m_ticksCount>=2);
208 208
209 209 QVector<qreal> points;
210 210 points.resize(m_ticksCount);
211 211
212 212 switch (m_type)
213 213 {
214 214 case X_AXIS:
215 215 {
216 216 const qreal deltaX = m_rect.width()/(m_ticksCount-1);
217 217 for (int i = 0; i < m_ticksCount; ++i) {
218 218 int x = i * deltaX + m_rect.left();
219 219 points[i] = x;
220 220 }
221 221 }
222 222 break;
223 223 case Y_AXIS:
224 224 {
225 225 const qreal deltaY = m_rect.height()/(m_ticksCount-1);
226 226 for (int i = 0; i < m_ticksCount; ++i) {
227 227 int y = i * -deltaY + m_rect.bottom();
228 228 points[i] = y;
229 229 }
230 230 }
231 231 break;
232 232 }
233 233 return points;
234 234 }
235 235
236 236 void AxisItem::setLayout(QVector<qreal>& layout)
237 237 {
238 238 int diff = m_layoutVector.size() - layout.size();
239 239
240 240 if(diff>0) {
241 241 deleteItems(diff);
242 242 }
243 243 else if(diff<0) {
244 244 createItems(-diff);
245 245 }
246 246
247 247 if(diff!=0) handleAxisUpdated();
248 248
249 249 QStringList ticksList = createLabels(layout.size(),m_min,m_max);
250 250
251 251 QList<QGraphicsItem *> lines = m_grid.childItems();
252 252 QList<QGraphicsItem *> labels = m_labels.childItems();
253 253 QList<QGraphicsItem *> shades = m_shades.childItems();
254 254 QList<QGraphicsItem *> axis = m_axis.childItems();
255 255
256 256 Q_ASSERT(labels.size() == ticksList.size());
257 257 Q_ASSERT(layout.size() == ticksList.size());
258 258
259 259 switch (m_type)
260 260 {
261 261 case X_AXIS:
262 262 {
263 263 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(axis.at(0));
264 264 lineItem->setLine(m_rect.left(), m_rect.bottom(), m_rect.right(), m_rect.bottom());
265 265
266 266 for (int i = 0; i < layout.size(); ++i) {
267 267 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(lines.at(i));
268 268 lineItem->setLine(layout[i], m_rect.top(), layout[i], m_rect.bottom());
269 269 QGraphicsSimpleTextItem *labelItem = static_cast<QGraphicsSimpleTextItem*>(labels.at(i));
270 270 labelItem->setText(ticksList.at(i));
271 271 QPointF center = labelItem->boundingRect().center();
272 272 labelItem->setTransformOriginPoint(center.x(), center.y());
273 273 labelItem->setPos(layout[i] - center.x(), m_rect.bottom() + label_padding);
274 274 if((i+1)%2 && i>1) {
275 275 QGraphicsRectItem *rectItem = static_cast<QGraphicsRectItem*>(shades.at(i/2-1));
276 276 rectItem->setRect(layout[i-1],m_rect.top(),layout[i]-layout[i-1],m_rect.height());
277 277 }
278 278 lineItem = static_cast<QGraphicsLineItem*>(axis.at(i+1));
279 279 lineItem->setLine(layout[i],m_rect.bottom(),layout[i],m_rect.bottom()+5);
280 280 }
281 281 }
282 282 break;
283 283
284 284 case Y_AXIS:
285 285 {
286 286 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(axis.at(0));
287 287 lineItem->setLine(m_rect.left() , m_rect.top(), m_rect.left(), m_rect.bottom());
288 288
289 289 for (int i = 0; i < layout.size(); ++i) {
290 290 QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(lines.at(i));
291 291 lineItem->setLine(m_rect.left() , layout[i], m_rect.right(), layout[i]);
292 292 QGraphicsSimpleTextItem *labelItem = static_cast<QGraphicsSimpleTextItem*>(labels.at(i));
293 293 labelItem->setText(ticksList.at(i));
294 294 QPointF center = labelItem->boundingRect().center();
295 295 labelItem->setTransformOriginPoint(center.x(), center.y());
296 296 labelItem->setPos(m_rect.left() - labelItem->boundingRect().width() - label_padding , layout[i]-center.y());
297 297 if((i+1)%2 && i>1) {
298 298 QGraphicsRectItem *rectItem = static_cast<QGraphicsRectItem*>(shades.at(i/2-1));
299 299 rectItem->setRect(m_rect.left(),layout[i],m_rect.width(),layout[i-1]-layout[i]);
300 300 }
301 301 lineItem = static_cast<QGraphicsLineItem*>(axis.at(i+1));
302 302 lineItem->setLine(m_rect.left()-5,layout[i],m_rect.left(),layout[i]);
303 303 }
304 304 }
305 305 break;
306 306 default:
307 307 qDebug()<<"Unknown axis type";
308 308 break;
309 309 }
310 310
311 311 m_layoutVector=layout;
312 312 }
313 313
314 314 bool AxisItem::isEmpty()
315 315 {
316 316 return m_rect.isEmpty() || m_min==m_max || m_ticksCount==0;
317 317 }
318 318
319 319 //handlers
320 320
321 321 void AxisItem::handleAxisCategoriesUpdated()
322 322 {
323 323 if(isEmpty()) return;
324 324 updateLayout(m_layoutVector);
325 325 }
326 326
327 327 void AxisItem::handleAxisUpdated()
328 328 {
329 329
330 330 if(isEmpty()) return;
331 331
332 332 if(m_chartAxis->isAxisVisible()) {
333 333 setAxisOpacity(100);
334 334 }
335 335 else {
336 336 setAxisOpacity(0);
337 337 }
338 338
339 339 if(m_chartAxis->isGridLineVisible()) {
340 340 setGridOpacity(100);
341 341 }
342 342 else {
343 343 setGridOpacity(0);
344 344 }
345 345
346 346 if(m_chartAxis->labelsVisible())
347 347 {
348 348 setLabelsOpacity(100);
349 349 }
350 350 else {
351 351 setLabelsOpacity(0);
352 352 }
353 353
354 354 if(m_chartAxis->shadesVisible()) {
355 355 setShadesOpacity(m_chartAxis->shadesOpacity());
356 356 }
357 357 else {
358 358 setShadesOpacity(0);
359 359 }
360 360
361 361 setLabelsAngle(m_chartAxis->labelsAngle());
362 362 setAxisPen(m_chartAxis->axisPen());
363 363 setLabelsPen(m_chartAxis->labelsPen());
364 364 setLabelsBrush(m_chartAxis->labelsBrush());
365 365 setLabelsFont(m_chartAxis->labelsFont());
366 366 setGridPen(m_chartAxis->gridLinePen());
367 367 setShadesPen(m_chartAxis->shadesPen());
368 368 setShadesBrush(m_chartAxis->shadesBrush());
369 369
370 370 }
371 371
372 372 void AxisItem::handleRangeChanged(qreal min, qreal max,int tickCount)
373 373 {
374 374 if(min==max || tickCount<2) return;
375 375
376 376 m_min = min;
377 377 m_max = max;
378 378 m_ticksCount= tickCount;
379 379
380 380 if(isEmpty()) return;
381 381 QVector<qreal> layout = calculateLayout();
382 382 updateLayout(layout);
383 383
384 384 }
385 385
386 386 void AxisItem::handleGeometryChanged(const QRectF& rect)
387 387 {
388 388 m_rect = rect;
389 389 if(isEmpty()) return;
390 390 QVector<qreal> layout = calculateLayout();
391 391 updateLayout(layout);
392 392 }
393 393
394 394 //painter
395 395
396 396 void AxisItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
397 397 {
398 Q_UNUSED(painter);
399 Q_UNUSED(option);
400 Q_UNUSED(widget);
398 Q_UNUSED(painter)
399 Q_UNUSED(option)
400 Q_UNUSED(widget)
401 401 }
402 402
403 403 //TODO "nice numbers algorithm"
404 404 #include "moc_axisitem_p.cpp"
405 405
406 406 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,93 +1,96
1 1 #include "bar_p.h"
2 2 #include <QDebug>
3 3 #include <QPainter>
4 4 #include <QGraphicsSceneEvent>
5 5
6 6 QTCOMMERCIALCHART_BEGIN_NAMESPACE
7 7
8 8 Bar::Bar(QString category, QGraphicsItem *parent)
9 9 : QGraphicsObject(parent),
10 10 mXpos(0),
11 11 mYpos(0),
12 12 mWidth(0),
13 13 mHeight(0),
14 14 mCategory(category)
15 15 {
16 16 setAcceptedMouseButtons(Qt::LeftButton|Qt::RightButton);
17 17 setAcceptHoverEvents(true);
18 18 }
19 19
20 20 void Bar::setSize(const QSizeF& size)
21 21 {
22 22 mWidth = size.width();
23 23 mHeight = size.height();
24 24 }
25 25
26 26
27 27 void Bar::resize( qreal w, qreal h )
28 28 {
29 29 mWidth = w;
30 30 mHeight = h;
31 31 }
32 32
33 33 void Bar::setPos(qreal x, qreal y)
34 34 {
35 35 mXpos = x;
36 36 mYpos = y;
37 37 }
38 38
39 39 void Bar::setPen(QPen pen)
40 40 {
41 41 mPen = pen;
42 42 }
43 43
44 44 void Bar::setBrush(QBrush brush)
45 45 {
46 46 mBrush = brush;
47 47 }
48 48
49 49 void Bar::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
50 50 {
51 Q_UNUSED(option)
52 Q_UNUSED(widget)
53
51 54 if (0 == mHeight) {
52 55 return;
53 56 }
54 57 painter->setBrush(mBrush);
55 58
56 59 // This compensates for rounding errors. drawRect takes ints and cumulative error of pos + size may be over 1.
57 60 int x0 = mXpos;
58 61 int x1 = (mXpos + mWidth);
59 62 int w = x1-x0;
60 63 int y0 = mYpos;
61 64 int y1 = (mYpos + mHeight);
62 65 int h = y1-y0;
63 66 painter->drawRect(x0, y0 ,w ,h);
64 67 }
65 68
66 69 QRectF Bar::boundingRect() const
67 70 {
68 71 QRectF r(mXpos, mYpos, mWidth, mHeight);
69 72 return r;
70 73 }
71 74
72 75 void Bar::mousePressEvent(QGraphicsSceneMouseEvent* event)
73 76 {
74 77 if (event->button() == Qt::LeftButton) {
75 78 emit clicked(mCategory);
76 79 } else if (event->button() == Qt::RightButton) {
77 80 emit rightClicked(mCategory);
78 81 }
79 82 }
80 83
81 84 void Bar::hoverEnterEvent(QGraphicsSceneHoverEvent* event)
82 85 {
83 86 emit hoverEntered(event->lastScreenPos());
84 87 }
85 88
86 89 void Bar::hoverLeaveEvent(QGraphicsSceneHoverEvent* /*event*/)
87 90 {
88 91 emit hoverLeaved();
89 92 }
90 93
91 94 #include "moc_bar_p.cpp"
92 95
93 96 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,184 +1,189
1 1 #include "barpresenterbase_p.h"
2 2 #include "bar_p.h"
3 3 #include "barvalue_p.h"
4 4 #include "separator_p.h"
5 5 #include "qbarset.h"
6 6 #include "qbarseries.h"
7 7 #include "qchart.h"
8 8 #include "qchartaxis.h"
9 9 #include "qchartaxiscategories.h"
10 10 #include "chartpresenter_p.h"
11 11 #include <QDebug>
12 12 #include <QToolTip>
13 13
14 14 QTCOMMERCIALCHART_BEGIN_NAMESPACE
15 15
16 16 BarPresenterBase::BarPresenterBase(QBarSeries *series, QChart *parent) :
17 17 ChartItem(parent),
18 18 mHeight(0),
19 19 mWidth(0),
20 20 mLayoutSet(false),
21 21 mSeries(series),
22 22 mChart(parent)
23 23 {
24 24 connect(series,SIGNAL(showToolTip(QPoint,QString)),this,SLOT(showToolTip(QPoint,QString)));
25 25 // connect(series,SIGNAL(enableSeparators(bool)),this,SLOT(enableSeparators(bool)));
26 26 // enableSeparators(series->separatorsVisible());
27 27 setZValue(ChartPresenter::BarSeriesZValue);
28 28 initAxisLabels();
29 29 dataChanged();
30 30 }
31 31
32 32 BarPresenterBase::~BarPresenterBase()
33 33 {
34 34 disconnect(this,SLOT(showToolTip(QPoint,QString)));
35 35 disconnect(this,SLOT(enableSeparators(bool)));
36 36 }
37 37
38 38 void BarPresenterBase::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
39 39 {
40 40 if (!mLayoutSet) {
41 41 qDebug() << "BarPresenterBase::paint called without layout set. Aborting.";
42 42 return;
43 43 }
44 44 foreach(QGraphicsItem* i, childItems()) {
45 45 i->paint(painter,option,widget);
46 46 }
47 47 }
48 48
49 49 QRectF BarPresenterBase::boundingRect() const
50 50 {
51 51 return QRectF(0, 0, mWidth, mHeight);
52 52 }
53 53
54 54 void BarPresenterBase::dataChanged()
55 55 {
56 56 // TODO: performance optimizations. Do we really need to delete and create items every time data is changed or can we reuse them?
57 57 // Delete old bars
58 58 foreach (QGraphicsItem* item, childItems()) {
59 59 delete item;
60 60 }
61 61
62 62 mBars.clear();
63 63 // mSeparators.clear();
64 64 mFloatingValues.clear();
65 65
66 66 // Create new graphic items for bars
67 67 for (int c=0; c<mSeries->categoryCount(); c++) {
68 68 QString category = mSeries->categoryName(c);
69 69 for (int s=0; s<mSeries->barsetCount(); s++) {
70 70 QBarSet *set = mSeries->barsetAt(s);
71 71 Bar *bar = new Bar(category,this);
72 72 childItems().append(bar);
73 73 mBars.append(bar);
74 74 connect(bar,SIGNAL(clicked(QString)),set,SIGNAL(clicked(QString)));
75 75 connect(bar,SIGNAL(rightClicked(QString)),set,SIGNAL(rightClicked(QString)));
76 76 connect(bar,SIGNAL(hoverEntered(QPoint)),set,SLOT(barHoverEnterEvent(QPoint)));
77 77 connect(bar,SIGNAL(hoverLeaved()),set,SLOT(barHoverLeaveEvent()));
78 78 }
79 79 }
80 80 /*
81 81 // Create separators
82 82 int count = mSeries->categoryCount() - 1; // There is one less separator than columns
83 83 for (int i=0; i<count; i++) {
84 84 Separator* sep = new Separator(this);
85 85 sep->setVisible(mSeries->separatorsVisible());
86 86 childItems().append(sep);
87 87 mSeparators.append(sep);
88 88 }
89 89 */
90 90 // Create floating values
91 91 for (int category=0; category<mSeries->categoryCount(); category++) {
92 92 for (int s=0; s<mSeries->barsetCount(); s++) {
93 93 QBarSet *set = mSeries->barsetAt(s);
94 94 BarValue *value = new BarValue(*set, this);
95 95 childItems().append(value);
96 96 mFloatingValues.append(value);
97 97 connect(set,SIGNAL(toggleFloatingValues()),value,SLOT(toggleVisible()));
98 98 }
99 99 }
100 100 }
101 101
102 102 void BarPresenterBase::initAxisLabels()
103 103 {
104 104 int count = mSeries->categoryCount();
105 105 if (0 == count) {
106 106 return;
107 107 }
108 108
109 109 mChart->axisX()->setTicksCount(count+2);
110 110
111 111 qreal min = 0;
112 112 qreal max = count+1;
113 113
114 114 mChart->axisX()->setMin(min);
115 115 mChart->axisX()->setMax(max);
116 116
117 117 QChartAxisCategories* categories = mChart->axisX()->categories();
118 118 categories->clear();
119 119 for (int i=0; i<count; i++) {
120 120 categories->insert(i+1,mSeries->categoryName(i));
121 121 }
122 122
123 123
124 124
125 125 mChart->axisX()->setLabelsVisible(true);
126 126 }
127 127
128 128 //handlers
129 129
130 130 void BarPresenterBase::handleModelChanged(int index)
131 131 {
132 // qDebug() << "BarPresenterBase::handleModelChanged" << index;
132 Q_UNUSED(index)
133 133 dataChanged();
134 134 }
135 135
136 void BarPresenterBase::handleDomainChanged(const Domain& domain)
136 void BarPresenterBase::handleDomainChanged(qreal minX, qreal maxX, qreal minY, qreal maxY)
137 137 {
138 qDebug() << "BarPresenterBase::handleDomainChanged";
138 // TODO:
139 Q_UNUSED(minX)
140 Q_UNUSED(maxX)
141 Q_UNUSED(minY)
142 Q_UNUSED(maxY)
143
139 144 /*
140 145 int count = mSeries->categoryCount();
141 146 if (0 == count) {
142 147 return;
143 148 }
144 149
145 150 // Position labels to domain
146 151 qreal min = domain.minX();
147 152 qreal max = domain.maxX();
148 153 qreal step = (max-min)/count;
149 154 QChartAxisCategories& categories = mChart->axisX()->categories();
150 155 categories.clear();
151 156 for (int i=0; i<count; i++) {
152 157 categories.insert(min,mSeries->categoryName(i));
153 158 min += step;
154 159 }
155 160 */
156 161 }
157 162
158 163 void BarPresenterBase::handleGeometryChanged(const QRectF& rect)
159 164 {
160 165 mWidth = rect.width();
161 166 mHeight = rect.height();
162 167 layoutChanged();
163 168 mLayoutSet = true;
164 169 setPos(rect.topLeft());
165 170 }
166 171
167 172 void BarPresenterBase::showToolTip(QPoint pos, QString tip)
168 173 {
169 174 // TODO: cool tooltip instead of default
170 175 QToolTip::showText(pos,tip);
171 176 }
172 177
173 178 /*
174 179 void BarPresenterBase::enableSeparators(bool enabled)
175 180 {
176 181 for (int i=0; i<mSeparators.count(); i++) {
177 182 mSeparators.at(i)->setVisible(enabled);
178 183 }
179 184 }
180 185 */
181 186
182 187 #include "moc_barpresenterbase_p.cpp"
183 188
184 189 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,67 +1,67
1 1 #ifndef BARPRESENTERBASE_H
2 2 #define BARPRESENTERBASE_H
3 3
4 4 #include "chartitem_p.h"
5 5 #include "qbarseries.h"
6 6 #include <QPen>
7 7 #include <QBrush>
8 8 #include <QGraphicsItem>
9 9
10 10 QTCOMMERCIALCHART_BEGIN_NAMESPACE
11 11
12 12 class Bar;
13 13 class Separator;
14 14 class BarValue;
15 15 class QChartAxisCategories;
16 16 class QChart;
17 17
18 18 // Common implemantation of different presenters. Not to be instantiated.
19 19 // TODO: combine this with BarPresenter and derive other presenters from it?
20 20 class BarPresenterBase : public QObject, public ChartItem
21 21 {
22 22 Q_OBJECT
23 23 public:
24 24 BarPresenterBase(QBarSeries *series, QChart *parent = 0);
25 25 virtual ~BarPresenterBase();
26 26
27 27 public:
28 28 // From QGraphicsItem
29 29 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
30 30 QRectF boundingRect() const;
31 31
32 32 // TODO: Consider the domain for layoutChanged. May be use case, may not be. If it is, then the derived classes need to implement it
33 33 virtual void dataChanged(); // data of series has changed -> need to recalculate bar sizes
34 34 virtual void layoutChanged() = 0; // layout has changed -> need to recalculate bar sizes
35 35
36 36 protected:
37 37 void initAxisLabels();
38 38
39 39 public slots:
40 40 void handleModelChanged(int index);
41 void handleDomainChanged(const Domain& domain);
41 void handleDomainChanged(qreal minX, qreal maxX, qreal minY, qreal maxY);
42 42 void handleGeometryChanged(const QRectF& size);
43 43
44 44 // Internal slots
45 45 void showToolTip(QPoint pos, QString tip); // shows tooltip (if enabled)
46 46 // void enableSeparators(bool enabled);
47 47
48 48 protected:
49 49
50 50 // TODO: consider these.
51 51 int mHeight; // Layout spesific
52 52 int mWidth;
53 53 qreal mBarWidth;
54 54
55 55 bool mLayoutSet; // True, if component has been laid out.
56 56
57 57 // Not owned.
58 58 QBarSeries* mSeries;
59 59 QList<Bar*> mBars;
60 60 // QList<Separator*> mSeparators;
61 61 QList<BarValue*> mFloatingValues;
62 62 QChart* mChart;
63 63 };
64 64
65 65 QTCOMMERCIALCHART_END_NAMESPACE
66 66
67 67 #endif // BARPRESENTERBASE_H
@@ -1,70 +1,73
1 1 #include "barvalue_p.h"
2 2 #include <QPainter>
3 3 #include <QPen>
4 4
5 5 QTCOMMERCIALCHART_BEGIN_NAMESPACE
6 6
7 7 BarValue::BarValue(QBarSet &set, QGraphicsItem *parent)
8 8 : QGraphicsObject(parent),
9 9 mBarSet(set),
10 10 mXpos(0),
11 11 mYpos(0),
12 12 mWidth(0),
13 13 mHeight(0)
14 14 {
15 15 setVisible(false);
16 16 }
17 17
18 18 void BarValue::setValueString(QString str)
19 19 {
20 20 mValueString = str;
21 21 }
22 22
23 23 QString BarValue::valueString()
24 24 {
25 25 return mValueString;
26 26 }
27 27
28 28 void BarValue::setPen(const QPen pen)
29 29 {
30 30 mPen = pen;
31 31 }
32 32
33 33 QPen BarValue::pen() const
34 34 {
35 35 return mPen;
36 36 }
37 37
38 38 void BarValue::resize(qreal w, qreal h)
39 39 {
40 40 mWidth = w;
41 41 mHeight = h;
42 42 }
43 43
44 44 void BarValue::setPos(qreal x, qreal y)
45 45 {
46 46 mXpos = x;
47 47 mYpos = y;
48 48 }
49 49
50 50 void BarValue::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
51 51 {
52 Q_UNUSED(option)
53 Q_UNUSED(widget)
54
52 55 if (isVisible()) {
53 56 painter->setPen(mPen);
54 57 painter->drawText(boundingRect(),mValueString);
55 58 }
56 59 }
57 60
58 61 QRectF BarValue::boundingRect() const
59 62 {
60 63 QRectF r(mXpos, mYpos, mWidth, mHeight);
61 64 return r;
62 65 }
63 66
64 67 void BarValue::toggleVisible()
65 68 {
66 69 setVisible(!isVisible());
67 70 }
68 71
69 72 #include "moc_barvalue_p.cpp"
70 73 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,242 +1,242
1 1 #include <QDebug>
2 2 #include "qbarseries.h"
3 3 #include "qbarset.h"
4 4 #include "barchartmodel_p.h"
5 5
6 6 QTCOMMERCIALCHART_BEGIN_NAMESPACE
7 7
8 8 /*!
9 9 \class QBarSeries
10 10 \brief part of QtCommercial chart API.
11 11
12 12 QBarSeries represents a series of data shown as bars. One QBarSeries can contain multible
13 13 QBarSet data sets. QBarSeries groups the data from sets to categories, which are defined
14 14 by QStringList.
15 15
16 16 \mainclass
17 17
18 18 \sa QBarSet, QStackedBarSeries, QPercentBarSeries
19 19 */
20 20
21 21 /*!
22 22 \fn virtual QSeriesType QBarSeries::type() const
23 23 \brief Returns type of series.
24 24 \sa QSeries, QSeriesType
25 25 */
26 26
27 27 /*!
28 28 \fn void QBarSeries::showToolTip(QPoint pos, QString tip)
29 29 \brief \internal \a pos \a tip
30 30 */
31 31
32 32 /*!
33 33 Constructs empty QBarSeries. Parameter \a categories defines the categories for chart.
34 34 QBarSeries is QObject which is a child of a \a parent.
35 35 */
36 36 QBarSeries::QBarSeries(QStringList categories, QObject *parent)
37 37 : QSeries(parent)
38 38 ,mModel(new BarChartModel(categories, this))
39 39 {
40 40 m_model = NULL;
41 41 m_mapCategories = -1;
42 42 m_mapBarBottom = -1;
43 43 m_mapBarTop = -1;
44 44 }
45 45
46 46 /*!
47 47 Adds a set of bars to series. Takes ownership of \a set.
48 48 Connects the clicked(QString) and rightClicked(QString) signals
49 49 of \a set to this series
50 50 */
51 51 void QBarSeries::addBarSet(QBarSet *set)
52 52 {
53 53 mModel->addBarSet(set);
54 54 connect(set,SIGNAL(clicked(QString)),this,SLOT(barsetClicked(QString)));
55 55 connect(set,SIGNAL(rightClicked(QString)),this,SLOT(barsetRightClicked(QString)));
56 56 }
57 57
58 58 /*!
59 59 Removes a set of bars from series. Releases ownership of \a set. Doesnt delete \a set.
60 60 Disconnects the clicked(QString) and rightClicked(QString) signals
61 61 of \a set from this series
62 62 */
63 63 void QBarSeries::removeBarSet(QBarSet *set)
64 64 {
65 65 disconnect(set,SIGNAL(clicked(QString)),this,SLOT(barsetClicked(QString)));
66 66 disconnect(set,SIGNAL(rightClicked(QString)),this,SLOT(barsetRightClicked(QString)));
67 67 mModel->removeBarSet(set);
68 68 }
69 69
70 70 /*!
71 71 Returns number of sets in series.
72 72 */
73 73 int QBarSeries::barsetCount()
74 74 {
75 75 if(m_model)
76 76 return m_mapBarTop - m_mapBarBottom;
77 77 else
78 78 return mModel->barsetCount();
79 79 }
80 80
81 81 /*!
82 82 Returns number of categories in series
83 83 */
84 84 int QBarSeries::categoryCount()
85 85 {
86 86 return mModel->categoryCount();
87 87 }
88 88
89 89 /*!
90 90 Returns a list of sets in series. Keeps ownership of sets.
91 91 */
92 92 QList<QBarSet*> QBarSeries::barSets()
93 93 {
94 94 return mModel->barSets();
95 95 }
96 96
97 97 /*!
98 98 \internal \a index
99 99 */
100 100 QBarSet* QBarSeries::barsetAt(int index)
101 101 {
102 102 return mModel->setAt(index);
103 103 }
104 104
105 105 /*!
106 106 \internal \a category
107 107 */
108 108 QString QBarSeries::categoryName(int category)
109 109 {
110 110 return mModel->categoryName(category);
111 111 }
112 112
113 113 /*!
114 114 Enables or disables tooltip depending on parameter \a enabled.
115 115 Tooltip shows the name of set, when mouse is hovering on top of bar.
116 116 Calling without parameter \a enabled, enables the tooltip
117 117 */
118 118 void QBarSeries::setToolTipEnabled(bool enabled)
119 119 {
120 120 // TODO: what if we add sets after call to this function? Those sets won't have tooltip enabled.
121 121 if (enabled) {
122 122 for (int i=0; i<mModel->barsetCount(); i++) {
123 123 QBarSet *set = mModel->setAt(i);
124 124 connect(set,SIGNAL(showToolTip(QPoint,QString)),this,SIGNAL(showToolTip(QPoint,QString)));
125 125 }
126 126 } else {
127 127 for (int i=0; i<mModel->barsetCount(); i++) {
128 128 QBarSet *set = mModel->setAt(i);
129 129 disconnect(set,SIGNAL(showToolTip(QPoint,QString)),this,SIGNAL(showToolTip(QPoint,QString)));
130 130 }
131 131 }
132 132 }
133 133
134 134 /*!
135 135 Enables or disables separators depending on parameter \a enabled.
136 136 Separators are visual elements that are drawn between categories.
137 137 Calling without parameter \a enabled, enables the separators
138 138 */
139 139 void QBarSeries::setSeparatorsVisible(bool visible)
140 140 {
141 141 mSeparatorsVisible = visible;
142 142 emit enableSeparators(visible);
143 143 }
144 144
145 145
146 146 /*!
147 147 \internal \a category
148 148 */
149 149 void QBarSeries::barsetClicked(QString category)
150 150 {
151 151 emit clicked(qobject_cast<QBarSet*>(sender()), category);
152 152 }
153 153
154 154 /*!
155 155 \internal \a category
156 156 */
157 157 void QBarSeries::barsetRightClicked(QString category)
158 158 {
159 159 emit rightClicked(qobject_cast<QBarSet*>(sender()), category);
160 160 }
161 161
162 162
163 163 /*!
164 164 \internal
165 165 */
166 166 qreal QBarSeries::min()
167 167 {
168 168 return mModel->min();
169 169 }
170 170
171 171 /*!
172 172 \internal
173 173 */
174 174 qreal QBarSeries::max()
175 175 {
176 176 return mModel->max();
177 177 }
178 178
179 179 /*!
180 180 \internal \a set \a category
181 181 */
182 182 qreal QBarSeries::valueAt(int set, int category)
183 183 {
184 184 return mModel->valueAt(set,category);
185 185 }
186 186
187 187 /*!
188 188 \internal \a set \a category
189 189 */
190 190 qreal QBarSeries::percentageAt(int set, int category)
191 191 {
192 192 return mModel->percentageAt(set,category);
193 193 }
194 194
195 195 /*!
196 196 \internal \a category
197 197 */
198 198 qreal QBarSeries::categorySum(int category)
199 199 {
200 200 return mModel->categorySum(category);
201 201 }
202 202
203 203 /*!
204 204 \internal
205 205 */
206 206 qreal QBarSeries::maxCategorySum()
207 207 {
208 208 return mModel->maxCategorySum();
209 209 }
210 210
211 211 /*!
212 212 \internal
213 213 */
214 214 BarChartModel& QBarSeries::model()
215 215 {
216 216 return *mModel;
217 217 }
218 218
219 219 bool QBarSeries::separatorsVisible()
220 220 {
221 221 return mSeparatorsVisible;
222 222 }
223 223
224 224 bool QBarSeries::setModel(QAbstractItemModel* model)
225 225 {
226 226 m_model = model;
227 227 return true;
228 228 }
229 229
230 void QBarSeries::setModelMappingCategories(int modelColumn)
230 // TODO
231 void QBarSeries::setModelMappingCategories(int /*modelColumn*/)
231 232 {
232 //
233 233 }
234 234
235 void QBarSeries::setModelMappingBarRange(int bottomBoundry, int topBoundry)
235 // TODO
236 void QBarSeries::setModelMappingBarRange(int /*bottomBoundry*/, int /*topBoundry*/)
236 237 {
237 //
238 238 }
239 239
240 240 #include "moc_qbarseries.cpp"
241 241
242 242 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,45 +1,48
1 1 #include "separator_p.h"
2 2 #include <QDebug>
3 3 #include <QPainter>
4 4
5 5 QTCOMMERCIALCHART_BEGIN_NAMESPACE
6 6
7 7 Separator::Separator(QGraphicsItem *parent)
8 8 : ChartItem(parent)
9 9 {
10 10 }
11 11
12 12 void Separator::setPos(qreal x, qreal y)
13 13 {
14 14 mXpos = x;
15 15 mYpos = y;
16 16 }
17 17
18 18 void Separator::setColor(QColor color)
19 19 {
20 20 mColor = color;
21 21 }
22 22
23 23 void Separator::setSize(const QSizeF &size)
24 24 {
25 25 mWidth = size.width();
26 26 mHeight = size.height();
27 27 }
28 28
29 29 void Separator::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
30 30 {
31 Q_UNUSED(option)
32 Q_UNUSED(widget)
33
31 34 if (isVisible()) {
32 35 QPen pen(mColor);
33 36 painter->setPen(pen);
34 37 painter->drawLine(mXpos,mYpos,mXpos,mHeight);
35 38 }
36 39 }
37 40
38 41 QRectF Separator::boundingRect() const
39 42 {
40 43 QRectF r(mXpos,mYpos,mWidth,mHeight);
41 44 return r;
42 45 }
43 46
44 47
45 48 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,401 +1,401
1 1 #include "qchart.h"
2 2 #include "qchartaxis.h"
3 3 #include "chartpresenter_p.h"
4 4 #include "chartdataset_p.h"
5 5 #include "charttheme_p.h"
6 6 #include "chartanimator_p.h"
7 7 //series
8 8 #include "qbarseries.h"
9 9 #include "qstackedbarseries.h"
10 10 #include "qpercentbarseries.h"
11 11 #include "qlineseries.h"
12 12 #include "qareaseries.h"
13 13 #include "qpieseries.h"
14 14 #include "qscatterseries.h"
15 15 #include "qsplineseries.h"
16 16 //items
17 17 #include "axisitem_p.h"
18 18 #include "areachartitem_p.h"
19 19 #include "barpresenter_p.h"
20 20 #include "stackedbarpresenter_p.h"
21 21 #include "percentbarpresenter_p.h"
22 22 #include "linechartitem_p.h"
23 23 #include "piechartitem_p.h"
24 24 #include "scatterchartitem_p.h"
25 25 #include "splinechartitem_p.h"
26 26
27 27 QTCOMMERCIALCHART_BEGIN_NAMESPACE
28 28
29 29 ChartPresenter::ChartPresenter(QChart* chart,ChartDataSet* dataset):QObject(chart),
30 30 m_chart(chart),
31 31 m_animator(0),
32 32 m_dataset(dataset),
33 33 m_chartTheme(0),
34 34 m_zoomIndex(0),
35 35 m_marginSize(0),
36 36 m_rect(QRectF(QPoint(0,0),m_chart->size())),
37 37 m_options(QChart::NoAnimation)
38 38 {
39 39 createConnections();
40 40 setChartTheme(QChart::ChartThemeDefault);
41 41 }
42 42
43 43 ChartPresenter::~ChartPresenter()
44 44 {
45 45 delete m_chartTheme;
46 46 }
47 47
48 48 void ChartPresenter::createConnections()
49 49 {
50 50 QObject::connect(m_chart,SIGNAL(geometryChanged()),this,SLOT(handleGeometryChanged()));
51 51 QObject::connect(m_dataset,SIGNAL(seriesAdded(QSeries*,Domain*)),this,SLOT(handleSeriesAdded(QSeries*,Domain*)));
52 52 QObject::connect(m_dataset,SIGNAL(seriesRemoved(QSeries*)),this,SLOT(handleSeriesRemoved(QSeries*)));
53 53 QObject::connect(m_dataset,SIGNAL(axisAdded(QChartAxis*,Domain*)),this,SLOT(handleAxisAdded(QChartAxis*,Domain*)));
54 54 QObject::connect(m_dataset,SIGNAL(axisRemoved(QChartAxis*)),this,SLOT(handleAxisRemoved(QChartAxis*)));
55 55 }
56 56
57 57
58 58 QRectF ChartPresenter::geometry() const
59 59 {
60 60 return m_rect;
61 61 }
62 62
63 63 void ChartPresenter::handleGeometryChanged()
64 64 {
65 65 QRectF rect(QPoint(0,0),m_chart->size());
66 66 rect.adjust(m_marginSize,m_marginSize, -m_marginSize, -m_marginSize);
67 67
68 68 //rewrite zoom stack
69 69 for(int i=0;i<m_zoomStack.count();i++){
70 70 QRectF r = m_zoomStack[i];
71 71 qreal w = rect.width()/m_rect.width();
72 72 qreal h = rect.height()/m_rect.height();
73 73 QPointF tl = r.topLeft();
74 74 tl.setX(tl.x()*w);
75 75 tl.setY(tl.y()*h);
76 76 QPointF br = r.bottomRight();
77 77 br.setX(br.x()*w);
78 78 br.setY(br.y()*h);
79 79 r.setTopLeft(tl);
80 80 r.setBottomRight(br);
81 81 m_zoomStack[i]=r;
82 82 }
83 83
84 84 m_rect = rect;
85 85 Q_ASSERT(m_rect.isValid());
86 86 emit geometryChanged(m_rect);
87 87 }
88 88
89 89 int ChartPresenter::margin() const
90 90 {
91 91 return m_marginSize;
92 92 }
93 93
94 94 void ChartPresenter::setMargin(int margin)
95 95 {
96 96 m_marginSize = margin;
97 97 }
98 98
99 99 void ChartPresenter::handleAxisAdded(QChartAxis* axis,Domain* domain)
100 100 {
101 101 AxisItem* item = new AxisItem(axis,this,axis==m_dataset->axisX()?AxisItem::X_AXIS : AxisItem::Y_AXIS,m_chart);
102 102
103 103 if(m_options.testFlag(QChart::GridAxisAnimations)){
104 104 m_animator->addAnimation(item);
105 105 }
106 106
107 107 if(axis==m_dataset->axisX()){
108 108 m_chartTheme->decorate(axis,true);
109 109 QObject::connect(domain,SIGNAL(rangeXChanged(qreal,qreal,int)),item,SLOT(handleRangeChanged(qreal,qreal,int)));
110 110 //initialize
111 111 item->handleRangeChanged(domain->minX(),domain->maxX(),domain->tickXCount());
112 112
113 113 }
114 114 else{
115 115 m_chartTheme->decorate(axis,false);
116 116 QObject::connect(domain,SIGNAL(rangeYChanged(qreal,qreal,int)),item,SLOT(handleRangeChanged(qreal,qreal,int)));
117 117 //initialize
118 118 item->handleRangeChanged(domain->minY(),domain->maxY(),domain->tickYCount());
119 119 }
120 120
121 121 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
122 122 //initialize
123 123 item->handleGeometryChanged(m_rect);
124 124 m_axisItems.insert(axis, item);
125 125 }
126 126
127 127 void ChartPresenter::handleAxisRemoved(QChartAxis* axis)
128 128 {
129 129 AxisItem* item = m_axisItems.take(axis);
130 130 Q_ASSERT(item);
131 131 if(m_animator) m_animator->removeAnimation(item);
132 132 delete item;
133 133 }
134 134
135 135
136 136 void ChartPresenter::handleSeriesAdded(QSeries* series,Domain* domain)
137 137 {
138 138 ChartItem *item = 0 ;
139 139
140 140 switch(series->type())
141 141 {
142 142 case QSeries::SeriesTypeLine: {
143 143
144 144 QLineSeries* lineSeries = static_cast<QLineSeries*>(series);
145 145 LineChartItem* line = new LineChartItem(lineSeries,m_chart);
146 146 if(m_options.testFlag(QChart::SeriesAnimations)) {
147 147 m_animator->addAnimation(line);
148 148 }
149 149 m_chartTheme->decorate(lineSeries, m_dataset->seriesIndex(series));
150 150 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),line,SLOT(handleGeometryChanged(const QRectF&)));
151 151 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),line,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
152 152 item = line;
153 153 break;
154 154 }
155 155
156 156 case QSeries::SeriesTypeArea: {
157 157
158 158 QAreaSeries* areaSeries = static_cast<QAreaSeries*>(series);
159 159 AreaChartItem* area = new AreaChartItem(areaSeries,m_chart);
160 160 if(m_options.testFlag(QChart::SeriesAnimations)) {
161 161 m_animator->addAnimation(area->upperLineItem());
162 162 if(areaSeries->lowerSeries()) m_animator->addAnimation(area->lowerLineItem());
163 163 }
164 164 m_chartTheme->decorate(areaSeries, m_dataset->seriesIndex(series));
165 165 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),area,SLOT(handleGeometryChanged(const QRectF&)));
166 166 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),area,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
167 167 item=area;
168 168 break;
169 169 }
170 170
171 171 case QSeries::SeriesTypeBar: {
172 172 QBarSeries* barSeries = static_cast<QBarSeries*>(series);
173 173 BarPresenter* bar = new BarPresenter(barSeries,m_chart);
174 174 if(m_options.testFlag(QChart::SeriesAnimations)) {
175 175 // m_animator->addAnimation(bar);
176 176 }
177 m_chartTheme->decorate(bar, barSeries, m_dataset->seriesIndex(barSeries));
177 m_chartTheme->decorate(barSeries, m_dataset->seriesIndex(barSeries));
178 178 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),bar,SLOT(handleGeometryChanged(const QRectF&)));
179 179 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),bar,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
180 180 item=bar;
181 181 break;
182 182 }
183 183
184 184 case QSeries::SeriesTypeStackedBar: {
185 185 QStackedBarSeries* stackedBarSeries = static_cast<QStackedBarSeries*>(series);
186 186 StackedBarPresenter* bar = new StackedBarPresenter(stackedBarSeries,m_chart);
187 187 if(m_options.testFlag(QChart::SeriesAnimations)) {
188 188 // m_animator->addAnimation(bar);
189 189 }
190 m_chartTheme->decorate(bar, stackedBarSeries, m_dataset->seriesIndex(stackedBarSeries));
190 m_chartTheme->decorate(stackedBarSeries, m_dataset->seriesIndex(stackedBarSeries));
191 191 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),bar,SLOT(handleGeometryChanged(const QRectF&)));
192 192 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),bar,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
193 193 item=bar;
194 194 break;
195 195 }
196 196
197 197 case QSeries::SeriesTypePercentBar: {
198 198 QPercentBarSeries* percentBarSeries = static_cast<QPercentBarSeries*>(series);
199 199 PercentBarPresenter* bar = new PercentBarPresenter(percentBarSeries,m_chart);
200 200 if(m_options.testFlag(QChart::SeriesAnimations)) {
201 201 // m_animator->addAnimation(bar);
202 202 }
203 m_chartTheme->decorate(bar, percentBarSeries, m_dataset->seriesIndex(percentBarSeries));
203 m_chartTheme->decorate(percentBarSeries, m_dataset->seriesIndex(percentBarSeries));
204 204 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),bar,SLOT(handleGeometryChanged(const QRectF&)));
205 205 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),bar,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
206 206 item=bar;
207 207 break;
208 208 }
209 209
210 210 case QSeries::SeriesTypeScatter: {
211 211 QScatterSeries *scatterSeries = static_cast<QScatterSeries *>(series);
212 212 ScatterChartItem *scatter = new ScatterChartItem(scatterSeries, m_chart);
213 213 if(m_options.testFlag(QChart::SeriesAnimations)) {
214 214 m_animator->addAnimation(scatter);
215 215 }
216 216 m_chartTheme->decorate(scatterSeries, m_dataset->seriesIndex(series));
217 217 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),scatter,SLOT(handleGeometryChanged(const QRectF&)));
218 218 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),scatter,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
219 219 item = scatter;
220 220 break;
221 221 }
222 222
223 223 case QSeries::SeriesTypePie: {
224 224 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
225 225 PieChartItem* pie = new PieChartItem(m_chart, pieSeries);
226 226 if(m_options.testFlag(QChart::SeriesAnimations)) {
227 227 // m_animator->addAnimation(pie);
228 228 }
229 m_chartTheme->decorate(pie, pieSeries, m_dataset->seriesIndex(series));
229 m_chartTheme->decorate(pieSeries, m_dataset->seriesIndex(series));
230 230 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),pie,SLOT(handleGeometryChanged(const QRectF&)));
231 231 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),pie,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
232 232 // Hide all from background when there is only piechart
233 233 // TODO: refactor this ugly code... should be one setting for this
234 234 if (m_chartItems.count() == 0) {
235 235 m_chart->axisX()->hide();
236 236 m_chart->axisY()->hide();
237 237 m_chart->setChartBackgroundBrush(Qt::transparent);
238 238 }
239 239 item=pie;
240 240 break;
241 241 }
242 242
243 243 case QSeries::SeriesTypeSpline: {
244 244 QSplineSeries* splineSeries = static_cast<QSplineSeries*>(series);
245 245 SplineChartItem* spline = new SplineChartItem(splineSeries, m_chart);
246 246 if(m_options.testFlag(QChart::SeriesAnimations)) {
247 247 m_animator->addAnimation(spline);
248 248 }
249 249 m_chartTheme->decorate(splineSeries, m_dataset->seriesIndex(series));
250 250 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),spline,SLOT(handleGeometryChanged(const QRectF&)));
251 251 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),spline,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
252 252 item=spline;
253 253 break;
254 254 }
255 255 default: {
256 256 qDebug()<< "Series type" << series->type() << "not implemented.";
257 257 break;
258 258 }
259 259 }
260 260
261 261 //initialize
262 262 item->handleDomainChanged(domain->minX(),domain->maxX(),domain->minY(),domain->maxY());
263 263 if(m_rect.isValid()) item->handleGeometryChanged(m_rect);
264 264 m_chartItems.insert(series,item);
265 265 zoomReset();
266 266 }
267 267
268 268 void ChartPresenter::handleSeriesRemoved(QSeries* series)
269 269 {
270 270 ChartItem* item = m_chartItems.take(series);
271 271 Q_ASSERT(item);
272 272 if(m_animator) {
273 273 //small hack to handle area animations
274 274 if(series->type()==QSeries::SeriesTypeArea){
275 275 QAreaSeries* areaSeries = static_cast<QAreaSeries*>(series);
276 276 AreaChartItem* area = static_cast<AreaChartItem*>(item);
277 277 m_animator->removeAnimation(area->upperLineItem());
278 278 if(areaSeries->lowerSeries()) m_animator->addAnimation(area->lowerLineItem());
279 279 }else
280 280 m_animator->removeAnimation(item);
281 281 }
282 282 delete item;
283 283 }
284 284
285 285 void ChartPresenter::setChartTheme(QChart::ChartTheme theme)
286 286 {
287 287 if(m_chartTheme && m_chartTheme->id() == theme) return;
288 288 delete m_chartTheme;
289 289 m_chartTheme = ChartTheme::createTheme(theme);
290 290 m_chartTheme->decorate(m_chart);
291 291 m_chartTheme->decorate(m_chart->legend());
292 292 resetAllElements();
293 293 }
294 294
295 295 QChart::ChartTheme ChartPresenter::chartTheme()
296 296 {
297 297 return m_chartTheme->id();
298 298 }
299 299
300 300 void ChartPresenter::setAnimationOptions(QChart::AnimationOptions options)
301 301 {
302 302 if(m_options!=options) {
303 303
304 304 m_options=options;
305 305
306 306 if(m_options!=QChart::NoAnimation && !m_animator) {
307 307 m_animator= new ChartAnimator(this);
308 308
309 309 }
310 310 resetAllElements();
311 311 }
312 312
313 313 }
314 314
315 315 void ChartPresenter::resetAllElements()
316 316 {
317 317 QList<QChartAxis*> axisList = m_axisItems.uniqueKeys();
318 318 QList<QSeries*> seriesList = m_chartItems.uniqueKeys();
319 319
320 320 foreach(QChartAxis* axis, axisList) {
321 321 handleAxisRemoved(axis);
322 322 handleAxisAdded(axis,m_dataset->domain(axis));
323 323 }
324 324 foreach(QSeries* series, seriesList) {
325 325 handleSeriesRemoved(series);
326 326 handleSeriesAdded(series,m_dataset->domain(series));
327 327 }
328 328 }
329 329
330 330 void ChartPresenter::zoomIn()
331 331 {
332 332 QRectF rect = geometry();
333 333 rect.setWidth(rect.width()/2);
334 334 rect.setHeight(rect.height()/2);
335 335 rect.moveCenter(geometry().center());
336 336 zoomIn(rect);
337 337 }
338 338
339 339 void ChartPresenter::zoomIn(const QRectF& rect)
340 340 {
341 341 QRectF r = rect.normalized();
342 342 r.translate(-m_marginSize, -m_marginSize);
343 343 if(m_animator) {
344 344
345 345 QPointF point(r.center().x()/geometry().width(),r.center().y()/geometry().height());
346 346 m_animator->setState(ChartAnimator::ZoomInState,point);
347 347 }
348 348 m_dataset->zoomInDomain(r,geometry().size());
349 349 m_zoomStack<<r;
350 350 m_zoomIndex++;
351 351 if(m_animator) {
352 352 m_animator->setState(ChartAnimator::ShowState);
353 353 }
354 354 }
355 355
356 356 void ChartPresenter::zoomOut()
357 357 {
358 358 if(m_zoomIndex==0) return;
359 359 if(m_animator)
360 360 {
361 361 m_animator->setState(ChartAnimator::ZoomOutState);
362 362 }
363 363 m_dataset->zoomOutDomain(m_zoomStack[m_zoomIndex-1],geometry().size());
364 364 m_zoomIndex--;
365 365 m_zoomStack.resize(m_zoomIndex);
366 366 if(m_animator){
367 367 m_animator->setState(ChartAnimator::ShowState);
368 368 }
369 369 }
370 370
371 371 void ChartPresenter::zoomReset()
372 372 {
373 373 m_zoomIndex=0;
374 374 m_zoomStack.resize(m_zoomIndex);
375 375 }
376 376
377 377 void ChartPresenter::scroll(int dx,int dy)
378 378 {
379 379 if(m_animator){
380 380 if(dx<0) m_animator->setState(ChartAnimator::ScrollLeftState,QPointF());
381 381 if(dx>0) m_animator->setState(ChartAnimator::ScrollRightState,QPointF());
382 382 if(dy<0) m_animator->setState(ChartAnimator::ScrollUpState,QPointF());
383 383 if(dy>0) m_animator->setState(ChartAnimator::ScrollDownState,QPointF());
384 384 }
385 385
386 386 m_dataset->scrollDomain(dx,dy,geometry().size());
387 387
388 388 if(m_animator){
389 389 m_animator->setState(ChartAnimator::ShowState);
390 390 }
391 391 }
392 392
393 393 QChart::AnimationOptions ChartPresenter::animationOptions() const
394 394 {
395 395 return m_options;
396 396 }
397 397
398 398
399 399 #include "moc_chartpresenter_p.cpp"
400 400
401 401 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,314 +1,314
1 1 #include "charttheme_p.h"
2 2 #include "qchart.h"
3 3 #include "qchartview.h"
4 4 #include "qlegend.h"
5 5 #include "qchartaxis.h"
6 6 #include <QTime>
7 7
8 8 //series
9 9 #include "qbarset.h"
10 10 #include "qbarseries.h"
11 11 #include "qstackedbarseries.h"
12 12 #include "qpercentbarseries.h"
13 13 #include "qlineseries.h"
14 14 #include "qareaseries.h"
15 15 #include "qscatterseries.h"
16 16 #include "qpieseries.h"
17 17 #include "qpieslice.h"
18 18 #include "qsplineseries.h"
19 19
20 20 //items
21 21 #include "axisitem_p.h"
22 22 #include "barpresenter_p.h"
23 23 #include "stackedbarpresenter_p.h"
24 24 #include "percentbarpresenter_p.h"
25 25 #include "linechartitem_p.h"
26 26 #include "areachartitem_p.h"
27 27 #include "scatterchartitem_p.h"
28 28 #include "piechartitem_p.h"
29 29 #include "splinechartitem_p.h"
30 30
31 31 //themes
32 32 #include "chartthemedefault_p.h"
33 33 #include "chartthemevanilla_p.h"
34 34 #include "chartthemeicy_p.h"
35 35 #include "chartthemegrayscale_p.h"
36 36 #include "chartthemescientific_p.h"
37 37 #include "chartthemebluecerulean_p.h"
38 38 #include "chartthemelight_p.h"
39 39
40 40
41 41 QTCOMMERCIALCHART_BEGIN_NAMESPACE
42 42
43 43 ChartTheme::ChartTheme(QChart::ChartTheme id)
44 44 {
45 45 m_id = id;
46 46 qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
47 47 }
48 48
49 49
50 50 ChartTheme* ChartTheme::createTheme(QChart::ChartTheme theme)
51 51 {
52 52 switch(theme) {
53 53 case QChart::ChartThemeVanilla:
54 54 return new ChartThemeVanilla();
55 55 case QChart::ChartThemeIcy:
56 56 return new ChartThemeIcy();
57 57 case QChart::ChartThemeGrayscale:
58 58 return new ChartThemeGrayscale();
59 59 case QChart::ChartThemeScientific:
60 60 return new ChartThemeScientific();
61 61 case QChart::ChartThemeBlueCerulean:
62 62 return new ChartThemeBlueCerulean();
63 63 case QChart::ChartThemeLight:
64 64 return new ChartThemeLight();
65 65 default:
66 66 return new ChartThemeDefault();
67 67 }
68 68 }
69 69
70 70 void ChartTheme::decorate(QChart* chart)
71 71 {
72 72 if (m_backgroundShades == BackgroundShadesNone) {
73 73 chart->setChartBackgroundBrush(m_chartBackgroundGradient);
74 74 } else {
75 75 chart->setChartBackgroundBrush(Qt::NoBrush);
76 76 }
77 77 chart->setChartTitleFont(m_masterFont);
78 78 }
79 79
80 80 void ChartTheme::decorate(QLegend* legend)
81 81 {
82 82 legend->setBackgroundBrush(m_chartBackgroundGradient);
83 83 }
84 84
85 85 void ChartTheme::decorate(QAreaSeries* series, int index)
86 86 {
87 87 QPen pen;
88 88 QBrush brush;
89 89
90 90 if (pen == series->pen()){
91 91 pen.setColor(colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 1.0));
92 92 pen.setWidthF(2);
93 93 series->setPen(pen);
94 94 }
95 95
96 96 if (brush == series->brush()) {
97 97 QBrush brush(m_seriesColors.at(index % m_seriesColors.size()));
98 98 series->setBrush(brush);
99 99 }
100 100 }
101 101
102 102
103 103 void ChartTheme::decorate(QLineSeries* series,int index)
104 104 {
105 105 QPen pen;
106 106 if(pen == series->pen()){
107 107 pen.setColor(m_seriesColors.at(index%m_seriesColors.size()));
108 108 pen.setWidthF(2);
109 109 series->setPen(pen);
110 110 }
111 111 }
112 112
113 void ChartTheme::decorate(BarPresenter* item, QBarSeries* series,int index)
113 void ChartTheme::decorate(QBarSeries* series,int index)
114 114 {
115 115 QList<QBarSet*> sets = series->barSets();
116 116 for (int i=0; i<sets.count(); i++) {
117 117 qreal pos = 0.5;
118 118 if (sets.count() > 1)
119 119 pos = (qreal) i / (qreal) (sets.count() - 1);
120 120 QColor c = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), pos);
121 121 sets.at(i)->setBrush(QBrush(c));
122 122
123 123 // Pick label color as far as possible from bar color (within gradient).
124 124 // 0.3 is magic number that was picked as value that gave enough contrast with icy theme gradient :)
125 125 // TODO: better picking of label color?
126 126 if (pos < 0.3) {
127 127 c = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 1);
128 128 } else {
129 129 c = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 0);
130 130 }
131 131 sets.at(i)->setFloatingValuePen(QPen(c));
132 132 }
133 133 }
134 134
135 void ChartTheme::decorate(StackedBarPresenter* item, QStackedBarSeries* series,int index)
135 void ChartTheme::decorate(QStackedBarSeries* series,int index)
136 136 {
137 137 QList<QBarSet*> sets = series->barSets();
138 138 for (int i=0; i<sets.count(); i++) {
139 139 qreal pos = 0.5;
140 140 if (sets.count() > 1)
141 141 pos = (qreal) i / (qreal) (sets.count() - 1);
142 142 QColor c = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), pos);
143 143 sets.at(i)->setBrush(QBrush(c));
144 144
145 145 if (pos < 0.3) {
146 146 c = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 1);
147 147 } else {
148 148 c = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 0);
149 149 }
150 150 sets.at(i)->setFloatingValuePen(QPen(c));
151 151 }
152 152 }
153 153
154 void ChartTheme::decorate(PercentBarPresenter* item, QPercentBarSeries* series,int index)
154 void ChartTheme::decorate(QPercentBarSeries* series,int index)
155 155 {
156 156 QList<QBarSet*> sets = series->barSets();
157 157 for (int i=0; i<sets.count(); i++) {
158 158 qreal pos = 0.5;
159 159 if (sets.count() > 1)
160 160 pos = (qreal) i / (qreal) (sets.count() - 1);
161 161 QColor c = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), pos);
162 162 sets.at(i)->setBrush(QBrush(c));
163 163
164 164 if (pos < 0.3) {
165 165 c = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 1);
166 166 } else {
167 167 c = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 0);
168 168 }
169 169 sets.at(i)->setFloatingValuePen(QPen(c));
170 170 }
171 171 }
172 172
173 173 void ChartTheme::decorate(QScatterSeries* series, int index)
174 174 {
175 175
176 176 QPen pen;
177 177 QBrush brush;
178 178
179 179 if (pen == series->pen()) {
180 180 pen.setColor(colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 1.0));
181 181 pen.setWidthF(2);
182 182 series->setPen(pen);
183 183 }
184 184
185 185 if (brush == series->brush()) {
186 186 QBrush brush(m_seriesColors.at(index % m_seriesColors.size()));
187 187 series->setBrush(brush);
188 188 }
189 189 }
190 190
191 void ChartTheme::decorate(PieChartItem* item, QPieSeries* series, int index)
191 void ChartTheme::decorate(QPieSeries* series, int index)
192 192 {
193 193 // Get color for a slice from a gradient linearly, beginning from the start of the gradient
194 194 for (int i(0); i < series->slices().count(); i++) {
195 195 qreal pos = (qreal) i / (qreal) series->count();
196 196 QColor penColor = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), 0.1);
197 197 series->slices().at(i)->setSlicePen(penColor);
198 198 QColor brushColor = colorAt(m_seriesGradients.at(index % m_seriesGradients.size()), pos);
199 199 series->slices().at(i)->setSliceBrush(brushColor);
200 200 }
201 201 }
202 202
203 203 void ChartTheme::decorate(QSplineSeries* series, int index)
204 204 {
205 205 QPen pen;
206 206 if(pen == series->pen()){
207 207 pen.setColor(m_seriesColors.at(index%m_seriesColors.size()));
208 208 pen.setWidthF(2);
209 209 series->setPen(pen);
210 210 }
211 211 }
212 212
213 213 void ChartTheme::decorate(QChartAxis* axis,bool axisX)
214 214 {
215 215 if (axis->isAxisVisible()) {
216 216 axis->setLabelsBrush(m_axisLabelBrush);
217 217 axis->setLabelsPen(m_axisLabelPen);
218 218 if (m_backgroundShades == BackgroundShadesBoth
219 219 || (m_backgroundShades == BackgroundShadesVertical && axisX)
220 220 || (m_backgroundShades == BackgroundShadesHorizontal && !axisX)) {
221 221 axis->setShadesPen(m_backgroundShadesPen);
222 222 axis->setShadesBrush(m_backgroundShadesBrush);
223 223 } else {
224 224 // The shades not supposed to be shown for this axis, clear possible brush and pen
225 225 axis->setShadesPen(Qt::NoPen);
226 226 axis->setShadesBrush(Qt::NoBrush);
227 227 }
228 228 axis->setAxisPen(m_axisLinePen);
229 229 axis->setGridLinePen(m_gridLinePen);
230 230 axis->setLabelsFont(m_masterFont);
231 231 }
232 232 }
233 233
234 234 void ChartTheme::generateSeriesGradients()
235 235 {
236 236 // Generate gradients in HSV color space
237 237 foreach (QColor color, m_seriesColors) {
238 238 QLinearGradient g;
239 239 qreal h = color.hsvHueF();
240 240 qreal s = color.hsvSaturationF();
241 241
242 242 // TODO: tune the algorithm to give nice results with most base colors defined in
243 243 // most themes. The rest of the gradients we can define manually in theme specific
244 244 // implementation.
245 245 QColor start = color;
246 246 start.setHsvF(h, 0.05, 0.95);
247 247 g.setColorAt(0.0, start);
248 248
249 249 g.setColorAt(0.5, color);
250 250
251 251 QColor end = color;
252 252 end.setHsvF(h, s, 0.25);
253 253 g.setColorAt(1.0, end);
254 254
255 255 m_seriesGradients << g;
256 256 }
257 257 }
258 258
259 259
260 260 QColor ChartTheme::colorAt(const QColor &start, const QColor &end, qreal pos)
261 261 {
262 262 Q_ASSERT(pos >=0.0 && pos <= 1.0);
263 263 qreal r = start.redF() + ((end.redF() - start.redF()) * pos);
264 264 qreal g = start.greenF() + ((end.greenF() - start.greenF()) * pos);
265 265 qreal b = start.blueF() + ((end.blueF() - start.blueF()) * pos);
266 266 QColor c;
267 267 c.setRgbF(r, g, b);
268 268 return c;
269 269 }
270 270
271 271 QColor ChartTheme::colorAt(const QGradient &gradient, qreal pos)
272 272 {
273 273 Q_ASSERT(pos >=0 && pos <= 1.0);
274 274
275 275 // another possibility:
276 276 // http://stackoverflow.com/questions/3306786/get-intermediate-color-from-a-gradient
277 277
278 278 QGradientStops stops = gradient.stops();
279 279 int count = stops.count();
280 280
281 281 // find previous stop relative to position
282 282 QGradientStop prev = stops.first();
283 283 for (int i=0; i<count; i++) {
284 284 QGradientStop stop = stops.at(i);
285 285 if (pos > stop.first)
286 286 prev = stop;
287 287
288 288 // given position is actually a stop position?
289 289 if (pos == stop.first) {
290 290 //qDebug() << "stop color" << pos;
291 291 return stop.second;
292 292 }
293 293 }
294 294
295 295 // find next stop relative to position
296 296 QGradientStop next = stops.last();
297 297 for (int i=count-1; i>=0; i--) {
298 298 QGradientStop stop = stops.at(i);
299 299 if (pos < stop.first)
300 300 next = stop;
301 301 }
302 302
303 303 //qDebug() << "prev" << prev.first << "pos" << pos << "next" << next.first;
304 304
305 305 qreal range = next.first - prev.first;
306 306 qreal posDelta = pos - prev.first;
307 307 qreal relativePos = posDelta / range;
308 308
309 309 //qDebug() << "range" << range << "posDelta" << posDelta << "relativePos" << relativePos;
310 310
311 311 return colorAt(prev.second, next.second, relativePos);
312 312 }
313 313
314 314 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,81 +1,81
1 1 #ifndef CHARTTHEME_H
2 2 #define CHARTTHEME_H
3 3
4 4 #include "qchartglobal.h"
5 5 #include "qchart.h"
6 6 #include <QColor>
7 7 #include <QGradientStops>
8 8
9 9 QTCOMMERCIALCHART_BEGIN_NAMESPACE
10 10
11 11 class ChartItem;
12 12 class QSeries;
13 13 class LineChartItem;
14 14 class QLineSeries;
15 15 class BarPresenter;
16 16 class QBarSeries;
17 17 class StackedBarPresenter;
18 18 class QStackedBarSeries;
19 19 class QPercentBarSeries;
20 20 class PercentBarPresenter;
21 21 class QScatterSeries;
22 22 class ScatterChartItem;
23 23 class PieChartItem;
24 24 class QPieSeries;
25 25 class SplineChartItem;
26 26 class QSplineSeries;
27 27 class AreaChartItem;
28 28 class QAreaSeries;
29 29
30 30 class ChartTheme
31 31 {
32 32 public:
33 33 enum BackgroundShadesMode {
34 34 BackgroundShadesNone = 0,
35 35 BackgroundShadesVertical,
36 36 BackgroundShadesHorizontal,
37 37 BackgroundShadesBoth
38 38 };
39 39
40 40 protected:
41 41 explicit ChartTheme(QChart::ChartTheme id = QChart::ChartThemeDefault);
42 42 public:
43 43 static ChartTheme* createTheme(QChart::ChartTheme theme);
44 44 QChart::ChartTheme id() const {return m_id;}
45 45 void decorate(QChart* chart);
46 46 void decorate(QLegend* legend);
47 47 //void decorate(ChartItem* item, QSeries* series,int index);
48 void decorate(BarPresenter* item, QBarSeries* series, int index);
49 void decorate(StackedBarPresenter* item, QStackedBarSeries* series, int index);
50 void decorate(PercentBarPresenter* item, QPercentBarSeries* series, int index);
48 void decorate(QBarSeries* series, int index);
49 void decorate(QStackedBarSeries* series, int index);
50 void decorate(QPercentBarSeries* series, int index);
51 51 void decorate(QLineSeries* series, int index);
52 52 void decorate(QAreaSeries* series, int index);
53 53 void decorate(QScatterSeries* series, int index);
54 void decorate(PieChartItem* item, QPieSeries* series, int index);
54 void decorate(QPieSeries* series, int index);
55 55 void decorate(QSplineSeries* series, int index);
56 56 void decorate(QChartAxis* axis, bool axisX);
57 57
58 58 public: // utils
59 59 void generateSeriesGradients();
60 60 static QColor colorAt(const QColor &start, const QColor &end, qreal pos);
61 61 static QColor colorAt(const QGradient &gradient, qreal pos);
62 62
63 63 protected:
64 64 QChart::ChartTheme m_id;
65 65 QList<QColor> m_seriesColors;
66 66 QList<QGradient> m_seriesGradients;
67 67 QLinearGradient m_chartBackgroundGradient;
68 68
69 69 QFont m_masterFont;
70 70 QPen m_axisLinePen;
71 71 QBrush m_axisLabelBrush;
72 72 QPen m_axisLabelPen;
73 73 QPen m_backgroundShadesPen;
74 74 QBrush m_backgroundShadesBrush;
75 75 BackgroundShadesMode m_backgroundShades;
76 76 QPen m_gridLinePen;
77 77 };
78 78
79 79 QTCOMMERCIALCHART_END_NAMESPACE
80 80
81 81 #endif // CHARTTHEME_H
@@ -1,144 +1,147
1 1 #include "qchartglobal.h"
2 2 #include "legendmarker_p.h"
3 3 #include <qpieslice.h>
4 4 #include <qbarset.h>
5 5 #include <QPainter>
6 6 #include <QGraphicsSceneEvent>
7 7
8 8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9 9
10 10 LegendMarker::LegendMarker(QSeries* series, QGraphicsItem *parent)
11 11 : QGraphicsObject(parent)
12 12 ,mBoundingRect(0,0,1,1)
13 13 ,mMarkerBoundingRect(0,0,1,1)
14 14 ,mSeries(series)
15 15 ,mBarset(0)
16 16 ,mPieslice(0)
17 17 ,mType(LegendMarkerTypeSeries)
18 18 ,mTextItem(new QGraphicsSimpleTextItem(this))
19 19 {
20 20 setAcceptedMouseButtons(Qt::LeftButton|Qt::RightButton);
21 21 }
22 22
23 23 LegendMarker::LegendMarker(QSeries *series, QBarSet *barset, QGraphicsItem *parent)
24 24 : QGraphicsObject(parent)
25 25 ,mBoundingRect(0,0,1,1)
26 26 ,mMarkerBoundingRect(0,0,1,1)
27 27 ,mSeries(series)
28 28 ,mBarset(barset)
29 29 ,mPieslice(0)
30 30 ,mType(LegendMarkerTypeBarset)
31 31 ,mTextItem(new QGraphicsSimpleTextItem(this))
32 32 {
33 33 setAcceptedMouseButtons(Qt::LeftButton|Qt::RightButton);
34 34 }
35 35
36 36 LegendMarker::LegendMarker(QSeries *series, QPieSlice *pieslice, QGraphicsItem *parent)
37 37 : QGraphicsObject(parent)
38 38 ,mBoundingRect(0,0,1,1)
39 39 ,mMarkerBoundingRect(0,0,1,1)
40 40 ,mSeries(series)
41 41 ,mBarset(0)
42 42 ,mPieslice(pieslice)
43 43 ,mType(LegendMarkerTypePieslice)
44 44 ,mTextItem(new QGraphicsSimpleTextItem(this))
45 45 {
46 46 setAcceptedMouseButtons(Qt::LeftButton|Qt::RightButton);
47 47 }
48 48
49 49 void LegendMarker::setBoundingRect(const QRectF rect)
50 50 {
51 51 mBoundingRect = rect;
52 52 // Calculate Marker pos
53 53
54 54 // TODO: remove hard coding. 5 is marigin around marker
55 55 QSizeF markerSize(10,10);
56 56 qreal x = mBoundingRect.x() + 5;
57 57 qreal y = mBoundingRect.y() + (mBoundingRect.height() - markerSize.height())/2;
58 58 mMarkerBoundingRect = QRectF(x,y,markerSize.width(),markerSize.height());
59 59
60 60 mTextItem.setPos(mBoundingRect.x() + markerSize.width() + 10, y );
61 61 }
62 62
63 63 void LegendMarker::setBrush(const QBrush brush)
64 64 {
65 65 mBrush = brush;
66 66 }
67 67
68 68 QBrush LegendMarker::brush() const
69 69 {
70 70 return mBrush;
71 71 }
72 72
73 73 void LegendMarker::setName(const QString name)
74 74 {
75 75 mTextItem.setText(name);
76 76 }
77 77
78 78 QString LegendMarker::name() const
79 79 {
80 80 return mTextItem.text();
81 81 }
82 82
83 83 QSeries* LegendMarker::series() const
84 84 {
85 85 return mSeries;
86 86 }
87 87
88 88 void LegendMarker::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
89 89 {
90 Q_UNUSED(option)
91 Q_UNUSED(widget)
92
90 93 painter->setBrush(mBrush);
91 94 painter->drawRect(mMarkerBoundingRect);
92 95 }
93 96
94 97 QRectF LegendMarker::boundingRect() const
95 98 {
96 99 return mBoundingRect;
97 100 }
98 101
99 102 void LegendMarker::mousePressEvent(QGraphicsSceneMouseEvent *event)
100 103 {
101 104 switch (mType)
102 105 {
103 106 case LegendMarkerTypeSeries: {
104 107 emit clicked(mSeries,event->button());
105 108 break;
106 109 }
107 110 case LegendMarkerTypeBarset: {
108 111 emit clicked(mBarset,event->button());
109 112 break;
110 113 }
111 114 case LegendMarkerTypePieslice: {
112 115 emit clicked(mPieslice,event->button());
113 116 break;
114 117 }
115 118 default: {
116 119 break;
117 120 }
118 121 }
119 122 }
120 123
121 124 void LegendMarker::changed()
122 125 {
123 126 switch (mType)
124 127 {
125 128 case LegendMarkerTypeSeries: {
126 129 // TODO:
127 130 break;
128 131 }
129 132 case LegendMarkerTypeBarset: {
130 133 setBrush(mBarset->brush());
131 134 setName(mBarset->name());
132 135 break;
133 136 }
134 137 case LegendMarkerTypePieslice: {
135 138 setBrush(mPieslice->sliceBrush());
136 139 setName(mPieslice->label());
137 140 break;
138 141 }
139 142 }
140 143 }
141 144
142 145 #include "moc_legendmarker_p.cpp"
143 146
144 147 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,81 +1,82
1 1 #include "linechartitem_p.h"
2 2 #include "qlineseries.h"
3 3 #include "chartpresenter_p.h"
4 4 #include <QPainter>
5 5
6 6
7 7 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8 8
9 9 //TODO: optimize : remove points which are not visible
10 10
11 11 LineChartItem::LineChartItem(QLineSeries* series,QGraphicsItem *parent):XYChartItem(series,parent),
12 12 m_series(series),
13 13 m_pointsVisible(false)
14 14 {
15 15 setZValue(ChartPresenter::LineChartZValue);
16 16 QObject::connect(series,SIGNAL(updated()),this,SLOT(handleUpdated()));
17 17 handleUpdated();
18 18 }
19 19
20 20 QRectF LineChartItem::boundingRect() const
21 21 {
22 22 return m_rect;
23 23 }
24 24
25 25 QPainterPath LineChartItem::shape() const
26 26 {
27 27 return m_path;
28 28 }
29 29
30 30 void LineChartItem::setLayout(QVector<QPointF>& points)
31 31 {
32 32 if(points.size()==0)
33 33 {
34 34 XYChartItem::setLayout(points);
35 35 return;
36 36 }
37 37
38 38 QList<QGraphicsItem*> items = m_items.childItems();
39 39
40 40 QPainterPath linePath(points.at(0));
41 41
42 42 for(int i=1; i< points.size();i++) {
43 43 linePath.lineTo(points.at(i));
44 44 }
45 45
46 46 prepareGeometryChange();
47 47 m_path = linePath;
48 48 m_rect = linePath.boundingRect();
49 49
50 50 XYChartItem::setLayout(points);
51 51 }
52 52
53 53 void LineChartItem::handleUpdated()
54 54 {
55 55 m_pointsVisible = m_series->pointsVisible();
56 56 m_linePen = m_series->pen();
57 57 m_pointPen = m_series->pen();
58 58 m_pointPen.setWidthF(2*m_pointPen.width());
59 59 update();
60 60 }
61 61
62 62 //painter
63 63
64 64 void LineChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
65 65 {
66 Q_UNUSED(widget);
67 Q_UNUSED(option);
66 Q_UNUSED(widget)
67 Q_UNUSED(option)
68
68 69 painter->save();
69 70 painter->setPen(m_linePen);
70 71 painter->setClipRect(clipRect());
71 72 painter->drawPath(m_path);
72 73 if(m_pointsVisible){
73 74 painter->setPen(m_pointPen);
74 75 painter->drawPoints(points());
75 76 }
76 77 painter->restore();
77 78 }
78 79
79 80 #include "moc_linechartitem_p.cpp"
80 81
81 82 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,143 +1,144
1 1 #include "piechartitem_p.h"
2 2 #include "pieslice_p.h"
3 3 #include "qpieslice.h"
4 4 #include "qpieseries.h"
5 5 #include "chartpresenter_p.h"
6 6 #include <QDebug>
7 7 #include <QPainter>
8 8
9 9
10 10 QTCOMMERCIALCHART_BEGIN_NAMESPACE
11 11
12 12 PieChartItem::PieChartItem(QGraphicsItem *parent, QPieSeries *series)
13 13 :ChartItem(parent),
14 14 m_series(series)
15 15 {
16 16 Q_ASSERT(series);
17 17 connect(series, SIGNAL(changed()), this, SLOT(handleSeriesChanged()));
18 18
19 19 // Note: the following does not affect as long as the item does not have anything to paint
20 20 setZValue(ChartPresenter::PieSeriesZValue);
21 21 }
22 22
23 23 PieChartItem::~PieChartItem()
24 24 {
25 25 // slices deleted automatically through QGraphicsItem
26 26 }
27 27
28 28 void PieChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
29 29 {
30 Q_UNUSED(painter)
30 31 // TODO: paint shadows for all components
31 32 // - get paths from items & merge & offset and draw with shadow color?
32 33 //painter->setBrush(QBrush(Qt::red));
33 34 //painter->drawRect(m_debugRect);
34 35 }
35 36
36 37 void PieChartItem::handleSeriesChanged()
37 38 {
38 39 QVector<PieSliceLayout> sliceLayout = calculateLayout();
39 40 applyLayout(sliceLayout);
40 41 update();
41 42 }
42 43
43 44 void PieChartItem::handleSliceChanged()
44 45 {
45 46 // TODO: optimize don't need to handle all slices
46 47 QVector<PieSliceLayout> sliceLayout = calculateLayout();
47 48 applyLayout(sliceLayout);
48 49 update();
49 50 }
50 51
51 52 void PieChartItem::handleDomainChanged(qreal, qreal, qreal, qreal)
52 53 {
53 54 // TODO
54 55 }
55 56
56 57 void PieChartItem::handleGeometryChanged(const QRectF& rect)
57 58 {
58 59 prepareGeometryChange();
59 60 m_rect = rect;
60 61 QVector<PieSliceLayout> sliceLayout = calculateLayout();
61 62 applyLayout(sliceLayout);
62 63 update();
63 64 }
64 65
65 66
66 67 QVector<PieSliceLayout> PieChartItem::calculateLayout()
67 68 {
68 69 // find pie center coordinates
69 70 QPointF center;
70 71 center.setX(m_rect.left() + (m_rect.width() * m_series->pieHorizontalPosition()));
71 72 center.setY(m_rect.top() + (m_rect.height() * m_series->pieVerticalPosition()));
72 73
73 74 // find maximum radius for pie
74 75 qreal radius = m_rect.height() / 2;
75 76 if (m_rect.width() < m_rect.height())
76 77 radius = m_rect.width() / 2;
77 78
78 79 // apply size factor
79 80 radius *= m_series->pieSize();
80 81
81 82 QVector<PieSliceLayout> layout;
82 83 foreach (QPieSlice* s, m_series->slices()) {
83 84 PieSliceLayout sliceLayout;
84 85 sliceLayout.m_data = s;
85 86 sliceLayout.m_center = PieSlice::sliceCenter(center, radius, s);
86 87 sliceLayout.m_radius = radius;
87 88 sliceLayout.m_startAngle = s->startAngle();
88 89 sliceLayout.m_angleSpan = s->m_angleSpan;
89 90 layout << sliceLayout;
90 91 }
91 92
92 93 return layout;
93 94 }
94 95
95 96 void PieChartItem::applyLayout(const QVector<PieSliceLayout> &layout)
96 97 {
97 98 //if(m_animator)
98 99 // m_animator->applyLayout(this,points);
99 100 //else
100 101 setLayout(layout);
101 102 }
102 103
103 104 void PieChartItem::setLayout(const QVector<PieSliceLayout> &layout)
104 105 {
105 106 foreach (PieSliceLayout l, layout) {
106 107
107 108 // find slice
108 109 PieSlice *slice = m_slices.value(l.m_data);
109 110 if (!slice) {
110 111 // add a new slice
111 112 slice = new PieSlice(this);
112 113 m_slices.insert(l.m_data, slice);
113 114
114 115 // connect signals
115 116 connect(l.m_data, SIGNAL(changed()), this, SLOT(handleSliceChanged()));
116 117 connect(slice, SIGNAL(clicked()), l.m_data, SIGNAL(clicked()));
117 118 connect(slice, SIGNAL(hoverEnter()), l.m_data, SIGNAL(hoverEnter()));
118 119 connect(slice, SIGNAL(hoverLeave()), l.m_data, SIGNAL(hoverLeave()));
119 120 }
120 121
121 122 // update
122 123 slice->setLayout(l);
123 124 slice->updateGeometry();
124 125 slice->update();
125 126 }
126 127
127 128 // delete slices
128 129 foreach (QPieSlice *s, m_slices.keys()) {
129 130
130 131 bool found = false;
131 132 foreach (PieSliceLayout l, layout) {
132 133 if (l.m_data == s)
133 134 found = true;
134 135 }
135 136
136 137 if (!found)
137 138 delete m_slices.take(s);
138 139 }
139 140 }
140 141
141 142 #include "moc_piechartitem_p.cpp"
142 143
143 144 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,636 +1,643
1 1 #include "qpieseries.h"
2 2 #include "qpieslice.h"
3 3 #include <QDebug>
4 4
5 5 QTCOMMERCIALCHART_BEGIN_NAMESPACE
6 6
7 7
8 8 /*!
9 9 \class QPieSeries::ChangeSet
10 10 \brief Defines the changes in the series.
11 11
12 12 Contains the changes that have occurred in the series. Lists of added, changed and removed slices.
13 13
14 14 \sa QPieSeries::changed()
15 15 */
16 16
17 17 /*!
18 18 \internal
19 19 */
20 20 void QPieSeries::ChangeSet::appendAdded(QPieSlice* slice)
21 21 {
22 22 if (!m_added.contains(slice))
23 23 m_added << slice;
24 24 }
25 25
26 26 /*!
27 27 \internal
28 28 */
29 29 void QPieSeries::ChangeSet::appendAdded(QList<QPieSlice*> slices)
30 30 {
31 31 foreach (QPieSlice* s, slices)
32 32 appendAdded(s);
33 33 }
34 34
35 35 /*!
36 36 \internal
37 37 */
38 38 void QPieSeries::ChangeSet::appendChanged(QPieSlice* slice)
39 39 {
40 40 if (!m_changed.contains(slice))
41 41 m_changed << slice;
42 42 }
43 43
44 44 /*!
45 45 \internal
46 46 */
47 47 void QPieSeries::ChangeSet::appendRemoved(QPieSlice* slice)
48 48 {
49 49 if (!m_removed.contains(slice))
50 50 m_removed << slice;
51 51 }
52 52
53 53 /*!
54 54 Returns a list of slices that have been added to the series.
55 55 \sa QPieSeries::changed()
56 56 */
57 57 QList<QPieSlice*> QPieSeries::ChangeSet::added() const
58 58 {
59 59 return m_added;
60 60 }
61 61
62 62 /*!
63 63 Returns a list of slices that have been changed in the series.
64 64 \sa QPieSeries::changed()
65 65 */
66 66 QList<QPieSlice*> QPieSeries::ChangeSet::changed() const
67 67 {
68 68 return m_changed;
69 69 }
70 70
71 71 /*!
72 72 Returns a list of slices that have been removed from the series.
73 73 \sa QPieSeries::changed()
74 74 */
75 75 QList<QPieSlice*> QPieSeries::ChangeSet::removed() const
76 76 {
77 77 return m_removed;
78 78 }
79 79
80 80
81 81 /*!
82 82 Returns true if there are no added/changed or removed slices in the change set.
83 83 */
84 84 bool QPieSeries::ChangeSet::isEmpty() const
85 85 {
86 86 if (m_added.count() || m_changed.count() || m_removed.count())
87 87 return false;
88 88 return true;
89 89 }
90 90
91 91 /*!
92 92 \class QPieSeries
93 93 \brief Pie series API for QtCommercial Charts
94 94
95 95 The pie series defines a pie chart which consists of pie slices which are QPieSlice objects.
96 96 The slices can have any values as the QPieSeries will calculate its relative value to the sum of all slices.
97 97 The actual slice size is determined by that relative value.
98 98
99 99 By default the pie is defined as a full pie but it can be a partial pie.
100 100 This can be done by setting a starting angle and angle span to the series.
101 101 */
102 102
103 103 /*!
104 104 Constructs a series object which is a child of \a parent.
105 105 */
106 106 QPieSeries::QPieSeries(QObject *parent) :
107 107 QSeries(parent),
108 108 m_pieRelativeHorPos(0.5),
109 109 m_pieRelativeVerPos(0.5),
110 110 m_pieRelativeSize(0.7),
111 111 m_pieStartAngle(0),
112 112 m_pieEndAngle(360),
113 113 m_total(0)
114 114 {
115 115
116 116 }
117 117
118 118 /*!
119 119 Destroys the object. Note that adding series to QChart transfers the ownership to the chart.
120 120 */
121 121 QPieSeries::~QPieSeries()
122 122 {
123 123
124 124 }
125 125
126 126 /*!
127 127 Returns QChartSeries::SeriesTypePie.
128 128 */
129 129 QSeries::QSeriesType QPieSeries::type() const
130 130 {
131 131 return QSeries::SeriesTypePie;
132 132 }
133 133
134 134 /*!
135 135 Sets an array of \a slices to the series replacing the existing slices.
136 136 Slice ownership is passed to the series.
137 137 */
138 138 void QPieSeries::replace(QList<QPieSlice*> slices)
139 139 {
140 140 clear();
141 141 add(slices);
142 142 }
143 143
144 144 /*!
145 145 Adds an array of \a slices to the series.
146 146 Slice ownership is passed to the series.
147 147 */
148 148 void QPieSeries::add(QList<QPieSlice*> slices)
149 149 {
150 150 foreach (QPieSlice* s, slices) {
151 151 s->setParent(this);
152 152 m_slices << s;
153 153 }
154 154
155 155 updateDerivativeData();
156 156
157 157 foreach (QPieSlice* s, slices) {
158 158 connect(s, SIGNAL(changed()), this, SLOT(sliceChanged()));
159 159 connect(s, SIGNAL(clicked()), this, SLOT(sliceClicked()));
160 160 connect(s, SIGNAL(hoverEnter()), this, SLOT(sliceHoverEnter()));
161 161 connect(s, SIGNAL(hoverLeave()), this, SLOT(sliceHoverLeave()));
162 162 }
163 163
164 164 emit changed();
165 165 }
166 166
167 167 /*!
168 168 Adds a single \a slice to the series.
169 169 Slice ownership is passed to the series.
170 170 */
171 171 void QPieSeries::add(QPieSlice* slice)
172 172 {
173 173 add(QList<QPieSlice*>() << slice);
174 174 }
175 175
176 176 /*!
177 177 Adds a single \a slice to the series and returns a reference to the series.
178 178 Slice ownership is passed to the series.
179 179 */
180 180 QPieSeries& QPieSeries::operator << (QPieSlice* slice)
181 181 {
182 182 add(slice);
183 183 return *this;
184 184 }
185 185
186 186
187 187 /*!
188 188 Adds a single slice to the series with give \a value and \a name.
189 189 Slice ownership is passed to the series.
190 190 */
191 191 QPieSlice* QPieSeries::add(qreal value, QString name)
192 192 {
193 193 QPieSlice* slice = new QPieSlice(value, name);
194 194 add(slice);
195 195 return slice;
196 196 }
197 197
198 198 void QPieSeries::insert(int i, QPieSlice* slice)
199 199 {
200 200 Q_ASSERT(i <= m_slices.count());
201 201 slice->setParent(this);
202 202 m_slices.insert(i, slice);
203 203
204 204 updateDerivativeData();
205 205
206 206 connect(slice, SIGNAL(changed()), this, SLOT(sliceChanged()));
207 207 connect(slice, SIGNAL(clicked()), this, SLOT(sliceClicked()));
208 208 connect(slice, SIGNAL(hoverEnter()), this, SLOT(sliceHoverEnter()));
209 209 connect(slice, SIGNAL(hoverLeave()), this, SLOT(sliceHoverLeave()));
210 210
211 211 emit changed();
212 212 }
213 213
214 214 /*!
215 215 Removes a single \a slice from the series and deletes the slice.
216 216
217 217 Do not reference this pointer after this call.
218 218 */
219 219 void QPieSeries::remove(QPieSlice* slice)
220 220 {
221 221 if (!m_slices.removeOne(slice)) {
222 222 Q_ASSERT(0); // TODO: how should this be reported?
223 223 return;
224 224 }
225 225 emit changed();
226 226
227 227 updateDerivativeData();
228 228
229 229 delete slice;
230 230 slice = NULL;
231 231 }
232 232
233 233 /*!
234 234 Clears all slices from the series.
235 235 */
236 236 void QPieSeries::clear()
237 237 {
238 238 if (m_slices.count() == 0)
239 239 return;
240 240
241 241 foreach (QPieSlice* s, m_slices) {
242 242 m_slices.removeOne(s);
243 243 delete s;
244 244 }
245 245
246 246 emit changed();
247 247
248 248 updateDerivativeData();
249 249 }
250 250
251 251 /*!
252 252 Counts the number of the slices in this series.
253 253 */
254 254 int QPieSeries::count() const
255 255 {
256 256 return m_slices.count();
257 257 }
258 258
259 259 /*!
260 260 Returns a list of slices that belong to this series.
261 261 */
262 262 QList<QPieSlice*> QPieSeries::slices() const
263 263 {
264 264 return m_slices;
265 265 }
266 266
267 267 /*!
268 268 Sets the center position of the pie by \a relativeHorizontalPosition and \a relativeVerticalPosition.
269 269
270 270 The factors are relative to the chart rectangle where:
271 271
272 272 \a relativeHorizontalPosition 0.0 means the absolute left.
273 273 \a relativeHorizontalPosition 1.0 means the absolute right.
274 274 \a relativeVerticalPosition 0.0 means the absolute top.
275 275 \a relativeVerticalPosition 1.0 means the absolute bottom.
276 276
277 277 By default both values are 0.5 which puts the pie in the middle of the chart rectangle.
278 278
279 279 \sa pieHorizontalPosition(), pieVerticalPosition(), setPieSize()
280 280 */
281 281 void QPieSeries::setPiePosition(qreal relativeHorizontalPosition, qreal relativeVerticalPosition)
282 282 {
283 283 if (relativeHorizontalPosition < 0.0 || relativeHorizontalPosition > 1.0 ||
284 284 relativeVerticalPosition < 0.0 || relativeVerticalPosition > 1.0)
285 285 return;
286 286
287 287 if (m_pieRelativeHorPos != relativeHorizontalPosition || m_pieRelativeVerPos != relativeVerticalPosition) {
288 288 m_pieRelativeHorPos = relativeHorizontalPosition;
289 289 m_pieRelativeVerPos = relativeVerticalPosition;
290 290 emit changed();
291 291 }
292 292 }
293 293
294 294 /*!
295 295 Gets the horizontal position of the pie.
296 296
297 297 The returned value is relative to the chart rectangle where:
298 298
299 299 0.0 means the absolute left.
300 300 1.0 means the absolute right.
301 301
302 302 By default it is 0.5 which puts the pie in the horizontal middle of the chart rectangle.
303 303
304 304 \sa setPiePosition(), pieVerticalPosition(), setPieSize()
305 305 */
306 306 qreal QPieSeries::pieHorizontalPosition() const
307 307 {
308 308 return m_pieRelativeHorPos;
309 309 }
310 310
311 311 /*!
312 312 Gets the vertical position position of the pie.
313 313
314 314 The returned value is relative to the chart rectangle where:
315 315
316 316 0.0 means the absolute top.
317 317 1.0 means the absolute bottom.
318 318
319 319 By default it is 0.5 which puts the pie in the vertical middle of the chart rectangle.
320 320
321 321 \sa setPiePosition(), pieHorizontalPosition(), setPieSize()
322 322 */
323 323 qreal QPieSeries::pieVerticalPosition() const
324 324 {
325 325 return m_pieRelativeVerPos;
326 326 }
327 327
328 328 /*!
329 329 Sets the relative size of the pie.
330 330
331 331 The \a relativeSize is defined so that the 1.0 is the maximum that can fit the given chart rectangle.
332 332
333 333 Default value is 0.7.
334 334
335 335 \sa pieSize(), setPiePosition(), pieVerticalPosition(), pieHorizontalPosition()
336 336 */
337 337 void QPieSeries::setPieSize(qreal relativeSize)
338 338 {
339 339 if (relativeSize < 0.0 || relativeSize > 1.0)
340 340 return;
341 341
342 342 if (m_pieRelativeSize != relativeSize) {
343 343 m_pieRelativeSize = relativeSize;
344 344 emit changed();
345 345 }
346 346 }
347 347
348 348 /*!
349 349 Gets the relative size of the pie.
350 350
351 351 The size is defined so that the 1.0 is the maximum that can fit the given chart rectangle.
352 352
353 353 Default value is 0.7.
354 354
355 355 \sa setPieSize(), setPiePosition(), pieVerticalPosition(), pieHorizontalPosition()
356 356 */
357 357 qreal QPieSeries::pieSize() const
358 358 {
359 359 return m_pieRelativeSize;
360 360 }
361 361
362 362
363 363 /*!
364 364 Sets the end angle of the pie.
365 365
366 366 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
367 367
368 368 \a angle must be less than pie end angle. Default value is 0.
369 369
370 370 \sa pieStartAngle(), pieEndAngle(), setPieEndAngle()
371 371 */
372 372 void QPieSeries::setPieStartAngle(qreal angle)
373 373 {
374 374 if (angle >= 0 && angle <= 360 && angle != m_pieStartAngle && angle <= m_pieEndAngle) {
375 375 m_pieStartAngle = angle;
376 376 updateDerivativeData();
377 377 }
378 378 }
379 379
380 380 /*!
381 381 Gets the start angle of the pie.
382 382
383 383 Full pie is 360 degrees where 0 degrees is at 12 a'clock. Default value is 360.
384 384
385 385 \sa setPieStartAngle(), pieEndAngle(), setPieEndAngle()
386 386 */
387 387 qreal QPieSeries::pieStartAngle() const
388 388 {
389 389 return m_pieStartAngle;
390 390 }
391 391
392 392 /*!
393 393 Sets the end angle of the pie.
394 394
395 395 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
396 396
397 397 \a angle must be greater than start angle.
398 398
399 399 \sa pieEndAngle(), pieStartAngle(), setPieStartAngle()
400 400 */
401 401 void QPieSeries::setPieEndAngle(qreal angle)
402 402 {
403 403 if (angle >= 0 && angle <= 360 && angle != m_pieEndAngle && angle >= m_pieStartAngle) {
404 404 m_pieEndAngle = angle;
405 405 updateDerivativeData();
406 406 }
407 407 }
408 408
409 409 /*!
410 410 Returns the end angle of the pie.
411 411
412 412 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
413 413
414 414 \sa setPieEndAngle(), pieStartAngle(), setPieStartAngle()
415 415 */
416 416 qreal QPieSeries::pieEndAngle() const
417 417 {
418 418 return m_pieEndAngle;
419 419 }
420 420
421 421 /*!
422 422 Sets the all the slice labels \a visible or invisible.
423 423
424 424 \sa QPieSlice::isLabelVisible(), QPieSlice::setLabelVisible()
425 425 */
426 426 void QPieSeries::setLabelsVisible(bool visible)
427 427 {
428 428 foreach (QPieSlice* s, m_slices)
429 429 s->setLabelVisible(visible);
430 430 }
431 431
432 432 /*!
433 433 Returns the sum of all slice values in this series.
434 434
435 435 \sa QPieSlice::value(), QPieSlice::setValue()
436 436 */
437 437 qreal QPieSeries::total() const
438 438 {
439 439 return m_total;
440 440 }
441 441
442 442 /*!
443 443 \fn void QPieSeries::changed()
444 444
445 445 This signal emitted when something has changed in the series.
446 446
447 447 \sa QPieSeries::ChangeSet, QPieSlice::changed()
448 448 */
449 449
450 450 /*!
451 451 \fn void QPieSeries::clicked(QPieSlice* slice)
452 452
453 453 This signal is emitted when a \a slice has been clicked.
454 454
455 455 \sa QPieSlice::clicked()
456 456 */
457 457
458 458 /*!
459 459 \fn void QPieSeries::hoverEnter(QPieSlice* slice)
460 460
461 461 This signal is emitted when user has hovered over a \a slice.
462 462
463 463 \sa QPieSlice::hoverEnter()
464 464 */
465 465
466 466 /*!
467 467 \fn void QPieSeries::hoverLeave(QPieSlice* slice)
468 468
469 469 This signal is emitted when user has hovered away from a \a slice.
470 470
471 471 \sa QPieSlice::hoverLeave()
472 472 */
473 473
474 474 void QPieSeries::sliceChanged()
475 475 {
476 476 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
477 477 Q_ASSERT(m_slices.contains(slice));
478 478 updateDerivativeData();
479 479 }
480 480
481 481 void QPieSeries::sliceClicked()
482 482 {
483 483 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
484 484 Q_ASSERT(m_slices.contains(slice));
485 485 emit clicked(slice);
486 486 }
487 487
488 488 void QPieSeries::sliceHoverEnter()
489 489 {
490 490 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
491 491 Q_ASSERT(m_slices.contains(slice));
492 492 emit hoverEnter(slice);
493 493 }
494 494
495 495 void QPieSeries::sliceHoverLeave()
496 496 {
497 497 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
498 498 Q_ASSERT(m_slices.contains(slice));
499 499 emit hoverLeave(slice);
500 500 }
501 501
502 502 void QPieSeries::updateDerivativeData()
503 503 {
504 504 m_total = 0;
505 505
506 506 // nothing to do?
507 507 if (m_slices.count() == 0)
508 508 return;
509 509
510 510 // calculate total
511 511 foreach (QPieSlice* s, m_slices)
512 512 m_total += s->value();
513 513
514 514 // we must have some values
515 515 if (m_total == 0) {
516 516 qDebug() << "QPieSeries::updateDerivativeData() total == 0";
517 517 Q_ASSERT(m_total > 0); // TODO: is this the correct way to handle this?
518 518 }
519 519
520 520 // update slice attributes
521 521 qreal sliceAngle = m_pieStartAngle;
522 522 qreal pieSpan = m_pieEndAngle - m_pieStartAngle;
523 523 foreach (QPieSlice* s, m_slices) {
524 524
525 525 bool changed = false;
526 526
527 527 qreal percentage = s->value() / m_total;
528 528 if (s->m_percentage != percentage) {
529 529 s->m_percentage = percentage;
530 530 changed = true;
531 531 }
532 532
533 533 qreal sliceSpan = pieSpan * percentage;
534 534 if (s->m_angleSpan != sliceSpan) {
535 535 s->m_angleSpan = sliceSpan;
536 536 changed = true;
537 537 }
538 538
539 539 if (s->m_startAngle != sliceAngle) {
540 540 s->m_startAngle = sliceAngle;
541 541 changed = true;
542 542 }
543 543 sliceAngle += sliceSpan;
544 544
545 545 if (changed)
546 546 emit s->changed();
547 547 }
548 548 }
549 549
550 550 bool QPieSeries::setModel(QAbstractItemModel* model)
551 551 {
552 552 // disconnect signals from old model
553 553 if(m_model)
554 554 {
555 555 disconnect(m_model,SIGNAL(dataChanged(QModelIndex,QModelIndex)), 0, 0);
556 556 disconnect(m_model,SIGNAL(rowsInserted(QModelIndex, int, int)), 0, 0);
557 557 disconnect(m_model, SIGNAL(rowsRemoved(QModelIndex, int, int)), 0, 0);
558 558 }
559 559
560 560 // set new model if not NULL and connect necessary signals from it
561 561 if(model)
562 562 {
563 563 m_model = model;
564 564 connect(m_model,SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(modelUpdated(QModelIndex, QModelIndex)));
565 565 connect(m_model,SIGNAL(rowsInserted(QModelIndex, int, int)), this, SLOT(modelDataAdded(QModelIndex,int,int)));
566 566 connect(m_model, SIGNAL(rowsRemoved(QModelIndex, int, int)), this, SLOT(modelDataRemoved(QModelIndex,int,int)));
567 567 }
568 568
569 569 return true;
570 570 }
571 571
572 572 void QPieSeries::setModelMapping(int modelValuesLine, int modelLabelsLine, Qt::Orientation orientation)
573 573 {
574 574 m_mapValues = modelValuesLine;
575 575 m_mapLabels = modelLabelsLine;
576 576 m_mapOrientation = orientation;
577 577
578 578 if (m_model == NULL)
579 579 return;
580 580
581 581 if (m_mapOrientation == Qt::Vertical)
582 582 for (int i = 0; i < m_model->rowCount(); i++)
583 583 add(m_model->data(m_model->index(i, m_mapValues), Qt::DisplayRole).toDouble(), m_model->data(m_model->index(i, m_mapLabels), Qt::DisplayRole).toString());
584 584 else
585 585 for (int i = 0; i < m_model->columnCount(); i++)
586 586 add(m_model->data(m_model->index(m_mapValues, i), Qt::DisplayRole).toDouble(), m_model->data(m_model->index(m_mapLabels, i), Qt::DisplayRole).toString());
587 587
588 588
589 589 }
590 590
591 591 void QPieSeries::modelUpdated(QModelIndex topLeft, QModelIndex bottomRight)
592 592 {
593 Q_UNUSED(bottomRight)
594
593 595 if (m_mapOrientation == Qt::Vertical)
594 596 {
595 597 // slices().at(topLeft.row())->setValue(m_model->data(m_model->index(topLeft.row(), topLeft.column()), Qt::DisplayRole).toDouble());
596 598 if (topLeft.column() == m_mapValues)
597 599 slices().at(topLeft.row())->setValue(m_model->data(topLeft, Qt::DisplayRole).toDouble());
598 600 else if (topLeft.column() == m_mapLabels)
599 601 slices().at(topLeft.row())->setLabel(m_model->data(topLeft, Qt::DisplayRole).toString());
600 602 }
601 603 else
602 604 {
603 605 // slices().at(topLeft.column())->setValue(m_model->data(m_model->index(topLeft.row(), topLeft.column()), Qt::DisplayRole).toDouble());
604 606 if (topLeft.column() == m_mapValues)
605 607 slices().at(topLeft.column())->setValue(m_model->data(topLeft, Qt::DisplayRole).toDouble());
606 608 else if (topLeft.column() == m_mapLabels)
607 609 slices().at(topLeft.column())->setLabel(m_model->data(topLeft, Qt::DisplayRole).toString());
608 610 }
609 611 }
610 612
611 613 void QPieSeries::modelDataAdded(QModelIndex parent, int start, int end)
612 614 {
615 Q_UNUSED(parent)
616 Q_UNUSED(end)
617
613 618 QPieSlice* newSlice = new QPieSlice;
614 619 newSlice->setLabelVisible(true);
615 620 if (m_mapOrientation == Qt::Vertical)
616 621 {
617 622 newSlice->setValue(m_model->data(m_model->index(start, m_mapValues), Qt::DisplayRole).toDouble());
618 623 newSlice->setLabel(m_model->data(m_model->index(start, m_mapLabels), Qt::DisplayRole).toString());
619 624 }
620 625 else
621 626 {
622 627 newSlice->setValue(m_model->data(m_model->index(m_mapValues, start), Qt::DisplayRole).toDouble());
623 628 newSlice->setLabel(m_model->data(m_model->index(m_mapLabels, start), Qt::DisplayRole).toString());
624 629 }
625 630
626 631 insert(start, newSlice);
627 632 }
628 633
629 634 void QPieSeries::modelDataRemoved(QModelIndex parent, int start, int end)
630 635 {
636 Q_UNUSED(parent)
637 Q_UNUSED(end)
631 638 remove(slices().at(start));
632 639 }
633 640
634 641 #include "moc_qpieseries.cpp"
635 642
636 643 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,217 +1,222
1 1 #include "qchartglobal.h"
2 2 #include "qlegend.h"
3 3 #include "qseries.h"
4 4 #include "legendmarker_p.h"
5 5 #include "qxyseries.h"
6 6 #include "qlineseries.h"
7 7 #include "qareaseries.h"
8 8 #include "qscatterseries.h"
9 9 #include "qsplineseries.h"
10 10 #include "qbarseries.h"
11 11 #include "qstackedbarseries.h"
12 12 #include "qpercentbarseries.h"
13 13 #include "qbarset.h"
14 14 #include "qpieseries.h"
15 15 #include "qpieslice.h"
16 16 #include <QPainter>
17 17 #include <QPen>
18 18
19 19 #include <QGraphicsSceneEvent>
20 20
21 21 QTCOMMERCIALCHART_BEGIN_NAMESPACE
22 22
23 23 QLegend::QLegend(QGraphicsItem *parent)
24 24 : QGraphicsObject(parent)
25 25 ,mBoundingRect(0,0,1,1)
26 26 ,mBackgroundBrush(Qt::darkGray) // TODO: from theme?
27 27 ,mMinimumSize(50,20) // TODO: magic numbers
28 28 {
29 29 setVisible(false);
30 30 }
31 31
32 32 void QLegend::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
33 33 {
34 Q_UNUSED(option)
35 Q_UNUSED(widget)
36
34 37 painter->setBrush(mBackgroundBrush);
35 38 painter->drawRect(mBoundingRect);
36 39 }
37 40
38 41 QRectF QLegend::boundingRect() const
39 42 {
40 43 return mBoundingRect;
41 44 }
42 45
43 46 void QLegend::setBackgroundBrush(const QBrush& brush)
44 47 {
45 48 mBackgroundBrush = brush;
46 49 }
47 50
48 51 QBrush QLegend::backgroundBrush() const
49 52 {
50 53 return mBackgroundBrush;
51 54 }
52 55
53 56 QSizeF QLegend::minimumSize() const
54 57 {
55 58 return mMinimumSize;
56 59 }
57 60
58 61 void QLegend::setMinimumSize(const QSizeF size)
59 62 {
60 63 mMinimumSize = size;
61 64 }
62 65
63 66 void QLegend::handleSeriesAdded(QSeries* series,Domain* domain)
64 67 {
68 Q_UNUSED(domain)
69
65 70 mSeriesList.append(series);
66 71 createMarkers(series);
67 72 layoutChanged();
68 73 }
69 74
70 75 void QLegend::handleSeriesRemoved(QSeries* series)
71 76 {
72 77 if (series->type() == QSeries::SeriesTypeArea)
73 78 {
74 79 // This is special case. Area series has upper and lower series, which each have markers
75 80 QAreaSeries* s = static_cast<QAreaSeries*> (series);
76 81 deleteMarkers(s->upperSeries());
77 82 deleteMarkers(s->lowerSeries());
78 83 } else {
79 84 deleteMarkers(series);
80 85 }
81 86
82 87 mSeriesList.removeOne(series);
83 88 layoutChanged();
84 89 }
85 90
86 91 void QLegend::handleGeometryChanged(const QRectF& size)
87 92 {
88 93 mBoundingRect = size;
89 94 layoutChanged();
90 95 }
91 96
92 97 void QLegend::createMarkers(QSeries *series)
93 98 {
94 99 switch (series->type())
95 100 {
96 101 case QSeries::SeriesTypeLine: {
97 102 QLineSeries* lineSeries = static_cast<QLineSeries*>(series);
98 103 appendMarkers(lineSeries);
99 104 break;
100 105 }
101 106 case QSeries::SeriesTypeArea: {
102 107 QAreaSeries* areaSeries = static_cast<QAreaSeries*>(series);
103 108 appendMarkers(areaSeries->upperSeries());
104 109 if(areaSeries->lowerSeries())
105 110 appendMarkers(areaSeries->lowerSeries());
106 111 break;
107 112 }
108 113
109 114 case QSeries::SeriesTypeBar: {
110 115 QBarSeries* barSeries = static_cast<QBarSeries*>(series);
111 116 appendMarkers(barSeries);
112 117 break;
113 118 }
114 119
115 120 case QSeries::SeriesTypeStackedBar: {
116 121 QStackedBarSeries* stackedBarSeries = static_cast<QStackedBarSeries*>(series);
117 122 appendMarkers(stackedBarSeries);
118 123 break;
119 124 }
120 125
121 126 case QSeries::SeriesTypePercentBar: {
122 127 QPercentBarSeries* percentBarSeries = static_cast<QPercentBarSeries*>(series);
123 128 appendMarkers(percentBarSeries);
124 129 break;
125 130 }
126 131
127 132 case QSeries::SeriesTypeScatter: {
128 133 QScatterSeries *scatterSeries = static_cast<QScatterSeries *>(series);
129 134 appendMarkers(scatterSeries);
130 135 break;
131 136 }
132 137
133 138 case QSeries::SeriesTypePie: {
134 139 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
135 140 appendMarkers(pieSeries);
136 141 break;
137 142 }
138 143
139 144 case QSeries::SeriesTypeSpline: {
140 145 QSplineSeries* splineSeries = static_cast<QSplineSeries*>(series);
141 146 appendMarkers(splineSeries);
142 147 break;
143 148 }
144 149 default: {
145 150 qDebug()<< "QLegend::createMarkers" << series->type() << "not implemented.";
146 151 break;
147 152 }
148 153 }
149 154 }
150 155
151 156 void QLegend::appendMarkers(QXYSeries* series)
152 157 {
153 158 LegendMarker* marker = new LegendMarker(series,this);
154 159 marker->setName(series->name());
155 160 marker->setBrush(series->brush());
156 161 connect(marker,SIGNAL(clicked(QSeries*,Qt::MouseButton)),this,SIGNAL(clicked(QSeries*,Qt::MouseButton)));
157 162 mMarkers.append(marker);
158 163 childItems().append(marker);
159 164 }
160 165
161 166 void QLegend::appendMarkers(QBarSeries *series)
162 167 {
163 168 foreach(QBarSet* s, series->barSets()) {
164 169 LegendMarker* marker = new LegendMarker(series,s,this);
165 170 marker->setName(s->name());
166 171 marker->setBrush(s->brush());
167 172 connect(marker,SIGNAL(clicked(QBarSet*,Qt::MouseButton)),this,SIGNAL(clicked(QBarSet*,Qt::MouseButton)));
168 173 connect(s,SIGNAL(changed()),marker,SLOT(changed()));
169 174 mMarkers.append(marker);
170 175 childItems().append(marker);
171 176 }
172 177 }
173 178
174 179 void QLegend::appendMarkers(QPieSeries *series)
175 180 {
176 181 foreach(QPieSlice* s, series->slices()) {
177 182 LegendMarker* marker = new LegendMarker(series,s,this);
178 183 marker->setName(s->label());
179 184 marker->setBrush(s->sliceBrush());
180 185 connect(marker,SIGNAL(clicked(QPieSlice*,Qt::MouseButton)),this,SIGNAL(clicked(QPieSlice*,Qt::MouseButton)));
181 186 connect(s,SIGNAL(changed()),marker,SLOT(changed()));
182 187 mMarkers.append(marker);
183 188 childItems().append(marker);
184 189 }
185 190 }
186 191
187 192 void QLegend::deleteMarkers(QSeries *series)
188 193 {
189 194 // Search all markers that belong to given series and delete them.
190 195 foreach (LegendMarker *m, mMarkers) {
191 196 if (m->series() == series) {
192 197 mMarkers.removeOne(m);
193 198 delete m;
194 199 }
195 200 }
196 201 }
197 202
198 203 void QLegend::layoutChanged()
199 204 {
200 205 // Calculate layout for markers and text
201 206 if (mMarkers.count() <= 0) {
202 207 // Nothing to do
203 208 return;
204 209 }
205 210
206 211 qreal steps = mMarkers.count();
207 212 qreal xStep = mBoundingRect.width() / steps;
208 213 qreal x=mBoundingRect.x();
209 214 qreal y = mBoundingRect.y() + (mBoundingRect.height()/4);
210 215 foreach (LegendMarker* m, mMarkers) {
211 216 m->setBoundingRect(QRectF(x,y,xStep,mBoundingRect.height()/2));
212 217 x += xStep;
213 218 }
214 219 }
215 220
216 221 #include "moc_qlegend.cpp"
217 222 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,184 +1,180
1 1 #include "scatterchartitem_p.h"
2 2 #include "qscatterseries.h"
3 3 #include "chartpresenter_p.h"
4 4 #include <QPainter>
5 5 #include <QGraphicsScene>
6 6
7 7 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8 8
9 9
10 10
11 11
12 12
13 13
14 14
15 15 ScatterChartItem::ScatterChartItem(QScatterSeries *series, QGraphicsItem *parent) :
16 16 XYChartItem(series,parent),
17 17 m_series(series),
18 18 m_items(this),
19 19 m_shape(QScatterSeries::MarkerShapeRectangle),
20 20 m_size(10)
21 21
22 22 {
23 23 Q_ASSERT(parent);
24 24 Q_ASSERT(series);
25 25
26 26 QObject::connect(m_series,SIGNAL(updated()), this, SLOT(handleUpdated()));
27 27
28 28 setZValue(ChartPresenter::ScatterSeriesZValue);
29 29 setFlags(QGraphicsItem::ItemHasNoContents);
30 30 setFlags(QGraphicsItem::ItemClipsChildrenToShape);
31 31
32 32 handleUpdated();
33 33
34 34 m_items.setHandlesChildEvents(false);
35 35
36 36 // TODO: how to draw a drop shadow?
37 37 // QGraphicsDropShadowEffect *dropShadow = new QGraphicsDropShadowEffect();
38 38 // dropShadow->setOffset(2.0);
39 39 // dropShadow->setBlurRadius(2.0);
40 40 // setGraphicsEffect(dropShadow);
41 41 }
42 42
43 43
44 44 QRectF ScatterChartItem::boundingRect() const
45 45 {
46 46 return m_rect;
47 47 }
48 48
49 49 void ScatterChartItem::createPoints(int count)
50 50 {
51 51 for (int i = 0; i < count; ++i) {
52 52
53 53 QGraphicsItem *item;
54 54
55 55 switch (m_shape) {
56 56 case QScatterSeries::MarkerShapeCircle:{
57 57 QGraphicsEllipseItem* i = new QGraphicsEllipseItem(0,0,m_size,m_size);
58 58 const QRectF& rect = i->boundingRect();
59 59 i->setPos(-rect.width()/2,-rect.height()/2);
60 60 item = new Marker(i,this);
61 61 break;
62 62 }
63 63 case QScatterSeries::MarkerShapeRectangle:{
64 64 QGraphicsRectItem* i = new QGraphicsRectItem(0,0,m_size,m_size);
65 65 i->setPos(-m_size/2,-m_size/2);
66 66 item = new Marker(i,this);
67 67 break;
68 68 }
69 69 default:
70 70 qWarning()<<"Unsupported marker type";
71 71 break;
72 72
73 73 }
74 74 m_items.addToGroup(item);
75 75 }
76 76 }
77 77
78 78 void ScatterChartItem::deletePoints(int count)
79 79 {
80 80 QList<QGraphicsItem *> items = m_items.childItems();
81 81
82 82 for (int i = 0; i < count; ++i) {
83 83 delete(items.takeLast());
84 84 }
85 85 }
86 86
87 87 void ScatterChartItem::markerSelected(Marker* marker)
88 88 {
89 89 emit XYChartItem::clicked(QPointF(m_series->x(marker->index()), m_series->y(marker->index())));
90 90 }
91 91
92 92 void ScatterChartItem::setLayout(QVector<QPointF>& points)
93 93 {
94 94 if(points.size()==0)
95 95 {
96 96 XYChartItem::setLayout(points);
97 97 return;
98 98 }
99 99
100 100 int diff = XYChartItem::points().size() - points.size();
101 101
102 102 if(diff>0) {
103 103 deletePoints(diff);
104 104 }
105 105 else if(diff<0) {
106 106 createPoints(-diff);
107 107 }
108 108
109 109 if(diff!=0) handleUpdated();
110 110
111 111 QList<QGraphicsItem*> items = m_items.childItems();
112 112
113 113 for(int i=0; i< points.size();i++) {
114 114 Marker* item = static_cast<Marker*>(items.at(i));
115 115 const QPointF& point = points.at(i);
116 116 const QRectF& rect = item->boundingRect();
117 117 item->setIndex(i);
118 118 item->setPos(point.x()-rect.width()/2,point.y()-rect.height()/2);
119 119 if(!clipRect().contains(point)) {
120 120 item->setVisible(false);
121 121 }
122 122 else {
123 123 item->setVisible(true);
124 124 }
125 125 }
126 126
127 127 prepareGeometryChange();
128 128 m_rect = clipRect();
129 129 XYChartItem::setLayout(points);
130 130 }
131 131
132 132
133 133 void ScatterChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
134 134 {
135 Q_UNUSED(painter);
136 Q_UNUSED(option);
137 Q_UNUSED(widget);
135 Q_UNUSED(painter)
136 Q_UNUSED(option)
137 Q_UNUSED(widget)
138 138 }
139 139
140 140 void ScatterChartItem::setPen(const QPen& pen)
141 141 {
142 142 foreach(QGraphicsItem* item , m_items.childItems()) {
143 143 static_cast<Marker*>(item)->setPen(pen);
144 144 }
145 145 }
146 146
147 147 void ScatterChartItem::setBrush(const QBrush& brush)
148 148 {
149 149 foreach(QGraphicsItem* item , m_items.childItems()) {
150 150 static_cast<Marker*>(item)->setBrush(brush);
151 151 }
152 152 }
153 153
154 154 void ScatterChartItem::handleUpdated()
155 155 {
156 156
157 157 int count = m_items.childItems().count();
158 158
159 159 if(count==0) return;
160 160
161 161 bool recreate = m_size != m_series->size() || m_shape != m_series->shape();
162 162
163 163 //TODO: only rewrite on size change
164 164
165 165 m_size = m_series->size();
166 166 m_shape = m_series->shape();
167 167
168 168 if(recreate){
169 169 deletePoints(count);
170 170 createPoints(count);
171 171 }
172 172
173 173 setPen(m_series->pen());
174 174 setBrush(m_series->brush());
175 175
176 176 }
177 177
178 void ScatterChartItem::mousePressEvent( QGraphicsSceneMouseEvent * event )
179 {
180 }
181
182 178 #include "moc_scatterchartitem_p.cpp"
183 179
184 180 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,120 +1,121
1 1 #ifndef SCATTERPRESENTER_H
2 2 #define SCATTERPRESENTER_H
3 3
4 4 #include "qchartglobal.h"
5 5 #include "xychartitem_p.h"
6 6 #include <QGraphicsEllipseItem>
7 7 #include <QPen>
8 8
9 9 QTCOMMERCIALCHART_BEGIN_NAMESPACE
10 10
11 11 class QScatterSeries;
12 12 class Marker;
13 13
14 14 class ScatterChartItem : public XYChartItem
15 15 {
16 16 Q_OBJECT
17 17 public:
18 18 explicit ScatterChartItem(QScatterSeries *series, QGraphicsItem *parent = 0);
19 19
20 20 public:
21 21 //from QGraphicsItem
22 22 QRectF boundingRect() const;
23 23 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
24 24
25 25 void setPen(const QPen& pen);
26 26 void setBrush(const QBrush& brush);
27 27
28 28 void markerSelected(Marker* item);
29 29
30 30 public slots:
31 31 void handleUpdated();
32 32
33 33 private:
34 34 void createPoints(int count);
35 35 void deletePoints(int count);
36 36
37 37 protected:
38 38 void setLayout(QVector<QPointF>& points);
39 39 void mousePressEvent( QGraphicsSceneMouseEvent * event );
40 40
41 41 private:
42 42 QScatterSeries *m_series;
43 43 QGraphicsItemGroup m_items;
44 44 int m_shape;
45 45 int m_size;
46 46 QRectF m_rect;
47 47
48 48 };
49 49
50 50
51 51 class Marker: public QAbstractGraphicsShapeItem
52 52 {
53 53
54 54 public:
55 55
56 56 Marker(QAbstractGraphicsShapeItem* item , ScatterChartItem* parent):QAbstractGraphicsShapeItem(0),m_item(item),m_parent(parent)
57 57 {
58 58 };
59 59
60 60 ~Marker()
61 61 {
62 62 delete m_item;
63 63 }
64 64
65 65 void setIndex(int index)
66 66 {
67 67 m_index=index;
68 68 }
69 69
70 70 int index() const
71 71 {
72 72 return m_index;
73 73 }
74 74
75 75 QPainterPath shape() const
76 76 {
77 77 return m_item->shape();
78 78 }
79 79
80 80 QRectF boundingRect() const
81 81 {
82 82 return m_item->boundingRect();
83 83 }
84 84
85 85 bool contains(const QPointF &point) const
86 86 {
87 87 return m_item->contains(point);
88 88 }
89 89
90 90 void setPen(const QPen& pen)
91 91 {
92 92 m_item->setPen(pen);
93 93 }
94 94
95 95 void setBrush(const QBrush& brush)
96 96 {
97 97 m_item->setBrush(brush);
98 98 }
99 99
100 100 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
101 101 {
102 102 m_item->paint(painter,option,widget);
103 103 }
104 104
105 105 protected:
106 106
107 107 void mousePressEvent( QGraphicsSceneMouseEvent * event )
108 108 {
109 Q_UNUSED(event)
109 110 m_parent->markerSelected(this);
110 111 }
111 112
112 113 private:
113 114 QAbstractGraphicsShapeItem* m_item;
114 115 ScatterChartItem* m_parent;
115 116 int m_index;
116 117 };
117 118
118 119 QTCOMMERCIALCHART_END_NAMESPACE
119 120
120 121 #endif // SCATTERPRESENTER_H
@@ -1,89 +1,90
1 1 #include "splinechartitem_p.h"
2 2 #include "chartpresenter_p.h"
3 3 #include <QPainter>
4 4
5 5 QTCOMMERCIALCHART_BEGIN_NAMESPACE
6 6
7 7 SplineChartItem::SplineChartItem(QSplineSeries* series, QGraphicsItem *parent) :
8 8 XYChartItem(series, parent),
9 9 m_series(series),
10 10 m_pointsVisible(false)
11 11 {
12 12 setZValue(ChartPresenter::LineChartZValue);
13 13 QObject::connect(series,SIGNAL(updated()),this,SLOT(handleUpdated()));
14 14 handleUpdated();
15 15 }
16 16
17 17 QRectF SplineChartItem::boundingRect() const
18 18 {
19 19 return m_rect;
20 20 }
21 21
22 22 QPainterPath SplineChartItem::shape() const
23 23 {
24 24 return m_path;
25 25 }
26 26
27 27 QPointF SplineChartItem::calculateGeometryControlPoint(int index) const
28 28 {
29 29 return XYChartItem::calculateGeometryPoint(m_series->controlPoint(index));
30 30 }
31 31
32 32 void SplineChartItem::setLayout(QVector<QPointF>& points)
33 33 {
34 34
35 35 if(points.size()==0)
36 36 {
37 37 XYChartItem::setLayout(points);
38 38 return;
39 39 }
40 40
41 41 QPainterPath splinePath;
42 42 const QPointF& point = points.at(0);
43 43 splinePath.moveTo(point);
44 44
45 45 for (int i = 0; i < points.size() - 1; i++)
46 46 {
47 47 const QPointF& point = points.at(i + 1);
48 48 splinePath.cubicTo(calculateGeometryControlPoint(2 * i), calculateGeometryControlPoint(2 * i + 1), point);
49 49 }
50 50
51 51 prepareGeometryChange();
52 52 m_path = splinePath;
53 53 m_rect = splinePath.boundingRect();
54 54 XYChartItem::setLayout(points);
55 55 }
56 56
57 57 //handlers
58 58
59 59 void SplineChartItem::handleUpdated()
60 60 {
61 61 m_pointsVisible = m_series->pointsVisible();
62 62 m_linePen = m_series->pen();
63 63 m_pointPen = m_series->pen();
64 64 m_pointPen.setWidthF(2*m_pointPen.width());
65 65 update();
66 66 }
67 67
68 68 //painter
69 69
70 70 void SplineChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
71 71 {
72 Q_UNUSED(widget);
73 Q_UNUSED(option);
72 Q_UNUSED(widget)
73 Q_UNUSED(option)
74
74 75 painter->save();
75 76 painter->setClipRect(clipRect());
76 77 painter->setPen(m_linePen);
77 78 painter->drawPath(m_path);
78 79 if(m_pointsVisible){
79 80 painter->setPen(m_pointPen);
80 81 painter->drawPoints(points());
81 82 }
82 83 painter->restore();
83 84 }
84 85
85 86
86 87
87 88 #include "moc_splinechartitem_p.cpp"
88 89
89 90 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,312 +1,318
1 1 #include "qxyseries.h"
2 2
3 3 QTCOMMERCIALCHART_BEGIN_NAMESPACE
4 4
5 5 /*!
6 6 \class QXYSeries
7 7 \brief The QXYSeries class is a base class for line, spline and scatter series.
8 8 */
9 9
10 10 /*!
11 11 \fn QPen QXYSeries::pen() const
12 12 \brief Returns pen used to draw points for series.
13 13 \sa setPen()
14 14 */
15 15
16 16 /*!
17 17 \fn QBrush QXYSeries::brush() const
18 18 \brief Returns brush used to draw points for series.
19 19 \sa setBrush()
20 20 */
21 21
22 22 /*!
23 23 \fn void QXYSeries::clicked(const QPointF& point)
24 24 \brief Signal is emitted when user clicks the \a point on chart.
25 25 */
26 26
27 27 /*!
28 28 \fn void QXYSeries::pointReplaced(int index)
29 29 \brief \internal \a index
30 30 */
31 31
32 32 /*!
33 33 \fn void QXYSeries::pointAdded(int index)
34 34 \brief \internal \a index
35 35 */
36 36
37 37 /*!
38 38 \fn void QXYSeries::pointRemoved(int index)
39 39 \brief \internal \a index
40 40 */
41 41
42 42 /*!
43 43 \fn void QXYSeries::updated()
44 44 \brief \internal
45 45 */
46 46
47 47 /*!
48 48 Constructs empty series object which is a child of \a parent.
49 49 When series object is added to QChartView or QChart instance ownerships is transfered.
50 50 */
51 51 QXYSeries::QXYSeries(QObject* parent):QSeries(parent)
52 52 {
53 53 m_mapX = -1;
54 54 m_mapY = -1;
55 55 m_mapOrientation = Qt::Vertical;
56 56 // m_mapYOrientation = Qt::Vertical;
57 57 }
58 58 /*!
59 59 Destroys the object. Series added to QChartView or QChart instances are owned by those,
60 60 and are deleted when mentioned object are destroyed.
61 61 */
62 62 QXYSeries::~QXYSeries()
63 63 {
64 64 }
65 65
66 66 /*!
67 67 Adds data point \a x \a y to the series. Points are connected with lines on the chart.
68 68 */
69 69 void QXYSeries::add(qreal x,qreal y)
70 70 {
71 71 Q_ASSERT(m_x.size() == m_y.size());
72 72 m_x<<x;
73 73 m_y<<y;
74 74 emit pointAdded(m_x.size()-1);
75 75 }
76 76
77 77 /*!
78 78 This is an overloaded function.
79 79 Adds data \a point to the series. Points are connected with lines on the chart.
80 80 */
81 81 void QXYSeries::add(const QPointF& point)
82 82 {
83 83 add(point.x(),point.y());
84 84 }
85 85
86 86 /*!
87 87 This is an overloaded function.
88 88 Adds list of data \a points to the series. Points are connected with lines on the chart.
89 89 */
90 90 void QXYSeries::add(const QList<QPointF> points)
91 91 {
92 92 foreach(const QPointF& point , points) {
93 93 add(point.x(),point.y());
94 94 }
95 95 }
96 96
97 97 /*!
98 98 Modifies \a y value for given \a x a value.
99 99 */
100 100 void QXYSeries::replace(qreal x,qreal y)
101 101 {
102 102 int index = m_x.indexOf(x);
103 103 m_x[index]=x;
104 104 m_y[index]=y;
105 105 emit pointReplaced(index);
106 106 }
107 107
108 108 /*!
109 109 This is an overloaded function.
110 110 Replaces current y value of for given \a point x value with \a point y value.
111 111 */
112 112 void QXYSeries::replace(const QPointF& point)
113 113 {
114 114 replace(point.x(),point.y());
115 115 }
116 116
117 117 /*!
118 118 Removes current \a x and \a y value.
119 119 */
120 120 void QXYSeries::remove(qreal x,qreal y)
121 121 {
122 122 int index =-1;
123 123 do{
124 124 index = m_x.indexOf(x,index+1);
125 125 }while(index !=-1 && m_y.at(index)!=y);
126 126
127 127 if(index==-1) return;
128 128
129 129 m_x.remove(index);
130 130 m_y.remove(index);
131 131 emit pointRemoved(index);
132 132 }
133 133
134 134 /*!
135 135 Removes current \a point x value. Note \a point y value is ignored.
136 136 */
137 137 void QXYSeries::remove(const QPointF& point)
138 138 {
139 139 remove(point.x(),point.y());
140 140 }
141 141
142 142 /*!
143 143 Removes all data points from the series.
144 144 */
145 145 void QXYSeries::removeAll()
146 146 {
147 147 m_x.clear();
148 148 m_y.clear();
149 149 }
150 150
151 151 /*!
152 152 \internal \a pos
153 153 */
154 154 qreal QXYSeries::x(int pos) const
155 155 {
156 156 if (m_model)
157 157 if (m_mapOrientation == Qt::Vertical)
158 158 // consecutive data is read from model's column
159 159 return m_model->data(m_model->index(pos, m_mapX), Qt::DisplayRole).toDouble();
160 160 else
161 161 // consecutive data is read from model's row
162 162 return m_model->data(m_model->index(m_mapX, pos), Qt::DisplayRole).toDouble();
163 163 else
164 164 // model is not specified, return the data from series' internal data store
165 165 return m_x.at(pos);
166 166 }
167 167
168 168 /*!
169 169 \internal \a pos
170 170 */
171 171 qreal QXYSeries::y(int pos) const
172 172 {
173 173 if (m_model)
174 174 if (m_mapOrientation == Qt::Vertical)
175 175 // consecutive data is read from model's column
176 176 return m_model->data(m_model->index(pos, m_mapY), Qt::DisplayRole).toDouble();
177 177 else
178 178 // consecutive data is read from model's row
179 179 return m_model->data(m_model->index(m_mapY, pos), Qt::DisplayRole).toDouble();
180 180 else
181 181 // model is not specified, return the data from series' internal data store
182 182 return m_y.at(pos);
183 183 }
184 184
185 185 /*!
186 186 Returns number of data points within series.
187 187 */
188 188 int QXYSeries::count() const
189 189 {
190 190 Q_ASSERT(m_x.size() == m_y.size());
191 191
192 192 if (m_model) {
193 193 if (m_mapOrientation == Qt::Vertical)
194 194 // data is in a column, so return the number of items in single column
195 195 return m_model->rowCount();
196 196 else
197 197 // data is in a row, so return the number of items in single row
198 198 return m_model->columnCount();
199 199 }
200 200
201 201 // model is not specified, return the number of points in the series internal data store
202 202 return m_x.size();
203 203 }
204 204
205 205 /*!
206 206 Returns the data points of the series.
207 207 */
208 208 QList<QPointF> QXYSeries::data()
209 209 {
210 210 QList<QPointF> data;
211 211 for (int i(0); i < m_x.count() && i < m_y.count(); i++)
212 212 data.append(QPointF(m_x.at(i), m_y.at(i)));
213 213 return data;
214 214 }
215 215
216 216
217 217 /*!
218 218 Sets \a pen used for drawing points on the chart. If the pen is not defined, the
219 219 pen from chart theme is used.
220 220 \sa QChart::setChartTheme()
221 221 */
222 222 void QXYSeries::setPen(const QPen& pen)
223 223 {
224 224 if(pen!=m_pen){
225 225 m_pen=pen;
226 226 emit updated();
227 227 }
228 228 }
229 229
230 230 /*!
231 231 Sets \a brush used for drawing points on the chart. If the brush is not defined, brush
232 232 from chart theme setting is used.
233 233 \sa QChart::setChartTheme()
234 234 */
235 235
236 236 void QXYSeries::setBrush(const QBrush& brush)
237 237 {
238 238 if(brush!=m_brush){
239 239 m_brush=brush;
240 240 emit updated();
241 241 }
242 242 }
243 243
244 244
245 245 /*!
246 246 Stream operator for adding a data \a point to the series.
247 247 \sa add()
248 248 */
249 249
250 250 QXYSeries& QXYSeries::operator<< (const QPointF &point)
251 251 {
252 252 add(point);
253 253 return *this;
254 254 }
255 255
256 256
257 257 /*!
258 258 Stream operator for adding a list of \a points to the series.
259 259 \sa add()
260 260 */
261 261
262 262 QXYSeries& QXYSeries::operator<< (const QList<QPointF> points)
263 263 {
264 264 add(points);
265 265 return *this;
266 266 }
267 267
268 268
269 269 void QXYSeries::modelUpdated(QModelIndex topLeft, QModelIndex bottomRight)
270 270 {
271 Q_UNUSED(bottomRight)
272
271 273 if (m_mapOrientation == Qt::Vertical)
272 274 emit pointReplaced(topLeft.row());
273 275 else
274 276 emit pointReplaced(topLeft.column());
275 277 }
276 278
277 279 void QXYSeries::modelDataAdded(QModelIndex parent, int start, int end)
278 280 {
281 Q_UNUSED(parent)
282 Q_UNUSED(end)
279 283 emit pointAdded(start);
280 284 }
281 285
282 286 void QXYSeries::modelDataRemoved(QModelIndex parent, int start, int end)
283 287 {
288 Q_UNUSED(parent)
289 Q_UNUSED(end)
284 290 emit pointRemoved(start);
285 291 }
286 292
287 293 bool QXYSeries::setModel(QAbstractItemModel* model) {
288 294 m_model = model;
289 295 // for (int i = 0; i < m_model->rowCount(); i++)
290 296 // emit pointAdded(i);
291 297 connect(m_model,SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(modelUpdated(QModelIndex, QModelIndex)));
292 298 connect(m_model,SIGNAL(rowsInserted(QModelIndex, int, int)), this, SLOT(modelDataAdded(QModelIndex,int,int)));
293 299 connect(m_model, SIGNAL(rowsRemoved(QModelIndex, int, int)), this, SLOT(modelDataRemoved(QModelIndex,int,int)));
294 300 return true;
295 301 }
296 302
297 303 void QXYSeries::setModelMapping(int modelX, int modelY, Qt::Orientation orientation)
298 304 {
299 305 m_mapX = modelX;
300 306 m_mapY = modelY;
301 307 m_mapOrientation = orientation;
302 308 }
303 309
304 310 //void QXYSeries::setModelMappingY(int modelLineIndex, Qt::Orientation orientation)
305 311 //{
306 312 // m_mapY = modelLineIndex;
307 313 // m_mapYOrientation = orientation;
308 314 //}
309 315
310 316 #include "moc_qxyseries.cpp"
311 317
312 318 QTCOMMERCIALCHART_END_NAMESPACE
General Comments 0
You need to be logged in to leave comments. Login now