##// END OF EJS Templates
Scrolling logic to legend
sauimone -
r716:e7d88adcf7ee
parent child
Show More
@@ -0,0 +1,26
1 #include "legendscrollbutton_p.h"
2 #include <QGraphicsSceneEvent>
3
4 QTCOMMERCIALCHART_BEGIN_NAMESPACE
5
6 LegendScrollButton::LegendScrollButton(ScrollButtonId id, QGraphicsItem *parent)
7 : QGraphicsPolygonItem(parent)
8 ,mId(id)
9 {
10 setAcceptedMouseButtons(Qt::LeftButton);
11 }
12
13 LegendScrollButton::ScrollButtonId LegendScrollButton::id()
14 {
15 return mId;
16 }
17
18 void LegendScrollButton::mousePressEvent(QGraphicsSceneMouseEvent *event)
19 {
20 emit clicked(event);
21 }
22
23 #include "moc_legendscrollbutton_p.cpp"
24
25 QTCOMMERCIALCHART_END_NAMESPACE
26
@@ -0,0 +1,38
1 #ifndef LEGENDSCROLLBUTTON_P_H
2 #define LEGENDSCROLLBUTTON_P_H
3
4 #include <QObject>
5 #include <qchartglobal.h>
6 #include <QGraphicsPolygonItem>
7
8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9
10 class LegendScrollButton : public QObject, public QGraphicsPolygonItem
11 {
12 Q_OBJECT
13 public:
14 enum ScrollButtonId {
15 ScrollButtonIdLeft,
16 ScrollButtonIdRight,
17 ScrollButtonIdUp,
18 ScrollButtonIdDown
19 };
20
21 explicit LegendScrollButton(ScrollButtonId id, QGraphicsItem *parent = 0);
22 ScrollButtonId id();
23
24 virtual void mousePressEvent(QGraphicsSceneMouseEvent *event);
25
26 signals:
27 void clicked(QGraphicsSceneMouseEvent* event);
28
29 public slots:
30
31 private:
32
33 ScrollButtonId mId;
34 };
35
36 QTCOMMERCIALCHART_END_NAMESPACE
37
38 #endif // LEGENDSCROLLBUTTON_P_H
@@ -1,391 +1,423
1 #include "qchart.h"
1 #include "qchart.h"
2 #include "qchartaxis.h"
2 #include "qchartaxis.h"
3 #include "qlegend.h"
3 #include "qlegend.h"
4 #include "chartpresenter_p.h"
4 #include "chartpresenter_p.h"
5 #include "chartdataset_p.h"
5 #include "chartdataset_p.h"
6 #include "chartbackground_p.h"
6 #include "chartbackground_p.h"
7 #include <QGraphicsScene>
7 #include <QGraphicsScene>
8 #include <QGraphicsSceneResizeEvent>
8 #include <QGraphicsSceneResizeEvent>
9
9
10 QTCOMMERCIALCHART_BEGIN_NAMESPACE
10 QTCOMMERCIALCHART_BEGIN_NAMESPACE
11
11
12 /*!
12 /*!
13 \enum QChart::ChartTheme
13 \enum QChart::ChartTheme
14
14
15 This enum describes the theme used by the chart.
15 This enum describes the theme used by the chart.
16
16
17 \value ChartThemeDefault Follows the GUI style of the Operating System
17 \value ChartThemeDefault Follows the GUI style of the Operating System
18 \value ChartThemeLight
18 \value ChartThemeLight
19 \value ChartThemeBlueCerulean
19 \value ChartThemeBlueCerulean
20 \value ChartThemeDark
20 \value ChartThemeDark
21 \value ChartThemeBrownSand
21 \value ChartThemeBrownSand
22 \value ChartThemeBlueNcs
22 \value ChartThemeBlueNcs
23 \value ChartThemeIcy
23 \value ChartThemeIcy
24 \value ChartThemeScientific
24 \value ChartThemeScientific
25 \value ChartThemeCount Not really a theme; the total count of themes.
25 \value ChartThemeCount Not really a theme; the total count of themes.
26 */
26 */
27
27
28 /*!
28 /*!
29 \enum QChart::AnimationOption
29 \enum QChart::AnimationOption
30
30
31 For enabling/disabling animations. Defaults to NoAnimation.
31 For enabling/disabling animations. Defaults to NoAnimation.
32
32
33 \value NoAnimation
33 \value NoAnimation
34 \value GridAxisAnimations
34 \value GridAxisAnimations
35 \value SeriesAnimations
35 \value SeriesAnimations
36 \value AllAnimations
36 \value AllAnimations
37 */
37 */
38
38
39 /*!
39 /*!
40 \class QChart
40 \class QChart
41 \brief QtCommercial chart API.
41 \brief QtCommercial chart API.
42
42
43 QChart is a QGraphicsWidget that you can show in a QGraphicsScene. It manages the graphical
43 QChart is a QGraphicsWidget that you can show in a QGraphicsScene. It manages the graphical
44 representation of different types of QChartSeries and other chart related objects like
44 representation of different types of QChartSeries and other chart related objects like
45 QChartAxis and QChartLegend. If you simply want to show a chart in a layout, you can use the
45 QChartAxis and QChartLegend. If you simply want to show a chart in a layout, you can use the
46 convenience class QChartView instead of QChart.
46 convenience class QChartView instead of QChart.
47 \sa QChartView
47 \sa QChartView
48 */
48 */
49
49
50 /*!
50 /*!
51 Constructs a chart object which is a child of a\a parent. Parameter \a wFlags is passed to the QGraphicsWidget constructor.
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 QChart::QChart(QGraphicsItem *parent, Qt::WindowFlags wFlags) : QGraphicsWidget(parent,wFlags),
53 QChart::QChart(QGraphicsItem *parent, Qt::WindowFlags wFlags) : QGraphicsWidget(parent,wFlags),
54 m_backgroundItem(0),
54 m_backgroundItem(0),
55 m_titleItem(0),
55 m_titleItem(0),
56 m_legend(new QLegend(this)),
56 m_legend(new QLegend(this)),
57 m_dataset(new ChartDataSet(this)),
57 m_dataset(new ChartDataSet(this)),
58 m_presenter(new ChartPresenter(this,m_dataset)),
58 m_presenter(new ChartPresenter(this,m_dataset)),
59 m_padding(50),
59 m_padding(50),
60 m_backgroundPadding(10)
60 m_backgroundPadding(10)
61 {
61 {
62 connect(m_dataset,SIGNAL(seriesAdded(QSeries*,Domain*)),m_legend,SLOT(handleSeriesAdded(QSeries*,Domain*)));
62 connect(m_dataset,SIGNAL(seriesAdded(QSeries*,Domain*)),m_legend,SLOT(handleSeriesAdded(QSeries*,Domain*)));
63 connect(m_dataset,SIGNAL(seriesRemoved(QSeries*)),m_legend,SLOT(handleSeriesRemoved(QSeries*)));
63 connect(m_dataset,SIGNAL(seriesRemoved(QSeries*)),m_legend,SLOT(handleSeriesRemoved(QSeries*)));
64 }
64 }
65
65
66 /*!
66 /*!
67 Destroys the object and it's children, like QChartSeries and QChartAxis object added to it.
67 Destroys the object and it's children, like QChartSeries and QChartAxis object added to it.
68 */
68 */
69 QChart::~QChart()
69 QChart::~QChart()
70 {
70 {
71 //delete first presenter , since this is a root of all the graphical items
71 //delete first presenter , since this is a root of all the graphical items
72 delete m_presenter;
72 delete m_presenter;
73 m_presenter=0;
73 m_presenter=0;
74 }
74 }
75
75
76 /*!
76 /*!
77 Adds the \a series and optional \a axisY onto the chart and takes the ownership of the objects.
77 Adds the \a series and optional \a axisY onto the chart and takes the ownership of the objects.
78 If auto scaling is enabled, re-scales the axes the series is bound to (both the x axis and
78 If auto scaling is enabled, re-scales the axes the series is bound to (both the x axis and
79 the y axis).
79 the y axis).
80 */
80 */
81 void QChart::addSeries(QSeries* series, QChartAxis* axisY)
81 void QChart::addSeries(QSeries* series, QChartAxis* axisY)
82 {
82 {
83 m_dataset->addSeries(series, axisY);
83 m_dataset->addSeries(series, axisY);
84 }
84 }
85
85
86 /*!
86 /*!
87 Removes the \a series specified in a perameter from the QChartView.
87 Removes the \a series specified in a perameter from the QChartView.
88 It releses its ownership of the specified QChartSeries object.
88 It releses its ownership of the specified QChartSeries object.
89 It does not delete the pointed QChartSeries data object
89 It does not delete the pointed QChartSeries data object
90 \sa addSeries(), removeAllSeries()
90 \sa addSeries(), removeAllSeries()
91 */
91 */
92 void QChart::removeSeries(QSeries* series)
92 void QChart::removeSeries(QSeries* series)
93 {
93 {
94 m_dataset->removeSeries(series);
94 m_dataset->removeSeries(series);
95 }
95 }
96
96
97 /*!
97 /*!
98 Removes all the QChartSeries that have been added to the QChartView
98 Removes all the QChartSeries that have been added to the QChartView
99 It also deletes the pointed QChartSeries data objects
99 It also deletes the pointed QChartSeries data objects
100 \sa addSeries(), removeSeries()
100 \sa addSeries(), removeSeries()
101 */
101 */
102 void QChart::removeAllSeries()
102 void QChart::removeAllSeries()
103 {
103 {
104 m_dataset->removeAllSeries();
104 m_dataset->removeAllSeries();
105 }
105 }
106
106
107 /*!
107 /*!
108 Sets the \a brush that is used for painting the background of the chart area.
108 Sets the \a brush that is used for painting the background of the chart area.
109 */
109 */
110 void QChart::setBackgroundBrush(const QBrush& brush)
110 void QChart::setBackgroundBrush(const QBrush& brush)
111 {
111 {
112 createChartBackgroundItem();
112 createChartBackgroundItem();
113 m_backgroundItem->setBrush(brush);
113 m_backgroundItem->setBrush(brush);
114 m_backgroundItem->update();
114 m_backgroundItem->update();
115 }
115 }
116
116
117 QBrush QChart::backgroundBrush() const
117 QBrush QChart::backgroundBrush() const
118 {
118 {
119 if(!m_backgroundItem) return QBrush();
119 if(!m_backgroundItem) return QBrush();
120 return m_backgroundItem->brush();
120 return m_backgroundItem->brush();
121 }
121 }
122
122
123 /*!
123 /*!
124 Sets the \a pen that is used for painting the background of the chart area.
124 Sets the \a pen that is used for painting the background of the chart area.
125 */
125 */
126 void QChart::setBackgroundPen(const QPen& pen)
126 void QChart::setBackgroundPen(const QPen& pen)
127 {
127 {
128 createChartBackgroundItem();
128 createChartBackgroundItem();
129 m_backgroundItem->setPen(pen);
129 m_backgroundItem->setPen(pen);
130 m_backgroundItem->update();
130 m_backgroundItem->update();
131 }
131 }
132
132
133 QPen QChart::backgroundPen() const
133 QPen QChart::backgroundPen() const
134 {
134 {
135 if(!m_backgroundItem) return QPen();
135 if(!m_backgroundItem) return QPen();
136 return m_backgroundItem->pen();
136 return m_backgroundItem->pen();
137 }
137 }
138
138
139 /*!
139 /*!
140 Sets the chart \a title. The description text that is drawn above the chart.
140 Sets the chart \a title. The description text that is drawn above the chart.
141 */
141 */
142 void QChart::setTitle(const QString& title)
142 void QChart::setTitle(const QString& title)
143 {
143 {
144 createChartTitleItem();
144 createChartTitleItem();
145 m_titleItem->setText(title);
145 m_titleItem->setText(title);
146 updateLayout();
146 updateLayout();
147 }
147 }
148
148
149 /*!
149 /*!
150 Returns the chart title. The description text that is drawn above the chart.
150 Returns the chart title. The description text that is drawn above the chart.
151 */
151 */
152 QString QChart::title() const
152 QString QChart::title() const
153 {
153 {
154 if(m_titleItem)
154 if(m_titleItem)
155 return m_titleItem->text();
155 return m_titleItem->text();
156 else
156 else
157 return QString();
157 return QString();
158 }
158 }
159
159
160 /*!
160 /*!
161 Sets the \a font that is used for rendering the description text that is rendered above the chart.
161 Sets the \a font that is used for rendering the description text that is rendered above the chart.
162 */
162 */
163 void QChart::setTitleFont(const QFont& font)
163 void QChart::setTitleFont(const QFont& font)
164 {
164 {
165 createChartTitleItem();
165 createChartTitleItem();
166 m_titleItem->setFont(font);
166 m_titleItem->setFont(font);
167 updateLayout();
167 updateLayout();
168 }
168 }
169
169
170 /*!
170 /*!
171 Sets the \a brush used for rendering the title text.
171 Sets the \a brush used for rendering the title text.
172 */
172 */
173 void QChart::setTitleBrush(const QBrush &brush)
173 void QChart::setTitleBrush(const QBrush &brush)
174 {
174 {
175 createChartTitleItem();
175 createChartTitleItem();
176 m_titleItem->setBrush(brush);
176 m_titleItem->setBrush(brush);
177 updateLayout();
177 updateLayout();
178 }
178 }
179
179
180 /*!
180 /*!
181 Returns the brush used for rendering the title text.
181 Returns the brush used for rendering the title text.
182 */
182 */
183 QBrush QChart::titleBrush() const
183 QBrush QChart::titleBrush() const
184 {
184 {
185 if(!m_titleItem) return QBrush();
185 if(!m_titleItem) return QBrush();
186 return m_titleItem->brush();
186 return m_titleItem->brush();
187 }
187 }
188
188
189 void QChart::createChartBackgroundItem()
189 void QChart::createChartBackgroundItem()
190 {
190 {
191 if(!m_backgroundItem) {
191 if(!m_backgroundItem) {
192 m_backgroundItem = new ChartBackground(this);
192 m_backgroundItem = new ChartBackground(this);
193 m_backgroundItem->setPen(Qt::NoPen);
193 m_backgroundItem->setPen(Qt::NoPen);
194 m_backgroundItem->setZValue(ChartPresenter::BackgroundZValue);
194 m_backgroundItem->setZValue(ChartPresenter::BackgroundZValue);
195 }
195 }
196 }
196 }
197
197
198 void QChart::createChartTitleItem()
198 void QChart::createChartTitleItem()
199 {
199 {
200 if(!m_titleItem) {
200 if(!m_titleItem) {
201 m_titleItem = new QGraphicsSimpleTextItem(this);
201 m_titleItem = new QGraphicsSimpleTextItem(this);
202 m_titleItem->setZValue(ChartPresenter::BackgroundZValue);
202 m_titleItem->setZValue(ChartPresenter::BackgroundZValue);
203 }
203 }
204 }
204 }
205
205
206 /*!
206 /*!
207 Sets the \a theme used by the chart for rendering the graphical representation of the data
207 Sets the \a theme used by the chart for rendering the graphical representation of the data
208 \sa ChartTheme, chartTheme()
208 \sa ChartTheme, chartTheme()
209 */
209 */
210 void QChart::setChartTheme(QChart::ChartTheme theme)
210 void QChart::setChartTheme(QChart::ChartTheme theme)
211 {
211 {
212 m_presenter->setChartTheme(theme);
212 m_presenter->setChartTheme(theme);
213 }
213 }
214
214
215 /*!
215 /*!
216 Returns the theme enum used by the chart.
216 Returns the theme enum used by the chart.
217 \sa ChartTheme, setChartTheme()
217 \sa ChartTheme, setChartTheme()
218 */
218 */
219 QChart::ChartTheme QChart::chartTheme() const
219 QChart::ChartTheme QChart::chartTheme() const
220 {
220 {
221 return m_presenter->chartTheme();
221 return m_presenter->chartTheme();
222 }
222 }
223
223
224 /*!
224 /*!
225 Zooms in the view by a factor of 2
225 Zooms in the view by a factor of 2
226 */
226 */
227 void QChart::zoomIn()
227 void QChart::zoomIn()
228 {
228 {
229 m_presenter->zoomIn();
229 m_presenter->zoomIn();
230 }
230 }
231
231
232 /*!
232 /*!
233 Zooms in the view to a maximum level at which \a rect is still fully visible.
233 Zooms in the view to a maximum level at which \a rect is still fully visible.
234 */
234 */
235 void QChart::zoomIn(const QRectF& rect)
235 void QChart::zoomIn(const QRectF& rect)
236 {
236 {
237
237
238 if(!rect.isValid()) return;
238 if(!rect.isValid()) return;
239 m_presenter->zoomIn(rect);
239 m_presenter->zoomIn(rect);
240 }
240 }
241
241
242 /*!
242 /*!
243 Restores the view zoom level to the previous one.
243 Restores the view zoom level to the previous one.
244 */
244 */
245 void QChart::zoomOut()
245 void QChart::zoomOut()
246 {
246 {
247 m_presenter->zoomOut();
247 m_presenter->zoomOut();
248 }
248 }
249
249
250 /*!
250 /*!
251 Returns the pointer to the x axis object of the chart
251 Returns the pointer to the x axis object of the chart
252 */
252 */
253 QChartAxis* QChart::axisX() const
253 QChartAxis* QChart::axisX() const
254 {
254 {
255 return m_dataset->axisX();
255 return m_dataset->axisX();
256 }
256 }
257
257
258 /*!
258 /*!
259 Returns the pointer to the y axis object of the chart
259 Returns the pointer to the y axis object of the chart
260 */
260 */
261 QChartAxis* QChart::axisY() const
261 QChartAxis* QChart::axisY() const
262 {
262 {
263 return m_dataset->axisY();
263 return m_dataset->axisY();
264 }
264 }
265
265
266 /*!
266 /*!
267 Returns the legend object of the chart. Ownership stays in chart.
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 }
272 }
273
273
274 /*!
274 /*!
275 Resizes and updates the chart area using the \a event data
275 Resizes and updates the chart area using the \a event data
276 */
276 */
277 void QChart::resizeEvent(QGraphicsSceneResizeEvent *event)
277 void QChart::resizeEvent(QGraphicsSceneResizeEvent *event)
278 {
278 {
279
279
280 m_rect = QRectF(QPoint(0,0),event->newSize());
280 m_rect = QRectF(QPoint(0,0),event->newSize());
281 updateLayout();
281 updateLayout();
282 QGraphicsWidget::resizeEvent(event);
282 QGraphicsWidget::resizeEvent(event);
283 update();
283 update();
284 }
284 }
285
285
286 /*!
286 /*!
287 Sets animation \a options for the chart
287 Sets animation \a options for the chart
288 */
288 */
289 void QChart::setAnimationOptions(AnimationOptions options)
289 void QChart::setAnimationOptions(AnimationOptions options)
290 {
290 {
291 m_presenter->setAnimationOptions(options);
291 m_presenter->setAnimationOptions(options);
292 }
292 }
293
293
294 /*!
294 /*!
295 Returns animation options for the chart
295 Returns animation options for the chart
296 */
296 */
297 QChart::AnimationOptions QChart::animationOptions() const
297 QChart::AnimationOptions QChart::animationOptions() const
298 {
298 {
299 return m_presenter->animationOptions();
299 return m_presenter->animationOptions();
300 }
300 }
301
301
302 void QChart::scrollLeft()
302 void QChart::scrollLeft()
303 {
303 {
304 m_presenter->scroll(-m_presenter->geometry().width()/(axisX()->ticksCount()-1),0);
304 m_presenter->scroll(-m_presenter->geometry().width()/(axisX()->ticksCount()-1),0);
305 }
305 }
306
306
307 void QChart::scrollRight()
307 void QChart::scrollRight()
308 {
308 {
309 m_presenter->scroll(m_presenter->geometry().width()/(axisX()->ticksCount()-1),0);
309 m_presenter->scroll(m_presenter->geometry().width()/(axisX()->ticksCount()-1),0);
310 }
310 }
311 void QChart::scrollUp()
311 void QChart::scrollUp()
312 {
312 {
313 m_presenter->scroll(0,m_presenter->geometry().width()/(axisY()->ticksCount()-1));
313 m_presenter->scroll(0,m_presenter->geometry().width()/(axisY()->ticksCount()-1));
314 }
314 }
315 void QChart::scrollDown()
315 void QChart::scrollDown()
316 {
316 {
317 m_presenter->scroll(0,-m_presenter->geometry().width()/(axisY()->ticksCount()-1));
317 m_presenter->scroll(0,-m_presenter->geometry().width()/(axisY()->ticksCount()-1));
318 }
318 }
319
319
320 void QChart::updateLayout()
320 void QChart::updateLayout()
321 {
321 {
322 if(!m_rect.isValid()) return;
322 if(!m_rect.isValid()) return;
323
323
324 QRectF rect = m_rect.adjusted(m_padding,m_padding, -m_padding, -m_padding);
324 QRectF rect = m_rect.adjusted(m_padding,m_padding, -m_padding, -m_padding);
325
325
326 // recalculate title position
326 // recalculate title position
327 if (m_titleItem) {
327 if (m_titleItem) {
328 QPointF center = m_rect.center() -m_titleItem->boundingRect().center();
328 QPointF center = m_rect.center() -m_titleItem->boundingRect().center();
329 m_titleItem->setPos(center.x(),m_rect.top()/2 + m_padding/2);
329 m_titleItem->setPos(center.x(),m_rect.top()/2 + m_padding/2);
330 }
330 }
331
331
332 //recalculate background gradient
332 //recalculate background gradient
333 if (m_backgroundItem) {
333 if (m_backgroundItem) {
334 m_backgroundItem->setRect(m_rect.adjusted(m_backgroundPadding,m_backgroundPadding, -m_backgroundPadding, -m_backgroundPadding));
334 m_backgroundItem->setRect(m_rect.adjusted(m_backgroundPadding,m_backgroundPadding, -m_backgroundPadding, -m_backgroundPadding));
335 }
335 }
336
336
337 // recalculate legend position
337 // recalculate legend position
338 if (m_legend) {
338 if (m_legend) {
339 if (m_legend->parentObject() == this) {
339 if (m_legend->parentObject() == this) {
340 m_legend->setMaximumSize(rect.size());
340 updateLegendLayout();
341 m_legend->setPos(rect.topLeft());
342 }
341 }
343 }
342 }
344 }
343 }
345
344
345 void QChart::updateLegendLayout()
346 {
347 QRectF plotRect = m_rect.adjusted(m_padding,m_padding, -m_padding, -m_padding);
348 QRectF legendRect;
349
350 switch (m_legend->preferredLayout())
351 {
352 case QLegend::PreferredLayoutTop:{
353 legendRect = m_rect.adjusted(m_padding,0,-m_padding,-m_padding - plotRect.height());
354 break;
355 }
356 case QLegend::PreferredLayoutBottom: {
357 legendRect = m_rect.adjusted(m_padding,m_padding + plotRect.height(),-m_padding,0);
358 break;
359 }
360 case QLegend::PreferredLayoutLeft: {
361 legendRect = m_rect.adjusted(0,m_padding,-m_padding - plotRect.width(),-m_padding);
362 break;
363 }
364 case QLegend::PreferredLayoutRight: {
365 legendRect = m_rect.adjusted(m_padding + plotRect.width(),m_padding,0,-m_padding);
366 break;
367 }
368 default: {
369 legendRect = plotRect;
370 break;
371 }
372 }
373
374 m_legend->setMaximumSize(legendRect.size());
375 m_legend->setPos(legendRect.topLeft());
376 }
377
346
378
347 int QChart::padding() const
379 int QChart::padding() const
348 {
380 {
349 return m_padding;
381 return m_padding;
350 }
382 }
351
383
352 void QChart::setPadding(int padding)
384 void QChart::setPadding(int padding)
353 {
385 {
354 if(m_padding==padding){
386 if(m_padding==padding){
355 m_padding = padding;
387 m_padding = padding;
356 m_presenter->handleGeometryChanged();
388 m_presenter->handleGeometryChanged();
357 updateLayout();
389 updateLayout();
358 }
390 }
359 }
391 }
360
392
361 void QChart::setBackgroundPadding(int padding)
393 void QChart::setBackgroundPadding(int padding)
362 {
394 {
363 if(m_backgroundPadding!=padding){
395 if(m_backgroundPadding!=padding){
364 m_backgroundPadding = padding;
396 m_backgroundPadding = padding;
365 updateLayout();
397 updateLayout();
366 }
398 }
367 }
399 }
368
400
369 void QChart::setBackgroundDiameter(int diameter)
401 void QChart::setBackgroundDiameter(int diameter)
370 {
402 {
371 createChartBackgroundItem();
403 createChartBackgroundItem();
372 m_backgroundItem->setDimeter(diameter);
404 m_backgroundItem->setDimeter(diameter);
373 m_backgroundItem->update();
405 m_backgroundItem->update();
374 }
406 }
375
407
376 void QChart::setBackgroundVisible(bool visible)
408 void QChart::setBackgroundVisible(bool visible)
377 {
409 {
378 createChartBackgroundItem();
410 createChartBackgroundItem();
379 m_backgroundItem->setVisible(visible);
411 m_backgroundItem->setVisible(visible);
380 }
412 }
381
413
382 bool QChart::isBackgroundVisible() const
414 bool QChart::isBackgroundVisible() const
383 {
415 {
384 if(!m_backgroundItem) return false;
416 if(!m_backgroundItem) return false;
385 return m_backgroundItem->isVisible();
417 return m_backgroundItem->isVisible();
386 }
418 }
387
419
388
420
389 #include "moc_qchart.cpp"
421 #include "moc_qchart.cpp"
390
422
391 QTCOMMERCIALCHART_END_NAMESPACE
423 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,121 +1,122
1 #ifndef QCHART_H
1 #ifndef QCHART_H
2 #define QCHART_H
2 #define QCHART_H
3
3
4 #include <qchartglobal.h>
4 #include <qchartglobal.h>
5 #include <qseries.h>
5 #include <qseries.h>
6 #include <QGraphicsWidget>
6 #include <QGraphicsWidget>
7 #include <QLinearGradient>
7 #include <QLinearGradient>
8 #include <QFont>
8 #include <QFont>
9
9
10 class QGraphicsSceneResizeEvent;
10 class QGraphicsSceneResizeEvent;
11
11
12 QTCOMMERCIALCHART_BEGIN_NAMESPACE
12 QTCOMMERCIALCHART_BEGIN_NAMESPACE
13
13
14 class Axis;
14 class Axis;
15 class QSeries;
15 class QSeries;
16 class PlotDomain;
16 class PlotDomain;
17 class BarChartItem;
17 class BarChartItem;
18 class QChartAxis;
18 class QChartAxis;
19 class ChartTheme;
19 class ChartTheme;
20 class ChartItem;
20 class ChartItem;
21 class ChartDataSet;
21 class ChartDataSet;
22 class ChartPresenter;
22 class ChartPresenter;
23 class QLegend;
23 class QLegend;
24 class ChartBackground;
24 class ChartBackground;
25
25
26
26
27 class QTCOMMERCIALCHART_EXPORT QChart : public QGraphicsWidget
27 class QTCOMMERCIALCHART_EXPORT QChart : public QGraphicsWidget
28 {
28 {
29 Q_OBJECT
29 Q_OBJECT
30 public:
30 public:
31 enum ChartTheme {
31 enum ChartTheme {
32 ChartThemeDefault,
32 ChartThemeDefault,
33 ChartThemeLight,
33 ChartThemeLight,
34 ChartThemeBlueCerulean,
34 ChartThemeBlueCerulean,
35 ChartThemeDark,
35 ChartThemeDark,
36 ChartThemeBrownSand,
36 ChartThemeBrownSand,
37 ChartThemeBlueNcs,
37 ChartThemeBlueNcs,
38 ChartThemeIcy,
38 ChartThemeIcy,
39 ChartThemeScientific,
39 ChartThemeScientific,
40 ChartThemeCount
40 ChartThemeCount
41 };
41 };
42
42
43 enum AnimationOption {
43 enum AnimationOption {
44 NoAnimation = 0x0,
44 NoAnimation = 0x0,
45 GridAxisAnimations = 0x1,
45 GridAxisAnimations = 0x1,
46 SeriesAnimations =0x2,
46 SeriesAnimations =0x2,
47 AllAnimations = 0x3
47 AllAnimations = 0x3
48 };
48 };
49 Q_DECLARE_FLAGS(AnimationOptions, AnimationOption)
49 Q_DECLARE_FLAGS(AnimationOptions, AnimationOption)
50
50
51 public:
51 public:
52 QChart(QGraphicsItem *parent = 0, Qt::WindowFlags wFlags = 0);
52 QChart(QGraphicsItem *parent = 0, Qt::WindowFlags wFlags = 0);
53 ~QChart();
53 ~QChart();
54
54
55 void addSeries(QSeries* series, QChartAxis* axisY = 0);
55 void addSeries(QSeries* series, QChartAxis* axisY = 0);
56 void removeSeries(QSeries* series); //returns ownership , deletes axis if no series attached
56 void removeSeries(QSeries* series); //returns ownership , deletes axis if no series attached
57 void removeAllSeries(); // deletes series and axis
57 void removeAllSeries(); // deletes series and axis
58
58
59 void setChartTheme(QChart::ChartTheme theme);
59 void setChartTheme(QChart::ChartTheme theme);
60 QChart::ChartTheme chartTheme() const;
60 QChart::ChartTheme chartTheme() const;
61
61
62 void setTitle(const QString& title);
62 void setTitle(const QString& title);
63 QString title() const;
63 QString title() const;
64 void setTitleFont(const QFont& font);
64 void setTitleFont(const QFont& font);
65 QFont titleFont() const;
65 QFont titleFont() const;
66 void setTitleBrush(const QBrush &brush);
66 void setTitleBrush(const QBrush &brush);
67 QBrush titleBrush() const;
67 QBrush titleBrush() const;
68 void setBackgroundBrush(const QBrush& brush);
68 void setBackgroundBrush(const QBrush& brush);
69 QBrush backgroundBrush() const;
69 QBrush backgroundBrush() const;
70 void setBackgroundPen(const QPen& pen);
70 void setBackgroundPen(const QPen& pen);
71 QPen backgroundPen() const;
71 QPen backgroundPen() const;
72
72
73 void setBackgroundVisible(bool visible);
73 void setBackgroundVisible(bool visible);
74 bool isBackgroundVisible() const;
74 bool isBackgroundVisible() const;
75
75
76 void setAnimationOptions(AnimationOptions options);
76 void setAnimationOptions(AnimationOptions options);
77 AnimationOptions animationOptions() const;
77 AnimationOptions animationOptions() const;
78
78
79 void zoomIn();
79 void zoomIn();
80 void zoomIn(const QRectF& rect);
80 void zoomIn(const QRectF& rect);
81 void zoomOut();
81 void zoomOut();
82 void scrollLeft();
82 void scrollLeft();
83 void scrollRight();
83 void scrollRight();
84 void scrollUp();
84 void scrollUp();
85 void scrollDown();
85 void scrollDown();
86
86
87 QChartAxis* axisX() const;
87 QChartAxis* axisX() const;
88 QChartAxis* axisY() const;
88 QChartAxis* axisY() const;
89
89
90 QLegend* legend() const;
90 QLegend* legend() const;
91
91
92 int padding() const;
92 int padding() const;
93
93
94 protected:
94 protected:
95 void resizeEvent(QGraphicsSceneResizeEvent *event);
95 void resizeEvent(QGraphicsSceneResizeEvent *event);
96
96
97 private:
97 private:
98 inline void createChartBackgroundItem();
98 inline void createChartBackgroundItem();
99 inline void createChartTitleItem();
99 inline void createChartTitleItem();
100 void setPadding(int padding);
100 void setPadding(int padding);
101 void setBackgroundPadding(int padding);
101 void setBackgroundPadding(int padding);
102 void setBackgroundDiameter(int diameter);
102 void setBackgroundDiameter(int diameter);
103 void updateLayout();
103 void updateLayout();
104 void updateLegendLayout();
104
105
105 private:
106 private:
106 Q_DISABLE_COPY(QChart)
107 Q_DISABLE_COPY(QChart)
107 ChartBackground* m_backgroundItem;
108 ChartBackground* m_backgroundItem;
108 QGraphicsSimpleTextItem* m_titleItem;
109 QGraphicsSimpleTextItem* m_titleItem;
109 QRectF m_rect;
110 QRectF m_rect;
110 QLegend* m_legend;
111 QLegend* m_legend;
111 ChartDataSet *m_dataset;
112 ChartDataSet *m_dataset;
112 ChartPresenter *m_presenter;
113 ChartPresenter *m_presenter;
113 int m_padding;
114 int m_padding;
114 int m_backgroundPadding;
115 int m_backgroundPadding;
115 };
116 };
116
117
117 QTCOMMERCIALCHART_END_NAMESPACE
118 QTCOMMERCIALCHART_END_NAMESPACE
118
119
119 Q_DECLARE_OPERATORS_FOR_FLAGS(QTCOMMERCIALCHART_NAMESPACE::QChart::AnimationOptions)
120 Q_DECLARE_OPERATORS_FOR_FLAGS(QTCOMMERCIALCHART_NAMESPACE::QChart::AnimationOptions)
120
121
121 #endif
122 #endif
@@ -1,491 +1,661
1 #include "qchartglobal.h"
1 #include "qchartglobal.h"
2 #include "qlegend.h"
2 #include "qlegend.h"
3 #include "qseries.h"
3 #include "qseries.h"
4 #include "legendmarker_p.h"
4 #include "legendmarker_p.h"
5 #include "legendscrollbutton_p.h"
5 #include "qxyseries.h"
6 #include "qxyseries.h"
6 #include "qlineseries.h"
7 #include "qlineseries.h"
7 #include "qareaseries.h"
8 #include "qareaseries.h"
8 #include "qscatterseries.h"
9 #include "qscatterseries.h"
9 #include "qsplineseries.h"
10 #include "qsplineseries.h"
10 #include "qbarseries.h"
11 #include "qbarseries.h"
11 #include "qstackedbarseries.h"
12 #include "qstackedbarseries.h"
12 #include "qpercentbarseries.h"
13 #include "qpercentbarseries.h"
13 #include "qbarset.h"
14 #include "qbarset.h"
14 #include "qpieseries.h"
15 #include "qpieseries.h"
15 #include "qpieslice.h"
16 #include "qpieslice.h"
16 #include "chartpresenter_p.h"
17 #include "chartpresenter_p.h"
17 #include <QPainter>
18 #include <QPainter>
18 #include <QPen>
19 #include <QPen>
19
20
20 #include <QGraphicsSceneEvent>
21 #include <QGraphicsSceneEvent>
21
22
22 QTCOMMERCIALCHART_BEGIN_NAMESPACE
23 QTCOMMERCIALCHART_BEGIN_NAMESPACE
23
24
24 QLegend::QLegend(QGraphicsItem *parent)
25 QLegend::QLegend(QGraphicsItem *parent)
25 : QGraphicsObject(parent)
26 : QGraphicsObject(parent)
26 ,mPos(0,0)
27 ,mPos(0,0)
27 ,mSize(0,0)
28 ,mSize(0,0)
28 ,mMinimumSize(50,20) // TODO: magic numbers
29 ,mMinimumSize(50,20) // TODO: magic numbers
29 ,mMaximumSize(150,100)
30 ,mMaximumSize(150,100)
30 ,m_brush(Qt::darkGray) // TODO: from theme?
31 ,m_brush(Qt::darkGray) // TODO: from theme?
31 ,mPreferredLayout(QLegend::PreferredLayoutVertical)
32 ,mPreferredLayout(QLegend::PreferredLayoutTop)
33 ,mFirstMarker(0)
34 ,mMargin(5)
32 {
35 {
33 setVisible(false);
36 // setVisible(false);
37
38 mScrollButtonLeft = new LegendScrollButton(LegendScrollButton::ScrollButtonIdLeft, this);
39 mScrollButtonRight = new LegendScrollButton(LegendScrollButton::ScrollButtonIdRight, this);
40 mScrollButtonUp = new LegendScrollButton(LegendScrollButton::ScrollButtonIdUp, this);
41 mScrollButtonDown = new LegendScrollButton(LegendScrollButton::ScrollButtonIdDown, this);
42
43 connect(mScrollButtonLeft,SIGNAL(clicked(QGraphicsSceneMouseEvent*)),this,SLOT(handleScrollButtonClicked(QGraphicsSceneMouseEvent*)));
44 connect(mScrollButtonRight,SIGNAL(clicked(QGraphicsSceneMouseEvent*)),this,SLOT(handleScrollButtonClicked(QGraphicsSceneMouseEvent*)));
45 connect(mScrollButtonUp,SIGNAL(clicked(QGraphicsSceneMouseEvent*)),this,SLOT(handleScrollButtonClicked(QGraphicsSceneMouseEvent*)));
46 connect(mScrollButtonDown,SIGNAL(clicked(QGraphicsSceneMouseEvent*)),this,SLOT(handleScrollButtonClicked(QGraphicsSceneMouseEvent*)));
47
34 setZValue(ChartPresenter::LegendZValue);
48 setZValue(ChartPresenter::LegendZValue);
35 }
49 }
36
50
37 void QLegend::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
51 void QLegend::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
38 {
52 {
39 Q_UNUSED(option)
53 Q_UNUSED(option)
40 Q_UNUSED(widget)
54 Q_UNUSED(widget)
41
55
42 painter->setOpacity(0.5);
56 painter->setOpacity(0.8);
43 painter->setPen(m_pen);
57 painter->setPen(m_pen);
44 painter->setBrush(m_brush);
58 painter->setBrush(m_brush);
45 painter->drawRect(boundingRect());
59 painter->drawRect(boundingRect());
46 }
60 }
47
61
48 QRectF QLegend::boundingRect() const
62 QRectF QLegend::boundingRect() const
49 {
63 {
50 return QRectF(mPos,mSize);
64 return QRectF(mPos,mSize);
51 }
65 }
52
66
53 void QLegend::setBrush(const QBrush& brush)
67 void QLegend::setBrush(const QBrush& brush)
54 {
68 {
55 if(m_brush!=brush){
69 if(m_brush!=brush){
56 m_brush = brush;
70 m_brush = brush;
57 update();
71 update();
58 }
72 }
59 }
73 }
60
74
61 QBrush QLegend::brush() const
75 QBrush QLegend::brush() const
62 {
76 {
63 return m_brush;
77 return m_brush;
64 }
78 }
65
79
66 void QLegend::setPen(const QPen& pen)
80 void QLegend::setPen(const QPen& pen)
67 {
81 {
68 if(m_pen!=pen){
82 if(m_pen!=pen){
69 m_pen = pen;
83 m_pen = pen;
70 update();
84 update();
71 }
85 }
72 }
86 }
73
87
74 QPen QLegend::pen() const
88 QPen QLegend::pen() const
75 {
89 {
76 return m_pen;
90 return m_pen;
77 }
91 }
78
92
79 void QLegend::setPreferredLayout(QLegend::PreferredLayout preferred)
93 void QLegend::setPreferredLayout(QLegend::PreferredLayout preferred)
80 {
94 {
81 mPreferredLayout = preferred;
95 mPreferredLayout = preferred;
82 layoutChanged();
96 updateLayout();
97 }
98
99 QLegend::PreferredLayout QLegend::preferredLayout() const
100 {
101 return mPreferredLayout;
83 }
102 }
84
103
85 QSizeF QLegend::maximumSize() const
104 QSizeF QLegend::maximumSize() const
86 {
105 {
87 return mMaximumSize;
106 return mMaximumSize;
88 }
107 }
89
108
90 void QLegend::setMaximumSize(const QSizeF size)
109 void QLegend::setMaximumSize(const QSizeF size)
91 {
110 {
92 mMaximumSize = size;
111 mMaximumSize = size;
93 layoutChanged();
112 updateLayout();
94 }
113 }
95
114
96 void QLegend::setSize(const QSizeF size)
115 void QLegend::setSize(const QSizeF size)
97 {
116 {
98 mSize = size;
117 mSize = size;
99 if (mSize.width() > mMaximumSize.width()) {
118 if (mSize.width() > mMaximumSize.width()) {
100 mSize.setWidth(mMaximumSize.width());
119 mSize.setWidth(mMaximumSize.width());
101 }
120 }
102 if (mSize.height() > mMaximumSize.height()) {
121 if (mSize.height() > mMaximumSize.height()) {
103 mSize.setHeight(mMaximumSize.height());
122 mSize.setHeight(mMaximumSize.height());
104 }
123 }
105 }
124 }
106
125
107 void QLegend::setPos(const QPointF &pos)
126 void QLegend::setPos(const QPointF &pos)
108 {
127 {
109 mPos = pos;
128 mPos = pos;
110 layoutChanged();
129 updateLayout();
111 }
130 }
112
131
113 void QLegend::handleSeriesAdded(QSeries* series, Domain* domain)
132 void QLegend::handleSeriesAdded(QSeries* series, Domain* domain)
114 {
133 {
115 Q_UNUSED(domain)
134 Q_UNUSED(domain)
116
135
117 createMarkers(series);
136 createMarkers(series);
118 connectSeries(series);
137 connectSeries(series);
119 layoutChanged();
138 updateLayout();
120 }
139 }
121
140
122 void QLegend::handleSeriesRemoved(QSeries* series)
141 void QLegend::handleSeriesRemoved(QSeries* series)
123 {
142 {
124 disconnectSeries(series);
143 disconnectSeries(series);
125
144
126 if (series->type() == QSeries::SeriesTypeArea)
145 if (series->type() == QSeries::SeriesTypeArea)
127 {
146 {
128 // This is special case. Area series has upper and lower series, which each have markers
147 // This is special case. Area series has upper and lower series, which each have markers
129 QAreaSeries* s = static_cast<QAreaSeries*> (series);
148 QAreaSeries* s = static_cast<QAreaSeries*> (series);
130 deleteMarkers(s->upperSeries());
149 deleteMarkers(s->upperSeries());
131 deleteMarkers(s->lowerSeries());
150 deleteMarkers(s->lowerSeries());
132 } else {
151 } else {
133 deleteMarkers(series);
152 deleteMarkers(series);
134 }
153 }
135
154
136 layoutChanged();
155 updateLayout();
137 }
156 }
138
157
139 void QLegend::handleAdded(QList<QPieSlice*> slices)
158 void QLegend::handleAdded(QList<QPieSlice*> slices)
140 {
159 {
141 QPieSeries* series = static_cast<QPieSeries*> (sender());
160 QPieSeries* series = static_cast<QPieSeries*> (sender());
142 foreach(QPieSlice* s, slices) {
161 foreach(QPieSlice* s, slices) {
143 LegendMarker* marker = new LegendMarker(series,s,this);
162 LegendMarker* marker = new LegendMarker(series,s,this);
144 marker->setName(s->label());
163 marker->setName(s->label());
145 marker->setBrush(s->sliceBrush());
164 marker->setBrush(s->sliceBrush());
146 connect(marker,SIGNAL(clicked(QPieSlice*,Qt::MouseButton)),this,SIGNAL(clicked(QPieSlice*,Qt::MouseButton)));
165 connect(marker,SIGNAL(clicked(QPieSlice*,Qt::MouseButton)),this,SIGNAL(clicked(QPieSlice*,Qt::MouseButton)));
147 connect(s,SIGNAL(changed()),marker,SLOT(changed()));
166 connect(s,SIGNAL(changed()),marker,SLOT(changed()));
148 connect(s,SIGNAL(destroyed()),marker,SLOT(deleteLater()));
167 connect(s,SIGNAL(destroyed()),marker,SLOT(deleteLater()));
149 connect(marker,SIGNAL(destroyed()),this,SLOT(handleMarkerDestroyed()));
168 connect(marker,SIGNAL(destroyed()),this,SLOT(handleMarkerDestroyed()));
150 mMarkers.append(marker);
169 mMarkers.append(marker);
151 childItems().append(marker);
170 childItems().append(marker);
152 }
171 }
153 layoutChanged();
172 updateLayout();
154 }
173 }
155
174
156 void QLegend::handleRemoved(QList<QPieSlice *> slices)
175 void QLegend::handleRemoved(QList<QPieSlice *> slices)
157 {
176 {
158 Q_UNUSED(slices)
177 Q_UNUSED(slices)
159 // Propably no need to listen for this, since removed slices are deleted and we listen destroyed signal
178 // Propably no need to listen for this, since removed slices are deleted and we listen destroyed signal
160 // qDebug() << "QLegend::handleRemoved(QList<QPieSlice*> slices) count:" << slices.count();
179 // qDebug() << "QLegend::handleRemoved(QList<QPieSlice*> slices) count:" << slices.count();
161 }
180 }
162
181
163
182
164 void QLegend::handleMarkerDestroyed()
183 void QLegend::handleMarkerDestroyed()
165 {
184 {
166 // TODO: what if more than one markers are destroyed and we update layout after first one?
185 // TODO: what if more than one markers are destroyed and we update layout after first one?
167 LegendMarker* m = static_cast<LegendMarker*> (sender());
186 LegendMarker* m = static_cast<LegendMarker*> (sender());
168 mMarkers.removeOne(m);
187 mMarkers.removeOne(m);
169 layoutChanged();
188 updateLayout();
189 }
190
191 void QLegend::handleScrollButtonClicked(QGraphicsSceneMouseEvent *event)
192 {
193 Q_UNUSED(event); // Maybe later somethin happens with right click...
194
195 // TODO: detect sender object. scroll to appropiate direction.
196 LegendScrollButton* scrollButton = static_cast<LegendScrollButton*> (sender());
197 Q_ASSERT(scrollButton);
198
199 switch (scrollButton->id()) {
200 case LegendScrollButton::ScrollButtonIdLeft:
201 case LegendScrollButton::ScrollButtonIdUp: {
202 // Lower limit is same in these cases
203 mFirstMarker--;
204 checkMarkerBounds();
205 break;
206 }
207 case LegendScrollButton::ScrollButtonIdRight:
208 case LegendScrollButton::ScrollButtonIdDown: {
209 mFirstMarker++;
210 checkMarkerBounds();
211 break;
212 }
213 default: {
214 break;
215 }
216 }
217 updateLayout();
170 }
218 }
171
219
172 void QLegend::connectSeries(QSeries *series)
220 void QLegend::connectSeries(QSeries *series)
173 {
221 {
174 // Connect relevant signals from series
222 // Connect relevant signals from series
175 switch (series->type())
223 switch (series->type())
176 {
224 {
177 case QSeries::SeriesTypeLine: {
225 case QSeries::SeriesTypeLine: {
178 // QLineSeries* lineSeries = static_cast<QLineSeries*>(series);
226 // QLineSeries* lineSeries = static_cast<QLineSeries*>(series);
179 break;
227 break;
180 }
228 }
181 case QSeries::SeriesTypeArea: {
229 case QSeries::SeriesTypeArea: {
182 // QAreaSeries* areaSeries = static_cast<QAreaSeries*>(series);
230 // QAreaSeries* areaSeries = static_cast<QAreaSeries*>(series);
183 break;
231 break;
184 }
232 }
185 case QSeries::SeriesTypeBar: {
233 case QSeries::SeriesTypeBar: {
186 // QBarSeries* barSeries = static_cast<QBarSeries*>(series);
234 // QBarSeries* barSeries = static_cast<QBarSeries*>(series);
187 break;
235 break;
188 }
236 }
189 case QSeries::SeriesTypeStackedBar: {
237 case QSeries::SeriesTypeStackedBar: {
190 // QStackedBarSeries* stackedBarSeries = static_cast<QStackedBarSeries*>(series);
238 // QStackedBarSeries* stackedBarSeries = static_cast<QStackedBarSeries*>(series);
191 break;
239 break;
192 }
240 }
193 case QSeries::SeriesTypePercentBar: {
241 case QSeries::SeriesTypePercentBar: {
194 // QPercentBarSeries* percentBarSeries = static_cast<QPercentBarSeries*>(series);
242 // QPercentBarSeries* percentBarSeries = static_cast<QPercentBarSeries*>(series);
195 break;
243 break;
196 }
244 }
197 case QSeries::SeriesTypeScatter: {
245 case QSeries::SeriesTypeScatter: {
198 // QScatterSeries *scatterSeries = static_cast<QScatterSeries *>(series);
246 // QScatterSeries *scatterSeries = static_cast<QScatterSeries *>(series);
199 break;
247 break;
200 }
248 }
201 case QSeries::SeriesTypePie: {
249 case QSeries::SeriesTypePie: {
202 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
250 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
203 connect(pieSeries,SIGNAL(added(QList<QPieSlice*>)),this,SLOT(handleAdded(QList<QPieSlice*>)));
251 connect(pieSeries,SIGNAL(added(QList<QPieSlice*>)),this,SLOT(handleAdded(QList<QPieSlice*>)));
204 // connect(pieSeries,SIGNAL(removed(QList<QPieSlice*>)),this,SLOT(handleRemoved(QList<QPieSlice*>)));
252 // connect(pieSeries,SIGNAL(removed(QList<QPieSlice*>)),this,SLOT(handleRemoved(QList<QPieSlice*>)));
205 break;
253 break;
206 }
254 }
207 case QSeries::SeriesTypeSpline: {
255 case QSeries::SeriesTypeSpline: {
208 // QSplineSeries* splineSeries = static_cast<QSplineSeries*>(series);
256 // QSplineSeries* splineSeries = static_cast<QSplineSeries*>(series);
209 break;
257 break;
210 }
258 }
211 default: {
259 default: {
212 qDebug()<< "QLegend::connectSeries" << series->type() << "not implemented.";
260 qDebug()<< "QLegend::connectSeries" << series->type() << "not implemented.";
213 break;
261 break;
214 }
262 }
215 }
263 }
216 }
264 }
217
265
218 void QLegend::disconnectSeries(QSeries *series)
266 void QLegend::disconnectSeries(QSeries *series)
219 {
267 {
220 // Connect relevant signals from series
268 // Connect relevant signals from series
221 switch (series->type())
269 switch (series->type())
222 {
270 {
223 case QSeries::SeriesTypeLine: {
271 case QSeries::SeriesTypeLine: {
224 // QLineSeries* lineSeries = static_cast<QLineSeries*>(series);
272 // QLineSeries* lineSeries = static_cast<QLineSeries*>(series);
225 break;
273 break;
226 }
274 }
227 case QSeries::SeriesTypeArea: {
275 case QSeries::SeriesTypeArea: {
228 // QAreaSeries* areaSeries = static_cast<QAreaSeries*>(series);
276 // QAreaSeries* areaSeries = static_cast<QAreaSeries*>(series);
229 break;
277 break;
230 }
278 }
231 case QSeries::SeriesTypeBar: {
279 case QSeries::SeriesTypeBar: {
232 // QBarSeries* barSeries = static_cast<QBarSeries*>(series);
280 // QBarSeries* barSeries = static_cast<QBarSeries*>(series);
233 break;
281 break;
234 }
282 }
235 case QSeries::SeriesTypeStackedBar: {
283 case QSeries::SeriesTypeStackedBar: {
236 // QStackedBarSeries* stackedBarSeries = static_cast<QStackedBarSeries*>(series);
284 // QStackedBarSeries* stackedBarSeries = static_cast<QStackedBarSeries*>(series);
237 break;
285 break;
238 }
286 }
239 case QSeries::SeriesTypePercentBar: {
287 case QSeries::SeriesTypePercentBar: {
240 // QPercentBarSeries* percentBarSeries = static_cast<QPercentBarSeries*>(series);
288 // QPercentBarSeries* percentBarSeries = static_cast<QPercentBarSeries*>(series);
241 break;
289 break;
242 }
290 }
243 case QSeries::SeriesTypeScatter: {
291 case QSeries::SeriesTypeScatter: {
244 // QScatterSeries *scatterSeries = static_cast<QScatterSeries *>(series);
292 // QScatterSeries *scatterSeries = static_cast<QScatterSeries *>(series);
245 break;
293 break;
246 }
294 }
247 case QSeries::SeriesTypePie: {
295 case QSeries::SeriesTypePie: {
248 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
296 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
249 disconnect(pieSeries,SIGNAL(added(QList<QPieSlice*>)),this,SLOT(handleAdded(QList<QPieSlice*>)));
297 disconnect(pieSeries,SIGNAL(added(QList<QPieSlice*>)),this,SLOT(handleAdded(QList<QPieSlice*>)));
250 // disconnect(pieSeries,SIGNAL(removed(QList<QPieSlice*>)),this,SLOT(handleRemoved(QList<QPieSlice*>)));
298 // disconnect(pieSeries,SIGNAL(removed(QList<QPieSlice*>)),this,SLOT(handleRemoved(QList<QPieSlice*>)));
251 break;
299 break;
252 }
300 }
253 case QSeries::SeriesTypeSpline: {
301 case QSeries::SeriesTypeSpline: {
254 // QSplineSeries* splineSeries = static_cast<QSplineSeries*>(series);
302 // QSplineSeries* splineSeries = static_cast<QSplineSeries*>(series);
255 break;
303 break;
256 }
304 }
257 default: {
305 default: {
258 qDebug()<< "QLegend::disconnectSeries" << series->type() << "not implemented.";
306 qDebug()<< "QLegend::disconnectSeries" << series->type() << "not implemented.";
259 break;
307 break;
260 }
308 }
261 }
309 }
262 }
310 }
263
311
264 void QLegend::createMarkers(QSeries *series)
312 void QLegend::createMarkers(QSeries *series)
265 {
313 {
266 switch (series->type())
314 switch (series->type())
267 {
315 {
268 case QSeries::SeriesTypeLine: {
316 case QSeries::SeriesTypeLine: {
269 QLineSeries* lineSeries = static_cast<QLineSeries*>(series);
317 QLineSeries* lineSeries = static_cast<QLineSeries*>(series);
270 appendMarkers(lineSeries);
318 appendMarkers(lineSeries);
271 break;
319 break;
272 }
320 }
273 case QSeries::SeriesTypeArea: {
321 case QSeries::SeriesTypeArea: {
274 QAreaSeries* areaSeries = static_cast<QAreaSeries*>(series);
322 QAreaSeries* areaSeries = static_cast<QAreaSeries*>(series);
275 appendMarkers(areaSeries->upperSeries());
323 appendMarkers(areaSeries->upperSeries());
276 if(areaSeries->lowerSeries())
324 if(areaSeries->lowerSeries())
277 appendMarkers(areaSeries->lowerSeries());
325 appendMarkers(areaSeries->lowerSeries());
278 break;
326 break;
279 }
327 }
280
328
281 case QSeries::SeriesTypeBar: {
329 case QSeries::SeriesTypeBar: {
282 QBarSeries* barSeries = static_cast<QBarSeries*>(series);
330 QBarSeries* barSeries = static_cast<QBarSeries*>(series);
283 appendMarkers(barSeries);
331 appendMarkers(barSeries);
284 break;
332 break;
285 }
333 }
286
334
287 case QSeries::SeriesTypeStackedBar: {
335 case QSeries::SeriesTypeStackedBar: {
288 QStackedBarSeries* stackedBarSeries = static_cast<QStackedBarSeries*>(series);
336 QStackedBarSeries* stackedBarSeries = static_cast<QStackedBarSeries*>(series);
289 appendMarkers(stackedBarSeries);
337 appendMarkers(stackedBarSeries);
290 break;
338 break;
291 }
339 }
292
340
293 case QSeries::SeriesTypePercentBar: {
341 case QSeries::SeriesTypePercentBar: {
294 QPercentBarSeries* percentBarSeries = static_cast<QPercentBarSeries*>(series);
342 QPercentBarSeries* percentBarSeries = static_cast<QPercentBarSeries*>(series);
295 appendMarkers(percentBarSeries);
343 appendMarkers(percentBarSeries);
296 break;
344 break;
297 }
345 }
298
346
299 case QSeries::SeriesTypeScatter: {
347 case QSeries::SeriesTypeScatter: {
300 QScatterSeries *scatterSeries = static_cast<QScatterSeries *>(series);
348 QScatterSeries *scatterSeries = static_cast<QScatterSeries *>(series);
301 appendMarkers(scatterSeries);
349 appendMarkers(scatterSeries);
302 break;
350 break;
303 }
351 }
304
352
305 case QSeries::SeriesTypePie: {
353 case QSeries::SeriesTypePie: {
306 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
354 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
307 appendMarkers(pieSeries);
355 appendMarkers(pieSeries);
308 break;
356 break;
309 }
357 }
310
358
311 case QSeries::SeriesTypeSpline: {
359 case QSeries::SeriesTypeSpline: {
312 QSplineSeries* splineSeries = static_cast<QSplineSeries*>(series);
360 QSplineSeries* splineSeries = static_cast<QSplineSeries*>(series);
313 appendMarkers(splineSeries);
361 appendMarkers(splineSeries);
314 break;
362 break;
315 }
363 }
316 default: {
364 default: {
317 qDebug()<< "QLegend::createMarkers" << series->type() << "not implemented.";
365 qDebug()<< "QLegend::createMarkers" << series->type() << "not implemented.";
318 break;
366 break;
319 }
367 }
320 }
368 }
321 }
369 }
322
370
323 void QLegend::appendMarkers(QXYSeries* series)
371 void QLegend::appendMarkers(QXYSeries* series)
324 {
372 {
325 LegendMarker* marker = new LegendMarker(series,this);
373 LegendMarker* marker = new LegendMarker(series,this);
326 marker->setName(series->name());
374 marker->setName(series->name());
327 marker->setBrush(series->brush());
375 marker->setBrush(series->brush());
328 connect(marker,SIGNAL(clicked(QSeries*,Qt::MouseButton)),this,SIGNAL(clicked(QSeries*,Qt::MouseButton)));
376 connect(marker,SIGNAL(clicked(QSeries*,Qt::MouseButton)),this,SIGNAL(clicked(QSeries*,Qt::MouseButton)));
329 connect(marker,SIGNAL(destroyed()),this,SLOT(handleMarkerDestroyed()));
377 connect(marker,SIGNAL(destroyed()),this,SLOT(handleMarkerDestroyed()));
330 mMarkers.append(marker);
378 mMarkers.append(marker);
331 childItems().append(marker);
379 childItems().append(marker);
332 }
380 }
333
381
334 void QLegend::appendMarkers(QBarSeries *series)
382 void QLegend::appendMarkers(QBarSeries *series)
335 {
383 {
336 foreach(QBarSet* s, series->barSets()) {
384 foreach(QBarSet* s, series->barSets()) {
337 LegendMarker* marker = new LegendMarker(series,s,this);
385 LegendMarker* marker = new LegendMarker(series,s,this);
338 marker->setName(s->name());
386 marker->setName(s->name());
339 marker->setBrush(s->brush());
387 marker->setBrush(s->brush());
340 connect(marker,SIGNAL(clicked(QBarSet*,Qt::MouseButton)),this,SIGNAL(clicked(QBarSet*,Qt::MouseButton)));
388 connect(marker,SIGNAL(clicked(QBarSet*,Qt::MouseButton)),this,SIGNAL(clicked(QBarSet*,Qt::MouseButton)));
341 connect(s,SIGNAL(valueChanged()),marker,SLOT(changed()));
389 connect(s,SIGNAL(valueChanged()),marker,SLOT(changed()));
342 connect(marker,SIGNAL(destroyed()),this,SLOT(handleMarkerDestroyed()));
390 connect(marker,SIGNAL(destroyed()),this,SLOT(handleMarkerDestroyed()));
343 mMarkers.append(marker);
391 mMarkers.append(marker);
344 childItems().append(marker);
392 childItems().append(marker);
345 }
393 }
346 }
394 }
347
395
348 void QLegend::appendMarkers(QPieSeries *series)
396 void QLegend::appendMarkers(QPieSeries *series)
349 {
397 {
350 foreach(QPieSlice* s, series->slices()) {
398 foreach(QPieSlice* s, series->slices()) {
351 LegendMarker* marker = new LegendMarker(series,s,this);
399 LegendMarker* marker = new LegendMarker(series,s,this);
352 marker->setName(s->label());
400 marker->setName(s->label());
353 marker->setBrush(s->sliceBrush());
401 marker->setBrush(s->sliceBrush());
354 connect(marker,SIGNAL(clicked(QPieSlice*,Qt::MouseButton)),this,SIGNAL(clicked(QPieSlice*,Qt::MouseButton)));
402 connect(marker,SIGNAL(clicked(QPieSlice*,Qt::MouseButton)),this,SIGNAL(clicked(QPieSlice*,Qt::MouseButton)));
355 connect(s,SIGNAL(changed()),marker,SLOT(changed()));
403 connect(s,SIGNAL(changed()),marker,SLOT(changed()));
356 connect(s,SIGNAL(destroyed()),marker,SLOT(deleteLater()));
404 connect(s,SIGNAL(destroyed()),marker,SLOT(deleteLater()));
357 connect(marker,SIGNAL(destroyed()),this,SLOT(handleMarkerDestroyed()));
405 connect(marker,SIGNAL(destroyed()),this,SLOT(handleMarkerDestroyed()));
358 mMarkers.append(marker);
406 mMarkers.append(marker);
359 childItems().append(marker);
407 childItems().append(marker);
360 }
408 }
361 }
409 }
362
410
363 void QLegend::deleteMarkers(QSeries *series)
411 void QLegend::deleteMarkers(QSeries *series)
364 {
412 {
365 // Search all markers that belong to given series and delete them.
413 // Search all markers that belong to given series and delete them.
366 foreach (LegendMarker *m, mMarkers) {
414 foreach (LegendMarker *m, mMarkers) {
367 if (m->series() == series) {
415 if (m->series() == series) {
368 mMarkers.removeOne(m);
416 mMarkers.removeOne(m);
369 delete m;
417 delete m;
370 }
418 }
371 }
419 }
372 }
420 }
373
421
374 void QLegend::layoutChanged()
422 void QLegend::updateLayout()
375 {
423 {
376 // Calculate layout for markers and text
424 // Calculate layout for markers and text
377 if (mMarkers.count() <= 0) {
425 if (mMarkers.count() <= 0) {
378 // Nothing to do
426 // Nothing to do
379 return;
427 return;
380 }
428 }
429 checkMarkerBounds();
381
430
382 // Find out widest item.
431 // Find out widest item.
383 qreal itemMaxWidth = 0;
432 QSizeF markerMaxSize = maximumMarkerSize();
384 qreal itemMaxHeight = 0;
385 foreach (LegendMarker* m, mMarkers) {
386 if (m->boundingRect().width() > itemMaxWidth) {
387 itemMaxWidth = m->boundingRect().width();
388 }
389 if (m->boundingRect().height() > itemMaxHeight) {
390 itemMaxHeight = m->boundingRect().height();
391 }
392 }
393
433
394 int maxHorizontalItems = boundingRect().width() / itemMaxWidth;
434 // Use max height as scroll button size
395 int maxVerticalItems = boundingRect().height() / itemMaxHeight;
435 rescaleScrollButtons(QSize(markerMaxSize.height() ,markerMaxSize.height()));
396
436
397 if (mMarkers.count() > maxHorizontalItems * maxVerticalItems) {
398 // TODO: overlapping layout
399 //qDebug() << "Warning. Not enough space to layout all legend items properly.";
400 }
401
402 qreal margin = 5;
403 qreal totalWidth = 0;
437 qreal totalWidth = 0;
404 qreal totalHeight = 0;
438 qreal totalHeight = 0;
405 switch (mPreferredLayout)
439 switch (mPreferredLayout)
406 {
440 {
407 case QLegend::PreferredLayoutHorizontal: {
441 // Both cases organise items horizontally
408 /*
442 case QLegend::PreferredLayoutBottom:
409 qreal xStep = mMaximumSize.width() / (mMarkers.count()+1);
443 case QLegend::PreferredLayoutTop: {
410 if (xStep > itemMaxWidth) {
444
411 xStep = itemMaxWidth;
445 qreal xStep = markerMaxSize.width();
412 }
446 qreal x = mPos.x() + mMargin;
413 qreal yStep = mMaximumSize.height() / (mMarkers.count()+1);
447 qreal y = mPos.y() + mMargin;
414 if (yStep > itemMaxHeight) {
415 yStep = itemMaxHeight;
416 }*/
417 qreal xStep = itemMaxWidth;
418 qreal yStep = itemMaxHeight;
419 qreal x = mPos.x() + margin;
420 qreal y = mPos.y() + margin;
421 int row = 1;
422 int column = 0;
448 int column = 0;
423 int maxRows = 1;
424 int maxColumns = 1;
449 int maxColumns = 1;
425 foreach (LegendMarker* m, mMarkers) {
450 qreal scrollButtonPadding = 0;
426 maxRows = row;
451
427 m->setPos(x,y);
452 // Set correct visibility for scroll scrollbuttons
428 x += xStep;
453 if (scrollButtonsVisible()) {
429 column++;
454 mScrollButtonLeft->setVisible(true);
430 if (column > maxColumns) {
455 mScrollButtonRight->setVisible(true);
431 maxColumns = column;
456 totalWidth += (mScrollButtonLeft->boundingRect().width() + mMargin) * 2; // scrollbuttons visible, so add their width to total width
432 }
457 x += mScrollButtonLeft->boundingRect().width() + mMargin; // start position changes by scrollbutton width
433 if ((x + itemMaxWidth + margin*2) > (mPos.x() + mMaximumSize.width())) {
458 scrollButtonPadding = mScrollButtonLeft->boundingRect().width();
434 x = mPos.x() + margin;
459 } else {
435 y += yStep;
460 mScrollButtonLeft->setVisible(false);
436 row++;
461 mScrollButtonRight->setVisible(false);
437 column = 0;
462 }
463 mScrollButtonUp->setVisible(false);
464 mScrollButtonDown->setVisible(false);
465
466 for (int i=0; i<mMarkers.count(); i++) {
467 LegendMarker* m = mMarkers.at(i);
468 if (i<mFirstMarker) {
469 // Markers before first are not visible.
470 m->setVisible(false);
471 } else {
472 if ((x + xStep + scrollButtonPadding) > (mPos.x() + mMaximumSize.width())) {
473 // This marker would go outside legend rect.
474 m->setVisible(false);
475 } else {
476 // This marker is ok
477 m->setVisible(true);
478 m->setPos(x,y);
479 x += xStep;
480 column++;
481 }
438 }
482 }
483 maxColumns = column;
439 }
484 }
440 totalWidth = maxColumns * itemMaxWidth + margin * 2;
485
441 totalHeight = maxRows * itemMaxHeight + margin * 2;
486 mScrollButtonLeft->setPos(mPos.x() + mMargin, y);
487 mScrollButtonRight->setPos(x+mMargin,y);
488
489 totalWidth += maxColumns * markerMaxSize.width() + mMargin * 2;
490 totalHeight = markerMaxSize.height() + mMargin * 2;
491
442 break;
492 break;
443 }
493 }
444 case QLegend::PreferredLayoutVertical: {
494 // Both cases organize items vertically
445 /*
495 case QLegend::PreferredLayoutLeft:
446 qreal xStep = mMaximumSize.width() / (mMarkers.count()+1);
496 case QLegend::PreferredLayoutRight: {
447 if (xStep > itemMaxWidth) {
497 qreal yStep = markerMaxSize.height();
448 xStep = itemMaxWidth;
498 qreal x = mPos.x() + mMargin;
499 qreal y = mPos.y() + mMargin;
500 int row = 1;
501 int maxRows = 1;
502 qreal scrollButtonPadding = 0;
503
504 // Set correct visibility for scroll scrollbuttons
505 if (scrollButtonsVisible()) {
506 mScrollButtonUp->setVisible(true);
507 mScrollButtonDown->setVisible(true);
508 totalHeight += (mScrollButtonUp->boundingRect().height() + mMargin) * 2; // scrollbuttons visible, so add their height to total height
509 y += mScrollButtonUp->boundingRect().height() + mMargin; // start position changes by scrollbutton height
510 scrollButtonPadding = mScrollButtonUp->boundingRect().height();
511 } else {
512 mScrollButtonUp->setVisible(false);
513 mScrollButtonDown->setVisible(false);
449 }
514 }
450 qreal yStep = mMaximumSize.height() / (mMarkers.count()+1);
515 mScrollButtonLeft->setVisible(false);
451 if (yStep > itemMaxHeight) {
516 mScrollButtonRight->setVisible(false);
452 yStep = itemMaxHeight;
517
453 }*/
518 for (int i=0; i<mMarkers.count(); i++) {
454 qreal xStep = itemMaxWidth;
519 LegendMarker* m = mMarkers.at(i);
455 qreal yStep = itemMaxHeight;
520 if (i<mFirstMarker) {
456 qreal x = mPos.x() + margin;
521 // Markers before first are not visible.
457 qreal y = mPos.y() + margin;
522 m->setVisible(false);
523 } else {
524 if ((y + yStep + scrollButtonPadding) > (mPos.y() + mMaximumSize.height())) {
525 // This marker would go outside legend rect.
526 m->setVisible(false);
527 } else {
528 // This marker is ok
529 m->setVisible(true);
530 m->setPos(x,y);
531 y += yStep;
532 row++;
533 }
534 }
535 maxRows = row;
536 }
537
538 mScrollButtonUp->setPos(mPos.x() + mMargin, mPos.y() + mMargin);
539 mScrollButtonDown->setPos(mPos.x() + mMargin, y + mMargin);
540
541 totalWidth += markerMaxSize.width() + mMargin * 2;
542 totalHeight = maxRows * markerMaxSize.height() + mMargin * 4 + scrollButtonPadding; // TODO: check this
543
544 /*
545 qreal yStep = markerMaxSize.height();
546 qreal x = mPos.x() + mMargin;
547 qreal y = mPos.y() + mMargin;
458 int row = 0;
548 int row = 0;
459 int column = 1;
460 int maxRows = 1;
549 int maxRows = 1;
461 int maxColumns = 1;
550 int maxColumns = 1;
462 foreach (LegendMarker* m, mMarkers) {
551 for (int i=0; i<mMarkers.count(); i++) {
463 maxColumns = column;
552 LegendMarker* m = mMarkers.at(i);
464 m->setPos(x,y);
553 if (i<mFirstMarker) {
465 y += yStep;
554 // Markers before first are not visible.
466 row++;
555 m->setVisible(false);
467 if (row > maxRows) {
556 } else {
468 maxRows = row;
557 if ((y + markerMaxSize.height() + mMargin*2) > (mPos.y() + mMaximumSize.height())) {
469 }
558 // This marker would go outside legend rect.
470 if ((y + itemMaxHeight + margin*2) > (mPos.y() + mMaximumSize.height())) {
559 m->setVisible(false);
471 y = mPos.y() + margin;
560 } else {
472 x += xStep;
561 // This marker is ok
473 column++;
562 m->setVisible(true);
474 row = 0;
563 maxRows = row;
564 m->setPos(x,y);
565 y += yStep;
566 row++;
567 }
475 }
568 }
569 maxRows = row;
476 }
570 }
477 totalWidth = maxColumns * itemMaxWidth + margin * 2;
571 totalWidth = maxColumns * markerMaxSize.width() + mMargin * 2;
478 totalHeight = maxRows * itemMaxHeight + margin * 2;
572 totalHeight = maxRows * markerMaxSize.height() + mMargin * 2;
573 */
479 break;
574 break;
480 }
575 }
481 default: {
576 default: {
482 break;
577 break;
483 }
578 }
484 }
579 }
485
580
486 mSize.setWidth(totalWidth);
581 mSize.setWidth(totalWidth);
487 mSize.setHeight(totalHeight);
582 mSize.setHeight(totalHeight);
583
584 update();
585 }
586
587 void QLegend::rescaleScrollButtons(const QSize &size)
588 {
589 QPolygonF left;
590 left << QPointF(size.width(),0) << QPointF(0,size.height()/2) << QPointF(size.width(),size.height());
591 QPolygonF right;
592 right << QPointF(0,0) << QPointF(size.width(),size.height()/2) << QPointF(0,size.height());
593 QPolygonF up;
594 up << QPointF(0,size.height()) << QPointF(size.width()/2,0) << QPointF(size.width(),size.height());
595 QPolygonF down;
596 down << QPointF(0,0) << QPointF(size.width()/2,size.height()) << QPointF(size.width(),0);
597
598 mScrollButtonLeft->setPolygon(left);
599 mScrollButtonRight->setPolygon(right);
600 mScrollButtonUp->setPolygon(up);
601 mScrollButtonDown->setPolygon(down);
602 }
603
604 QSizeF QLegend::maximumMarkerSize()
605 {
606 QSizeF max(0,0);
607 foreach (LegendMarker* m, mMarkers) {
608 if (m->boundingRect().width() > max.width()) {
609 max.setWidth(m->boundingRect().width());
610 }
611 if (m->boundingRect().height() > max.height()) {
612 max.setHeight(m->boundingRect().height());
613 }
614 }
615 return max;
616 }
617
618 void QLegend::checkMarkerBounds()
619 {
620 if ((mPreferredLayout == QLegend::PreferredLayoutLeft) || (mPreferredLayout == QLegend::PreferredLayoutRight)) {
621 // Bounds limited by height
622 int max;
623 if (scrollButtonsVisible()) {
624 max = (mMaximumSize.height() - mScrollButtonLeft->boundingRect().height() * 2 - mMargin*2) / maximumMarkerSize().height();
625 } else {
626 max = mMaximumSize.height() / maximumMarkerSize().height();
627 }
628
629 if (mFirstMarker > mMarkers.count() - max) {
630 mFirstMarker = mMarkers.count() - max;
631 }
632 } else {
633 // Bounds limited by width
634 int max;
635 if (scrollButtonsVisible()) {
636 max = (mMaximumSize.width() - mScrollButtonLeft->boundingRect().width() * 2 - mMargin*2) / maximumMarkerSize().width();
637 } else {
638 max = mMaximumSize.width() / maximumMarkerSize().width();
639 }
640
641 if (mFirstMarker > mMarkers.count() - max) {
642 mFirstMarker = mMarkers.count() - max;
643 }
644 }
645
646 if (mFirstMarker < 0) {
647 mFirstMarker = 0;
648 }
649 }
650
651 bool QLegend::scrollButtonsVisible()
652 {
653 // Just a helper to clarify, what the magic below means :)
654 if ((mPreferredLayout == QLegend::PreferredLayoutTop) || (mPreferredLayout == QLegend::PreferredLayoutBottom)) {
655 return (maximumMarkerSize().width() * mMarkers.count() + mMargin * 3 > mMaximumSize.width());
656 }
657 return (maximumMarkerSize().height() * mMarkers.count() + mMargin * 3 > mMaximumSize.height());
488 }
658 }
489
659
490 #include "moc_qlegend.cpp"
660 #include "moc_qlegend.cpp"
491 QTCOMMERCIALCHART_END_NAMESPACE
661 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,86 +1,106
1 #ifndef QLEGEND_H
1 #ifndef QLEGEND_H
2 #define QLEGEND_H
2 #define QLEGEND_H
3
3
4 #include <qchartglobal.h>
4 #include <qchartglobal.h>
5 #include <qseries.h>
5 #include <qseries.h>
6 #include <QGraphicsObject>
6 #include <QGraphicsObject>
7
7
8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9
9
10 class Domain;
10 class Domain;
11 class LegendMarker;
11 class LegendMarker;
12 class QPieSlice;
12 class QPieSlice;
13 class QXYSeries;
13 class QXYSeries;
14 class QBarSet;
14 class QBarSet;
15 class QBarSeries;
15 class QBarSeries;
16 class QPieSeries;
16 class QPieSeries;
17 class LegendScrollButton;
17
18
18 class QTCOMMERCIALCHART_EXPORT QLegend : public QGraphicsObject
19 class QTCOMMERCIALCHART_EXPORT QLegend : public QGraphicsObject
19 {
20 {
20 Q_OBJECT
21 Q_OBJECT
21 public:
22 public:
22
23
23 enum PreferredLayout {
24 enum PreferredLayout {
24 PreferredLayoutHorizontal,
25 PreferredLayoutTop,
25 PreferredLayoutVertical
26 PreferredLayoutBottom,
27 PreferredLayoutLeft,
28 PreferredLayoutRight,
26 };
29 };
27
30
28 explicit QLegend(QGraphicsItem *parent = 0);
31 explicit QLegend(QGraphicsItem *parent = 0);
29
32
30 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
33 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
31 QRectF boundingRect() const;
34 QRectF boundingRect() const;
32
35
33 void setBrush(const QBrush& brush);
36 void setBrush(const QBrush& brush);
34 QBrush brush() const;
37 QBrush brush() const;
35
38
36 void setPen(const QPen& pen);
39 void setPen(const QPen& pen);
37 QPen pen() const;
40 QPen pen() const;
38
41
39 void setPreferredLayout(QLegend::PreferredLayout preferred);
42 void setPreferredLayout(QLegend::PreferredLayout preferred);
43 QLegend::PreferredLayout preferredLayout() const;
40
44
41 QSizeF maximumSize() const;
45 QSizeF maximumSize() const;
42 void setMaximumSize(const QSizeF size);
46 void setMaximumSize(const QSizeF size);
43
47
44 void setSize(const QSizeF size);
48 void setSize(const QSizeF size);
45 void setPos(const QPointF &pos);
49 void setPos(const QPointF &pos);
46
50
47 signals:
51 signals:
48 // for interactions.
52 // for interactions.
49 void clicked(QSeries* series, Qt::MouseButton button);
53 void clicked(QSeries* series, Qt::MouseButton button);
50 void clicked(QBarSet* barset, Qt::MouseButton button);
54 void clicked(QBarSet* barset, Qt::MouseButton button);
51 void clicked(QPieSlice* slice, Qt::MouseButton button);
55 void clicked(QPieSlice* slice, Qt::MouseButton button);
52
56
53 public slots:
57 public slots:
54 void handleSeriesAdded(QSeries* series,Domain* domain);
58 void handleSeriesAdded(QSeries* series,Domain* domain);
55 void handleSeriesRemoved(QSeries* series);
59 void handleSeriesRemoved(QSeries* series);
56 void handleAdded(QList<QPieSlice*> slices);
60 void handleAdded(QList<QPieSlice*> slices);
57 void handleRemoved(QList<QPieSlice*> slices);
61 void handleRemoved(QList<QPieSlice*> slices);
58 void handleMarkerDestroyed();
62 void handleMarkerDestroyed();
63 void handleScrollButtonClicked(QGraphicsSceneMouseEvent* event);
59
64
60 private:
65 private:
61 // PIMPL --->
66 // PIMPL --->
62 void connectSeries(QSeries* series);
67 void connectSeries(QSeries* series);
63 void disconnectSeries(QSeries* series);
68 void disconnectSeries(QSeries* series);
64 void createMarkers(QSeries* series);
69 void createMarkers(QSeries* series);
65 void appendMarkers(QXYSeries* series); // All line series are derived from QXYSeries, so this works for now
70 void appendMarkers(QXYSeries* series); // All line series are derived from QXYSeries, so this works for now
66 void appendMarkers(QBarSeries* series);
71 void appendMarkers(QBarSeries* series);
67 void appendMarkers(QPieSeries* series);
72 void appendMarkers(QPieSeries* series);
68 void deleteMarkers(QSeries* series);
73 void deleteMarkers(QSeries* series);
69 void layoutChanged();
74 // void layoutChanged(); // This tries to fit all items to legend
70 // <--- PIMPL
75 void updateLayout(); // New version of layout. Fits items only to row or column and adds scrollbars.
76 void rescaleScrollButtons(const QSize& size);
77 QSizeF maximumMarkerSize();
78 void checkMarkerBounds();
79 bool scrollButtonsVisible();
80 // void updateScrollButtonsLayout();
71
81
72 QPointF mPos;
82 QPointF mPos;
73 QSizeF mSize;
83 QSizeF mSize;
74 QSizeF mMinimumSize;
84 QSizeF mMinimumSize;
75 QSizeF mMaximumSize;
85 QSizeF mMaximumSize;
76
86
77 QList<LegendMarker*> mMarkers;
87 QList<LegendMarker*> mMarkers;
78
88
79 QBrush m_brush;
89 QBrush m_brush;
80 QPen m_pen;
90 QPen m_pen;
81 QLegend::PreferredLayout mPreferredLayout;
91 QLegend::PreferredLayout mPreferredLayout;
92
93 int mFirstMarker;
94
95 LegendScrollButton* mScrollButtonLeft;
96 LegendScrollButton* mScrollButtonRight;
97 LegendScrollButton* mScrollButtonUp;
98 LegendScrollButton* mScrollButtonDown;
99
100 qreal mMargin;
101 // <--- PIMPL
82 };
102 };
83
103
84 QTCOMMERCIALCHART_END_NAMESPACE
104 QTCOMMERCIALCHART_END_NAMESPACE
85
105
86 #endif // QLEGEND_H
106 #endif // QLEGEND_H
@@ -1,156 +1,158
1 !include( ../common.pri ):error( Couldn't find the common.pri file! )
1 !include( ../common.pri ):error( Couldn't find the common.pri file! )
2 TARGET = QtCommercialChart
2 TARGET = QtCommercialChart
3 DESTDIR = $$CHART_BUILD_LIB_DIR
3 DESTDIR = $$CHART_BUILD_LIB_DIR
4 TEMPLATE = lib
4 TEMPLATE = lib
5 QT += core \
5 QT += core \
6 gui
6 gui
7 win32-msvc*: LIBS += User32.lib
7 win32-msvc*: LIBS += User32.lib
8 CONFIG += debug_and_release
8 CONFIG += debug_and_release
9 CONFIG(debug, debug|release):TARGET = QtCommercialChartd
9 CONFIG(debug, debug|release):TARGET = QtCommercialChartd
10 SOURCES += \
10 SOURCES += \
11 $$PWD/chartdataset.cpp \
11 $$PWD/chartdataset.cpp \
12 $$PWD/chartpresenter.cpp \
12 $$PWD/chartpresenter.cpp \
13 $$PWD/charttheme.cpp \
13 $$PWD/charttheme.cpp \
14 $$PWD/domain.cpp \
14 $$PWD/domain.cpp \
15 $$PWD/qchart.cpp \
15 $$PWD/qchart.cpp \
16 $$PWD/qchartview.cpp \
16 $$PWD/qchartview.cpp \
17 $$PWD/qseries.cpp \
17 $$PWD/qseries.cpp \
18 $$PWD/qlegend.cpp \
18 $$PWD/qlegend.cpp \
19 $$PWD/legendmarker.cpp \
19 $$PWD/legendmarker.cpp \
20 $$PWD/legendscrollbutton.cpp \
20 $$PWD/chartbackground.cpp \
21 $$PWD/chartbackground.cpp \
21 $$PWD/chart.cpp
22 $$PWD/chart.cpp
22 PRIVATE_HEADERS += \
23 PRIVATE_HEADERS += \
23 $$PWD/chartdataset_p.h \
24 $$PWD/chartdataset_p.h \
24 $$PWD/chartitem_p.h \
25 $$PWD/chartitem_p.h \
25 $$PWD/chartpresenter_p.h \
26 $$PWD/chartpresenter_p.h \
26 $$PWD/charttheme_p.h \
27 $$PWD/charttheme_p.h \
27 $$PWD/domain_p.h \
28 $$PWD/domain_p.h \
28 $$PWD/legendmarker_p.h \
29 $$PWD/legendmarker_p.h \
30 $$PWD/legendscrollbutton_p.h \
29 $$PWD/chartbackground_p.h \
31 $$PWD/chartbackground_p.h \
30 $$PWD/chart_p.h
32 $$PWD/chart_p.h
31 PUBLIC_HEADERS += \
33 PUBLIC_HEADERS += \
32 $$PWD/qchart.h \
34 $$PWD/qchart.h \
33 $$PWD/qchartglobal.h \
35 $$PWD/qchartglobal.h \
34 $$PWD/qseries.h \
36 $$PWD/qseries.h \
35 $$PWD/qchartview.h \
37 $$PWD/qchartview.h \
36 $$PWD/qlegend.h
38 $$PWD/qlegend.h
37
39
38 include(animations/animations.pri)
40 include(animations/animations.pri)
39 include(axis/axis.pri)
41 include(axis/axis.pri)
40 include(xychart/xychart.pri)
42 include(xychart/xychart.pri)
41 include(linechart/linechart.pri)
43 include(linechart/linechart.pri)
42 include(areachart/areachart.pri)
44 include(areachart/areachart.pri)
43 include(barchart/barchart.pri)
45 include(barchart/barchart.pri)
44 include(piechart/piechart.pri)
46 include(piechart/piechart.pri)
45 include(scatterseries/scatter.pri)
47 include(scatterseries/scatter.pri)
46 include(splinechart/splinechart.pri)
48 include(splinechart/splinechart.pri)
47 include(themes/themes.pri)
49 include(themes/themes.pri)
48
50
49
51
50 HEADERS += $$PUBLIC_HEADERS
52 HEADERS += $$PUBLIC_HEADERS
51 HEADERS += $$PRIVATE_HEADERS
53 HEADERS += $$PRIVATE_HEADERS
52 HEADERS += $$THEMES
54 HEADERS += $$THEMES
53 INCLUDEPATH += linechart \
55 INCLUDEPATH += linechart \
54 barchart \
56 barchart \
55 themes \
57 themes \
56 .
58 .
57 OBJECTS_DIR = $$CHART_BUILD_DIR/lib
59 OBJECTS_DIR = $$CHART_BUILD_DIR/lib
58 MOC_DIR = $$CHART_BUILD_DIR/lib
60 MOC_DIR = $$CHART_BUILD_DIR/lib
59 UI_DIR = $$CHART_BUILD_DIR/lib
61 UI_DIR = $$CHART_BUILD_DIR/lib
60 RCC_DIR = $$CHART_BUILD_DIR/lib
62 RCC_DIR = $$CHART_BUILD_DIR/lib
61 DEFINES += QTCOMMERCIALCHART_LIBRARY
63 DEFINES += QTCOMMERCIALCHART_LIBRARY
62
64
63 #qt public headers
65 #qt public headers
64 #this is very primitive and lame parser , TODO: make perl script insted
66 #this is very primitive and lame parser , TODO: make perl script insted
65 !exists($$CHART_BUILD_PUBLIC_HEADER_DIR/QChartGlobal)
67 !exists($$CHART_BUILD_PUBLIC_HEADER_DIR/QChartGlobal)
66 {
68 {
67 system($$QMAKE_MKDIR $$CHART_BUILD_PUBLIC_HEADER_DIR)
69 system($$QMAKE_MKDIR $$CHART_BUILD_PUBLIC_HEADER_DIR)
68 win32:{
70 win32:{
69 command = "echo $${LITERAL_HASH}include \"qchartglobal.h\" > $$CHART_BUILD_PUBLIC_HEADER_DIR/QChartGlobal"
71 command = "echo $${LITERAL_HASH}include \"qchartglobal.h\" > $$CHART_BUILD_PUBLIC_HEADER_DIR/QChartGlobal"
70 }else{
72 }else{
71 command = "echo \"$${LITERAL_HASH}include \\\"qchartglobal.h\\\"\" > $$CHART_BUILD_PUBLIC_HEADER_DIR/QChartGlobal"
73 command = "echo \"$${LITERAL_HASH}include \\\"qchartglobal.h\\\"\" > $$CHART_BUILD_PUBLIC_HEADER_DIR/QChartGlobal"
72 }
74 }
73 system($$command)
75 system($$command)
74 }
76 }
75
77
76 for(file, PUBLIC_HEADERS) {
78 for(file, PUBLIC_HEADERS) {
77 name = $$split(file,'/')
79 name = $$split(file,'/')
78 name = $$last(name)
80 name = $$last(name)
79 class = "$$cat($$file)"
81 class = "$$cat($$file)"
80 class = $$find(class,class)
82 class = $$find(class,class)
81 !isEmpty(class){
83 !isEmpty(class){
82 class = $$split(class,QTCOMMERCIALCHART_EXPORT)
84 class = $$split(class,QTCOMMERCIALCHART_EXPORT)
83 class = $$member(class,1)
85 class = $$member(class,1)
84 class = $$split(class,' ')
86 class = $$split(class,' ')
85 class = $$replace(class,' ','')
87 class = $$replace(class,' ','')
86 class = $$member(class,0)
88 class = $$member(class,0)
87 win32:{
89 win32:{
88 command = "echo $${LITERAL_HASH}include \"$$name\" > $$CHART_BUILD_PUBLIC_HEADER_DIR/$$class"
90 command = "echo $${LITERAL_HASH}include \"$$name\" > $$CHART_BUILD_PUBLIC_HEADER_DIR/$$class"
89 }else{
91 }else{
90 command = "echo \"$${LITERAL_HASH}include \\\"$$name\\\"\" > $$CHART_BUILD_PUBLIC_HEADER_DIR/$$class"
92 command = "echo \"$${LITERAL_HASH}include \\\"$$name\\\"\" > $$CHART_BUILD_PUBLIC_HEADER_DIR/$$class"
91 }
93 }
92 PUBLIC_QT_HEADERS += $$CHART_BUILD_PUBLIC_HEADER_DIR/$$class
94 PUBLIC_QT_HEADERS += $$CHART_BUILD_PUBLIC_HEADER_DIR/$$class
93 system($$command)
95 system($$command)
94 }
96 }
95 }
97 }
96
98
97 public_headers.path = $$[QT_INSTALL_HEADERS]/QtCommercialChart
99 public_headers.path = $$[QT_INSTALL_HEADERS]/QtCommercialChart
98 public_headers.files = $$PUBLIC_HEADERS $$PUBLIC_QT_HEADERS
100 public_headers.files = $$PUBLIC_HEADERS $$PUBLIC_QT_HEADERS
99
101
100 target.path = $$[QT_INSTALL_LIBS]
102 target.path = $$[QT_INSTALL_LIBS]
101 INSTALLS += target public_headers
103 INSTALLS += target public_headers
102
104
103 install_build_public_headers.name = build_public_headers
105 install_build_public_headers.name = build_public_headers
104 install_build_public_headers.output = $$CHART_BUILD_PUBLIC_HEADER_DIR/${QMAKE_FILE_BASE}.h
106 install_build_public_headers.output = $$CHART_BUILD_PUBLIC_HEADER_DIR/${QMAKE_FILE_BASE}.h
105 install_build_public_headers.input = PUBLIC_HEADERS
107 install_build_public_headers.input = PUBLIC_HEADERS
106 install_build_public_headers.commands = $$QMAKE_COPY \
108 install_build_public_headers.commands = $$QMAKE_COPY \
107 ${QMAKE_FILE_NAME} \
109 ${QMAKE_FILE_NAME} \
108 $$CHART_BUILD_PUBLIC_HEADER_DIR
110 $$CHART_BUILD_PUBLIC_HEADER_DIR
109 install_build_public_headers.CONFIG += target_predeps \
111 install_build_public_headers.CONFIG += target_predeps \
110 no_link
112 no_link
111
113
112 install_build_private_headers.name = buld_private_headers
114 install_build_private_headers.name = buld_private_headers
113 install_build_private_headers.output = $$CHART_BUILD_PRIVATE_HEADER_DIR/${QMAKE_FILE_BASE}.h
115 install_build_private_headers.output = $$CHART_BUILD_PRIVATE_HEADER_DIR/${QMAKE_FILE_BASE}.h
114 install_build_private_headers.input = PRIVATE_HEADERS
116 install_build_private_headers.input = PRIVATE_HEADERS
115 install_build_private_headers.commands = $$QMAKE_COPY \
117 install_build_private_headers.commands = $$QMAKE_COPY \
116 ${QMAKE_FILE_NAME} \
118 ${QMAKE_FILE_NAME} \
117 $$CHART_BUILD_PRIVATE_HEADER_DIR
119 $$CHART_BUILD_PRIVATE_HEADER_DIR
118 install_build_private_headers.CONFIG += target_predeps \
120 install_build_private_headers.CONFIG += target_predeps \
119 no_link
121 no_link
120
122
121 QMAKE_EXTRA_COMPILERS += install_build_public_headers \
123 QMAKE_EXTRA_COMPILERS += install_build_public_headers \
122 install_build_private_headers \
124 install_build_private_headers \
123
125
124
126
125 chartversion.target = qchartversion_p.h
127 chartversion.target = qchartversion_p.h
126 unix:{
128 unix:{
127 chartversion.commands = @echo \
129 chartversion.commands = @echo \
128 "const char *buildTime = \\\"`date +'%y%m%d%H%M'`\\\" \\; \
130 "const char *buildTime = \\\"`date +'%y%m%d%H%M'`\\\" \\; \
129 const char *gitHead = \\\"`git rev-parse HEAD`\\\" \\; " \
131 const char *gitHead = \\\"`git rev-parse HEAD`\\\" \\; " \
130 > \
132 > \
131 $$chartversion.target;
133 $$chartversion.target;
132 }else{
134 }else{
133 chartversion.commands = @echo \
135 chartversion.commands = @echo \
134 "const char *buildTime = \"%date%_%time%\" ; \
136 "const char *buildTime = \"%date%_%time%\" ; \
135 const char *gitHead = \"unknown\" ; " \
137 const char *gitHead = \"unknown\" ; " \
136 > \
138 > \
137 $$chartversion.target
139 $$chartversion.target
138 }
140 }
139 chartversion.depends = $$HEADERS \
141 chartversion.depends = $$HEADERS \
140 $$SOURCES
142 $$SOURCES
141 PRE_TARGETDEPS += qchartversion_p.h
143 PRE_TARGETDEPS += qchartversion_p.h
142 QMAKE_CLEAN += qchartversion_p.h
144 QMAKE_CLEAN += qchartversion_p.h
143 QMAKE_EXTRA_TARGETS += chartversion
145 QMAKE_EXTRA_TARGETS += chartversion
144 unix:QMAKE_DISTCLEAN += -r \
146 unix:QMAKE_DISTCLEAN += -r \
145 $$CHART_BUILD_HEADER_DIR \
147 $$CHART_BUILD_HEADER_DIR \
146 $$CHART_BUILD_LIB_DIR
148 $$CHART_BUILD_LIB_DIR
147 win32:QMAKE_DISTCLEAN += /Q \
149 win32:QMAKE_DISTCLEAN += /Q \
148 $$CHART_BUILD_HEADER_DIR \
150 $$CHART_BUILD_HEADER_DIR \
149 $$CHART_BUILD_LIB_DIR
151 $$CHART_BUILD_LIB_DIR
150
152
151 # treat warnings as errors
153 # treat warnings as errors
152 win32-msvc*: {
154 win32-msvc*: {
153 QMAKE_CXXFLAGS += /WX
155 QMAKE_CXXFLAGS += /WX
154 } else {
156 } else {
155 QMAKE_CXXFLAGS += -Werror
157 QMAKE_CXXFLAGS += -Werror
156 }
158 }
General Comments 0
You need to be logged in to leave comments. Login now