##// END OF EJS Templates
legend example to documentation. minor legend fixes
sauimone -
r1300:6bd3a3b0fd91
parent child
Show More
@@ -0,0 +1,29
1 /*!
2 \example examples/legend
3 \title Legend Example
4 \subtitle
5
6 This example shows how to detach legend from chart and how to attach it back. By default the chart
7 draws the legend inside same view with the chart. In some cases user may want to draw legend to somewhere else. To make this possible the legend can be detached from the chart. Detaching means that chart doesn't draw the legend or try to change it's layout. Detached can then be drawn where user wants, for example in different graphics scene. In this example we do so.
8
9 First we create our chart as usual.
10
11 \snippet ../examples/legend/mainwidget.cpp 1
12
13 Here we create custom graphics scene, where we want to draw the detached legend.
14
15 \snippet ../examples/legend/mainwidget.cpp 2
16
17 Add some series to the chart.
18
19 \snippet ../examples/legend/mainwidget.cpp 3
20
21 Here we detach the legend. After detaching, we set new geometry for it and add it to the custom scene. The custom scene adopts the legend and becomes new parent for it. Note that chart will still update the contents of the legend.
22
23 \snippet ../examples/legend/mainwidget.cpp 4
24
25 To attach legend back to chart we first remove it from the custom scene. Then we add legend to the scene, where chart is. Last we attach legend to chart. Attaching legend to chart automatically sets the QChart as parent for legend.
26
27 \snippet ../examples/legend/mainwidget.cpp 5
28
29 */
@@ -1,37 +1,38
1 /*!
1 /*!
2 \page examples.html
2 \page examples.html
3 \title Examples
3 \title Examples
4 \keyword Examples
4 \keyword Examples
5
5
6 \raw HTML
6 \raw HTML
7 <table cellpadding="2" cellspacing="1" border="0" width="100%" class="indextable">
7 <table cellpadding="2" cellspacing="1" border="0" width="100%" class="indextable">
8 <tr>
8 <tr>
9 <th class="titleheader" width="33%">
9 <th class="titleheader" width="33%">
10 List of examples
10 List of examples
11 </th>
11 </th>
12 </tr>
12 </tr>
13 <tr>
13 <tr>
14 <td valign="top">
14 <td valign="top">
15 <ul>
15 <ul>
16 <li><a href="examples-areachart.html">Area chart</a></li>
16 <li><a href="examples-areachart.html">Area chart</a></li>
17 <li><a href="examples-barchart.html">Bar chart</a></li>
17 <li><a href="examples-barchart.html">Bar chart</a></li>
18 <li><a href="examples-customchart.html">Custom chart</a></li>
18 <li><a href="examples-customchart.html">Custom chart</a></li>
19 <li><a href="examples-groupedbarchart.html">Grouped bar chart</a></li>
19 <li><a href="examples-groupedbarchart.html">Grouped bar chart</a></li>
20 <li><a href="examples-legend.html">Legend</a></li>
20 <li><a href="examples-linechart.html">Line chart</a></li>
21 <li><a href="examples-linechart.html">Line chart</a></li>
21 <li><a href="examples-modeldata.html">Model data</a></li>
22 <li><a href="examples-modeldata.html">Model data</a></li>
22 <li><a href="examples-percentbarchart.html">Percent bar chart</a></li>
23 <li><a href="examples-percentbarchart.html">Percent bar chart</a></li>
23 <li><a href="examples-piechart.html">Pie chart</a></li>
24 <li><a href="examples-piechart.html">Pie chart</a></li>
24 <li><a href="examples-piechartdrilldown.html">Pie chart drilldown</a></li>
25 <li><a href="examples-piechartdrilldown.html">Pie chart drilldown</a></li>
25 <li><a href="examples-presenterchart.html">Presenter chart</a></li>
26 <li><a href="examples-presenterchart.html">Presenter chart</a></li>
26 <li><a href="examples-scatterchart.html">Scatter chart</a></li>
27 <li><a href="examples-scatterchart.html">Scatter chart</a></li>
27 <li><a href="examples-scatterinteractions.html">Scatter interactions</a></li>
28 <li><a href="examples-scatterinteractions.html">Scatter interactions</a></li>
28 <li><a href="examples-splinechart.html">Spline chart</a></li>
29 <li><a href="examples-splinechart.html">Spline chart</a></li>
29 <li><a href="examples-stackedbarchart.html">Stacked bar chart</a></li>
30 <li><a href="examples-stackedbarchart.html">Stacked bar chart</a></li>
30 <li><a href="examples-stackedbarchartdrilldown.html">Stacked bar chart drilldown</a></li>
31 <li><a href="examples-stackedbarchartdrilldown.html">Stacked bar chart drilldown</a></li>
31 <li><a href="examples-zoomlinechart.html">Zoom line</a></li>
32 <li><a href="examples-zoomlinechart.html">Zoom line</a></li>
32 </ul>
33 </ul>
33 </td>
34 </td>
34 </tr>
35 </tr>
35 </table>
36 </table>
36 \endraw
37 \endraw
37 */
38 */
@@ -1,131 +1,129
1 #include "mainwidget.h"
1 #include "mainwidget.h"
2 #include <QChart>
2 #include <QChart>
3 #include <QChartView>
3 #include <QChartView>
4 #include <QPushButton>
4 #include <QPushButton>
5 #include <QLabel>
5 #include <QLabel>
6 #include <QDebug>
6 #include <QDebug>
7 #include <QBarSet>
7 #include <QBarSet>
8 #include <QBarSeries>
8 #include <QBarSeries>
9 #include <QLegend>
9 #include <QLegend>
10
10
11 QTCOMMERCIALCHART_USE_NAMESPACE
11 QTCOMMERCIALCHART_USE_NAMESPACE
12
12
13 MainWidget::MainWidget(QWidget *parent) :
13 MainWidget::MainWidget(QWidget *parent) :
14 QWidget(parent)
14 QWidget(parent)
15 {
15 {
16 m_setCount = 0;
16 // Create buttons for ui
17 m_chart = new QChart();
18
19 //![1]
20 m_buttonLayout = new QGridLayout();
17 m_buttonLayout = new QGridLayout();
21 QPushButton *detachLegendButton = new QPushButton("detach legend");
18 QPushButton *detachLegendButton = new QPushButton("detach legend");
22 connect(detachLegendButton, SIGNAL(clicked()), this, SLOT(detachLegend()));
19 connect(detachLegendButton, SIGNAL(clicked()), this, SLOT(detachLegend()));
23 m_buttonLayout->addWidget(detachLegendButton, 0, 0);
20 m_buttonLayout->addWidget(detachLegendButton, 0, 0);
24 QPushButton *attachLegendButton = new QPushButton("attach legend");
21 QPushButton *attachLegendButton = new QPushButton("attach legend");
25 connect(attachLegendButton, SIGNAL(clicked()), this, SLOT(attachLegend()));
22 connect(attachLegendButton, SIGNAL(clicked()), this, SLOT(attachLegend()));
26 m_buttonLayout->addWidget(attachLegendButton, 1, 0);
23 m_buttonLayout->addWidget(attachLegendButton, 1, 0);
27
24
28 QPushButton *addSetButton = new QPushButton("add barset");
25 QPushButton *addSetButton = new QPushButton("add barset");
29 connect(addSetButton, SIGNAL(clicked()), this, SLOT(addBarset()));
26 connect(addSetButton, SIGNAL(clicked()), this, SLOT(addBarset()));
30 m_buttonLayout->addWidget(addSetButton, 2, 0);
27 m_buttonLayout->addWidget(addSetButton, 2, 0);
31 QPushButton *removeBarsetButton = new QPushButton("remove barset");
28 QPushButton *removeBarsetButton = new QPushButton("remove barset");
32 connect(removeBarsetButton, SIGNAL(clicked()), this, SLOT(removeBarset()));
29 connect(removeBarsetButton, SIGNAL(clicked()), this, SLOT(removeBarset()));
33 m_buttonLayout->addWidget(removeBarsetButton, 3, 0);
30 m_buttonLayout->addWidget(removeBarsetButton, 3, 0);
34 //![1]
35
31
36 // Create chart view with the chart
32 // Create chart view with the chart
33 //![1]
34 m_chart = new QChart();
37 m_chartView = new QChartView(m_chart, this);
35 m_chartView = new QChartView(m_chart, this);
38 m_chartView->setRubberBand(QChartView::HorizonalRubberBand);
36 m_chartView->setRubberBand(QChartView::HorizonalRubberBand);
37 //![1]
39
38
39 // Create custom scene and view, where detached legend will be drawn
40 //![2]
40 //![2]
41 m_customView = new QGraphicsView(this);
41 m_customView = new QGraphicsView(this);
42 m_customScene = new QGraphicsScene(this);
42 m_customScene = new QGraphicsScene(this);
43 m_customView->setScene(m_customScene);
43 m_customView->setScene(m_customScene);
44 //![2]
44 //![2]
45
45
46 // Create layout for grid and detached legend
46 // Create layout for grid and detached legend
47 m_mainLayout = new QGridLayout();
47 m_mainLayout = new QGridLayout();
48 m_mainLayout->addLayout(m_buttonLayout, 0, 0);
48 m_mainLayout->addLayout(m_buttonLayout, 0, 0);
49 m_mainLayout->addWidget(m_chartView, 0, 1, 3, 1);
49 m_mainLayout->addWidget(m_chartView, 0, 1, 3, 1);
50 m_mainLayout->addWidget(m_customView, 0, 2, 3, 1);
50 m_mainLayout->addWidget(m_customView, 0, 2, 3, 1);
51 setLayout(m_mainLayout);
51 setLayout(m_mainLayout);
52
52
53 createSeries();
53 createSeries();
54 }
54 }
55
55
56 void MainWidget::createSeries()
56 void MainWidget::createSeries()
57 {
57 {
58 //![3]
58 m_series = new QBarSeries();
59 m_series = new QBarSeries();
59 addBarset();
60 addBarset();
60 addBarset();
61 addBarset();
61 addBarset();
62 addBarset();
62 addBarset();
63 addBarset();
63
64
64 m_chart->addSeries(m_series);
65 m_chart->addSeries(m_series);
65 m_chart->setTitle("Legend detach example");
66 m_chart->setTitle("Legend detach example");
66
67
67 m_chart->legend()->setVisible(true);
68 m_chart->legend()->setVisible(true);
68 m_chart->legend()->setAlignment(QLegend::AlignmentBottom);
69 m_chart->legend()->setAlignment(QLegend::AlignmentBottom);
69 m_chart->axisY()->setNiceNumbersEnabled(true);
70 m_chart->axisY()->setNiceNumbersEnabled(true);
70
71
71 m_chartView->setRenderHint(QPainter::Antialiasing);
72 m_chartView->setRenderHint(QPainter::Antialiasing);
73 //![3]
72 }
74 }
73
75
74 void MainWidget::detachLegend()
76 void MainWidget::detachLegend()
75 {
77 {
76 //![3]
78 // Detach legend from chart and
77 // Detach legend from chart
79 // put legend to our custom scene
80 //![4]
78 QLegend *legend = m_chart->legend();
81 QLegend *legend = m_chart->legend();
79 legend->detachFromChart();
82 legend->detachFromChart();
80 legend->setGeometry(m_customView->rect());
83 legend->setGeometry(m_customView->rect());
81 // legend->setAlignment(QLegend::AlignmentLeft);
82
83 // Put legend to our custom scene
84 m_customScene->addItem(legend);
84 m_customScene->addItem(legend);
85 //![3]
85 //![4]
86
86
87 // This causes redraw
87 // This forces redraw
88 QSize size(1,1);
88 QSize delta(1,1);
89 this->resize(this->size() + size);
89 resize(size() + delta);
90 this->resize(this->size() - size);
90 resize(size() - delta);
91 }
91 }
92
92
93
93
94 void MainWidget::attachLegend()
94 void MainWidget::attachLegend()
95 {
95 {
96 //![4]
96 // Remove legend from custom scene and put it back to chartview scene.
97 // Attach legend back to chart, so that layout works.
98
99 //![5]
97 QLegend *legend = m_chart->legend();
100 QLegend *legend = m_chart->legend();
98
101
99 if (m_customScene->items().contains(legend)) {
102 if (m_customScene->items().contains(legend)) {
100 // Remove legend from custom scene and put it back to chartview scene.
101 // Attach legend back to chart, so that layout works.
102 m_customScene->removeItem(legend);
103 m_customScene->removeItem(legend);
103 legend->setParent(m_chart);
104 m_chartView->scene()->addItem(legend);
104 m_chartView->scene()->addItem(legend);
105 // legend->setAlignment(QLegend::AlignmentBottom);
106 legend->attachToChart();
105 legend->attachToChart();
107 }
106 }
108 //![4]
107 //![5]
109
108
110 // This causes redraw
109 // This forces redraw
111 QSize size(1,1);
110 QSize delta(1,1);
112 this->resize(this->size() + size);
111 resize(size() + delta);
113 this->resize(this->size() - size);
112 resize(size() - delta);
114 }
113 }
115
114
116 void MainWidget::addBarset()
115 void MainWidget::addBarset()
117 {
116 {
118 QBarSet *barSet = new QBarSet(QString("set ") + QString::number(m_setCount));
117 QBarSet *barSet = new QBarSet(QString("set ") + QString::number(m_series->barsetCount()));
119 m_setCount++;
120 qreal delta = m_series->barsetCount() * 0.1;
118 qreal delta = m_series->barsetCount() * 0.1;
121 *barSet << QPointF(0.0 + delta, 1 + delta) << QPointF(1.0 + delta, 2 + delta) << QPointF(2.0 + delta, 3 + delta) << QPointF(3.0 + delta, 4 + delta);
119 *barSet << QPointF(0.0 + delta, 1 + delta) << QPointF(1.0 + delta, 2 + delta) << QPointF(2.0 + delta, 3 + delta) << QPointF(3.0 + delta, 4 + delta);
122 m_series->append(barSet);
120 m_series->append(barSet);
123 }
121 }
124
122
125 void MainWidget::removeBarset()
123 void MainWidget::removeBarset()
126 {
124 {
127 QList<QBarSet*> sets = m_series->barSets();
125 QList<QBarSet*> sets = m_series->barSets();
128 if (sets.count() > 0) {
126 if (sets.count() > 0) {
129 m_series->remove(sets.at(sets.count()-1));
127 m_series->remove(sets.at(sets.count()-1));
130 }
128 }
131 }
129 }
@@ -1,49 +1,44
1 #ifndef MAINWIDGET_H
1 #ifndef MAINWIDGET_H
2 #define MAINWIDGET_H
2 #define MAINWIDGET_H
3
3
4 #include "qchartglobal.h"
4 #include "qchartglobal.h"
5 #include "qchart.h"
5 #include "qchart.h"
6 #include "qchartview.h"
6 #include "qchartview.h"
7 #include <QWidget>
7 #include <QWidget>
8 #include <QGraphicsWidget>
8 #include <QGraphicsWidget>
9 #include <QGridLayout>
9 #include <QGridLayout>
10 #include <QGraphicsGridLayout>
10 #include <QGraphicsGridLayout>
11
11
12 QTCOMMERCIALCHART_USE_NAMESPACE
12 QTCOMMERCIALCHART_USE_NAMESPACE
13
13
14 class MainWidget : public QWidget
14 class MainWidget : public QWidget
15 //class MainWidget : public QGraphicsWidget
15 //class MainWidget : public QGraphicsWidget
16 {
16 {
17 Q_OBJECT
17 Q_OBJECT
18 public:
18 public:
19 explicit MainWidget(QWidget *parent = 0);
19 explicit MainWidget(QWidget *parent = 0);
20
20
21 void createSeries();
21 void createSeries();
22
22
23 signals:
23 signals:
24
24
25 public slots:
25 public slots:
26 void detachLegend();
26 void detachLegend();
27 void attachLegend();
27 void attachLegend();
28 void addBarset();
28 void addBarset();
29 void removeBarset();
29 void removeBarset();
30
30
31 private:
31 private:
32
32
33 QChart *m_chart;
33 QChart *m_chart;
34 QBarSeries *m_series;
34 QBarSeries *m_series;
35
35
36 QGraphicsScene *m_scene;
37 QChartView *m_chartView;
36 QChartView *m_chartView;
38 QGridLayout *m_mainLayout;
37 QGridLayout *m_mainLayout;
39 QGridLayout *m_buttonLayout;
38 QGridLayout *m_buttonLayout;
40
39
41 QGraphicsView *m_customView;
40 QGraphicsView *m_customView;
42 QGraphicsScene *m_customScene;
41 QGraphicsScene *m_customScene;
43 QGraphicsGridLayout *m_customLayout;
44
45
46 int m_setCount;
47 };
42 };
48
43
49 #endif // MAINWIDGET_H
44 #endif // MAINWIDGET_H
@@ -1,429 +1,429
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20 #include "chartpresenter_p.h"
20 #include "chartpresenter_p.h"
21 #include "qchart.h"
21 #include "qchart.h"
22 #include "qchart_p.h"
22 #include "qchart_p.h"
23 #include "qaxis.h"
23 #include "qaxis.h"
24 #include "chartdataset_p.h"
24 #include "chartdataset_p.h"
25 #include "charttheme_p.h"
25 #include "charttheme_p.h"
26 #include "chartanimator_p.h"
26 #include "chartanimator_p.h"
27 #include "chartanimation_p.h"
27 #include "chartanimation_p.h"
28 #include "qabstractseries_p.h"
28 #include "qabstractseries_p.h"
29 #include "qareaseries.h"
29 #include "qareaseries.h"
30 #include "chartaxis_p.h"
30 #include "chartaxis_p.h"
31 #include "chartaxisx_p.h"
31 #include "chartaxisx_p.h"
32 #include "chartaxisy_p.h"
32 #include "chartaxisy_p.h"
33 #include "areachartitem_p.h"
33 #include "areachartitem_p.h"
34 #include "chartbackground_p.h"
34 #include "chartbackground_p.h"
35 #include <QTimer>
35 #include <QTimer>
36
36
37 QTCOMMERCIALCHART_BEGIN_NAMESPACE
37 QTCOMMERCIALCHART_BEGIN_NAMESPACE
38
38
39 ChartPresenter::ChartPresenter(QChart* chart,ChartDataSet* dataset):QObject(chart),
39 ChartPresenter::ChartPresenter(QChart* chart,ChartDataSet* dataset):QObject(chart),
40 m_chart(chart),
40 m_chart(chart),
41 m_animator(0),
41 m_animator(0),
42 m_dataset(dataset),
42 m_dataset(dataset),
43 m_chartTheme(0),
43 m_chartTheme(0),
44 m_chartRect(QRectF(QPoint(0,0),m_chart->size())),
44 m_chartRect(QRectF(QPoint(0,0),m_chart->size())),
45 m_options(QChart::NoAnimation),
45 m_options(QChart::NoAnimation),
46 m_minLeftMargin(0),
46 m_minLeftMargin(0),
47 m_minBottomMargin(0),
47 m_minBottomMargin(0),
48 m_state(ShowState),
48 m_state(ShowState),
49 m_backgroundItem(0),
49 m_backgroundItem(0),
50 m_titleItem(0),
50 m_titleItem(0),
51 m_marginBig(60),
51 m_marginBig(60),
52 m_marginSmall(20),
52 m_marginSmall(20),
53 m_marginTiny(10),
53 m_marginTiny(10),
54 m_chartMargins(QRect(m_marginBig,m_marginBig,0,0))
54 m_chartMargins(QRect(m_marginBig,m_marginBig,0,0))
55 {
55 {
56
56
57 }
57 }
58
58
59 ChartPresenter::~ChartPresenter()
59 ChartPresenter::~ChartPresenter()
60 {
60 {
61 delete m_chartTheme;
61 delete m_chartTheme;
62 }
62 }
63
63
64 void ChartPresenter::setGeometry(const QRectF& rect)
64 void ChartPresenter::setGeometry(const QRectF& rect)
65 {
65 {
66 m_rect = rect;
66 m_rect = rect;
67 Q_ASSERT(m_rect.isValid());
67 Q_ASSERT(m_rect.isValid());
68 updateLayout();
68 updateLayout();
69 }
69 }
70
70
71 void ChartPresenter::setMinimumMarginWidth(ChartAxis* axis, qreal width)
71 void ChartPresenter::setMinimumMarginWidth(ChartAxis* axis, qreal width)
72 {
72 {
73 switch(axis->axisType()){
73 switch(axis->axisType()){
74 case ChartAxis::X_AXIS:
74 case ChartAxis::X_AXIS:
75 {
75 {
76 if(width>m_chartRect.width()+ m_chartMargins.left()) {
76 if(width>m_chartRect.width()+ m_chartMargins.left()) {
77 m_minLeftMargin= width - m_chartRect.width();
77 m_minLeftMargin= width - m_chartRect.width();
78 updateLayout();
78 updateLayout();
79 }
79 }
80 break;
80 break;
81 }
81 }
82 case ChartAxis::Y_AXIS:
82 case ChartAxis::Y_AXIS:
83 {
83 {
84
84
85 if(m_minLeftMargin!=width){
85 if(m_minLeftMargin!=width){
86 m_minLeftMargin= width;
86 m_minLeftMargin= width;
87 updateLayout();
87 updateLayout();
88 }
88 }
89 break;
89 break;
90 }
90 }
91
91
92 }
92 }
93 }
93 }
94
94
95 void ChartPresenter::setMinimumMarginHeight(ChartAxis* axis, qreal height)
95 void ChartPresenter::setMinimumMarginHeight(ChartAxis* axis, qreal height)
96 {
96 {
97 switch(axis->axisType()){
97 switch(axis->axisType()){
98 case ChartAxis::X_AXIS:
98 case ChartAxis::X_AXIS:
99 {
99 {
100 if(m_minBottomMargin!=height) {
100 if(m_minBottomMargin!=height) {
101 m_minBottomMargin= height;
101 m_minBottomMargin= height;
102 updateLayout();
102 updateLayout();
103 }
103 }
104 break;
104 break;
105 }
105 }
106 case ChartAxis::Y_AXIS:
106 case ChartAxis::Y_AXIS:
107 {
107 {
108
108
109 if(height>m_chartMargins.bottom()+m_chartRect.height()){
109 if(height>m_chartMargins.bottom()+m_chartRect.height()){
110 m_minBottomMargin= height - m_chartRect.height();
110 m_minBottomMargin= height - m_chartRect.height();
111 updateLayout();
111 updateLayout();
112 }
112 }
113 break;
113 break;
114 }
114 }
115
115
116 }
116 }
117 }
117 }
118
118
119 void ChartPresenter::handleAxisAdded(QAxis* axis,Domain* domain)
119 void ChartPresenter::handleAxisAdded(QAxis* axis,Domain* domain)
120 {
120 {
121 ChartAxis* item;
121 ChartAxis* item;
122
122
123 if(axis == m_dataset->axisX()){
123 if(axis == m_dataset->axisX()){
124 item = new ChartAxisX(axis,this);
124 item = new ChartAxisX(axis,this);
125 }else{
125 }else{
126 item = new ChartAxisY(axis,this);
126 item = new ChartAxisY(axis,this);
127 }
127 }
128
128
129 if(m_options.testFlag(QChart::GridAxisAnimations)){
129 if(m_options.testFlag(QChart::GridAxisAnimations)){
130 item->setAnimator(m_animator);
130 item->setAnimator(m_animator);
131 item->setAnimation(new AxisAnimation(item));
131 item->setAnimation(new AxisAnimation(item));
132 }
132 }
133
133
134 if(axis==m_dataset->axisX()){
134 if(axis==m_dataset->axisX()){
135 m_chartTheme->decorate(axis,true);
135 m_chartTheme->decorate(axis,true);
136 QObject::connect(domain,SIGNAL(rangeXChanged(qreal,qreal,int)),item,SLOT(handleRangeChanged(qreal,qreal,int)));
136 QObject::connect(domain,SIGNAL(rangeXChanged(qreal,qreal,int)),item,SLOT(handleRangeChanged(qreal,qreal,int)));
137 //initialize
137 //initialize
138 item->handleRangeChanged(domain->minX(),domain->maxX(),domain->tickXCount());
138 item->handleRangeChanged(domain->minX(),domain->maxX(),domain->tickXCount());
139
139
140 }
140 }
141 else{
141 else{
142 m_chartTheme->decorate(axis,false);
142 m_chartTheme->decorate(axis,false);
143 QObject::connect(domain,SIGNAL(rangeYChanged(qreal,qreal,int)),item,SLOT(handleRangeChanged(qreal,qreal,int)));
143 QObject::connect(domain,SIGNAL(rangeYChanged(qreal,qreal,int)),item,SLOT(handleRangeChanged(qreal,qreal,int)));
144 //initialize
144 //initialize
145 item->handleRangeChanged(domain->minY(),domain->maxY(),domain->tickYCount());
145 item->handleRangeChanged(domain->minY(),domain->maxY(),domain->tickYCount());
146 }
146 }
147
147
148 QObject::connect(this,SIGNAL(geometryChanged(QRectF)),item,SLOT(handleGeometryChanged(QRectF)));
148 QObject::connect(this,SIGNAL(geometryChanged(QRectF)),item,SLOT(handleGeometryChanged(QRectF)));
149 //initialize
149 //initialize
150 if(m_chartRect.isValid()) item->handleGeometryChanged(m_chartRect);
150 if(m_chartRect.isValid()) item->handleGeometryChanged(m_chartRect);
151 m_axisItems.insert(axis, item);
151 m_axisItems.insert(axis, item);
152 }
152 }
153
153
154 void ChartPresenter::handleAxisRemoved(QAxis* axis)
154 void ChartPresenter::handleAxisRemoved(QAxis* axis)
155 {
155 {
156 ChartAxis* item = m_axisItems.take(axis);
156 ChartAxis* item = m_axisItems.take(axis);
157 Q_ASSERT(item);
157 Q_ASSERT(item);
158 if(m_animator) m_animator->removeAnimation(item);
158 if(m_animator) m_animator->removeAnimation(item);
159 delete item;
159 delete item;
160 }
160 }
161
161
162
162
163 void ChartPresenter::handleSeriesAdded(QAbstractSeries* series,Domain* domain)
163 void ChartPresenter::handleSeriesAdded(QAbstractSeries* series,Domain* domain)
164 {
164 {
165 Chart *item = series->d_ptr->createGraphics(this);
165 Chart *item = series->d_ptr->createGraphics(this);
166 Q_ASSERT(item);
166 Q_ASSERT(item);
167 QObject::connect(this,SIGNAL(geometryChanged(QRectF)),item,SLOT(handleGeometryChanged(QRectF)));
167 QObject::connect(this,SIGNAL(geometryChanged(QRectF)),item,SLOT(handleGeometryChanged(QRectF)));
168 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),item,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
168 QObject::connect(domain,SIGNAL(domainChanged(qreal,qreal,qreal,qreal)),item,SLOT(handleDomainChanged(qreal,qreal,qreal,qreal)));
169 //initialize
169 //initialize
170 item->handleDomainChanged(domain->minX(),domain->maxX(),domain->minY(),domain->maxY());
170 item->handleDomainChanged(domain->minX(),domain->maxX(),domain->minY(),domain->maxY());
171 if(m_chartRect.isValid()) item->handleGeometryChanged(m_chartRect);
171 if(m_chartRect.isValid()) item->handleGeometryChanged(m_chartRect);
172 m_chartItems.insert(series,item);
172 m_chartItems.insert(series,item);
173 }
173 }
174
174
175 void ChartPresenter::handleSeriesRemoved(QAbstractSeries* series)
175 void ChartPresenter::handleSeriesRemoved(QAbstractSeries* series)
176 {
176 {
177 Chart* item = m_chartItems.take(series);
177 Chart* item = m_chartItems.take(series);
178 Q_ASSERT(item);
178 Q_ASSERT(item);
179 if(m_animator) {
179 if(m_animator) {
180 //small hack to handle area animations
180 //small hack to handle area animations
181 if(series->type() == QAbstractSeries::SeriesTypeArea){
181 if(series->type() == QAbstractSeries::SeriesTypeArea){
182 QAreaSeries* areaSeries = static_cast<QAreaSeries*>(series);
182 QAreaSeries* areaSeries = static_cast<QAreaSeries*>(series);
183 AreaChartItem* area = static_cast<AreaChartItem*>(item);
183 AreaChartItem* area = static_cast<AreaChartItem*>(item);
184 m_animator->removeAnimation(area->upperLineItem());
184 m_animator->removeAnimation(area->upperLineItem());
185 if(areaSeries->lowerSeries()) m_animator->removeAnimation(area->lowerLineItem());
185 if(areaSeries->lowerSeries()) m_animator->removeAnimation(area->lowerLineItem());
186 }else
186 }else
187 m_animator->removeAnimation(item);
187 m_animator->removeAnimation(item);
188 }
188 }
189 delete item;
189 delete item;
190 }
190 }
191
191
192 void ChartPresenter::setTheme(QChart::ChartTheme theme,bool force)
192 void ChartPresenter::setTheme(QChart::ChartTheme theme,bool force)
193 {
193 {
194 if(m_chartTheme && m_chartTheme->id() == theme) return;
194 if(m_chartTheme && m_chartTheme->id() == theme) return;
195 delete m_chartTheme;
195 delete m_chartTheme;
196 m_chartTheme = ChartTheme::createTheme(theme);
196 m_chartTheme = ChartTheme::createTheme(theme);
197 m_chartTheme->setForced(force);
197 m_chartTheme->setForced(force);
198 m_chartTheme->decorate(m_chart);
198 m_chartTheme->decorate(m_chart);
199 m_chartTheme->decorate(m_chart->legend());
199 m_chartTheme->decorate(m_chart->legend());
200 resetAllElements();
200 resetAllElements();
201
201
202 // We do not want "force" to stay on.
202 // We do not want "force" to stay on.
203 // Bar/pie are calling decorate when adding/removing slices/bars which means
203 // Bar/pie are calling decorate when adding/removing slices/bars which means
204 // that to preserve users colors "force" must not be on.
204 // that to preserve users colors "force" must not be on.
205 m_chartTheme->setForced(false);
205 m_chartTheme->setForced(false);
206 }
206 }
207
207
208 QChart::ChartTheme ChartPresenter::theme()
208 QChart::ChartTheme ChartPresenter::theme()
209 {
209 {
210 return m_chartTheme->id();
210 return m_chartTheme->id();
211 }
211 }
212
212
213 void ChartPresenter::setAnimationOptions(QChart::AnimationOptions options)
213 void ChartPresenter::setAnimationOptions(QChart::AnimationOptions options)
214 {
214 {
215 if(m_options!=options) {
215 if(m_options!=options) {
216
216
217 m_options=options;
217 m_options=options;
218
218
219 if(m_options!=QChart::NoAnimation && !m_animator) {
219 if(m_options!=QChart::NoAnimation && !m_animator) {
220 m_animator= new ChartAnimator(this);
220 m_animator= new ChartAnimator(this);
221 }
221 }
222 resetAllElements();
222 resetAllElements();
223 }
223 }
224
224
225 }
225 }
226
226
227 void ChartPresenter::resetAllElements()
227 void ChartPresenter::resetAllElements()
228 {
228 {
229 QList<QAxis *> axisList = m_axisItems.uniqueKeys();
229 QList<QAxis *> axisList = m_axisItems.uniqueKeys();
230 QList<QAbstractSeries *> seriesList = m_chartItems.uniqueKeys();
230 QList<QAbstractSeries *> seriesList = m_chartItems.uniqueKeys();
231
231
232 foreach(QAxis *axis, axisList) {
232 foreach(QAxis *axis, axisList) {
233 handleAxisRemoved(axis);
233 handleAxisRemoved(axis);
234 handleAxisAdded(axis,m_dataset->domain(axis));
234 handleAxisAdded(axis,m_dataset->domain(axis));
235 }
235 }
236 foreach(QAbstractSeries *series, seriesList) {
236 foreach(QAbstractSeries *series, seriesList) {
237 handleSeriesRemoved(series);
237 handleSeriesRemoved(series);
238 handleSeriesAdded(series,m_dataset->domain(series));
238 handleSeriesAdded(series,m_dataset->domain(series));
239 // m_dataset->removeSeries(series);
239 // m_dataset->removeSeries(series);
240 // m_dataset->addSeries(series);
240 // m_dataset->addSeries(series);
241 }
241 }
242 }
242 }
243
243
244 void ChartPresenter::zoomIn(qreal factor)
244 void ChartPresenter::zoomIn(qreal factor)
245 {
245 {
246 QRectF rect = chartGeometry();
246 QRectF rect = chartGeometry();
247 rect.setWidth(rect.width()/factor);
247 rect.setWidth(rect.width()/factor);
248 rect.setHeight(rect.height()/factor);
248 rect.setHeight(rect.height()/factor);
249 rect.moveCenter(chartGeometry().center());
249 rect.moveCenter(chartGeometry().center());
250 zoomIn(rect);
250 zoomIn(rect);
251 }
251 }
252
252
253 void ChartPresenter::zoomIn(const QRectF& rect)
253 void ChartPresenter::zoomIn(const QRectF& rect)
254 {
254 {
255 QRectF r = rect.normalized();
255 QRectF r = rect.normalized();
256 r.translate(-m_chartMargins.topLeft());
256 r.translate(-m_chartMargins.topLeft());
257 if (!r.isValid())
257 if (!r.isValid())
258 return;
258 return;
259
259
260 m_state = ZoomInState;
260 m_state = ZoomInState;
261 m_statePoint = QPointF(r.center().x()/chartGeometry().width(),r.center().y()/chartGeometry().height());
261 m_statePoint = QPointF(r.center().x()/chartGeometry().width(),r.center().y()/chartGeometry().height());
262 m_dataset->zoomInDomain(r,chartGeometry().size());
262 m_dataset->zoomInDomain(r,chartGeometry().size());
263 m_state = ShowState;
263 m_state = ShowState;
264 }
264 }
265
265
266 void ChartPresenter::zoomOut(qreal factor)
266 void ChartPresenter::zoomOut(qreal factor)
267 {
267 {
268 m_state = ZoomOutState;
268 m_state = ZoomOutState;
269
269
270 QRectF chartRect;
270 QRectF chartRect;
271 chartRect.setSize(chartGeometry().size());
271 chartRect.setSize(chartGeometry().size());
272
272
273 QRectF rect;
273 QRectF rect;
274 rect.setSize(chartRect.size()/factor);
274 rect.setSize(chartRect.size()/factor);
275 rect.moveCenter(chartRect.center());
275 rect.moveCenter(chartRect.center());
276 if (!rect.isValid())
276 if (!rect.isValid())
277 return;
277 return;
278 m_statePoint = QPointF(rect.center().x()/chartGeometry().width(),rect.center().y()/chartGeometry().height());
278 m_statePoint = QPointF(rect.center().x()/chartGeometry().width(),rect.center().y()/chartGeometry().height());
279 m_dataset->zoomOutDomain(rect, chartRect.size());
279 m_dataset->zoomOutDomain(rect, chartRect.size());
280 m_state = ShowState;
280 m_state = ShowState;
281 }
281 }
282
282
283 void ChartPresenter::scroll(qreal dx,qreal dy)
283 void ChartPresenter::scroll(qreal dx,qreal dy)
284 {
284 {
285 if(dx<0) m_state=ScrollLeftState;
285 if(dx<0) m_state=ScrollLeftState;
286 if(dx>0) m_state=ScrollRightState;
286 if(dx>0) m_state=ScrollRightState;
287 if(dy<0) m_state=ScrollUpState;
287 if(dy<0) m_state=ScrollUpState;
288 if(dy>0) m_state=ScrollDownState;
288 if(dy>0) m_state=ScrollDownState;
289
289
290 m_dataset->scrollDomain(dx,dy,chartGeometry().size());
290 m_dataset->scrollDomain(dx,dy,chartGeometry().size());
291 m_state = ShowState;
291 m_state = ShowState;
292 }
292 }
293
293
294 QChart::AnimationOptions ChartPresenter::animationOptions() const
294 QChart::AnimationOptions ChartPresenter::animationOptions() const
295 {
295 {
296 return m_options;
296 return m_options;
297 }
297 }
298
298
299 void ChartPresenter::updateLayout()
299 void ChartPresenter::updateLayout()
300 {
300 {
301 if (!m_rect.isValid()) return;
301 if (!m_rect.isValid()) return;
302
302
303 // recalculate title size
303 // recalculate title size
304
304
305 QSize titleSize;
305 QSize titleSize;
306 int titlePadding=0;
306 int titlePadding=0;
307
307
308 if (m_titleItem) {
308 if (m_titleItem) {
309 titleSize= m_titleItem->boundingRect().size().toSize();
309 titleSize= m_titleItem->boundingRect().size().toSize();
310 }
310 }
311
311
312 //defaults
312 //defaults
313 m_chartMargins = QRect(QPoint(m_minLeftMargin>m_marginBig?m_minLeftMargin:m_marginBig,m_marginBig),QPoint(m_marginBig,m_minBottomMargin>m_marginBig?m_minBottomMargin:m_marginBig));
313 m_chartMargins = QRect(QPoint(m_minLeftMargin>m_marginBig?m_minLeftMargin:m_marginBig,m_marginBig),QPoint(m_marginBig,m_minBottomMargin>m_marginBig?m_minBottomMargin:m_marginBig));
314 titlePadding = m_chartMargins.top()/2;
314 titlePadding = m_chartMargins.top()/2;
315
315
316 QLegend* legend = m_chart->d_ptr->m_legend;
316 QLegend* legend = m_chart->d_ptr->m_legend;
317
317
318 // recalculate legend position
318 // recalculate legend position
319 if (legend->isAttachedToChart() && legend->isEnabled()) {
319 if (legend != 0 && legend->isAttachedToChart() && legend->isEnabled()) {
320
320
321 QRect legendRect;
321 QRect legendRect;
322
322
323 // Reserve some space for legend
323 // Reserve some space for legend
324 switch (legend->alignment()) {
324 switch (legend->alignment()) {
325
325
326 case QLegend::AlignmentTop: {
326 case QLegend::AlignmentTop: {
327 int ledgendSize = legend->minHeight();
327 int ledgendSize = legend->minHeight();
328 int topPadding = 2*m_marginTiny + titleSize.height() + ledgendSize + m_marginTiny;
328 int topPadding = 2*m_marginTiny + titleSize.height() + ledgendSize + m_marginTiny;
329 m_chartMargins = QRect(QPoint(m_chartMargins.left(),topPadding),QPoint(m_chartMargins.right(),m_chartMargins.bottom()));
329 m_chartMargins = QRect(QPoint(m_chartMargins.left(),topPadding),QPoint(m_chartMargins.right(),m_chartMargins.bottom()));
330 m_legendMargins = QRect(QPoint(m_chartMargins.left(),topPadding - (ledgendSize + m_marginTiny)),QPoint(m_chartMargins.right(),m_rect.height()-topPadding + m_marginTiny));
330 m_legendMargins = QRect(QPoint(m_chartMargins.left(),topPadding - (ledgendSize + m_marginTiny)),QPoint(m_chartMargins.right(),m_rect.height()-topPadding + m_marginTiny));
331 titlePadding = m_marginTiny + m_marginTiny;
331 titlePadding = m_marginTiny + m_marginTiny;
332 break;
332 break;
333 }
333 }
334 case QLegend::AlignmentBottom: {
334 case QLegend::AlignmentBottom: {
335 int ledgendSize = legend->minHeight();
335 int ledgendSize = legend->minHeight();
336 int bottomPadding = m_marginTiny + m_marginSmall + ledgendSize + m_marginTiny + m_minBottomMargin;
336 int bottomPadding = m_marginTiny + m_marginSmall + ledgendSize + m_marginTiny + m_minBottomMargin;
337 m_chartMargins = QRect(QPoint(m_chartMargins.left(),m_chartMargins.top()),QPoint(m_chartMargins.right(),bottomPadding));
337 m_chartMargins = QRect(QPoint(m_chartMargins.left(),m_chartMargins.top()),QPoint(m_chartMargins.right(),bottomPadding));
338 m_legendMargins = QRect(QPoint(m_chartMargins.left(),m_rect.height()-bottomPadding + m_marginTiny + m_minBottomMargin),QPoint(m_chartMargins.right(),m_marginTiny + m_marginSmall));
338 m_legendMargins = QRect(QPoint(m_chartMargins.left(),m_rect.height()-bottomPadding + m_marginTiny + m_minBottomMargin),QPoint(m_chartMargins.right(),m_marginTiny + m_marginSmall));
339 titlePadding = m_chartMargins.top()/2;
339 titlePadding = m_chartMargins.top()/2;
340 break;
340 break;
341 }
341 }
342 case QLegend::AlignmentLeft: {
342 case QLegend::AlignmentLeft: {
343 int ledgendSize = legend->minWidth();
343 int ledgendSize = legend->minWidth();
344 int leftPadding = m_marginTiny + m_marginSmall + ledgendSize + m_marginTiny + m_minLeftMargin;
344 int leftPadding = m_marginTiny + m_marginSmall + ledgendSize + m_marginTiny + m_minLeftMargin;
345 m_chartMargins = QRect(QPoint(leftPadding,m_chartMargins.top()),QPoint(m_chartMargins.right(),m_chartMargins.bottom()));
345 m_chartMargins = QRect(QPoint(leftPadding,m_chartMargins.top()),QPoint(m_chartMargins.right(),m_chartMargins.bottom()));
346 m_legendMargins = QRect(QPoint(m_marginTiny + m_marginSmall,m_chartMargins.top()),QPoint(m_rect.width()-leftPadding + m_marginTiny + m_minLeftMargin,m_chartMargins.bottom()));
346 m_legendMargins = QRect(QPoint(m_marginTiny + m_marginSmall,m_chartMargins.top()),QPoint(m_rect.width()-leftPadding + m_marginTiny + m_minLeftMargin,m_chartMargins.bottom()));
347 titlePadding = m_chartMargins.top()/2;
347 titlePadding = m_chartMargins.top()/2;
348 break;
348 break;
349 }
349 }
350 case QLegend::AlignmentRight: {
350 case QLegend::AlignmentRight: {
351 int ledgendSize = legend->minWidth();
351 int ledgendSize = legend->minWidth();
352 int rightPadding = m_marginTiny + m_marginSmall + ledgendSize + m_marginTiny;
352 int rightPadding = m_marginTiny + m_marginSmall + ledgendSize + m_marginTiny;
353 m_chartMargins = QRect(QPoint(m_chartMargins.left(),m_chartMargins.top()),QPoint(rightPadding,m_chartMargins.bottom()));
353 m_chartMargins = QRect(QPoint(m_chartMargins.left(),m_chartMargins.top()),QPoint(rightPadding,m_chartMargins.bottom()));
354 m_legendMargins = QRect(QPoint(m_rect.width()- rightPadding+ m_marginTiny ,m_chartMargins.top()),QPoint(m_marginTiny + m_marginSmall,m_chartMargins.bottom()));
354 m_legendMargins = QRect(QPoint(m_rect.width()- rightPadding+ m_marginTiny ,m_chartMargins.top()),QPoint(m_marginTiny + m_marginSmall,m_chartMargins.bottom()));
355 titlePadding = m_chartMargins.top()/2;
355 titlePadding = m_chartMargins.top()/2;
356 break;
356 break;
357 }
357 }
358 default: {
358 default: {
359 break;
359 break;
360 }
360 }
361 }
361 }
362 }
362 }
363
363
364 if(m_rect.width()<2*(m_chartMargins.top()+m_chartMargins.bottom()) || m_rect.height()< 2*(m_chartMargins.top() + m_chartMargins.bottom()))
364 if(m_rect.width()<2*(m_chartMargins.top()+m_chartMargins.bottom()) || m_rect.height()< 2*(m_chartMargins.top() + m_chartMargins.bottom()))
365 {
365 {
366 m_chart->setMinimumSize(2*(m_chartMargins.top()+m_chartMargins.bottom()),2*(m_chartMargins.top() + m_chartMargins.bottom()));
366 m_chart->setMinimumSize(2*(m_chartMargins.top()+m_chartMargins.bottom()),2*(m_chartMargins.top() + m_chartMargins.bottom()));
367 return;
367 return;
368 }
368 }
369
369
370
370
371 // recalculate title position
371 // recalculate title position
372 if (m_titleItem) {
372 if (m_titleItem) {
373 QPointF center = m_rect.center() -m_titleItem->boundingRect().center();
373 QPointF center = m_rect.center() -m_titleItem->boundingRect().center();
374 m_titleItem->setPos(center.x(),titlePadding);
374 m_titleItem->setPos(center.x(),titlePadding);
375 }
375 }
376
376
377 //recalculate background gradient
377 //recalculate background gradient
378 if (m_backgroundItem) {
378 if (m_backgroundItem) {
379 m_backgroundItem->setRect(m_rect.adjusted(m_marginTiny,m_marginTiny, -m_marginTiny, -m_marginTiny));
379 m_backgroundItem->setRect(m_rect.adjusted(m_marginTiny,m_marginTiny, -m_marginTiny, -m_marginTiny));
380 }
380 }
381
381
382
382
383 QRectF chartRect = m_rect.adjusted(m_chartMargins.left(),m_chartMargins.top(),-m_chartMargins.right(),-m_chartMargins.bottom());
383 QRectF chartRect = m_rect.adjusted(m_chartMargins.left(),m_chartMargins.top(),-m_chartMargins.right(),-m_chartMargins.bottom());
384
384
385 legend->setGeometry(m_rect.adjusted(m_legendMargins.left(),m_legendMargins.top(),-m_legendMargins.right(),-m_legendMargins.bottom()));
385 legend->setGeometry(m_rect.adjusted(m_legendMargins.left(),m_legendMargins.top(),-m_legendMargins.right(),-m_legendMargins.bottom()));
386
386
387 if(m_chartRect!=chartRect && chartRect.isValid()){
387 if(m_chartRect!=chartRect && chartRect.isValid()){
388 m_chartRect=chartRect;
388 m_chartRect=chartRect;
389 emit geometryChanged(m_chartRect);
389 emit geometryChanged(m_chartRect);
390 }
390 }
391
391
392 }
392 }
393
393
394 void ChartPresenter::createChartBackgroundItem()
394 void ChartPresenter::createChartBackgroundItem()
395 {
395 {
396 if (!m_backgroundItem) {
396 if (!m_backgroundItem) {
397 m_backgroundItem = new ChartBackground(rootItem());
397 m_backgroundItem = new ChartBackground(rootItem());
398 m_backgroundItem->setPen(Qt::NoPen);
398 m_backgroundItem->setPen(Qt::NoPen);
399 m_backgroundItem->setZValue(ChartPresenter::BackgroundZValue);
399 m_backgroundItem->setZValue(ChartPresenter::BackgroundZValue);
400 }
400 }
401 }
401 }
402
402
403 void ChartPresenter::createChartTitleItem()
403 void ChartPresenter::createChartTitleItem()
404 {
404 {
405 if (!m_titleItem) {
405 if (!m_titleItem) {
406 m_titleItem = new QGraphicsSimpleTextItem(rootItem());
406 m_titleItem = new QGraphicsSimpleTextItem(rootItem());
407 m_titleItem->setZValue(ChartPresenter::BackgroundZValue);
407 m_titleItem->setZValue(ChartPresenter::BackgroundZValue);
408 }
408 }
409 }
409 }
410
410
411 void ChartPresenter::handleAnimationFinished()
411 void ChartPresenter::handleAnimationFinished()
412 {
412 {
413 m_animations.removeAll(qobject_cast<ChartAnimation*>(sender()));
413 m_animations.removeAll(qobject_cast<ChartAnimation*>(sender()));
414 if(m_animations.empty()) emit animationsFinished();
414 if(m_animations.empty()) emit animationsFinished();
415 }
415 }
416
416
417 void ChartPresenter::startAnimation(ChartAnimation* animation)
417 void ChartPresenter::startAnimation(ChartAnimation* animation)
418 {
418 {
419 if (animation->state() != QAbstractAnimation::Stopped) animation->stop();
419 if (animation->state() != QAbstractAnimation::Stopped) animation->stop();
420 QObject::connect(animation, SIGNAL(finished()),this,SLOT(handleAnimationFinished()),Qt::UniqueConnection);
420 QObject::connect(animation, SIGNAL(finished()),this,SLOT(handleAnimationFinished()),Qt::UniqueConnection);
421 if(!m_animations.isEmpty()){
421 if(!m_animations.isEmpty()){
422 m_animations.append(animation);
422 m_animations.append(animation);
423 }
423 }
424 QTimer::singleShot(0, animation, SLOT(start()));
424 QTimer::singleShot(0, animation, SLOT(start()));
425 }
425 }
426
426
427 #include "moc_chartpresenter_p.cpp"
427 #include "moc_chartpresenter_p.cpp"
428
428
429 QTCOMMERCIALCHART_END_NAMESPACE
429 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,471 +1,478
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "qlegend.h"
21 #include "qlegend.h"
22 #include "qlegend_p.h"
22 #include "qlegend_p.h"
23 #include "qabstractseries.h"
23 #include "qabstractseries.h"
24 #include "qabstractseries_p.h"
24 #include "qabstractseries_p.h"
25 #include "qchart_p.h"
25 #include "qchart_p.h"
26
26
27 #include "legendmarker_p.h"
27 #include "legendmarker_p.h"
28 #include "qxyseries.h"
28 #include "qxyseries.h"
29 #include "qlineseries.h"
29 #include "qlineseries.h"
30 #include "qareaseries.h"
30 #include "qareaseries.h"
31 #include "qscatterseries.h"
31 #include "qscatterseries.h"
32 #include "qsplineseries.h"
32 #include "qsplineseries.h"
33 #include "qbarseries.h"
33 #include "qbarseries.h"
34 #include "qstackedbarseries.h"
34 #include "qstackedbarseries.h"
35 #include "qpercentbarseries.h"
35 #include "qpercentbarseries.h"
36 #include "qbarset.h"
36 #include "qbarset.h"
37 #include "qpieseries.h"
37 #include "qpieseries.h"
38 #include "qpieseries_p.h"
38 #include "qpieseries_p.h"
39 #include "qpieslice.h"
39 #include "qpieslice.h"
40 #include "chartpresenter_p.h"
40 #include "chartpresenter_p.h"
41 #include <QPainter>
41 #include <QPainter>
42 #include <QPen>
42 #include <QPen>
43 #include <QTimer>
43 #include <QTimer>
44
44
45 #include <QGraphicsSceneEvent>
45 #include <QGraphicsSceneEvent>
46
46
47 QTCOMMERCIALCHART_BEGIN_NAMESPACE
47 QTCOMMERCIALCHART_BEGIN_NAMESPACE
48
48
49 /*!
49 /*!
50 \class QLegend
50 \class QLegend
51 \brief part of QtCommercial chart API.
51 \brief part of QtCommercial chart API.
52 \mainclass
52 \mainclass
53
53
54 QLegend is a graphical object, whics displays legend of the chart. Legend state is updated by QChart, when
54 QLegend is a graphical object, whics displays legend of the chart. Legend state is updated by QChart, when
55 series have been changed. By default, legend is drawn by QChart, but user can set a new parent to legend and
55 series have been changed. By default, legend is drawn by QChart, but user can set a new parent to legend and
56 handle the drawing manually.
56 handle the drawing manually.
57 User isn't supposed to create or delete legend objects, but can reference it via QChart class.
57 User isn't supposed to create or delete legend objects, but can reference it via QChart class.
58
58
59 \image examples_percentbarchart_legend.png
59 \image examples_percentbarchart_legend.png
60
60
61 \sa QChart
61 \sa QChart
62 */
62 */
63
63
64 /*!
64 /*!
65 \enum QLegend::Alignment
65 \enum QLegend::Alignment
66
66
67 This enum describes the possible position for legend inside chart.
67 This enum describes the possible position for legend inside chart.
68
68
69 \value AlignmentTop
69 \value AlignmentTop
70 \value AlignmentBottom
70 \value AlignmentBottom
71 \value AlignmentLeft
71 \value AlignmentLeft
72 \value AlignmentRight
72 \value AlignmentRight
73 */
73 */
74
74
75 /*!
75 /*!
76 \fn qreal QLegend::minWidth() const
76 \fn qreal QLegend::minWidth() const
77 Returns minimum width of the legend
77 Returns minimum width of the legend
78 */
78 */
79
79
80 /*!
80 /*!
81 \fn qreal QLegend::minHeight() const
81 \fn qreal QLegend::minHeight() const
82 Returns minimum height of the legend
82 Returns minimum height of the legend
83 */
83 */
84
84
85 /*!
85 /*!
86 Constructs the legend object and sets the parent to \a parent
86 Constructs the legend object and sets the parent to \a parent
87 */
87 */
88
88
89 QLegend::QLegend(QChart *chart):QGraphicsWidget(chart),
89 QLegend::QLegend(QChart *chart):QGraphicsWidget(chart),
90 d_ptr(new QLegendPrivate(chart->d_ptr->m_presenter,this))
90 d_ptr(new QLegendPrivate(chart->d_ptr->m_presenter,chart,this))
91 {
91 {
92 setZValue(ChartPresenter::LegendZValue);
92 setZValue(ChartPresenter::LegendZValue);
93 setFlags(QGraphicsItem::ItemClipsChildrenToShape);
93 setFlags(QGraphicsItem::ItemClipsChildrenToShape);
94 QObject::connect(chart->d_ptr->m_dataset,SIGNAL(seriesAdded(QAbstractSeries*,Domain*)),d_ptr.data(),SLOT(handleSeriesAdded(QAbstractSeries*,Domain*)));
94 QObject::connect(chart->d_ptr->m_dataset,SIGNAL(seriesAdded(QAbstractSeries*,Domain*)),d_ptr.data(),SLOT(handleSeriesAdded(QAbstractSeries*,Domain*)));
95 QObject::connect(chart->d_ptr->m_dataset,SIGNAL(seriesRemoved(QAbstractSeries*)),d_ptr.data(),SLOT(handleSeriesRemoved(QAbstractSeries*)));
95 QObject::connect(chart->d_ptr->m_dataset,SIGNAL(seriesRemoved(QAbstractSeries*)),d_ptr.data(),SLOT(handleSeriesRemoved(QAbstractSeries*)));
96 QObject::connect(chart->d_ptr->m_dataset,SIGNAL(seriesUpdated(QAbstractSeries*)),d_ptr.data(),SLOT(handleSeriesUpdated(QAbstractSeries*)));
96 QObject::connect(chart->d_ptr->m_dataset,SIGNAL(seriesUpdated(QAbstractSeries*)),d_ptr.data(),SLOT(handleSeriesUpdated(QAbstractSeries*)));
97 }
97 }
98
98
99 /*!
99 /*!
100 Destroys the legend object. Legend is always owned by a QChart, so an application should never call this.
100 Destroys the legend object. Legend is always owned by a QChart, so an application should never call this.
101 */
101 */
102 QLegend::~QLegend()
102 QLegend::~QLegend()
103 {
103 {
104 }
104 }
105
105
106 /*!
106 /*!
107 Paints the legend to given \a painter. Paremeters \a option and \a widget arent used.
107 Paints the legend to given \a painter. Paremeters \a option and \a widget arent used.
108 */
108 */
109
109
110 void QLegend::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
110 void QLegend::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
111 {
111 {
112 Q_UNUSED(option)
112 Q_UNUSED(option)
113 Q_UNUSED(widget)
113 Q_UNUSED(widget)
114 if(!d_ptr->m_backgroundVisible) return;
114 if(!d_ptr->m_backgroundVisible) return;
115
115
116 painter->setOpacity(opacity());
116 painter->setOpacity(opacity());
117 painter->setPen(d_ptr->m_pen);
117 painter->setPen(d_ptr->m_pen);
118 painter->setBrush(d_ptr->m_brush);
118 painter->setBrush(d_ptr->m_brush);
119 painter->drawRect(boundingRect());
119 painter->drawRect(boundingRect());
120 }
120 }
121
121
122 /*!
122 /*!
123 Bounding rect of legend.
123 Bounding rect of legend.
124 */
124 */
125
125
126 QRectF QLegend::boundingRect() const
126 QRectF QLegend::boundingRect() const
127 {
127 {
128 return d_ptr->m_rect;
128 return d_ptr->m_rect;
129 }
129 }
130
130
131 /*!
131 /*!
132 Sets the \a brush of legend. Brush affects the background of legend.
132 Sets the \a brush of legend. Brush affects the background of legend.
133 */
133 */
134 void QLegend::setBrush(const QBrush &brush)
134 void QLegend::setBrush(const QBrush &brush)
135 {
135 {
136 if (d_ptr->m_brush != brush) {
136 if (d_ptr->m_brush != brush) {
137 d_ptr->m_brush = brush;
137 d_ptr->m_brush = brush;
138 update();
138 update();
139 }
139 }
140 }
140 }
141
141
142 /*!
142 /*!
143 Returns the brush used by legend.
143 Returns the brush used by legend.
144 */
144 */
145 QBrush QLegend::brush() const
145 QBrush QLegend::brush() const
146 {
146 {
147 return d_ptr->m_brush;
147 return d_ptr->m_brush;
148 }
148 }
149
149
150 /*!
150 /*!
151 Sets the \a pen of legend. Pen affects the legend borders.
151 Sets the \a pen of legend. Pen affects the legend borders.
152 */
152 */
153 void QLegend::setPen(const QPen &pen)
153 void QLegend::setPen(const QPen &pen)
154 {
154 {
155 if (d_ptr->m_pen != pen) {
155 if (d_ptr->m_pen != pen) {
156 d_ptr->m_pen = pen;
156 d_ptr->m_pen = pen;
157 update();
157 update();
158 }
158 }
159 }
159 }
160
160
161 /*!
161 /*!
162 Returns the pen used by legend
162 Returns the pen used by legend
163 */
163 */
164
164
165 QPen QLegend::pen() const
165 QPen QLegend::pen() const
166 {
166 {
167 return d_ptr->m_pen;
167 return d_ptr->m_pen;
168 }
168 }
169
169
170 /*!
170 /*!
171 Sets the \a alignment for legend. Legend tries to paint itself on the defined position in chart.
171 Sets the \a alignment for legend. Legend tries to paint itself on the defined position in chart.
172 \sa QLegend::Alignment
172 \sa QLegend::Alignment
173 */
173 */
174 void QLegend::setAlignment(QLegend::Alignments alignment)
174 void QLegend::setAlignment(QLegend::Alignments alignment)
175 {
175 {
176 if(d_ptr->m_alignment!=alignment) {
176 if(d_ptr->m_alignment!=alignment) {
177 d_ptr->m_alignment = alignment;
177 d_ptr->m_alignment = alignment;
178 d_ptr->updateLayout();
178 d_ptr->updateLayout();
179 }
179 }
180 }
180 }
181
181
182 /*!
182 /*!
183 Returns the preferred layout for legend
183 Returns the preferred layout for legend
184 */
184 */
185 QLegend::Alignments QLegend::alignment() const
185 QLegend::Alignments QLegend::alignment() const
186 {
186 {
187 return d_ptr->m_alignment;
187 return d_ptr->m_alignment;
188 }
188 }
189
189
190 /*!
190 /*!
191 Detaches the legend from chart. Chart won't change layout of the legend.
191 Detaches the legend from chart. Chart won't change layout of the legend.
192 */
192 */
193 void QLegend::detachFromChart()
193 void QLegend::detachFromChart()
194 {
194 {
195 d_ptr->m_attachedToChart = false;
195 d_ptr->m_attachedToChart = false;
196 }
196 }
197
197
198 /*!
198 /*!
199 Attaches the legend to chart. Chart may change layout of the legend.
199 Attaches the legend to chart. Chart may change layout of the legend.
200 */
200 */
201 void QLegend::attachToChart()
201 void QLegend::attachToChart()
202 {
202 {
203 d_ptr->m_attachedToChart = true;
203 d_ptr->attachToChart();
204 }
204 }
205
205
206 /*!
206 /*!
207 Returns true, if legend is attached to chart.
207 Returns true, if legend is attached to chart.
208 */
208 */
209 bool QLegend::isAttachedToChart()
209 bool QLegend::isAttachedToChart()
210 {
210 {
211 return d_ptr->m_attachedToChart;
211 return d_ptr->m_attachedToChart;
212 }
212 }
213
213
214 /*!
214 /*!
215 Sets the legend's scrolling offset to value defined by \a point.
215 Sets the legend's scrolling offset to value defined by \a point.
216 */
216 */
217 void QLegend::setOffset(const QPointF& point)
217 void QLegend::setOffset(const QPointF& point)
218 {
218 {
219 d_ptr->setOffset(point.x(),point.y());
219 d_ptr->setOffset(point.x(),point.y());
220 }
220 }
221
221
222 /*!
222 /*!
223 Returns the legend's scrolling offset.
223 Returns the legend's scrolling offset.
224 */
224 */
225 QPointF QLegend::offset() const
225 QPointF QLegend::offset() const
226 {
226 {
227 return QPointF(d_ptr->m_offsetX,d_ptr->m_offsetY);
227 return QPointF(d_ptr->m_offsetX,d_ptr->m_offsetY);
228 }
228 }
229
229
230 /*!
230 /*!
231 Sets the visibility of legend background to \a visible
231 Sets the visibility of legend background to \a visible
232 */
232 */
233 void QLegend::setBackgroundVisible(bool visible)
233 void QLegend::setBackgroundVisible(bool visible)
234 {
234 {
235 if(d_ptr->m_backgroundVisible!=visible)
235 if(d_ptr->m_backgroundVisible!=visible)
236 {
236 {
237 d_ptr->m_backgroundVisible=visible;
237 d_ptr->m_backgroundVisible=visible;
238 update();
238 update();
239 }
239 }
240 }
240 }
241
241
242 /*!
242 /*!
243 Returns the visibility of legend background
243 Returns the visibility of legend background
244 */
244 */
245 bool QLegend::isBackgroundVisible() const
245 bool QLegend::isBackgroundVisible() const
246 {
246 {
247 return d_ptr->m_backgroundVisible;
247 return d_ptr->m_backgroundVisible;
248 }
248 }
249
249
250 /*!
250 /*!
251 \internal \a event see QGraphicsWidget for details
251 \internal \a event see QGraphicsWidget for details
252 */
252 */
253 void QLegend::resizeEvent(QGraphicsSceneResizeEvent *event)
253 void QLegend::resizeEvent(QGraphicsSceneResizeEvent *event)
254 {
254 {
255 const QRectF& rect = QRectF(QPoint(0,0),event->newSize());
255 const QRectF& rect = QRectF(QPoint(0,0),event->newSize());
256 QGraphicsWidget::resizeEvent(event);
256 QGraphicsWidget::resizeEvent(event);
257 if(d_ptr->m_rect != rect) {
257 if(d_ptr->m_rect != rect) {
258 d_ptr->m_rect = rect;
258 d_ptr->m_rect = rect;
259 d_ptr->updateLayout();
259 d_ptr->updateLayout();
260 }
260 }
261 }
261 }
262
262
263 /*!
263 /*!
264 \internal \a event see QGraphicsWidget for details
264 \internal \a event see QGraphicsWidget for details
265 */
265 */
266 void QLegend::hideEvent(QHideEvent *event)
266 void QLegend::hideEvent(QHideEvent *event)
267 {
267 {
268 QGraphicsWidget::hideEvent(event);
268 QGraphicsWidget::hideEvent(event);
269 setEnabled(false);
269 setEnabled(false);
270 d_ptr->updateLayout();
270 d_ptr->updateLayout();
271 }
271 }
272
272
273 /*!
273 /*!
274 \internal \a event see QGraphicsWidget for details
274 \internal \a event see QGraphicsWidget for details
275 */
275 */
276 void QLegend::showEvent(QShowEvent *event)
276 void QLegend::showEvent(QShowEvent *event)
277 {
277 {
278 QGraphicsWidget::showEvent(event);
278 QGraphicsWidget::showEvent(event);
279 setEnabled(true);
279 setEnabled(true);
280 d_ptr->updateLayout();
280 d_ptr->updateLayout();
281 }
281 }
282
282
283 qreal QLegend::minWidth() const
283 qreal QLegend::minWidth() const
284 {
284 {
285 return d_ptr->m_minWidth;
285 return d_ptr->m_minWidth;
286 }
286 }
287
287
288 qreal QLegend::minHeight() const
288 qreal QLegend::minHeight() const
289 {
289 {
290 return d_ptr->m_minHeight;
290 return d_ptr->m_minHeight;
291 }
291 }
292
292
293 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
293 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
294
294
295 QLegendPrivate::QLegendPrivate(ChartPresenter* presenter,QLegend *q):
295 QLegendPrivate::QLegendPrivate(ChartPresenter* presenter, QChart *chart, QLegend *q):
296 q_ptr(q),
296 q_ptr(q),
297 m_presenter(presenter),
297 m_presenter(presenter),
298 m_markers(new QGraphicsItemGroup(q)),
298 m_chart(chart),
299 m_alignment(QLegend::AlignmentTop),
299 m_markers(new QGraphicsItemGroup(q)),
300 m_offsetX(0),
300 m_alignment(QLegend::AlignmentTop),
301 m_offsetY(0),
301 m_offsetX(0),
302 m_minWidth(0),
302 m_offsetY(0),
303 m_minHeight(0),
303 m_minWidth(0),
304 m_width(0),
304 m_minHeight(0),
305 m_height(0),
305 m_width(0),
306 m_attachedToChart(true),
306 m_height(0),
307 m_backgroundVisible(false)
307 m_attachedToChart(true),
308 m_backgroundVisible(false)
308 {
309 {
309
310
310 }
311 }
311
312
312 QLegendPrivate::~QLegendPrivate()
313 QLegendPrivate::~QLegendPrivate()
313 {
314 {
314
315
315 }
316 }
316
317
317 void QLegendPrivate::setOffset(qreal x, qreal y)
318 void QLegendPrivate::setOffset(qreal x, qreal y)
318 {
319 {
319
320
320 switch(m_alignment) {
321 switch(m_alignment) {
321
322
322 case QLegend::AlignmentTop:
323 case QLegend::AlignmentTop:
323 case QLegend::AlignmentBottom: {
324 case QLegend::AlignmentBottom: {
324 if(m_width<=m_rect.width()) return;
325 if(m_width<=m_rect.width()) return;
325
326
326 if (x != m_offsetX) {
327 if (x != m_offsetX) {
327 m_offsetX = qBound(qreal(0), x, m_width - m_rect.width());
328 m_offsetX = qBound(qreal(0), x, m_width - m_rect.width());
328 m_markers->setPos(-m_offsetX,m_rect.top());
329 m_markers->setPos(-m_offsetX,m_rect.top());
329 }
330 }
330 break;
331 break;
331 }
332 }
332 case QLegend::AlignmentLeft:
333 case QLegend::AlignmentLeft:
333 case QLegend::AlignmentRight: {
334 case QLegend::AlignmentRight: {
334
335
335 if(m_height<=m_rect.height()) return;
336 if(m_height<=m_rect.height()) return;
336
337
337 if (y != m_offsetY) {
338 if (y != m_offsetY) {
338 m_offsetY = qBound(qreal(0), y, m_height - m_rect.height());
339 m_offsetY = qBound(qreal(0), y, m_height - m_rect.height());
339 m_markers->setPos(m_rect.left(),-m_offsetY);
340 m_markers->setPos(m_rect.left(),-m_offsetY);
340 }
341 }
341 break;
342 break;
342 }
343 }
343 }
344 }
344 }
345 }
345
346
346
347
347 void QLegendPrivate::updateLayout()
348 void QLegendPrivate::updateLayout()
348 {
349 {
349 m_offsetX=0;
350 m_offsetX=0;
350 QList<QGraphicsItem *> items = m_markers->childItems();
351 QList<QGraphicsItem *> items = m_markers->childItems();
351
352
352 if(items.isEmpty()) return;
353 if(items.isEmpty()) return;
353
354
354 m_minWidth=0;
355 m_minWidth=0;
355 m_minHeight=0;
356 m_minHeight=0;
356
357
357 switch(m_alignment) {
358 switch(m_alignment) {
358
359
359 case QLegend::AlignmentTop:
360 case QLegend::AlignmentTop:
360 case QLegend::AlignmentBottom: {
361 case QLegend::AlignmentBottom: {
361 QPointF point = m_rect.topLeft();
362 QPointF point = m_rect.topLeft();
362 m_width = 0;
363 m_width = 0;
363 foreach (QGraphicsItem *item, items) {
364 foreach (QGraphicsItem *item, items) {
364 item->setPos(point.x(),m_rect.height()/2 -item->boundingRect().height()/2);
365 item->setPos(point.x(),m_rect.height()/2 -item->boundingRect().height()/2);
365 const QRectF& rect = item->boundingRect();
366 const QRectF& rect = item->boundingRect();
366 qreal w = rect.width();
367 qreal w = rect.width();
367 m_minWidth=qMax(m_minWidth,w);
368 m_minWidth=qMax(m_minWidth,w);
368 m_minHeight=qMax(m_minHeight,rect.height());
369 m_minHeight=qMax(m_minHeight,rect.height());
369 m_width+=w;
370 m_width+=w;
370 point.setX(point.x() + w);
371 point.setX(point.x() + w);
371 }
372 }
372 if(m_width<m_rect.width()) {
373 if(m_width<m_rect.width()) {
373 m_markers->setPos(m_rect.width()/2-m_width/2,m_rect.top());
374 m_markers->setPos(m_rect.width()/2-m_width/2,m_rect.top());
374 }
375 }
375 else {
376 else {
376 m_markers->setPos(m_rect.topLeft());
377 m_markers->setPos(m_rect.topLeft());
377 }
378 }
378 m_height=m_minHeight;
379 m_height=m_minHeight;
379 }
380 }
380 break;
381 break;
381 case QLegend::AlignmentLeft:
382 case QLegend::AlignmentLeft:
382 case QLegend::AlignmentRight: {
383 case QLegend::AlignmentRight: {
383 QPointF point = m_rect.topLeft();
384 QPointF point = m_rect.topLeft();
384 m_height = 0;
385 m_height = 0;
385 foreach (QGraphicsItem *item, items) {
386 foreach (QGraphicsItem *item, items) {
386 item->setPos(point);
387 item->setPos(point);
387 const QRectF& rect = item->boundingRect();
388 const QRectF& rect = item->boundingRect();
388 qreal h = rect.height();
389 qreal h = rect.height();
389 m_minWidth=qMax(m_minWidth,rect.width());
390 m_minWidth=qMax(m_minWidth,rect.width());
390 m_minHeight=qMax(m_minHeight,h);
391 m_minHeight=qMax(m_minHeight,h);
391 m_height+=h;
392 m_height+=h;
392 point.setY(point.y() + h);
393 point.setY(point.y() + h);
393 }
394 }
394 if(m_height<m_rect.height()) {
395 if(m_height<m_rect.height()) {
395 m_markers->setPos(m_rect.left(),m_rect.height()/2-m_height/2);
396 m_markers->setPos(m_rect.left(),m_rect.height()/2-m_height/2);
396 }
397 }
397 else {
398 else {
398 m_markers->setPos(m_rect.topLeft());
399 m_markers->setPos(m_rect.topLeft());
399 }
400 }
400 m_width=m_minWidth;
401 m_width=m_minWidth;
401 }
402 }
402 break;
403 break;
403 }
404 }
404
405
405 if (m_attachedToChart) {
406 if (m_attachedToChart) {
406 m_presenter->updateLayout();
407 m_presenter->updateLayout();
407 }
408 }
408 }
409 }
409
410
411 void QLegendPrivate::attachToChart()
412 {
413 m_attachedToChart = true;
414 q_ptr->setParent(m_chart);
415 }
416
410 void QLegendPrivate::handleSeriesAdded(QAbstractSeries *series, Domain *domain)
417 void QLegendPrivate::handleSeriesAdded(QAbstractSeries *series, Domain *domain)
411 {
418 {
412 Q_UNUSED(domain)
419 Q_UNUSED(domain)
413
420
414 QList<LegendMarker*> markers = series->d_ptr->createLegendMarker(q_ptr);
421 QList<LegendMarker*> markers = series->d_ptr->createLegendMarker(q_ptr);
415 foreach(LegendMarker* marker , markers)
422 foreach(LegendMarker* marker , markers)
416 m_markers->addToGroup(marker);
423 m_markers->addToGroup(marker);
417
424
418 if(series->type() == QAbstractSeries::SeriesTypePie)
425 if(series->type() == QAbstractSeries::SeriesTypePie)
419 {
426 {
420 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
427 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
421 QObject::connect(pieSeries, SIGNAL(added(QList<QPieSlice*>)), this, SLOT(handleUpdatePieSeries()));
428 QObject::connect(pieSeries, SIGNAL(added(QList<QPieSlice*>)), this, SLOT(handleUpdatePieSeries()));
422 QObject::connect(pieSeries, SIGNAL(removed(QList<QPieSlice*>)), this, SLOT(handleUpdatePieSeries()));
429 QObject::connect(pieSeries, SIGNAL(removed(QList<QPieSlice*>)), this, SLOT(handleUpdatePieSeries()));
423 }
430 }
424
431
425 updateLayout();
432 updateLayout();
426 }
433 }
427
434
428 void QLegendPrivate::handleSeriesRemoved(QAbstractSeries *series)
435 void QLegendPrivate::handleSeriesRemoved(QAbstractSeries *series)
429 {
436 {
430
437
431 QList<QGraphicsItem *> items = m_markers->childItems();
438 QList<QGraphicsItem *> items = m_markers->childItems();
432
439
433 foreach (QGraphicsItem *markers, items) {
440 foreach (QGraphicsItem *markers, items) {
434 LegendMarker *marker = static_cast<LegendMarker*>(markers);
441 LegendMarker *marker = static_cast<LegendMarker*>(markers);
435 if (marker->series() == series) {
442 if (marker->series() == series) {
436 delete marker;
443 delete marker;
437 }
444 }
438 }
445 }
439
446
440 if(series->type() == QAbstractSeries::SeriesTypePie)
447 if(series->type() == QAbstractSeries::SeriesTypePie)
441 {
448 {
442 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
449 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
443 QObject::disconnect(pieSeries, SIGNAL(added(QList<QPieSlice*>)), this, SLOT(handleUpdatePieSeries()));
450 QObject::disconnect(pieSeries, SIGNAL(added(QList<QPieSlice*>)), this, SLOT(handleUpdatePieSeries()));
444 QObject::disconnect(pieSeries, SIGNAL(removed(QList<QPieSlice*>)), this, SLOT(handleUpdatePieSeries()));
451 QObject::disconnect(pieSeries, SIGNAL(removed(QList<QPieSlice*>)), this, SLOT(handleUpdatePieSeries()));
445 }
452 }
446
453
447 updateLayout();
454 updateLayout();
448 }
455 }
449
456
450 void QLegendPrivate::handleSeriesUpdated(QAbstractSeries *series)
457 void QLegendPrivate::handleSeriesUpdated(QAbstractSeries *series)
451 {
458 {
452 // TODO: find out which markers are are added or removed. Update them
459 // TODO: find out which markers are are added or removed. Update them
453 // TODO: better implementation
460 // TODO: better implementation
454 handleSeriesRemoved(series);
461 handleSeriesRemoved(series);
455 Domain domain;
462 Domain domain;
456 handleSeriesAdded(series, &domain);
463 handleSeriesAdded(series, &domain);
457 }
464 }
458
465
459 void QLegendPrivate::handleUpdatePieSeries()
466 void QLegendPrivate::handleUpdatePieSeries()
460 {
467 {
461 //TODO: reimplement to be optimal
468 //TODO: reimplement to be optimal
462 QPieSeries* series = qobject_cast<QPieSeries *> (sender());
469 QPieSeries* series = qobject_cast<QPieSeries *> (sender());
463 Q_ASSERT(series);
470 Q_ASSERT(series);
464 handleSeriesRemoved(series);
471 handleSeriesRemoved(series);
465 handleSeriesAdded(series, 0);
472 handleSeriesAdded(series, 0);
466 }
473 }
467
474
468 #include "moc_qlegend.cpp"
475 #include "moc_qlegend.cpp"
469 #include "moc_qlegend_p.cpp"
476 #include "moc_qlegend_p.cpp"
470
477
471 QTCOMMERCIALCHART_END_NAMESPACE
478 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,79 +1,82
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 // W A R N I N G
21 // W A R N I N G
22 // -------------
22 // -------------
23 //
23 //
24 // This file is not part of the QtCommercial Chart API. It exists purely as an
24 // This file is not part of the QtCommercial Chart API. It exists purely as an
25 // implementation detail. This header file may change from version to
25 // implementation detail. This header file may change from version to
26 // version without notice, or even be removed.
26 // version without notice, or even be removed.
27 //
27 //
28 // We mean it.
28 // We mean it.
29
29
30 #ifndef QLEGEND_P_H
30 #ifndef QLEGEND_P_H
31 #define QLEGEND_P_H
31 #define QLEGEND_P_H
32
32
33 #include "qlegend.h"
33 #include "qlegend.h"
34
34
35 QTCOMMERCIALCHART_BEGIN_NAMESPACE
35 QTCOMMERCIALCHART_BEGIN_NAMESPACE
36
36
37 class QChart;
37 class ChartPresenter;
38 class ChartPresenter;
38 class QAbstractSeries;
39 class QAbstractSeries;
39
40
40 class QLegendPrivate : public QObject
41 class QLegendPrivate : public QObject
41 {
42 {
42 Q_OBJECT
43 Q_OBJECT
43 public:
44 public:
44 QLegendPrivate(ChartPresenter *chart,QLegend *q);
45 QLegendPrivate(ChartPresenter *presenter, QChart *chart, QLegend *q);
45 ~QLegendPrivate();
46 ~QLegendPrivate();
46
47
47 void setOffset(qreal x, qreal y);
48 void setOffset(qreal x, qreal y);
48 void updateLayout();
49 void updateLayout();
50 void attachToChart();
49
51
50 public Q_SLOTS:
52 public Q_SLOTS:
51 void handleSeriesAdded(QAbstractSeries *series, Domain *domain);
53 void handleSeriesAdded(QAbstractSeries *series, Domain *domain);
52 void handleSeriesRemoved(QAbstractSeries *series);
54 void handleSeriesRemoved(QAbstractSeries *series);
53 void handleSeriesUpdated(QAbstractSeries *series);
55 void handleSeriesUpdated(QAbstractSeries *series);
54 void handleUpdatePieSeries(); //TODO remove this function
56 void handleUpdatePieSeries(); //TODO remove this function
55
57
56 private:
58 private:
57 QLegend *q_ptr;
59 QLegend *q_ptr;
58 ChartPresenter *m_presenter;
60 ChartPresenter *m_presenter;
61 QChart* m_chart;
59 QGraphicsItemGroup* m_markers;
62 QGraphicsItemGroup* m_markers;
60 QLegend::Alignments m_alignment;
63 QLegend::Alignments m_alignment;
61 QBrush m_brush;
64 QBrush m_brush;
62 QPen m_pen;
65 QPen m_pen;
63 QRectF m_rect;
66 QRectF m_rect;
64 qreal m_offsetX;
67 qreal m_offsetX;
65 qreal m_offsetY;
68 qreal m_offsetY;
66 qreal m_minWidth;
69 qreal m_minWidth;
67 qreal m_minHeight;
70 qreal m_minHeight;
68 qreal m_width;
71 qreal m_width;
69 qreal m_height;
72 qreal m_height;
70 bool m_attachedToChart;
73 bool m_attachedToChart;
71 bool m_backgroundVisible;
74 bool m_backgroundVisible;
72
75
73 friend class QLegend;
76 friend class QLegend;
74
77
75 };
78 };
76
79
77 QTCOMMERCIALCHART_END_NAMESPACE
80 QTCOMMERCIALCHART_END_NAMESPACE
78
81
79 #endif
82 #endif
General Comments 0
You need to be logged in to leave comments. Login now