##// END OF EJS Templates
legend documentation fix. detaching and attaching the legend
sauimone -
r728:7d3fdc2fff63
parent child
Show More
@@ -1,79 +1,80
1 1 /*!
2 2 \page classes.html
3 3 \title QtCommercial Charts API
4 4 \keyword All Classes
5 5
6 6 Charts API is build on top of Qt Graphics View Framework. Charts can be displayed as QGraphicsWidget using QChart class. However
7 7 there is also convenience class QChartView which is QWidget based. These lets quickly use QCharts as normal Qt widget.
8 8 Currently API supports following chart types:
9 9
10 10 \list
11 11 \o area
12 12 \o line
13 13 \o bar
14 14 \o percent bar
15 15 \o pie
16 16 \o scatter
17 17 \o spline
18 18 \o stacked bar
19 19 \endlist
20 20
21 21
22 22 Each chart type is represented by QSeries derived class. To create given chart type users have to use instace of releted sereis class and add it to QChart/QChartView instance.
23 23 \code
24 24 QLineSeries* series = new QLineSeries();
25 25 series->add(0, 6);
26 26 series->add(2, 4);
27 27 ...
28 28 chartView->addSeries(series);
29 29 \endcode
30 30
31 31 \image class_diagram.png
32 32 \raw HTML
33 33 <table cellpadding="2" cellspacing="1" border="0" width="100%" class="indextable">
34 34 <tr>
35 35 <th class="titleheader" width="33%">
36 36 List of classes
37 37 </th>
38 38 </tr>
39 39 <tr>
40 40 <td valign="top">
41 41 <ul>
42 42 <li><a href="qareaseries.html">QAreaSeries</a></li>
43 43 <li><a href="qbarseries.html">QBarSeries</a></li>
44 44 <li><a href="qbarset.html">QBarSet</a></li>
45 45 <li><a href="qchart.html">QChart</a></li>
46 46 <li><a href="qchartaxis.html">QChartAxis</a></li>
47 47 <li><a href="qchartview.html">QChartView</a></li>
48 48 <li><a href="qlineseries.html">QLineSeries</a></li>
49 49 <li><a href="qpercentbarseries.html">QPercentBarSeries</a></li>
50 50 <li><a href="qpieseries.html">QPieSeries</a></li>
51 51 <li><a href="qpieslice.html">QPieSlice</a></li>
52 52 <li><a href="qscatterseries.html">QScatterSeries</a></li>
53 53 <li><a href="qseries.html">QSeries</a></li>
54 54 <li><a href="qsplineseries.html">QSplineSeries</a></li>
55 55 <li><a href="qstackedbarseries.html">QStackedBarSeries</a></li>
56 56 <li><a href="qxyseries.html">QXYSeries</a></li>
57 <li><a href="qlegend.html">QLegend</a></li>
57 58 </ul>
58 59 </td>
59 60 </tr>
60 61 </table>
61 62
62 63 <table cellpadding="2" cellspacing="1" border="0" width="100%" class="indextable">
63 64 <tr>
64 65 <th class="titleheader" width="33%">
65 66 Other files:
66 67 </th>
67 68 </tr>
68 69 <tr>
69 70 <td valign="top">
70 71 <ul>
71 72 <li><a href="qchartglobal.html">QChartGlobal</a></li>
72 73 </ul>
73 74 </td>
74 75 </tr>
75 76 </table>
76 77
77 78 \endraw
78 79
79 80 */
@@ -1,424 +1,454
1 1 #include "qchart.h"
2 2 #include "qchartaxis.h"
3 3 #include "qlegend.h"
4 4 #include "chartpresenter_p.h"
5 5 #include "chartdataset_p.h"
6 6 #include "chartbackground_p.h"
7 7 #include <QGraphicsScene>
8 8 #include <QGraphicsSceneResizeEvent>
9 9
10 10 QTCOMMERCIALCHART_BEGIN_NAMESPACE
11 11
12 12 /*!
13 13 \enum QChart::ChartTheme
14 14
15 15 This enum describes the theme used by the chart.
16 16
17 17 \value ChartThemeDefault Follows the GUI style of the Operating System
18 18 \value ChartThemeLight
19 19 \value ChartThemeBlueCerulean
20 20 \value ChartThemeDark
21 21 \value ChartThemeBrownSand
22 22 \value ChartThemeBlueNcs
23 23 \value ChartThemeIcy
24 24 \value ChartThemeScientific
25 25 \value ChartThemeCount Not really a theme; the total count of themes.
26 26 */
27 27
28 28 /*!
29 29 \enum QChart::AnimationOption
30 30
31 31 For enabling/disabling animations. Defaults to NoAnimation.
32 32
33 33 \value NoAnimation
34 34 \value GridAxisAnimations
35 35 \value SeriesAnimations
36 36 \value AllAnimations
37 37 */
38 38
39 39 /*!
40 40 \class QChart
41 41 \brief QtCommercial chart API.
42 42
43 43 QChart is a QGraphicsWidget that you can show in a QGraphicsScene. It manages the graphical
44 44 representation of different types of QChartSeries and other chart related objects like
45 45 QChartAxis and QChartLegend. If you simply want to show a chart in a layout, you can use the
46 46 convenience class QChartView instead of QChart.
47 47 \sa QChartView
48 48 */
49 49
50 50 /*!
51 51 Constructs a chart object which is a child of a\a parent. Parameter \a wFlags is passed to the QGraphicsWidget constructor.
52 52 */
53 53 QChart::QChart(QGraphicsItem *parent, Qt::WindowFlags wFlags) : QGraphicsWidget(parent,wFlags),
54 54 m_backgroundItem(0),
55 55 m_titleItem(0),
56 56 m_legend(new QLegend(this)),
57 57 m_dataset(new ChartDataSet(this)),
58 58 m_presenter(new ChartPresenter(this,m_dataset)),
59 59 m_padding(50),
60 60 m_backgroundPadding(10)
61 61 {
62 62 connect(m_dataset,SIGNAL(seriesAdded(QSeries*,Domain*)),m_legend,SLOT(handleSeriesAdded(QSeries*,Domain*)));
63 63 connect(m_dataset,SIGNAL(seriesRemoved(QSeries*)),m_legend,SLOT(handleSeriesRemoved(QSeries*)));
64 64 }
65 65
66 66 /*!
67 67 Destroys the object and it's children, like QChartSeries and QChartAxis object added to it.
68 68 */
69 69 QChart::~QChart()
70 70 {
71 71 //delete first presenter , since this is a root of all the graphical items
72 72 delete m_presenter;
73 73 m_presenter=0;
74 74 }
75 75
76 76 /*!
77 77 Adds the \a series and optional \a axisY onto the chart and takes the ownership of the objects.
78 78 If auto scaling is enabled, re-scales the axes the series is bound to (both the x axis and
79 79 the y axis).
80 80 */
81 81 void QChart::addSeries(QSeries* series, QChartAxis* axisY)
82 82 {
83 83 m_dataset->addSeries(series, axisY);
84 84 }
85 85
86 86 /*!
87 87 Removes the \a series specified in a perameter from the QChartView.
88 88 It releses its ownership of the specified QChartSeries object.
89 89 It does not delete the pointed QChartSeries data object
90 90 \sa addSeries(), removeAllSeries()
91 91 */
92 92 void QChart::removeSeries(QSeries* series)
93 93 {
94 94 m_dataset->removeSeries(series);
95 95 }
96 96
97 97 /*!
98 98 Removes all the QChartSeries that have been added to the QChartView
99 99 It also deletes the pointed QChartSeries data objects
100 100 \sa addSeries(), removeSeries()
101 101 */
102 102 void QChart::removeAllSeries()
103 103 {
104 104 m_dataset->removeAllSeries();
105 105 }
106 106
107 107 /*!
108 108 Sets the \a brush that is used for painting the background of the chart area.
109 109 */
110 110 void QChart::setBackgroundBrush(const QBrush& brush)
111 111 {
112 112 createChartBackgroundItem();
113 113 m_backgroundItem->setBrush(brush);
114 114 m_backgroundItem->update();
115 115 }
116 116
117 117 QBrush QChart::backgroundBrush() const
118 118 {
119 119 if(!m_backgroundItem) return QBrush();
120 120 return m_backgroundItem->brush();
121 121 }
122 122
123 123 /*!
124 124 Sets the \a pen that is used for painting the background of the chart area.
125 125 */
126 126 void QChart::setBackgroundPen(const QPen& pen)
127 127 {
128 128 createChartBackgroundItem();
129 129 m_backgroundItem->setPen(pen);
130 130 m_backgroundItem->update();
131 131 }
132 132
133 133 QPen QChart::backgroundPen() const
134 134 {
135 135 if(!m_backgroundItem) return QPen();
136 136 return m_backgroundItem->pen();
137 137 }
138 138
139 139 /*!
140 140 Sets the chart \a title. The description text that is drawn above the chart.
141 141 */
142 142 void QChart::setTitle(const QString& title)
143 143 {
144 144 createChartTitleItem();
145 145 m_titleItem->setText(title);
146 146 updateLayout();
147 147 }
148 148
149 149 /*!
150 150 Returns the chart title. The description text that is drawn above the chart.
151 151 */
152 152 QString QChart::title() const
153 153 {
154 154 if(m_titleItem)
155 155 return m_titleItem->text();
156 156 else
157 157 return QString();
158 158 }
159 159
160 160 /*!
161 161 Sets the \a font that is used for rendering the description text that is rendered above the chart.
162 162 */
163 163 void QChart::setTitleFont(const QFont& font)
164 164 {
165 165 createChartTitleItem();
166 166 m_titleItem->setFont(font);
167 167 updateLayout();
168 168 }
169 169
170 170 /*!
171 171 Sets the \a brush used for rendering the title text.
172 172 */
173 173 void QChart::setTitleBrush(const QBrush &brush)
174 174 {
175 175 createChartTitleItem();
176 176 m_titleItem->setBrush(brush);
177 177 updateLayout();
178 178 }
179 179
180 180 /*!
181 181 Returns the brush used for rendering the title text.
182 182 */
183 183 QBrush QChart::titleBrush() const
184 184 {
185 185 if(!m_titleItem) return QBrush();
186 186 return m_titleItem->brush();
187 187 }
188 188
189 189 void QChart::createChartBackgroundItem()
190 190 {
191 191 if(!m_backgroundItem) {
192 192 m_backgroundItem = new ChartBackground(this);
193 193 m_backgroundItem->setPen(Qt::NoPen);
194 194 m_backgroundItem->setZValue(ChartPresenter::BackgroundZValue);
195 195 }
196 196 }
197 197
198 198 void QChart::createChartTitleItem()
199 199 {
200 200 if(!m_titleItem) {
201 201 m_titleItem = new QGraphicsSimpleTextItem(this);
202 202 m_titleItem->setZValue(ChartPresenter::BackgroundZValue);
203 203 }
204 204 }
205 205
206 206 /*!
207 207 Sets the \a theme used by the chart for rendering the graphical representation of the data
208 208 \sa ChartTheme, chartTheme()
209 209 */
210 210 void QChart::setChartTheme(QChart::ChartTheme theme)
211 211 {
212 212 m_presenter->setChartTheme(theme);
213 213 }
214 214
215 215 /*!
216 216 Returns the theme enum used by the chart.
217 217 \sa ChartTheme, setChartTheme()
218 218 */
219 219 QChart::ChartTheme QChart::chartTheme() const
220 220 {
221 221 return m_presenter->chartTheme();
222 222 }
223 223
224 224 /*!
225 225 Zooms in the view by a factor of 2
226 226 */
227 227 void QChart::zoomIn()
228 228 {
229 229 m_presenter->zoomIn();
230 230 }
231 231
232 232 /*!
233 233 Zooms in the view to a maximum level at which \a rect is still fully visible.
234 234 */
235 235 void QChart::zoomIn(const QRectF& rect)
236 236 {
237 237
238 238 if(!rect.isValid()) return;
239 239 m_presenter->zoomIn(rect);
240 240 }
241 241
242 242 /*!
243 243 Restores the view zoom level to the previous one.
244 244 */
245 245 void QChart::zoomOut()
246 246 {
247 247 m_presenter->zoomOut();
248 248 }
249 249
250 250 /*!
251 251 Returns the pointer to the x axis object of the chart
252 252 */
253 253 QChartAxis* QChart::axisX() const
254 254 {
255 255 return m_dataset->axisX();
256 256 }
257 257
258 258 /*!
259 259 Returns the pointer to the y axis object of the chart
260 260 */
261 261 QChartAxis* QChart::axisY() const
262 262 {
263 263 return m_dataset->axisY();
264 264 }
265 265
266 266 /*!
267 267 Returns the legend object of the chart. Ownership stays in chart.
268 268 */
269 QLegend* QChart::legend() const
269 QLegend& QChart::legend() const
270 270 {
271 return m_legend;
271 return *m_legend;
272 }
273
274 /*!
275 Gives ownership of legend to user.
276 */
277 QLegend* QChart::takeLegend()
278 {
279 QLegend* l = m_legend;
280 m_legend = 0;
281 return l;
282 }
283
284 /*!
285 Gives ownership of legend back to chart. QChart takes ownership of \a legend and deletes existing one
286 */
287 void QChart::giveLegend(QLegend* legend)
288 {
289 if (m_legend) {
290 // Should not happen.
291 qDebug() << "Warning! Giving more than one legend to chart."
292 delete m_legend;
293 }
294
295 m_legend = legend;
296
297 // Reconnect legend, in case not already connected.
298 disconnect(m_dataset,SIGNAL(seriesAdded(QSeries*,Domain*)),m_legend,SLOT(handleSeriesAdded(QSeries*,Domain*)));
299 disconnect(m_dataset,SIGNAL(seriesRemoved(QSeries*)),m_legend,SLOT(handleSeriesRemoved(QSeries*)));
300 connect(m_dataset,SIGNAL(seriesAdded(QSeries*,Domain*)),m_legend,SLOT(handleSeriesAdded(QSeries*,Domain*)));
301 connect(m_dataset,SIGNAL(seriesRemoved(QSeries*)),m_legend,SLOT(handleSeriesRemoved(QSeries*)));
272 302 }
273 303
274 304 /*!
275 305 Resizes and updates the chart area using the \a event data
276 306 */
277 307 void QChart::resizeEvent(QGraphicsSceneResizeEvent *event)
278 308 {
279 309
280 310 m_rect = QRectF(QPoint(0,0),event->newSize());
281 311 updateLayout();
282 312 QGraphicsWidget::resizeEvent(event);
283 313 update();
284 314 }
285 315
286 316 /*!
287 317 Sets animation \a options for the chart
288 318 */
289 319 void QChart::setAnimationOptions(AnimationOptions options)
290 320 {
291 321 m_presenter->setAnimationOptions(options);
292 322 }
293 323
294 324 /*!
295 325 Returns animation options for the chart
296 326 */
297 327 QChart::AnimationOptions QChart::animationOptions() const
298 328 {
299 329 return m_presenter->animationOptions();
300 330 }
301 331
302 332 void QChart::scrollLeft()
303 333 {
304 334 m_presenter->scroll(-m_presenter->geometry().width()/(axisX()->ticksCount()-1),0);
305 335 }
306 336
307 337 void QChart::scrollRight()
308 338 {
309 339 m_presenter->scroll(m_presenter->geometry().width()/(axisX()->ticksCount()-1),0);
310 340 }
311 341 void QChart::scrollUp()
312 342 {
313 343 m_presenter->scroll(0,m_presenter->geometry().width()/(axisY()->ticksCount()-1));
314 344 }
315 345 void QChart::scrollDown()
316 346 {
317 347 m_presenter->scroll(0,-m_presenter->geometry().width()/(axisY()->ticksCount()-1));
318 348 }
319 349
320 350 void QChart::updateLayout()
321 351 {
322 352 if(!m_rect.isValid()) return;
323 353
324 354 QRectF rect = m_rect.adjusted(m_padding,m_padding, -m_padding, -m_padding);
325 355
326 356 // recalculate title position
327 357 if (m_titleItem) {
328 358 QPointF center = m_rect.center() -m_titleItem->boundingRect().center();
329 359 m_titleItem->setPos(center.x(),m_rect.top()/2 + m_padding/2);
330 360 }
331 361
332 362 //recalculate background gradient
333 363 if (m_backgroundItem) {
334 364 m_backgroundItem->setRect(m_rect.adjusted(m_backgroundPadding,m_backgroundPadding, -m_backgroundPadding, -m_backgroundPadding));
335 365 }
336 366
337 367 // recalculate legend position
338 368 if (m_legend) {
339 369 if (m_legend->parentObject() == this) {
340 370 updateLegendLayout();
341 371 }
342 372 }
343 373 }
344 374
345 375 void QChart::updateLegendLayout()
346 376 {
347 377 QRectF plotRect = m_rect.adjusted(m_padding,m_padding, -m_padding, -m_padding);
348 378 QRectF legendRect;
349 379
350 380 switch (m_legend->preferredLayout())
351 381 {
352 382 case QLegend::PreferredLayoutTop:{
353 383 // legendRect = plotRect.adjusted(m_padding,0,-m_padding,-m_padding - plotRect.height());
354 384 legendRect = plotRect.adjusted(0,0,0,-m_padding - plotRect.height());
355 385 break;
356 386 }
357 387 case QLegend::PreferredLayoutBottom: {
358 388 legendRect = plotRect.adjusted(m_padding,m_padding + plotRect.height(),-m_padding,0);
359 389 break;
360 390 }
361 391 case QLegend::PreferredLayoutLeft: {
362 392 legendRect = plotRect.adjusted(0,m_padding,-m_padding - plotRect.width(),-m_padding);
363 393 break;
364 394 }
365 395 case QLegend::PreferredLayoutRight: {
366 396 legendRect = plotRect.adjusted(m_padding + plotRect.width(),m_padding,0,-m_padding);
367 397 break;
368 398 }
369 399 default: {
370 400 legendRect = plotRect;
371 401 break;
372 402 }
373 403 }
374 404
375 405 m_legend->setMaximumSize(legendRect.size());
376 406 m_legend->setPos(legendRect.topLeft());
377 407 }
378 408
379 409
380 410 int QChart::padding() const
381 411 {
382 412 return m_padding;
383 413 }
384 414
385 415 void QChart::setPadding(int padding)
386 416 {
387 417 if(m_padding==padding){
388 418 m_padding = padding;
389 419 m_presenter->handleGeometryChanged();
390 420 updateLayout();
391 421 }
392 422 }
393 423
394 424 void QChart::setBackgroundPadding(int padding)
395 425 {
396 426 if(m_backgroundPadding!=padding){
397 427 m_backgroundPadding = padding;
398 428 updateLayout();
399 429 }
400 430 }
401 431
402 432 void QChart::setBackgroundDiameter(int diameter)
403 433 {
404 434 createChartBackgroundItem();
405 435 m_backgroundItem->setDimeter(diameter);
406 436 m_backgroundItem->update();
407 437 }
408 438
409 439 void QChart::setBackgroundVisible(bool visible)
410 440 {
411 441 createChartBackgroundItem();
412 442 m_backgroundItem->setVisible(visible);
413 443 }
414 444
415 445 bool QChart::isBackgroundVisible() const
416 446 {
417 447 if(!m_backgroundItem) return false;
418 448 return m_backgroundItem->isVisible();
419 449 }
420 450
421 451
422 452 #include "moc_qchart.cpp"
423 453
424 454 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,122 +1,124
1 1 #ifndef QCHART_H
2 2 #define QCHART_H
3 3
4 4 #include <qchartglobal.h>
5 5 #include <qseries.h>
6 6 #include <QGraphicsWidget>
7 7 #include <QLinearGradient>
8 8 #include <QFont>
9 9
10 10 class QGraphicsSceneResizeEvent;
11 11
12 12 QTCOMMERCIALCHART_BEGIN_NAMESPACE
13 13
14 14 class Axis;
15 15 class QSeries;
16 16 class PlotDomain;
17 17 class BarChartItem;
18 18 class QChartAxis;
19 19 class ChartTheme;
20 20 class ChartItem;
21 21 class ChartDataSet;
22 22 class ChartPresenter;
23 23 class QLegend;
24 24 class ChartBackground;
25 25
26 26
27 27 class QTCOMMERCIALCHART_EXPORT QChart : public QGraphicsWidget
28 28 {
29 29 Q_OBJECT
30 30 public:
31 31 enum ChartTheme {
32 32 ChartThemeDefault,
33 33 ChartThemeLight,
34 34 ChartThemeBlueCerulean,
35 35 ChartThemeDark,
36 36 ChartThemeBrownSand,
37 37 ChartThemeBlueNcs,
38 38 ChartThemeIcy,
39 39 ChartThemeScientific,
40 40 ChartThemeCount
41 41 };
42 42
43 43 enum AnimationOption {
44 44 NoAnimation = 0x0,
45 45 GridAxisAnimations = 0x1,
46 46 SeriesAnimations =0x2,
47 47 AllAnimations = 0x3
48 48 };
49 49 Q_DECLARE_FLAGS(AnimationOptions, AnimationOption)
50 50
51 51 public:
52 52 QChart(QGraphicsItem *parent = 0, Qt::WindowFlags wFlags = 0);
53 53 ~QChart();
54 54
55 55 void addSeries(QSeries* series, QChartAxis* axisY = 0);
56 56 void removeSeries(QSeries* series); //returns ownership , deletes axis if no series attached
57 57 void removeAllSeries(); // deletes series and axis
58 58
59 59 void setChartTheme(QChart::ChartTheme theme);
60 60 QChart::ChartTheme chartTheme() const;
61 61
62 62 void setTitle(const QString& title);
63 63 QString title() const;
64 64 void setTitleFont(const QFont& font);
65 65 QFont titleFont() const;
66 66 void setTitleBrush(const QBrush &brush);
67 67 QBrush titleBrush() const;
68 68 void setBackgroundBrush(const QBrush& brush);
69 69 QBrush backgroundBrush() const;
70 70 void setBackgroundPen(const QPen& pen);
71 71 QPen backgroundPen() const;
72 72
73 73 void setBackgroundVisible(bool visible);
74 74 bool isBackgroundVisible() const;
75 75
76 76 void setAnimationOptions(AnimationOptions options);
77 77 AnimationOptions animationOptions() const;
78 78
79 79 void zoomIn();
80 80 void zoomIn(const QRectF& rect);
81 81 void zoomOut();
82 82 void scrollLeft();
83 83 void scrollRight();
84 84 void scrollUp();
85 85 void scrollDown();
86 86
87 87 QChartAxis* axisX() const;
88 88 QChartAxis* axisY() const;
89 89
90 QLegend* legend() const;
90 QLegend& legend() const;
91 QLegend* takeLegend();
92 void giveLegend(QLegend* legend);
91 93
92 94 int padding() const;
93 95
94 96 protected:
95 97 void resizeEvent(QGraphicsSceneResizeEvent *event);
96 98
97 99 private:
98 100 inline void createChartBackgroundItem();
99 101 inline void createChartTitleItem();
100 102 void setPadding(int padding);
101 103 void setBackgroundPadding(int padding);
102 104 void setBackgroundDiameter(int diameter);
103 105 void updateLayout();
104 106 void updateLegendLayout();
105 107
106 108 private:
107 109 Q_DISABLE_COPY(QChart)
108 110 ChartBackground* m_backgroundItem;
109 111 QGraphicsSimpleTextItem* m_titleItem;
110 112 QRectF m_rect;
111 113 QLegend* m_legend;
112 114 ChartDataSet *m_dataset;
113 115 ChartPresenter *m_presenter;
114 116 int m_padding;
115 117 int m_backgroundPadding;
116 118 };
117 119
118 120 QTCOMMERCIALCHART_END_NAMESPACE
119 121
120 122 Q_DECLARE_OPERATORS_FOR_FLAGS(QTCOMMERCIALCHART_NAMESPACE::QChart::AnimationOptions)
121 123
122 124 #endif
@@ -1,775 +1,789
1 1 #include "qchartglobal.h"
2 2 #include "qlegend.h"
3 3 #include "qseries.h"
4 4 #include "legendmarker_p.h"
5 5 #include "legendscrollbutton_p.h"
6 6 #include "qxyseries.h"
7 7 #include "qlineseries.h"
8 8 #include "qareaseries.h"
9 9 #include "qscatterseries.h"
10 10 #include "qsplineseries.h"
11 11 #include "qbarseries.h"
12 12 #include "qstackedbarseries.h"
13 13 #include "qpercentbarseries.h"
14 14 #include "qbarset.h"
15 15 #include "qpieseries.h"
16 16 #include "qpieslice.h"
17 17 #include "chartpresenter_p.h"
18 18 #include <QPainter>
19 19 #include <QPen>
20 20
21 21 #include <QGraphicsSceneEvent>
22 22
23 23 QTCOMMERCIALCHART_BEGIN_NAMESPACE
24 24
25 25 /*!
26 \class QLegend
27 \brief part of QtCommercial chart API.
28
29 QLegend is a graphical object, whics displays legend of the chart. Legend state is updated by QChart, when
30 series have been changed. By default, legend is drawn by QChart, but user can set a new parent to legend and
31 handle the drawing manually.
32 User isn't supposed to create or delete legend objects, but can reference it via QChart class.
33
34 \mainclass
35
36 \sa QChart, QSeries
37 */
38
39 /*!
26 40 \enum QLegend::PreferredLayout
27 41
28 42 This enum describes the possible position for legend inside chart.
29 43
30 44 \value PreferredLayoutTop
31 45 \value PreferredLayoutBottom
32 46 \value PreferredLayoutLeft
33 47 \value PreferredLayoutRight
34 48 */
35 49
36 50
37 51 /*!
38 \fn void clicked(QSeries* series, Qt::MouseButton button)
52 \fn void QLegend::clicked(QSeries* series, Qt::MouseButton button)
39 53 \brief Notifies when series has been clicked on legend \a series \a button
40 54 */
41 55
42 56 /*!
43 \fn void clicked(QBarSet* barset, Qt::MouseButton button);
57 \fn void QLegend::clicked(QBarSet* barset, Qt::MouseButton button)
44 58 \brief Notifies when barset has been clicked on legend \a barset \a button
45 59 */
46 60
47 61 /*!
48 \fn void clicked(QPieSlice* slice, Qt::MouseButton button);
62 \fn void QLegend::clicked(QPieSlice* slice, Qt::MouseButton button)
49 63 \brief Notifies when pie slice has been clicked on legend \a slice \a button
50 64 */
51 65
52 66 /*!
53 67 Constructs the legend object and sets the parent to \a parent
54 68 */
55 69 QLegend::QLegend(QGraphicsItem *parent)
56 70 : QGraphicsObject(parent)
57 71 ,mPos(0,0)
58 72 ,mSize(0,0)
59 73 ,mMinimumSize(50,20) // TODO: magic numbers
60 74 ,mMaximumSize(150,100)
61 75 ,m_brush(Qt::darkGray) // TODO: from theme?
62 76 ,mPreferredLayout(QLegend::PreferredLayoutTop)
63 77 ,mFirstMarker(0)
64 78 ,mMargin(5)
65 79 {
66 80 // setVisible(false);
67 81
68 82 mScrollButtonLeft = new LegendScrollButton(LegendScrollButton::ScrollButtonIdLeft, this);
69 83 mScrollButtonRight = new LegendScrollButton(LegendScrollButton::ScrollButtonIdRight, this);
70 84 mScrollButtonUp = new LegendScrollButton(LegendScrollButton::ScrollButtonIdUp, this);
71 85 mScrollButtonDown = new LegendScrollButton(LegendScrollButton::ScrollButtonIdDown, this);
72 86
73 87 connect(mScrollButtonLeft,SIGNAL(clicked(QGraphicsSceneMouseEvent*)),this,SLOT(handleScrollButtonClicked(QGraphicsSceneMouseEvent*)));
74 88 connect(mScrollButtonRight,SIGNAL(clicked(QGraphicsSceneMouseEvent*)),this,SLOT(handleScrollButtonClicked(QGraphicsSceneMouseEvent*)));
75 89 connect(mScrollButtonUp,SIGNAL(clicked(QGraphicsSceneMouseEvent*)),this,SLOT(handleScrollButtonClicked(QGraphicsSceneMouseEvent*)));
76 90 connect(mScrollButtonDown,SIGNAL(clicked(QGraphicsSceneMouseEvent*)),this,SLOT(handleScrollButtonClicked(QGraphicsSceneMouseEvent*)));
77 91
78 92 setZValue(ChartPresenter::LegendZValue);
79 93 }
80 94
81 95 /*!
82 96 Paints the legend to given \a painter. Paremeters \a option and \a widget arent used.
83 97 */
84 98 void QLegend::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
85 99 {
86 100 Q_UNUSED(option)
87 101 Q_UNUSED(widget)
88 102
89 103 painter->setOpacity(opacity());
90 104 painter->setPen(m_pen);
91 105 painter->setBrush(m_brush);
92 106 painter->drawRect(boundingRect());
93 107 }
94 108
95 109 /*!
96 110 Bounding rect of legend.
97 111 */
98 112 QRectF QLegend::boundingRect() const
99 113 {
100 114 return QRectF(mPos,mSize);
101 115 }
102 116
103 117 /*!
104 118 Sets the \a brush of legend. Brush affects the background of legend.
105 119 */
106 120 void QLegend::setBrush(const QBrush& brush)
107 121 {
108 122 if(m_brush!=brush){
109 123 m_brush = brush;
110 124 update();
111 125 }
112 126 }
113 127
114 128 /*!
115 129 Returns the brush used by legend.
116 130 */
117 131 QBrush QLegend::brush() const
118 132 {
119 133 return m_brush;
120 134 }
121 135
122 136 /*!
123 137 Sets the \a pen of legend. Pen affects the legend borders.
124 138 */
125 139 void QLegend::setPen(const QPen& pen)
126 140 {
127 141 if(m_pen!=pen){
128 142 m_pen = pen;
129 143 update();
130 144 }
131 145 }
132 146
133 147 /*!
134 148 Returns the pen used by legend
135 149 */
136 150
137 151 QPen QLegend::pen() const
138 152 {
139 153 return m_pen;
140 154 }
141 155
142 156 /*!
143 157 Sets the \a preferred layout for legend. Legend tries to paint itself on the defined position in chart.
144 sa \QLegend::PreferredLayout
158 \sa QLegend::PreferredLayout
145 159 */
146 160 void QLegend::setPreferredLayout(QLegend::PreferredLayout preferred)
147 161 {
148 162 mPreferredLayout = preferred;
149 163 updateLayout();
150 164 }
151 165
152 166 /*!
153 167 Returns the preferred layout for legend
154 168 */
155 169 QLegend::PreferredLayout QLegend::preferredLayout() const
156 170 {
157 171 return mPreferredLayout;
158 172 }
159 173
160 174 /*!
161 175 Returns the maximum size of legend.
162 176 */
163 177 QSizeF QLegend::maximumSize() const
164 178 {
165 179 return mMaximumSize;
166 180 }
167 181
168 182 /*!
169 183 Sets the maximum \a size for legend. The legend can't grow bigger than this size. If there are
170 184 more series than legend can fit to this size, scroll buttons are displayed.
171 185 */
172 186 void QLegend::setMaximumSize(const QSizeF size)
173 187 {
174 188 mMaximumSize = size;
175 189 updateLayout();
176 190 }
177 191
178 192 /*!
179 193 Returns the current size of legend.
180 194 */
181 195 QSizeF QLegend::size() const
182 196 {
183 197 return mSize;
184 198 }
185 199
186 200 /*!
187 201 Sets the \a size of legend. If size is bigger than maximum size of legend, the legend is resized to the maximum size.
188 202 \sa setMmaximumSize()
189 203 */
190 204 void QLegend::setSize(const QSizeF size)
191 205 {
192 206 mSize = size;
193 207 if (mSize.width() > mMaximumSize.width()) {
194 208 mSize.setWidth(mMaximumSize.width());
195 209 }
196 210 if (mSize.height() > mMaximumSize.height()) {
197 211 mSize.setHeight(mMaximumSize.height());
198 212 }
199 213 }
200 214
201 215 /*!
202 216 Sets position of legend to \a pos
203 217 */
204 218 void QLegend::setPos(const QPointF &pos)
205 219 {
206 220 mPos = pos;
207 221 updateLayout();
208 222 }
209 223
210 224 /*!
211 225 \internal \a series \a domain Should be called when series is added to chart.
212 226 */
213 227 void QLegend::handleSeriesAdded(QSeries* series, Domain* domain)
214 228 {
215 229 Q_UNUSED(domain)
216 230
217 231 createMarkers(series);
218 232 connectSeries(series);
219 233 updateLayout();
220 234 }
221 235
222 236 /*!
223 237 \internal \a series Should be called when series is removed from chart.
224 238 */
225 239 void QLegend::handleSeriesRemoved(QSeries* series)
226 240 {
227 241 disconnectSeries(series);
228 242
229 243 if (series->type() == QSeries::SeriesTypeArea)
230 244 {
231 245 // This is special case. Area series has upper and lower series, which each have markers
232 246 QAreaSeries* s = static_cast<QAreaSeries*> (series);
233 247 deleteMarkers(s->upperSeries());
234 248 deleteMarkers(s->lowerSeries());
235 249 } else {
236 250 deleteMarkers(series);
237 251 }
238 252
239 253 updateLayout();
240 254 }
241 255
242 256 /*!
243 257 \internal \a slices Should be called when slices are added to pie chart.
244 258 */
245 259 void QLegend::handleAdded(QList<QPieSlice*> slices)
246 260 {
247 261 QPieSeries* series = static_cast<QPieSeries*> (sender());
248 262 foreach(QPieSlice* s, slices) {
249 263 LegendMarker* marker = new LegendMarker(series,s,this);
250 264 marker->setName(s->label());
251 265 marker->setBrush(s->sliceBrush());
252 266 connect(marker,SIGNAL(clicked(QPieSlice*,Qt::MouseButton)),this,SIGNAL(clicked(QPieSlice*,Qt::MouseButton)));
253 267 connect(s,SIGNAL(changed()),marker,SLOT(changed()));
254 268 connect(s,SIGNAL(destroyed()),marker,SLOT(deleteLater()));
255 269 connect(marker,SIGNAL(destroyed()),this,SLOT(handleMarkerDestroyed()));
256 270 mMarkers.append(marker);
257 271 childItems().append(marker);
258 272 }
259 273 updateLayout();
260 274 }
261 275
262 276 /*!
263 277 \internal \a slices Should be called when slices are removed from pie chart. Currently unused,
264 278 because removed slices are also deleted and we listen destroyed signal
265 279 */
266 280 void QLegend::handleRemoved(QList<QPieSlice *> slices)
267 281 {
268 282 Q_UNUSED(slices)
269 283 // Propably no need to listen for this, since removed slices are deleted and we listen destroyed signal
270 284 // qDebug() << "QLegend::handleRemoved(QList<QPieSlice*> slices) count:" << slices.count();
271 285 }
272 286
273 287
274 288 /*!
275 289 \internal Notifies legend that some marker has been removed. Sent by legend markers when destroyed
276 290 */
277 291 void QLegend::handleMarkerDestroyed()
278 292 {
279 293 // TODO: what if more than one markers are destroyed and we update layout after first one?
280 294 LegendMarker* m = static_cast<LegendMarker*> (sender());
281 295 mMarkers.removeOne(m);
282 296 updateLayout();
283 297 }
284 298
285 299 /*!
286 300 \internal \a event Handles clicked signals from scroll buttons
287 301 */
288 302 void QLegend::handleScrollButtonClicked(QGraphicsSceneMouseEvent *event)
289 303 {
290 304 Q_UNUSED(event); // Maybe later something happens with right click...
291 305
292 306 LegendScrollButton* scrollButton = static_cast<LegendScrollButton*> (sender());
293 307 Q_ASSERT(scrollButton);
294 308
295 309 switch (scrollButton->id()) {
296 310 case LegendScrollButton::ScrollButtonIdLeft:
297 311 case LegendScrollButton::ScrollButtonIdUp: {
298 312 // Lower limit is same in these cases
299 313 mFirstMarker--;
300 314 checkFirstMarkerBounds();
301 315 break;
302 316 }
303 317 case LegendScrollButton::ScrollButtonIdRight:
304 318 case LegendScrollButton::ScrollButtonIdDown: {
305 319 mFirstMarker++;
306 320 checkFirstMarkerBounds();
307 321 break;
308 322 }
309 323 default: {
310 324 break;
311 325 }
312 326 }
313 327 updateLayout();
314 328 }
315 329
316 330 /*!
317 331 \internal Connects the \a series to legend. Legend listens changes in series, for example pie slices added / removed.
318 332 Not all series notify about events
319 333 */
320 334 void QLegend::connectSeries(QSeries *series)
321 335 {
322 336 // Connect relevant signals from series
323 337 switch (series->type())
324 338 {
325 339 case QSeries::SeriesTypeLine: {
326 340 // QLineSeries* lineSeries = static_cast<QLineSeries*>(series);
327 341 break;
328 342 }
329 343 case QSeries::SeriesTypeArea: {
330 344 // QAreaSeries* areaSeries = static_cast<QAreaSeries*>(series);
331 345 break;
332 346 }
333 347 case QSeries::SeriesTypeBar: {
334 348 // QBarSeries* barSeries = static_cast<QBarSeries*>(series);
335 349 break;
336 350 }
337 351 case QSeries::SeriesTypeStackedBar: {
338 352 // QStackedBarSeries* stackedBarSeries = static_cast<QStackedBarSeries*>(series);
339 353 break;
340 354 }
341 355 case QSeries::SeriesTypePercentBar: {
342 356 // QPercentBarSeries* percentBarSeries = static_cast<QPercentBarSeries*>(series);
343 357 break;
344 358 }
345 359 case QSeries::SeriesTypeScatter: {
346 360 // QScatterSeries *scatterSeries = static_cast<QScatterSeries *>(series);
347 361 break;
348 362 }
349 363 case QSeries::SeriesTypePie: {
350 364 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
351 365 connect(pieSeries,SIGNAL(added(QList<QPieSlice*>)),this,SLOT(handleAdded(QList<QPieSlice*>)));
352 366 // connect(pieSeries,SIGNAL(removed(QList<QPieSlice*>)),this,SLOT(handleRemoved(QList<QPieSlice*>)));
353 367 break;
354 368 }
355 369 case QSeries::SeriesTypeSpline: {
356 370 // QSplineSeries* splineSeries = static_cast<QSplineSeries*>(series);
357 371 break;
358 372 }
359 373 default: {
360 374 qDebug()<< "QLegend::connectSeries" << series->type() << "not implemented.";
361 375 break;
362 376 }
363 377 }
364 378 }
365 379
366 380 /*!
367 381 \internal Disconnects \a series from legend. No more status updates from series to legend.
368 382 */
369 383 void QLegend::disconnectSeries(QSeries *series)
370 384 {
371 385 // Connect relevant signals from series
372 386 switch (series->type())
373 387 {
374 388 case QSeries::SeriesTypeLine: {
375 389 // QLineSeries* lineSeries = static_cast<QLineSeries*>(series);
376 390 break;
377 391 }
378 392 case QSeries::SeriesTypeArea: {
379 393 // QAreaSeries* areaSeries = static_cast<QAreaSeries*>(series);
380 394 break;
381 395 }
382 396 case QSeries::SeriesTypeBar: {
383 397 // QBarSeries* barSeries = static_cast<QBarSeries*>(series);
384 398 break;
385 399 }
386 400 case QSeries::SeriesTypeStackedBar: {
387 401 // QStackedBarSeries* stackedBarSeries = static_cast<QStackedBarSeries*>(series);
388 402 break;
389 403 }
390 404 case QSeries::SeriesTypePercentBar: {
391 405 // QPercentBarSeries* percentBarSeries = static_cast<QPercentBarSeries*>(series);
392 406 break;
393 407 }
394 408 case QSeries::SeriesTypeScatter: {
395 409 // QScatterSeries *scatterSeries = static_cast<QScatterSeries *>(series);
396 410 break;
397 411 }
398 412 case QSeries::SeriesTypePie: {
399 413 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
400 414 disconnect(pieSeries,SIGNAL(added(QList<QPieSlice*>)),this,SLOT(handleAdded(QList<QPieSlice*>)));
401 415 // disconnect(pieSeries,SIGNAL(removed(QList<QPieSlice*>)),this,SLOT(handleRemoved(QList<QPieSlice*>)));
402 416 break;
403 417 }
404 418 case QSeries::SeriesTypeSpline: {
405 419 // QSplineSeries* splineSeries = static_cast<QSplineSeries*>(series);
406 420 break;
407 421 }
408 422 default: {
409 423 qDebug()<< "QLegend::disconnectSeries" << series->type() << "not implemented.";
410 424 break;
411 425 }
412 426 }
413 427 }
414 428
415 429 /*!
416 430 \internal Creates new markers for \a series. Marker contains the colored rectangle and series name.
417 431 With pie chart, created markers depend on pie slices.
418 432 With bar chart, created markers depend on bar sets.
419 433 */
420 434 void QLegend::createMarkers(QSeries *series)
421 435 {
422 436 switch (series->type())
423 437 {
424 438 case QSeries::SeriesTypeLine: {
425 439 QLineSeries* lineSeries = static_cast<QLineSeries*>(series);
426 440 appendMarkers(lineSeries);
427 441 break;
428 442 }
429 443 case QSeries::SeriesTypeArea: {
430 444 QAreaSeries* areaSeries = static_cast<QAreaSeries*>(series);
431 445 appendMarkers(areaSeries->upperSeries());
432 446 if(areaSeries->lowerSeries())
433 447 appendMarkers(areaSeries->lowerSeries());
434 448 break;
435 449 }
436 450
437 451 case QSeries::SeriesTypeBar: {
438 452 QBarSeries* barSeries = static_cast<QBarSeries*>(series);
439 453 appendMarkers(barSeries);
440 454 break;
441 455 }
442 456
443 457 case QSeries::SeriesTypeStackedBar: {
444 458 QStackedBarSeries* stackedBarSeries = static_cast<QStackedBarSeries*>(series);
445 459 appendMarkers(stackedBarSeries);
446 460 break;
447 461 }
448 462
449 463 case QSeries::SeriesTypePercentBar: {
450 464 QPercentBarSeries* percentBarSeries = static_cast<QPercentBarSeries*>(series);
451 465 appendMarkers(percentBarSeries);
452 466 break;
453 467 }
454 468
455 469 case QSeries::SeriesTypeScatter: {
456 470 QScatterSeries *scatterSeries = static_cast<QScatterSeries *>(series);
457 471 appendMarkers(scatterSeries);
458 472 break;
459 473 }
460 474
461 475 case QSeries::SeriesTypePie: {
462 476 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
463 477 appendMarkers(pieSeries);
464 478 break;
465 479 }
466 480
467 481 case QSeries::SeriesTypeSpline: {
468 482 QSplineSeries* splineSeries = static_cast<QSplineSeries*>(series);
469 483 appendMarkers(splineSeries);
470 484 break;
471 485 }
472 486 default: {
473 487 qDebug()<< "QLegend::createMarkers" << series->type() << "not implemented.";
474 488 break;
475 489 }
476 490 }
477 491 }
478 492
479 493 /*!
480 494 \internal Helper function. Appends markers from \a series to legend.
481 495 */
482 496 void QLegend::appendMarkers(QXYSeries* series)
483 497 {
484 498 LegendMarker* marker = new LegendMarker(series,this);
485 499 marker->setName(series->name());
486 500 marker->setPen(series->pen());
487 501 marker->setBrush(series->brush());
488 502 connect(marker,SIGNAL(clicked(QSeries*,Qt::MouseButton)),this,SIGNAL(clicked(QSeries*,Qt::MouseButton)));
489 503 connect(marker,SIGNAL(destroyed()),this,SLOT(handleMarkerDestroyed()));
490 504 mMarkers.append(marker);
491 505 childItems().append(marker);
492 506 }
493 507
494 508 /*!
495 509 \internal Helper function. Appends markers from \a series to legend.
496 510 */
497 511 void QLegend::appendMarkers(QBarSeries *series)
498 512 {
499 513 foreach(QBarSet* s, series->barSets()) {
500 514 LegendMarker* marker = new LegendMarker(series,s,this);
501 515 marker->setName(s->name());
502 516 marker->setPen(s->pen());
503 517 marker->setBrush(s->brush());
504 518 connect(marker,SIGNAL(clicked(QBarSet*,Qt::MouseButton)),this,SIGNAL(clicked(QBarSet*,Qt::MouseButton)));
505 519 connect(s,SIGNAL(valueChanged()),marker,SLOT(changed()));
506 520 connect(marker,SIGNAL(destroyed()),this,SLOT(handleMarkerDestroyed()));
507 521 mMarkers.append(marker);
508 522 childItems().append(marker);
509 523 }
510 524 }
511 525
512 526 /*!
513 527 \internal Helper function. Appends markers from \a series to legend.
514 528 */
515 529 void QLegend::appendMarkers(QPieSeries *series)
516 530 {
517 531 foreach(QPieSlice* s, series->slices()) {
518 532 LegendMarker* marker = new LegendMarker(series,s,this);
519 533 marker->setName(s->label());
520 534 marker->setPen(s->slicePen());
521 535 marker->setBrush(s->sliceBrush());
522 536 connect(marker,SIGNAL(clicked(QPieSlice*,Qt::MouseButton)),this,SIGNAL(clicked(QPieSlice*,Qt::MouseButton)));
523 537 connect(s,SIGNAL(changed()),marker,SLOT(changed()));
524 538 connect(s,SIGNAL(destroyed()),marker,SLOT(deleteLater()));
525 539 connect(marker,SIGNAL(destroyed()),this,SLOT(handleMarkerDestroyed()));
526 540 mMarkers.append(marker);
527 541 childItems().append(marker);
528 542 }
529 543 }
530 544
531 545 /*!
532 546 \internal Deletes all markers that are created from \a series
533 547 */
534 548 void QLegend::deleteMarkers(QSeries *series)
535 549 {
536 550 // Search all markers that belong to given series and delete them.
537 551 foreach (LegendMarker *m, mMarkers) {
538 552 if (m->series() == series) {
539 553 mMarkers.removeOne(m);
540 554 delete m;
541 555 }
542 556 }
543 557 }
544 558
545 559 /*!
546 560 \internal Updates layout of legend. Tries to fit as many markers as possible up to the maximum size of legend.
547 561 If items don't fit, sets the visibility of scroll buttons accordingly.
548 562 Causes legend to be resized.
549 563 */
550 564 void QLegend::updateLayout()
551 565 {
552 566 // Calculate layout for markers and text
553 567 if (mMarkers.count() <= 0) {
554 568 // Nothing to do
555 569 return;
556 570 }
557 571
558 572 // Find out widest item.
559 573 QSizeF markerMaxSize = maximumMarkerSize();
560 574 checkFirstMarkerBounds();
561 575
562 576 // Use max height as scroll button size
563 577 rescaleScrollButtons(QSize(markerMaxSize.height() ,markerMaxSize.height()));
564 578
565 579
566 580 qreal totalWidth = 0;
567 581 qreal totalHeight = 0;
568 582 switch (mPreferredLayout)
569 583 {
570 584 // Both cases organise items horizontally
571 585 case QLegend::PreferredLayoutBottom:
572 586 case QLegend::PreferredLayoutTop: {
573 587
574 588 qreal xStep = markerMaxSize.width();
575 589 qreal x = mPos.x() + mMargin;
576 590 qreal y = mPos.y() + mMargin;
577 591 int column = 0;
578 592 int maxColumns = 1;
579 593 qreal scrollButtonWidth = 0;
580 594
581 595 // Set correct visibility for scroll scrollbuttons
582 596 if (scrollButtonsVisible()) {
583 597 mScrollButtonLeft->setVisible(true);
584 598 mScrollButtonRight->setVisible(true);
585 599 totalWidth += (mScrollButtonLeft->boundingRect().width() + mMargin) * 2; // scrollbuttons visible, so add their width to total width
586 600 scrollButtonWidth = mScrollButtonLeft->boundingRect().width() + mMargin;
587 601 x += scrollButtonWidth; // start position changes by scrollbutton width
588 602 } else {
589 603 mScrollButtonLeft->setVisible(false);
590 604 mScrollButtonRight->setVisible(false);
591 605 }
592 606 mScrollButtonUp->setVisible(false);
593 607 mScrollButtonDown->setVisible(false);
594 608
595 609 for (int i=0; i<mMarkers.count(); i++) {
596 610 LegendMarker* m = mMarkers.at(i);
597 611 if (i<mFirstMarker) {
598 612 // Markers before first are not visible.
599 613 m->setVisible(false);
600 614 } else {
601 615 if ((x + xStep + scrollButtonWidth + mMargin) > (mPos.x() + mMaximumSize.width())) {
602 616 // This marker would go outside legend rect.
603 617 m->setVisible(false);
604 618 } else {
605 619 // This marker is ok
606 620 m->setVisible(true);
607 621 m->setPos(x,y);
608 622 x += xStep;
609 623 column++;
610 624 }
611 625 }
612 626 maxColumns = column;
613 627 }
614 628
615 629 mScrollButtonLeft->setPos(mPos.x() + mMargin, y);
616 630 mScrollButtonRight->setPos(x+mMargin,y);
617 631
618 632 totalWidth += maxColumns * markerMaxSize.width() + mMargin * 2;
619 633 totalHeight = markerMaxSize.height() + mMargin * 2;
620 634
621 635 break;
622 636 }
623 637 // Both cases organize items vertically
624 638 case QLegend::PreferredLayoutLeft:
625 639 case QLegend::PreferredLayoutRight: {
626 640 qreal yStep = markerMaxSize.height();
627 641 qreal x = mPos.x() + mMargin;
628 642 qreal y = mPos.y() + mMargin;
629 643 int row = 1;
630 644 int maxRows = 1;
631 645 qreal scrollButtonHeight = 0;
632 646
633 647 // Set correct visibility for scroll scrollbuttons
634 648 if (scrollButtonsVisible()) {
635 649 mScrollButtonUp->setVisible(true);
636 650 mScrollButtonDown->setVisible(true);
637 651 totalHeight += (mScrollButtonUp->boundingRect().height() + mMargin) * 2; // scrollbuttons visible, so add their height to total height
638 652 scrollButtonHeight = mScrollButtonUp->boundingRect().height();
639 653 y += scrollButtonHeight + mMargin; // start position changes by scrollbutton height
640 654 } else {
641 655 mScrollButtonUp->setVisible(false);
642 656 mScrollButtonDown->setVisible(false);
643 657 }
644 658 mScrollButtonLeft->setVisible(false);
645 659 mScrollButtonRight->setVisible(false);
646 660
647 661 for (int i=0; i<mMarkers.count(); i++) {
648 662 LegendMarker* m = mMarkers.at(i);
649 663 if (i<mFirstMarker) {
650 664 // Markers before first are not visible.
651 665 m->setVisible(false);
652 666 } else {
653 667 if ((y + yStep + scrollButtonHeight) > (mPos.y() + mMaximumSize.height())) {
654 668 // This marker would go outside legend rect.
655 669 m->setVisible(false);
656 670 } else {
657 671 // This marker is ok
658 672 m->setVisible(true);
659 673 m->setPos(x,y);
660 674 y += yStep;
661 675 row++;
662 676 }
663 677 }
664 678 maxRows = row;
665 679 }
666 680
667 681 mScrollButtonUp->setPos(mPos.x() + mMargin, mPos.y() + mMargin);
668 682 mScrollButtonDown->setPos(mPos.x() + mMargin, y + mMargin);
669 683
670 684 totalWidth += markerMaxSize.width() + mMargin * 2;
671 685 totalHeight = maxRows * markerMaxSize.height() + mMargin * 4 + scrollButtonHeight; // TODO: check this
672 686 break;
673 687 }
674 688 default: {
675 689 break;
676 690 }
677 691 }
678 692
679 693 mSize.setWidth(totalWidth);
680 694 mSize.setHeight(totalHeight);
681 695
682 696 update();
683 697 }
684 698
685 699 /*!
686 700 \internal Sets the size of scroll buttons to \a size
687 701 */
688 702 void QLegend::rescaleScrollButtons(const QSize &size)
689 703 {
690 704 QPolygonF left;
691 705 left << QPointF(size.width(),0) << QPointF(0,size.height()/2) << QPointF(size.width(),size.height());
692 706 QPolygonF right;
693 707 right << QPointF(0,0) << QPointF(size.width(),size.height()/2) << QPointF(0,size.height());
694 708 QPolygonF up;
695 709 up << QPointF(0,size.height()) << QPointF(size.width()/2,0) << QPointF(size.width(),size.height());
696 710 QPolygonF down;
697 711 down << QPointF(0,0) << QPointF(size.width()/2,size.height()) << QPointF(size.width(),0);
698 712
699 713 mScrollButtonLeft->setPolygon(left);
700 714 mScrollButtonRight->setPolygon(right);
701 715 mScrollButtonUp->setPolygon(up);
702 716 mScrollButtonDown->setPolygon(down);
703 717 }
704 718
705 719 /*!
706 720 \internal Finds out maximum size of single marker. Marker sizes depend on series names.
707 721 */
708 722 QSizeF QLegend::maximumMarkerSize()
709 723 {
710 724 QSizeF max(0,0);
711 725 foreach (LegendMarker* m, mMarkers) {
712 726 if (m->boundingRect().width() > max.width()) {
713 727 max.setWidth(m->boundingRect().width());
714 728 }
715 729 if (m->boundingRect().height() > max.height()) {
716 730 max.setHeight(m->boundingRect().height());
717 731 }
718 732 }
719 733 return max;
720 734 }
721 735
722 736 /*!
723 737 \internal Checks that first marker is in acceptable bounds. Bounds range from 0 to (maximum number of markers - visible markers)
724 738 If scrollbuttons are visible, they affect the number of visible markers.
725 739 */
726 740 void QLegend::checkFirstMarkerBounds()
727 741 {
728 742 if ((mPreferredLayout == QLegend::PreferredLayoutLeft) || (mPreferredLayout == QLegend::PreferredLayoutRight)) {
729 743 // Bounds limited by height.
730 744 int max;
731 745 if (scrollButtonsVisible()) {
732 746 max = (mMaximumSize.height() - mScrollButtonLeft->boundingRect().height() * 2 - mMargin*4) / maximumMarkerSize().height();
733 747 } else {
734 748 max = mMaximumSize.height() / maximumMarkerSize().height();
735 749 }
736 750
737 751 if (mFirstMarker > mMarkers.count() - max) {
738 752 mFirstMarker = mMarkers.count() - max;
739 753 }
740 754 } else {
741 755 // Bounds limited by width
742 756 int max;
743 757 if (scrollButtonsVisible()) {
744 758 max = (mMaximumSize.width() - mScrollButtonLeft->boundingRect().width() * 2 - mMargin*4) / maximumMarkerSize().width();
745 759 } else {
746 760 max = mMaximumSize.width() / maximumMarkerSize().width();
747 761 }
748 762
749 763 if (mFirstMarker > mMarkers.count() - max) {
750 764 mFirstMarker = mMarkers.count() - max;
751 765 }
752 766 }
753 767
754 768 if (mFirstMarker < 0) {
755 769 mFirstMarker = 0;
756 770 }
757 771 }
758 772
759 773 /*!
760 774 \internal Helper function. Visibility of scroll buttons isn't quite obvious, so helper function clarifies the logic.
761 775 */
762 776 bool QLegend::scrollButtonsVisible()
763 777 {
764 778 // Just a helper to clarify, what the magic below means :)
765 779 if ((mPreferredLayout == QLegend::PreferredLayoutTop) || (mPreferredLayout == QLegend::PreferredLayoutBottom)) {
766 780 return (maximumMarkerSize().width() * mMarkers.count() + mMargin * 2 > mMaximumSize.width());
767 781 } else if ((mPreferredLayout == QLegend::PreferredLayoutLeft) || (mPreferredLayout == QLegend::PreferredLayoutRight)) {
768 782 return (maximumMarkerSize().height() * mMarkers.count() + mMargin * 2 > mMaximumSize.height());
769 783 }
770 784
771 785 return (maximumMarkerSize().height() * mMarkers.count() + mMargin * 2 > mMaximumSize.height());
772 786 }
773 787
774 788 #include "moc_qlegend.cpp"
775 789 QTCOMMERCIALCHART_END_NAMESPACE
General Comments 0
You need to be logged in to leave comments. Login now