##// END OF EJS Templates
legend detach example. Bug fixes to legend.
sauimone -
r1263:d5f432b5ffc0
parent child
Show More
@@ -0,0 +1,12
1 !include( ../examples.pri ) {
2 error( "Couldn't find the examples.pri file!" )
3 }
4
5 TARGET = legend
6 SOURCES += main.cpp \
7 mainwidget.cpp
8
9 !system_build:mac: QMAKE_POST_LINK += "$$MAC_POST_LINK_PREFIX $$MAC_EXAMPLES_BIN_DIR"
10
11 HEADERS += \
12 mainwidget.h
@@ -0,0 +1,41
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
14 **
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
18 **
19 ****************************************************************************/
20
21 #include "mainwidget.h"
22
23 #include <QApplication>
24 #include <QMainWindow>
25 #include <QChartView>
26 #include <QBarSeries>
27 #include <QBarSet>
28 #include <QLegend>
29
30 QTCOMMERCIALCHART_USE_NAMESPACE
31
32 int main(int argc, char *argv[])
33 {
34 QApplication a(argc, argv);
35
36 MainWidget w;
37 w.resize(1024,768);
38 w.show();
39
40 return a.exec();
41 }
@@ -0,0 +1,134
1 #include "mainwidget.h"
2 #include <QChart>
3 #include <QChartView>
4 #include <QPushButton>
5 #include <QLabel>
6 #include <QDebug>
7 #include <QBarSet>
8 #include <QBarSeries>
9 #include <QLegend>
10
11 QTCOMMERCIALCHART_USE_NAMESPACE
12
13 MainWidget::MainWidget(QWidget *parent) :
14 QWidget(parent)
15 {
16 m_setCount = 0;
17 m_chart = new QChart();
18
19 m_buttonLayout = new QGridLayout();
20 QPushButton *detachLegendButton = new QPushButton("detach legend");
21 connect(detachLegendButton, SIGNAL(clicked()), this, SLOT(detachLegend()));
22 m_buttonLayout->addWidget(detachLegendButton, 0, 0);
23 QPushButton *attachLegendButton = new QPushButton("attach legend");
24 connect(attachLegendButton, SIGNAL(clicked()), this, SLOT(attachLegend()));
25 m_buttonLayout->addWidget(attachLegendButton, 1, 0);
26
27 QPushButton *addSetButton = new QPushButton("add barset");
28 connect(addSetButton, SIGNAL(clicked()), this, SLOT(addBarset()));
29 m_buttonLayout->addWidget(addSetButton, 2, 0);
30 QPushButton *removeBarsetButton = new QPushButton("remove barset");
31 connect(removeBarsetButton, SIGNAL(clicked()), this, SLOT(removeBarset()));
32 m_buttonLayout->addWidget(removeBarsetButton, 3, 0);
33
34 // add row with empty label to make all the other rows static
35 m_buttonLayout->addWidget(new QLabel(""), m_buttonLayout->rowCount(), 0);
36 m_buttonLayout->setRowStretch(m_buttonLayout->rowCount() - 1, 1);
37
38 // Create chart view with the chart
39 m_chartView = new QChartView(m_chart, this);
40 m_chartView->setRubberBand(QChartView::HorizonalRubberBand);
41
42 m_customView = new QGraphicsView(this);
43 m_customScene = new QGraphicsScene(this);
44 m_customView->setScene(m_customScene);
45
46 // Create layout for grid and detached legend
47 m_mainLayout = new QGridLayout();
48 m_mainLayout->addLayout(m_buttonLayout, 0, 0);
49 m_mainLayout->addWidget(m_chartView, 0, 1, 3, 1);
50 m_mainLayout->addWidget(m_customView, 0, 2, 3, 1);
51 setLayout(m_mainLayout);
52
53 createSeries();
54 }
55
56 void MainWidget::createSeries()
57 {
58 //![1]
59 m_series = new QBarSeries();
60
61 addBarset();
62 addBarset();
63 addBarset();
64 addBarset();
65 //![1]
66
67 //![2]
68 m_chart->addSeries(m_series);
69 m_chart->setTitle("Legend detach example");
70 //![2]
71
72 //![3]
73 m_chart->legend()->setVisible(true);
74 m_chart->legend()->setAlignment(QLegend::AlignmentBottom);
75 m_chart->axisY()->setNiceNumbersEnabled(true);
76 //![3]
77
78 //![4]
79 m_chartView->setRenderHint(QPainter::Antialiasing);
80 //![4]
81 }
82
83 void MainWidget::attachLegend()
84 {
85 qDebug() << "attach legend";
86 QLegend *legend = m_chart->legend();
87
88 if (m_customScene->items().contains(legend)) {
89 qDebug() << "legend removed from other scene";
90 m_customScene->removeItem(legend);
91 legend->setParent(m_chart);
92 legend->attachToChart();
93 }
94
95 // legend->attachToChart();
96 // This causes redraw
97 QSize size(1,1);
98 this->resize(this->size() + size);
99 this->resize(this->size() - size);
100 }
101
102 void MainWidget::detachLegend()
103 {
104 qDebug() << "detach legend";
105 QLegend *legend = m_chart->legend();
106 legend->detachFromChart();
107
108 m_customScene->addItem(legend);
109 // m_mainLayout->addWidget(legend,0,2,3,1);
110 // setLayout(m_layout);
111
112 // TODO: layout legend to somewhere else
113 // This causes redraw
114 QSize size(1,1);
115 this->resize(this->size() + size);
116 this->resize(this->size() - size);
117 }
118
119 void MainWidget::addBarset()
120 {
121 QBarSet *barSet = new QBarSet(QString("set ") + QString::number(m_setCount));
122 m_setCount++;
123 qreal delta = m_series->barsetCount() * 0.1;
124 *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);
125 m_series->append(barSet);
126 }
127
128 void MainWidget::removeBarset()
129 {
130 QList<QBarSet*> sets = m_series->barSets();
131 if (sets.count() > 0) {
132 m_series->remove(sets.at(sets.count()-1));
133 }
134 }
@@ -0,0 +1,49
1 #ifndef MAINWIDGET_H
2 #define MAINWIDGET_H
3
4 #include "qchartglobal.h"
5 #include "qchart.h"
6 #include "qchartview.h"
7 #include <QWidget>
8 #include <QGraphicsWidget>
9 #include <QGridLayout>
10 #include <QGraphicsGridLayout>
11
12 QTCOMMERCIALCHART_USE_NAMESPACE
13
14 class MainWidget : public QWidget
15 //class MainWidget : public QGraphicsWidget
16 {
17 Q_OBJECT
18 public:
19 explicit MainWidget(QWidget *parent = 0);
20
21 void createSeries();
22
23 signals:
24
25 public slots:
26 void attachLegend();
27 void detachLegend();
28 void addBarset();
29 void removeBarset();
30
31 private:
32
33 QChart *m_chart;
34 QBarSeries *m_series;
35
36 QGraphicsScene *m_scene;
37 QChartView *m_chartView;
38 QGridLayout *m_mainLayout;
39 QGridLayout *m_buttonLayout;
40
41 QGraphicsView *m_customView;
42 QGraphicsScene *m_customScene;
43 QGraphicsGridLayout *m_customLayout;
44
45
46 int m_setCount;
47 };
48
49 #endif // MAINWIDGET_H
@@ -1,23 +1,24
1 CURRENTLY_BUILDING_COMPONENTS = "examples"
1 CURRENTLY_BUILDING_COMPONENTS = "examples"
2 !include( ../config.pri ) {
2 !include( ../config.pri ) {
3 error( "Couldn't find the config.pri file!" )
3 error( "Couldn't find the config.pri file!" )
4 }
4 }
5
5
6 TEMPLATE = subdirs
6 TEMPLATE = subdirs
7 SUBDIRS += \
7 SUBDIRS += \
8 areachart \
8 areachart \
9 barchart \
9 barchart \
10 customchart \
10 customchart \
11 linechart \
11 linechart \
12 percentbarchart \
12 percentbarchart \
13 piechart \
13 piechart \
14 piechartdrilldown \
14 piechartdrilldown \
15 presenterchart \
15 presenterchart \
16 scatterchart \
16 scatterchart \
17 scatterinteractions \
17 scatterinteractions \
18 splinechart \
18 splinechart \
19 stackedbarchart \
19 stackedbarchart \
20 stackedbarchartdrilldown \
20 stackedbarchartdrilldown \
21 zoomlinechart \
21 zoomlinechart \
22 modeldata \
22 modeldata \
23 groupedbarchart
23 groupedbarchart \
24 legend
@@ -1,492 +1,530
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 "qbarseries.h"
21 #include "qbarseries.h"
22 #include "qbarseries_p.h"
22 #include "qbarseries_p.h"
23 #include "qbarset.h"
23 #include "qbarset.h"
24 #include "qbarset_p.h"
24 #include "qbarset_p.h"
25 #include "domain_p.h"
25 #include "domain_p.h"
26 #include "legendmarker_p.h"
26 #include "legendmarker_p.h"
27 #include "chartdataset_p.h"
27 #include "chartdataset_p.h"
28 #include "charttheme_p.h"
28 #include "charttheme_p.h"
29 #include "chartanimator_p.h"
29 #include "chartanimator_p.h"
30
30
31 QTCOMMERCIALCHART_BEGIN_NAMESPACE
31 QTCOMMERCIALCHART_BEGIN_NAMESPACE
32
32
33 /*!
33 /*!
34 \class QBarSeries
34 \class QBarSeries
35 \brief part of QtCommercial chart API.
35 \brief part of QtCommercial chart API.
36 \mainclass
36 \mainclass
37
37
38 QBarSeries represents a series of data shown as bars. The purpose of this class is to draw bars to
38 QBarSeries represents a series of data shown as bars. The purpose of this class is to draw bars to
39 the position defined by data. Single bar is defined by QPointF, where x value is the x-coordinate of the bar
39 the position defined by data. Single bar is defined by QPointF, where x value is the x-coordinate of the bar
40 and y-value is the height of the bar. The category names are ignored with this series and x-axis
40 and y-value is the height of the bar. The category names are ignored with this series and x-axis
41 shows the x-values.
41 shows the x-values.
42
42
43 See the \l {BarChart Example} {bar chart example} to learn how to create a simple bar chart.
43 See the \l {BarChart Example} {bar chart example} to learn how to create a simple bar chart.
44 \image examples_barchart.png
44 \image examples_barchart.png
45
45
46 \sa QBarSet, QStackedBarSeries, QPercentBarSeries
46 \sa QBarSet, QStackedBarSeries, QPercentBarSeries
47 */
47 */
48
48
49 /*!
49 /*!
50 \fn void QBarSeries::clicked(QBarSet *barset, QString category)
50 \fn void QBarSeries::clicked(QBarSet *barset, QString category)
51
51
52 The signal is emitted if the user clicks with a mouse on top of QBarSet \a barset of category \a category
52 The signal is emitted if the user clicks with a mouse on top of QBarSet \a barset of category \a category
53 contained by the series.
53 contained by the series.
54 */
54 */
55
55
56 /*!
56 /*!
57 \fn void QBarSeries::hovered(QBarSet* barset, bool status)
57 \fn void QBarSeries::hovered(QBarSet* barset, bool status)
58
58
59 The signal is emitted if mouse is hovered on top of series.
59 The signal is emitted if mouse is hovered on top of series.
60 Parameter \a barset is the pointer of barset, where hover happened.
60 Parameter \a barset is the pointer of barset, where hover happened.
61 Parameter \a status is true, if mouse entered on top of series, false if mouse left from top of series.
61 Parameter \a status is true, if mouse entered on top of series, false if mouse left from top of series.
62 */
62 */
63
63
64 /*!
64 /*!
65 Constructs empty QBarSeries.
65 Constructs empty QBarSeries.
66 QBarSeries is QObject which is a child of a \a parent.
66 QBarSeries is QObject which is a child of a \a parent.
67 */
67 */
68 QBarSeries::QBarSeries(QObject *parent) :
68 QBarSeries::QBarSeries(QObject *parent) :
69 QAbstractSeries(*new QBarSeriesPrivate(this),parent)
69 QAbstractSeries(*new QBarSeriesPrivate(this),parent)
70 {
70 {
71 }
71 }
72
72
73 /*!
73 /*!
74 Destructs barseries and owned barsets.
74 Destructs barseries and owned barsets.
75 */
75 */
76 QBarSeries::~QBarSeries()
76 QBarSeries::~QBarSeries()
77 {
77 {
78 // NOTE: d_ptr destroyed by QObject
78 Q_D(QBarSeries);
79 if(d->m_dataset){
80 d->m_dataset->removeSeries(this);
81 }
79 }
82 }
80
83
81 /*!
84 /*!
82 \internal
85 \internal
83 */
86 */
84 QBarSeries::QBarSeries(QBarSeriesPrivate &d, QObject *parent) :
87 QBarSeries::QBarSeries(QBarSeriesPrivate &d, QObject *parent) :
85 QAbstractSeries(d,parent)
88 QAbstractSeries(d,parent)
86 {
89 {
87 }
90 }
88
91
89 /*!
92 /*!
90 Returns the type of series. Derived classes override this.
93 Returns the type of series. Derived classes override this.
91 */
94 */
92 QAbstractSeries::SeriesType QBarSeries::type() const
95 QAbstractSeries::SeriesType QBarSeries::type() const
93 {
96 {
94 return QAbstractSeries::SeriesTypeBar;
97 return QAbstractSeries::SeriesTypeBar;
95 }
98 }
96
99
97 /*!
100 /*!
98 Sets the \a categories, which are used to to group the data.
101 Sets the \a categories, which are used to to group the data.
99 */
102 */
100 void QBarSeries::setCategories(QBarCategories categories)
103 void QBarSeries::setCategories(QBarCategories categories)
101 {
104 {
102 Q_D(QBarSeries);
105 Q_D(QBarSeries);
103 d->setCategories(categories);
106 d->setCategories(categories);
104 emit d->categoriesUpdated();
107 emit d->categoriesUpdated();
105 }
108 }
106
109
107 /*!
110 /*!
108 Adds a set of bars to series. Takes ownership of \a set. If the set is null or is already in series, it won't be appended.
111 Adds a set of bars to series. Takes ownership of \a set. If the set is null or is already in series, it won't be appended.
109 Returns true, if appending succeeded.
112 Returns true, if appending succeeded.
110
113
111 */
114 */
112 bool QBarSeries::append(QBarSet *set)
115 bool QBarSeries::append(QBarSet *set)
113 {
116 {
114 Q_D(QBarSeries);
117 Q_D(QBarSeries);
115 if ((d->m_barSets.contains(set)) || (set == 0)) {
118 return d->append(set);
116 // Fail if set is already in list or set is null.
117 return false;
118 }
119 d->m_barSets.append(set);
120 QObject::connect(set->d_ptr.data(), SIGNAL(updatedBars()), d, SLOT(barsetChanged()));
121 emit d->restructuredBars();
122 return true;
123 }
119 }
124
120
125 /*!
121 /*!
126 Removes a set of bars from series. Releases ownership of \a set. Doesn't delete \a set.
122 Removes a set of bars from series. Releases ownership of \a set. Doesn't delete \a set.
127 Returns true, if set was removed.
123 Returns true, if set was removed.
128 */
124 */
129 bool QBarSeries::remove(QBarSet *set)
125 bool QBarSeries::remove(QBarSet *set)
130 {
126 {
131 Q_D(QBarSeries);
127 Q_D(QBarSeries);
132 if (!d->m_barSets.contains(set)) {
128 return d->remove(set);
133 // Fail if set is not in list
134 return false;
135 }
136 d->m_barSets.removeOne(set);
137 QObject::disconnect(set->d_ptr.data(), SIGNAL(updatedBars()), d, SLOT(barsetChanged()));
138 emit d->restructuredBars();
139 return true;
140 }
129 }
141
130
142 /*!
131 /*!
143 Adds a list of barsets to series. Takes ownership of \a sets.
132 Adds a list of barsets to series. Takes ownership of \a sets.
144 Returns true, if all sets were appended succesfully. If any of the sets is null or is already appended to series,
133 Returns true, if all sets were appended succesfully. If any of the sets is null or is already appended to series,
145 nothing is appended and function returns false. If any of the sets is in list more than once, nothing is appended
134 nothing is appended and function returns false. If any of the sets is in list more than once, nothing is appended
146 and function returns false.
135 and function returns false.
147 */
136 */
148 bool QBarSeries::append(QList<QBarSet* > sets)
137 bool QBarSeries::append(QList<QBarSet* > sets)
149 {
138 {
150 Q_D(QBarSeries);
139 Q_D(QBarSeries);
151 foreach (QBarSet* set, sets) {
140 return d->append(sets);
152 if ((set == 0) || (d->m_barSets.contains(set))) {
153 // Fail if any of the sets is null or is already appended.
154 return false;
155 }
156 if (sets.count(set) != 1) {
157 // Also fail if same set is more than once in given list.
158 return false;
159 }
160 }
161
162 foreach (QBarSet* set, sets) {
163 d->m_barSets.append(set);
164 QObject::connect(set->d_ptr.data(), SIGNAL(updatedBars()), d, SLOT(barsetChanged()));
165 }
166 emit d->restructuredBars();
167 return true;
168 }
141 }
169
142
170 /*!
143 /*!
171 Removes a list of barsets from series. Releases ownership of \a sets. Doesn't delete \a sets.
144 Removes a list of barsets from series. Releases ownership of \a sets. Doesn't delete \a sets.
172 */
145 */
173 bool QBarSeries::remove(QList<QBarSet* > sets)
146 bool QBarSeries::remove(QList<QBarSet* > sets)
174 {
147 {
175 Q_D(QBarSeries);
148 Q_D(QBarSeries);
176
149 return d->remove(sets);
177 bool setsRemoved = false;
178 foreach (QBarSet* set, sets) {
179 if (d->m_barSets.contains(set)) {
180 d->m_barSets.removeOne(set);
181 QObject::disconnect(set->d_ptr.data(), SIGNAL(updatedBars()), d, SLOT(barsetChanged()));
182 setsRemoved = true;
183 }
184 }
185
186 if (setsRemoved) {
187 emit d->restructuredBars();
188 }
189 return setsRemoved;
190 }
150 }
191
151
192 /*!
152 /*!
193 Returns number of sets in series.
153 Returns number of sets in series.
194 */
154 */
195 int QBarSeries::barsetCount() const
155 int QBarSeries::barsetCount() const
196 {
156 {
197 Q_D(const QBarSeries);
157 Q_D(const QBarSeries);
198 return d->m_barSets.count();
158 return d->m_barSets.count();
199 }
159 }
200
160
201 /*!
161 /*!
202 Returns number of categories in series
162 Returns number of categories in series
203 */
163 */
204 int QBarSeries::categoryCount() const
164 int QBarSeries::categoryCount() const
205 {
165 {
206 Q_D(const QBarSeries);
166 Q_D(const QBarSeries);
207 return d->categoryCount();
167 return d->categoryCount();
208 }
168 }
209
169
210 /*!
170 /*!
211 Returns a list of sets in series. Keeps ownership of sets.
171 Returns a list of sets in series. Keeps ownership of sets.
212 */
172 */
213 QList<QBarSet*> QBarSeries::barSets() const
173 QList<QBarSet*> QBarSeries::barSets() const
214 {
174 {
215 Q_D(const QBarSeries);
175 Q_D(const QBarSeries);
216 return d->m_barSets;
176 return d->m_barSets;
217 }
177 }
218
178
219 /*!
179 /*!
220 Returns the bar categories of the series.
180 Returns the bar categories of the series.
221 */
181 */
222 QBarCategories QBarSeries::categories() const
182 QBarCategories QBarSeries::categories() const
223 {
183 {
224 Q_D(const QBarSeries);
184 Q_D(const QBarSeries);
225 return d->categories();
185 return d->categories();
226 }
186 }
227
187
228 /*!
188 /*!
229 Sets the visibility of labels in series to \a visible
189 Sets the visibility of labels in series to \a visible
230 */
190 */
231 void QBarSeries::setLabelsVisible(bool visible)
191 void QBarSeries::setLabelsVisible(bool visible)
232 {
192 {
233 Q_D(QBarSeries);
193 Q_D(QBarSeries);
234 if (d->m_labelsVisible != visible) {
194 if (d->m_labelsVisible != visible) {
235 d->m_labelsVisible = visible;
195 d->m_labelsVisible = visible;
236 emit d->updatedBars();
196 emit d->updatedBars();
237 }
197 }
238 }
198 }
239
199
240 bool QBarSeries::isLabelsVisible() const
200 bool QBarSeries::isLabelsVisible() const
241 {
201 {
242 Q_D(const QBarSeries);
202 Q_D(const QBarSeries);
243 return d->m_labelsVisible;
203 return d->m_labelsVisible;
244 }
204 }
245
205
246 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
206 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
247
207
248 QBarSeriesPrivate::QBarSeriesPrivate(QBarSeries *q) :
208 QBarSeriesPrivate::QBarSeriesPrivate(QBarSeries *q) :
249 QAbstractSeriesPrivate(q),
209 QAbstractSeriesPrivate(q),
250 m_barMargin(0.05), // Default value is 5% of category width
210 m_barMargin(0.05), // Default value is 5% of category width
251 m_labelsVisible(false)
211 m_labelsVisible(false)
252 {
212 {
253 }
213 }
254
214
255 void QBarSeriesPrivate::setCategories(QBarCategories categories)
215 void QBarSeriesPrivate::setCategories(QBarCategories categories)
256 {
216 {
257 m_categories = categories;
217 m_categories = categories;
258 }
218 }
259
219
260 void QBarSeriesPrivate::insertCategory(int index, const QString category)
220 void QBarSeriesPrivate::insertCategory(int index, const QString category)
261 {
221 {
262 m_categories.insert(index, category);
222 m_categories.insert(index, category);
263 emit categoriesUpdated();
223 emit categoriesUpdated();
264 }
224 }
265
225
266 void QBarSeriesPrivate::removeCategory(int index)
226 void QBarSeriesPrivate::removeCategory(int index)
267 {
227 {
268 m_categories.removeAt(index);
228 m_categories.removeAt(index);
269 emit categoriesUpdated();
229 emit categoriesUpdated();
270 }
230 }
271
231
272 int QBarSeriesPrivate::categoryCount() const
232 int QBarSeriesPrivate::categoryCount() const
273 {
233 {
274 if (m_categories.count() > 0) {
234 if (m_categories.count() > 0) {
275 return m_categories.count();
235 return m_categories.count();
276 }
236 }
277
237
278 // No categories defined. return count of longest set.
238 // No categories defined. return count of longest set.
279 int count = 0;
239 int count = 0;
280 for (int i=0; i<m_barSets.count(); i++) {
240 for (int i=0; i<m_barSets.count(); i++) {
281 if (m_barSets.at(i)->count() > count) {
241 if (m_barSets.at(i)->count() > count) {
282 count = m_barSets.at(i)->count();
242 count = m_barSets.at(i)->count();
283 }
243 }
284 }
244 }
285
245
286 return count;
246 return count;
287 }
247 }
288
248
289 QBarCategories QBarSeriesPrivate::categories() const
249 QBarCategories QBarSeriesPrivate::categories() const
290 {
250 {
291 if (m_categories.count() > 0) {
251 if (m_categories.count() > 0) {
292 return m_categories;
252 return m_categories;
293 }
253 }
294
254
295 // No categories defined. retun list of indices.
255 // No categories defined. retun list of indices.
296 QBarCategories categories;
256 QBarCategories categories;
297
257
298 int count = categoryCount();
258 int count = categoryCount();
299 for (int i = 0; i < count; i++) {
259 for (int i = 0; i < count; i++) {
300 categories.append(QString::number(i));
260 categories.append(QString::number(i));
301 }
261 }
302 return categories;
262 return categories;
303 }
263 }
304
264
305 void QBarSeriesPrivate::setBarMargin(qreal margin)
265 void QBarSeriesPrivate::setBarMargin(qreal margin)
306 {
266 {
307 if (margin > 1.0) {
267 if (margin > 1.0) {
308 margin = 1.0;
268 margin = 1.0;
309 } else if (margin < 0.0) {
269 } else if (margin < 0.0) {
310 margin = 0.0;
270 margin = 0.0;
311 }
271 }
312
272
313 m_barMargin = margin;
273 m_barMargin = margin;
314 emit updatedBars();
274 emit updatedBars();
315 }
275 }
316
276
317 qreal QBarSeriesPrivate::barMargin()
277 qreal QBarSeriesPrivate::barMargin()
318 {
278 {
319 return m_barMargin;
279 return m_barMargin;
320 }
280 }
321
281
322 QBarSet* QBarSeriesPrivate::barsetAt(int index)
282 QBarSet* QBarSeriesPrivate::barsetAt(int index)
323 {
283 {
324 return m_barSets.at(index);
284 return m_barSets.at(index);
325 }
285 }
326
286
327 QString QBarSeriesPrivate::categoryName(int category)
287 QString QBarSeriesPrivate::categoryName(int category)
328 {
288 {
329 if ((category >= 0) && (category < m_categories.count())) {
289 if ((category >= 0) && (category < m_categories.count())) {
330 return m_categories.at(category);
290 return m_categories.at(category);
331 }
291 }
332
292
333 return QString::number(category);
293 return QString::number(category);
334 }
294 }
335
295
336 qreal QBarSeriesPrivate::min()
296 qreal QBarSeriesPrivate::min()
337 {
297 {
338 if (m_barSets.count() <= 0) {
298 if (m_barSets.count() <= 0) {
339 return 0;
299 return 0;
340 }
300 }
341 qreal min = INT_MAX;
301 qreal min = INT_MAX;
342
302
343 for (int i = 0; i < m_barSets.count(); i++) {
303 for (int i = 0; i < m_barSets.count(); i++) {
344 int categoryCount = m_barSets.at(i)->count();
304 int categoryCount = m_barSets.at(i)->count();
345 for (int j = 0; j < categoryCount; j++) {
305 for (int j = 0; j < categoryCount; j++) {
346 qreal temp = m_barSets.at(i)->at(j).y();
306 qreal temp = m_barSets.at(i)->at(j).y();
347 if (temp < min)
307 if (temp < min)
348 min = temp;
308 min = temp;
349 }
309 }
350 }
310 }
351 return min;
311 return min;
352 }
312 }
353
313
354 qreal QBarSeriesPrivate::max()
314 qreal QBarSeriesPrivate::max()
355 {
315 {
356 if (m_barSets.count() <= 0) {
316 if (m_barSets.count() <= 0) {
357 return 0;
317 return 0;
358 }
318 }
359 qreal max = INT_MIN;
319 qreal max = INT_MIN;
360
320
361 for (int i = 0; i < m_barSets.count(); i++) {
321 for (int i = 0; i < m_barSets.count(); i++) {
362 int categoryCount = m_barSets.at(i)->count();
322 int categoryCount = m_barSets.at(i)->count();
363 for (int j = 0; j < categoryCount; j++) {
323 for (int j = 0; j < categoryCount; j++) {
364 qreal temp = m_barSets.at(i)->at(j).y();
324 qreal temp = m_barSets.at(i)->at(j).y();
365 if (temp > max)
325 if (temp > max)
366 max = temp;
326 max = temp;
367 }
327 }
368 }
328 }
369
329
370 return max;
330 return max;
371 }
331 }
372
332
373 qreal QBarSeriesPrivate::valueAt(int set, int category)
333 qreal QBarSeriesPrivate::valueAt(int set, int category)
374 {
334 {
375 if ((set < 0) || (set >= m_barSets.count())) {
335 if ((set < 0) || (set >= m_barSets.count())) {
376 // No set, no value.
336 // No set, no value.
377 return 0;
337 return 0;
378 } else if ((category < 0) || (category >= m_barSets.at(set)->count())) {
338 } else if ((category < 0) || (category >= m_barSets.at(set)->count())) {
379 // No category, no value.
339 // No category, no value.
380 return 0;
340 return 0;
381 }
341 }
382
342
383 return m_barSets.at(set)->at(category).y();
343 return m_barSets.at(set)->at(category).y();
384 }
344 }
385
345
386 qreal QBarSeriesPrivate::percentageAt(int set, int category)
346 qreal QBarSeriesPrivate::percentageAt(int set, int category)
387 {
347 {
388 if ((set < 0) || (set >= m_barSets.count())) {
348 if ((set < 0) || (set >= m_barSets.count())) {
389 // No set, no value.
349 // No set, no value.
390 return 0;
350 return 0;
391 } else if ((category < 0) || (category >= m_barSets.at(set)->count())) {
351 } else if ((category < 0) || (category >= m_barSets.at(set)->count())) {
392 // No category, no value.
352 // No category, no value.
393 return 0;
353 return 0;
394 }
354 }
395
355
396 qreal value = m_barSets.at(set)->at(category).y();
356 qreal value = m_barSets.at(set)->at(category).y();
397 qreal sum = categorySum(category);
357 qreal sum = categorySum(category);
398 if ( qFuzzyIsNull(sum) ) {
358 if ( qFuzzyIsNull(sum) ) {
399 return 0;
359 return 0;
400 }
360 }
401
361
402 return value / sum;
362 return value / sum;
403 }
363 }
404
364
405 qreal QBarSeriesPrivate::categorySum(int category)
365 qreal QBarSeriesPrivate::categorySum(int category)
406 {
366 {
407 qreal sum(0);
367 qreal sum(0);
408 int count = m_barSets.count(); // Count sets
368 int count = m_barSets.count(); // Count sets
409 for (int set = 0; set < count; set++) {
369 for (int set = 0; set < count; set++) {
410 if (category < m_barSets.at(set)->count())
370 if (category < m_barSets.at(set)->count())
411 sum += m_barSets.at(set)->at(category).y();
371 sum += m_barSets.at(set)->at(category).y();
412 }
372 }
413 return sum;
373 return sum;
414 }
374 }
415
375
416 qreal QBarSeriesPrivate::absoluteCategorySum(int category)
376 qreal QBarSeriesPrivate::absoluteCategorySum(int category)
417 {
377 {
418 qreal sum(0);
378 qreal sum(0);
419 int count = m_barSets.count(); // Count sets
379 int count = m_barSets.count(); // Count sets
420 for (int set = 0; set < count; set++) {
380 for (int set = 0; set < count; set++) {
421 if (category < m_barSets.at(set)->count())
381 if (category < m_barSets.at(set)->count())
422 sum += qAbs(m_barSets.at(set)->at(category).y());
382 sum += qAbs(m_barSets.at(set)->at(category).y());
423 }
383 }
424 return sum;
384 return sum;
425 }
385 }
426
386
427 qreal QBarSeriesPrivate::maxCategorySum()
387 qreal QBarSeriesPrivate::maxCategorySum()
428 {
388 {
429 qreal max = INT_MIN;
389 qreal max = INT_MIN;
430 int count = categoryCount();
390 int count = categoryCount();
431 for (int i = 0; i < count; i++) {
391 for (int i = 0; i < count; i++) {
432 qreal sum = categorySum(i);
392 qreal sum = categorySum(i);
433 if (sum > max)
393 if (sum > max)
434 max = sum;
394 max = sum;
435 }
395 }
436 return max;
396 return max;
437 }
397 }
438
398
439 void QBarSeriesPrivate::barsetChanged()
399 void QBarSeriesPrivate::barsetChanged()
440 {
400 {
441 emit updatedBars();
401 emit updatedBars();
442 }
402 }
443
403
444 void QBarSeriesPrivate::scaleDomain(Domain& domain)
404 void QBarSeriesPrivate::scaleDomain(Domain& domain)
445 {
405 {
446 qreal minX(domain.minX());
406 qreal minX(domain.minX());
447 qreal minY(domain.minY());
407 qreal minY(domain.minY());
448 qreal maxX(domain.maxX());
408 qreal maxX(domain.maxX());
449 qreal maxY(domain.maxY());
409 qreal maxY(domain.maxY());
450 int tickXCount(domain.tickXCount());
410 int tickXCount(domain.tickXCount());
451 int tickYCount(domain.tickYCount());
411 int tickYCount(domain.tickYCount());
452
412
453 qreal x = categoryCount();
413 qreal x = categoryCount();
454 qreal y = max();
414 qreal y = max();
455 minX = qMin(minX, x) - 0.5;
415 minX = qMin(minX, x) - 0.5;
456 minY = qMin(minY, y);
416 minY = qMin(minY, y);
457 maxX = qMax(maxX, x) - 0.5;
417 maxX = qMax(maxX, x) + 0.5;
458 maxY = qMax(maxY, y);
418 maxY = qMax(maxY, y);
459 tickXCount = x+1;
419 tickXCount = x+1;
460
420
461 domain.setRange(minX,maxX,minY,maxY,tickXCount,tickYCount);
421 domain.setRange(minX,maxX,minY,maxY,tickXCount,tickYCount);
462 }
422 }
463
423
464 Chart* QBarSeriesPrivate::createGraphics(ChartPresenter* presenter)
424 Chart* QBarSeriesPrivate::createGraphics(ChartPresenter* presenter)
465 {
425 {
466 Q_Q(QBarSeries);
426 Q_Q(QBarSeries);
467
427
468 BarChartItem* bar = new BarChartItem(q,presenter);
428 BarChartItem* bar = new BarChartItem(q,presenter);
469 if(presenter->animationOptions().testFlag(QChart::SeriesAnimations)) {
429 if(presenter->animationOptions().testFlag(QChart::SeriesAnimations)) {
470 presenter->animator()->addAnimation(bar);
430 presenter->animator()->addAnimation(bar);
471 }
431 }
472 presenter->chartTheme()->decorate(q, presenter->dataSet()->seriesIndex(q));
432 presenter->chartTheme()->decorate(q, presenter->dataSet()->seriesIndex(q));
473 return bar;
433 return bar;
474
434
475 }
435 }
476
436
477 QList<LegendMarker*> QBarSeriesPrivate::createLegendMarker(QLegend* legend)
437 QList<LegendMarker*> QBarSeriesPrivate::createLegendMarker(QLegend* legend)
478 {
438 {
479 Q_Q(QBarSeries);
439 Q_Q(QBarSeries);
480 QList<LegendMarker*> markers;
440 QList<LegendMarker*> markers;
481 foreach(QBarSet* set, q->barSets()) {
441 foreach(QBarSet* set, q->barSets()) {
482 BarLegendMarker* marker = new BarLegendMarker(q,set,legend);
442 BarLegendMarker* marker = new BarLegendMarker(q,set,legend);
483 markers << marker;
443 markers << marker;
484 }
444 }
485
445
486 return markers;
446 return markers;
487 }
447 }
488
448
449 bool QBarSeriesPrivate::append(QBarSet *set)
450 {
451 Q_Q(QBarSeries);
452 if ((m_barSets.contains(set)) || (set == 0)) {
453 // Fail if set is already in list or set is null.
454 return false;
455 }
456 m_barSets.append(set);
457 QObject::connect(set->d_ptr.data(), SIGNAL(updatedBars()), this, SLOT(barsetChanged()));
458 if (m_dataset) {
459 m_dataset->updateSeries(q); // this notifies legend
460 }
461 emit restructuredBars(); // this notifies barchartitem
462 return true;
463 }
464
465 bool QBarSeriesPrivate::remove(QBarSet *set)
466 {
467 Q_Q(QBarSeries);
468 if (!m_barSets.contains(set)) {
469 // Fail if set is not in list
470 return false;
471 }
472 m_barSets.removeOne(set);
473 QObject::disconnect(set->d_ptr.data(), SIGNAL(updatedBars()), this, SLOT(barsetChanged()));
474 if (m_dataset) {
475 m_dataset->updateSeries(q); // this notifies legend
476 }
477 emit restructuredBars(); // this notifies barchartitem
478 return true;
479 }
480
481 bool QBarSeriesPrivate::append(QList<QBarSet* > sets)
482 {
483 Q_Q(QBarSeries);
484 foreach (QBarSet* set, sets) {
485 if ((set == 0) || (m_barSets.contains(set))) {
486 // Fail if any of the sets is null or is already appended.
487 return false;
488 }
489 if (sets.count(set) != 1) {
490 // Also fail if same set is more than once in given list.
491 return false;
492 }
493 }
494
495 foreach (QBarSet* set, sets) {
496 m_barSets.append(set);
497 QObject::connect(set->d_ptr.data(), SIGNAL(updatedBars()), this, SLOT(barsetChanged()));
498 }
499 if (m_dataset) {
500 m_dataset->updateSeries(q); // this notifies legend
501 }
502 emit restructuredBars(); // this notifies barchartitem
503 return true;
504 }
505
506 bool QBarSeriesPrivate::remove(QList<QBarSet* > sets)
507 {
508 Q_Q(QBarSeries);
509 bool setsRemoved = false;
510 foreach (QBarSet* set, sets) {
511 if (m_barSets.contains(set)) {
512 m_barSets.removeOne(set);
513 QObject::disconnect(set->d_ptr.data(), SIGNAL(updatedBars()), this, SLOT(barsetChanged()));
514 setsRemoved = true;
515 }
516 }
517
518 if (setsRemoved) {
519 if (m_dataset) {
520 m_dataset->updateSeries(q); // this notifies legend
521 }
522 emit restructuredBars(); // this notifies barchartitem
523 }
524 return setsRemoved;
525 }
526
489 #include "moc_qbarseries.cpp"
527 #include "moc_qbarseries.cpp"
490 #include "moc_qbarseries_p.cpp"
528 #include "moc_qbarseries_p.cpp"
491
529
492 QTCOMMERCIALCHART_END_NAMESPACE
530 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,92 +1,97
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 QBARSERIES_P_H
30 #ifndef QBARSERIES_P_H
31 #define QBARSERIES_P_H
31 #define QBARSERIES_P_H
32
32
33 #include "qbarseries.h"
33 #include "qbarseries.h"
34 #include "qabstractseries_p.h"
34 #include "qabstractseries_p.h"
35 #include <QStringList>
35 #include <QStringList>
36 #include <QAbstractSeries>
36 #include <QAbstractSeries>
37
37
38 QTCOMMERCIALCHART_BEGIN_NAMESPACE
38 QTCOMMERCIALCHART_BEGIN_NAMESPACE
39
39
40 class QBarModelMapper;
40 class QBarModelMapper;
41
41
42 class QBarSeriesPrivate : public QAbstractSeriesPrivate
42 class QBarSeriesPrivate : public QAbstractSeriesPrivate
43 {
43 {
44 Q_OBJECT
44 Q_OBJECT
45 public:
45 public:
46 QBarSeriesPrivate(QBarSeries *parent);
46 QBarSeriesPrivate(QBarSeries *parent);
47 void setCategories(QBarCategories categories);
47 void setCategories(QBarCategories categories);
48 void insertCategory(int index, const QString category);
48 void insertCategory(int index, const QString category);
49 void removeCategory(int index);
49 void removeCategory(int index);
50 int categoryCount() const;
50 int categoryCount() const;
51 QBarCategories categories() const;
51 QBarCategories categories() const;
52
52
53 void setBarMargin(qreal margin);
53 void setBarMargin(qreal margin);
54 qreal barMargin();
54 qreal barMargin();
55
55
56 void scaleDomain(Domain& domain);
56 void scaleDomain(Domain& domain);
57 Chart* createGraphics(ChartPresenter* presenter);
57 Chart* createGraphics(ChartPresenter* presenter);
58 QList<LegendMarker*> createLegendMarker(QLegend* legend);
58 QList<LegendMarker*> createLegendMarker(QLegend* legend);
59
59
60 bool append(QBarSet *set);
61 bool remove(QBarSet *set);
62 bool append(QList<QBarSet* > sets);
63 bool remove(QList<QBarSet* > sets);
64
60 QBarSet* barsetAt(int index);
65 QBarSet* barsetAt(int index);
61 QString categoryName(int category);
66 QString categoryName(int category);
62 qreal min();
67 qreal min();
63 qreal max();
68 qreal max();
64 qreal valueAt(int set, int category);
69 qreal valueAt(int set, int category);
65 qreal percentageAt(int set, int category);
70 qreal percentageAt(int set, int category);
66 qreal categorySum(int category);
71 qreal categorySum(int category);
67 qreal absoluteCategorySum(int category);
72 qreal absoluteCategorySum(int category);
68 qreal maxCategorySum();
73 qreal maxCategorySum();
69
74
70 Q_SIGNALS:
75 Q_SIGNALS:
71 void clicked(QBarSet *barset, QString category);
76 void clicked(QBarSet *barset, QString category);
72 void updatedBars();
77 void updatedBars();
73 void restructuredBars();
78 void restructuredBars();
74 void categoriesUpdated();
79 void categoriesUpdated();
75 void labelsVisibleChanged(bool visible);
80 void labelsVisibleChanged(bool visible);
76
81
77 private Q_SLOTS:
82 private Q_SLOTS:
78 void barsetChanged();
83 void barsetChanged();
79
84
80 protected:
85 protected:
81 QList<QBarSet *> m_barSets;
86 QList<QBarSet *> m_barSets;
82 QBarCategories m_categories;
87 QBarCategories m_categories;
83 qreal m_barMargin;
88 qreal m_barMargin;
84 bool m_labelsVisible;
89 bool m_labelsVisible;
85
90
86 private:
91 private:
87 Q_DECLARE_PUBLIC(QBarSeries)
92 Q_DECLARE_PUBLIC(QBarSeries)
88 };
93 };
89
94
90 QTCOMMERCIALCHART_END_NAMESPACE
95 QTCOMMERCIALCHART_END_NAMESPACE
91
96
92 #endif // QBARSERIESPRIVATE_P_H
97 #endif // QBARSERIESPRIVATE_P_H
@@ -1,291 +1,296
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 "chartdataset_p.h"
21 #include "chartdataset_p.h"
22 #include "qaxis.h"
22 #include "qaxis.h"
23 #include "qaxis_p.h"
23 #include "qaxis_p.h"
24 #include "qabstractseries_p.h"
24 #include "qabstractseries_p.h"
25 #include "qbarseries.h"
25 #include "qbarseries.h"
26 #include "qstackedbarseries.h"
26 #include "qstackedbarseries.h"
27 #include "qpercentbarseries.h"
27 #include "qpercentbarseries.h"
28 #include "qpieseries.h"
28 #include "qpieseries.h"
29
29
30 QTCOMMERCIALCHART_BEGIN_NAMESPACE
30 QTCOMMERCIALCHART_BEGIN_NAMESPACE
31
31
32 ChartDataSet::ChartDataSet(QObject *parent):QObject(parent),
32 ChartDataSet::ChartDataSet(QObject *parent):QObject(parent),
33 m_axisX(new QAxis(this)),
33 m_axisX(new QAxis(this)),
34 m_axisY(new QAxis(this)),
34 m_axisY(new QAxis(this)),
35 m_domainIndex(0),
35 m_domainIndex(0),
36 m_axisXInitialized(false),
36 m_axisXInitialized(false),
37 m_axisYInitialized(false)
37 m_axisYInitialized(false)
38 {
38 {
39 //create main domain
39 //create main domain
40 Domain* domain = new Domain(m_axisY);
40 Domain* domain = new Domain(m_axisY);
41 m_axisDomainMap.insert(m_axisY,domain);
41 m_axisDomainMap.insert(m_axisY,domain);
42 QObject::connect(m_axisY->d_ptr.data(),SIGNAL(changed(qreal,qreal,int,bool)),domain,SLOT(handleAxisYChanged(qreal,qreal,int,bool)));
42 QObject::connect(m_axisY->d_ptr.data(),SIGNAL(changed(qreal,qreal,int,bool)),domain,SLOT(handleAxisYChanged(qreal,qreal,int,bool)));
43 QObject::connect(m_axisX->d_ptr.data(),SIGNAL(changed(qreal,qreal,int,bool)),domain,SLOT(handleAxisXChanged(qreal,qreal,int,bool)));
43 QObject::connect(m_axisX->d_ptr.data(),SIGNAL(changed(qreal,qreal,int,bool)),domain,SLOT(handleAxisXChanged(qreal,qreal,int,bool)));
44 QObject::connect(domain,SIGNAL(rangeYChanged(qreal,qreal,int)),m_axisY->d_ptr.data(),SLOT(handleAxisRangeChanged(qreal,qreal,int)));
44 QObject::connect(domain,SIGNAL(rangeYChanged(qreal,qreal,int)),m_axisY->d_ptr.data(),SLOT(handleAxisRangeChanged(qreal,qreal,int)));
45 QObject::connect(domain,SIGNAL(rangeXChanged(qreal,qreal,int)),m_axisX->d_ptr.data(),SLOT(handleAxisRangeChanged(qreal,qreal,int)));
45 QObject::connect(domain,SIGNAL(rangeXChanged(qreal,qreal,int)),m_axisX->d_ptr.data(),SLOT(handleAxisRangeChanged(qreal,qreal,int)));
46 }
46 }
47
47
48 ChartDataSet::~ChartDataSet()
48 ChartDataSet::~ChartDataSet()
49 {
49 {
50 removeAllSeries();
50 removeAllSeries();
51 }
51 }
52
52
53 void ChartDataSet::addSeries(QAbstractSeries* series, QAxis *axisY)
53 void ChartDataSet::addSeries(QAbstractSeries* series, QAxis *axisY)
54 {
54 {
55 if(axisY==0) axisY = m_axisY;
55 if(axisY==0) axisY = m_axisY;
56
56
57 QAxis* axis = m_seriesAxisMap.value(series);
57 QAxis* axis = m_seriesAxisMap.value(series);
58
58
59 if(axis) {
59 if(axis) {
60 qWarning() << "Can not add series. Series already on the chart";
60 qWarning() << "Can not add series. Series already on the chart";
61 return;
61 return;
62 }
62 }
63
63
64 series->setParent(this); // take ownership
64 series->setParent(this); // take ownership
65 axisY->setParent(this); // take ownership
65 axisY->setParent(this); // take ownership
66
66
67 Domain* domain = m_axisDomainMap.value(axisY);
67 Domain* domain = m_axisDomainMap.value(axisY);
68
68
69 if(!domain) {
69 if(!domain) {
70 domain = new Domain(axisY);
70 domain = new Domain(axisY);
71 QObject::connect(axisY->d_ptr.data(),SIGNAL(changed(qreal,qreal,int,bool)),domain,SLOT(handleAxisYChanged(qreal,qreal,int,bool)));
71 QObject::connect(axisY->d_ptr.data(),SIGNAL(changed(qreal,qreal,int,bool)),domain,SLOT(handleAxisYChanged(qreal,qreal,int,bool)));
72 QObject::connect(axisX()->d_ptr.data(),SIGNAL(changed(qreal,qreal,int,bool)),domain,SLOT(handleAxisXChanged(qreal,qreal,int)));
72 QObject::connect(axisX()->d_ptr.data(),SIGNAL(changed(qreal,qreal,int,bool)),domain,SLOT(handleAxisXChanged(qreal,qreal,int)));
73 QObject::connect(domain,SIGNAL(rangeYChanged(qreal,qreal,int)),axisY->d_ptr.data(),SLOT(handleAxisRangeChanged(qreal,qreal,int)));
73 QObject::connect(domain,SIGNAL(rangeYChanged(qreal,qreal,int)),axisY->d_ptr.data(),SLOT(handleAxisRangeChanged(qreal,qreal,int)));
74 //initialize
74 //initialize
75 m_axisDomainMap.insert(axisY,domain);
75 m_axisDomainMap.insert(axisY,domain);
76 emit axisAdded(axisY,domain);
76 emit axisAdded(axisY,domain);
77 }
77 }
78
78
79 if(!m_axisXInitialized){
79 if(!m_axisXInitialized){
80 m_axisXInitialized=true;
80 m_axisXInitialized=true;
81 emit axisAdded(m_axisX,domain);
81 emit axisAdded(m_axisX,domain);
82 }
82 }
83
83
84 if(!m_axisYInitialized && axisY==m_axisY){
84 if(!m_axisYInitialized && axisY==m_axisY){
85 m_axisYInitialized=true;
85 m_axisYInitialized=true;
86 emit axisAdded(m_axisY,domain);
86 emit axisAdded(m_axisY,domain);
87 }
87 }
88
88
89 series->d_ptr->scaleDomain(*domain);
89 series->d_ptr->scaleDomain(*domain);
90
90
91 // Note that with SeriesTypeBar we don't set up categories, but use real values on x-asis
91 // Note that with SeriesTypeBar we don't set up categories, but use real values on x-asis
92 if(series->type() == QAbstractSeries::SeriesTypeGroupedBar
92 if(series->type() == QAbstractSeries::SeriesTypeGroupedBar
93 || series->type() == QAbstractSeries::SeriesTypeStackedBar
93 || series->type() == QAbstractSeries::SeriesTypeStackedBar
94 || series->type() == QAbstractSeries::SeriesTypePercentBar) {
94 || series->type() == QAbstractSeries::SeriesTypePercentBar) {
95 QBarSeries* barSeries = static_cast<QBarSeries*>(series);
95 QBarSeries* barSeries = static_cast<QBarSeries*>(series);
96 setupCategories(barSeries);
96 setupCategories(barSeries);
97 }
97 }
98
98
99 if (series->type()== QAbstractSeries::SeriesTypePie && m_seriesAxisMap.count() == 0) {
99 if (series->type()== QAbstractSeries::SeriesTypePie && m_seriesAxisMap.count() == 0) {
100 axisX()->hide();
100 axisX()->hide();
101 this->axisY()->hide();
101 this->axisY()->hide();
102 }
102 }
103
103
104 m_seriesAxisMap.insert(series,axisY);
104 m_seriesAxisMap.insert(series,axisY);
105
105
106 QMapIterator<int, QAbstractSeries*> i(m_indexSeriesMap);
106 QMapIterator<int, QAbstractSeries*> i(m_indexSeriesMap);
107
107
108 int key=0;
108 int key=0;
109 while (i.hasNext()) {
109 while (i.hasNext()) {
110 i.next();
110 i.next();
111 if(i.key()!=key) {
111 if(i.key()!=key) {
112 break;
112 break;
113 }
113 }
114 key++;
114 key++;
115 }
115 }
116
116
117 m_indexSeriesMap.insert(key,series);
117 m_indexSeriesMap.insert(key,series);
118
118
119 series->d_ptr->m_dataset=this;
119 series->d_ptr->m_dataset=this;
120
120
121 emit seriesAdded(series,domain);
121 emit seriesAdded(series,domain);
122
122
123 }
123 }
124
124
125 QAxis* ChartDataSet::removeSeries(QAbstractSeries* series)
125 QAxis* ChartDataSet::removeSeries(QAbstractSeries* series)
126 {
126 {
127 QAxis* axis = m_seriesAxisMap.value(series);
127 QAxis* axis = m_seriesAxisMap.value(series);
128
128
129 if(!axis){
129 if(!axis){
130 qWarning()<<"Can not remove series. Series not found on the chart.";
130 qWarning()<<"Can not remove series. Series not found on the chart.";
131 return 0;
131 return 0;
132 }
132 }
133
133
134 emit seriesRemoved(series);
134 emit seriesRemoved(series);
135
135
136 m_seriesAxisMap.remove(series);
136 m_seriesAxisMap.remove(series);
137 int key = seriesIndex(series);
137 int key = seriesIndex(series);
138 Q_ASSERT(key!=-1);
138 Q_ASSERT(key!=-1);
139
139
140 m_indexSeriesMap.remove(key);
140 m_indexSeriesMap.remove(key);
141 series->setParent(0);
141 series->setParent(0);
142 series->d_ptr->m_dataset=0;
142 series->d_ptr->m_dataset=0;
143
143
144 QList<QAxis*> axes = m_seriesAxisMap.values();
144 QList<QAxis*> axes = m_seriesAxisMap.values();
145
145
146 int i = axes.indexOf(axis);
146 int i = axes.indexOf(axis);
147
147
148 if(i==-1){
148 if(i==-1){
149 Domain* domain = m_axisDomainMap.take(axis);
149 Domain* domain = m_axisDomainMap.take(axis);
150 emit axisRemoved(axis);
150 emit axisRemoved(axis);
151 if(axis!=m_axisY){
151 if(axis!=m_axisY){
152 axis->setParent(0);
152 axis->setParent(0);
153 delete domain;
153 delete domain;
154 }else{
154 }else{
155 m_axisYInitialized=false;
155 m_axisYInitialized=false;
156 m_axisDomainMap.insert(m_axisY,domain);
156 m_axisDomainMap.insert(m_axisY,domain);
157 }
157 }
158 }
158 }
159
159
160 if(m_seriesAxisMap.values().size()==0)
160 if(m_seriesAxisMap.values().size()==0)
161 {
161 {
162 m_axisXInitialized=false;
162 m_axisXInitialized=false;
163 emit axisRemoved(axisX());
163 emit axisRemoved(axisX());
164 }
164 }
165
165
166 return axis;
166 return axis;
167 }
167 }
168
168
169 void ChartDataSet::removeAllSeries()
169 void ChartDataSet::removeAllSeries()
170 {
170 {
171 QList<QAbstractSeries*> series = m_seriesAxisMap.keys();
171 QList<QAbstractSeries*> series = m_seriesAxisMap.keys();
172 QList<QAxis*> axes;
172 QList<QAxis*> axes;
173 foreach(QAbstractSeries *s , series) {
173 foreach(QAbstractSeries *s , series) {
174 QAxis* axis = removeSeries(s);
174 QAxis* axis = removeSeries(s);
175 if(axis==axisY()) continue;
175 if(axis==axisY()) continue;
176 int i = axes.indexOf(axis);
176 int i = axes.indexOf(axis);
177 if(i==-1){
177 if(i==-1){
178 axes<<axis;
178 axes<<axis;
179 }
179 }
180 }
180 }
181
181
182 Q_ASSERT(m_seriesAxisMap.count()==0);
182 Q_ASSERT(m_seriesAxisMap.count()==0);
183 Q_ASSERT(m_axisDomainMap.count()==1);
183 Q_ASSERT(m_axisDomainMap.count()==1);
184
184
185 qDeleteAll(series);
185 qDeleteAll(series);
186 qDeleteAll(axes);
186 qDeleteAll(axes);
187 }
187 }
188
188
189 void ChartDataSet::setupCategories(QBarSeries* series)
189 void ChartDataSet::setupCategories(QBarSeries* series)
190 {
190 {
191 QAxisCategories* categories = axisX()->categories();
191 QAxisCategories* categories = axisX()->categories();
192 categories->clear();
192 categories->clear();
193 categories->insert(series->categories());
193 categories->insert(series->categories());
194 }
194 }
195
195
196 void ChartDataSet::zoomInDomain(const QRectF& rect, const QSizeF& size)
196 void ChartDataSet::zoomInDomain(const QRectF& rect, const QSizeF& size)
197 {
197 {
198 QMapIterator<QAxis*, Domain*> i(m_axisDomainMap);
198 QMapIterator<QAxis*, Domain*> i(m_axisDomainMap);
199 //main domain has to be the last one;
199 //main domain has to be the last one;
200 Domain *domain = m_axisDomainMap.value(axisY());
200 Domain *domain = m_axisDomainMap.value(axisY());
201 Q_ASSERT(domain);
201 Q_ASSERT(domain);
202 while (i.hasNext()) {
202 while (i.hasNext()) {
203 i.next();
203 i.next();
204 if(i.value()==domain) continue;
204 if(i.value()==domain) continue;
205 i.value()->zoomIn(rect,size);
205 i.value()->zoomIn(rect,size);
206 }
206 }
207 domain->zoomIn(rect,size);
207 domain->zoomIn(rect,size);
208 }
208 }
209
209
210 void ChartDataSet::zoomOutDomain(const QRectF& rect, const QSizeF& size)
210 void ChartDataSet::zoomOutDomain(const QRectF& rect, const QSizeF& size)
211 {
211 {
212 QMapIterator<QAxis*, Domain*> i(m_axisDomainMap);
212 QMapIterator<QAxis*, Domain*> i(m_axisDomainMap);
213 //main domain has to be the last one;
213 //main domain has to be the last one;
214 Domain *domain = m_axisDomainMap.value(axisY());
214 Domain *domain = m_axisDomainMap.value(axisY());
215 Q_ASSERT(domain);
215 Q_ASSERT(domain);
216 while (i.hasNext()) {
216 while (i.hasNext()) {
217 i.next();
217 i.next();
218 if(i.value()==domain) continue;
218 if(i.value()==domain) continue;
219 i.value()->zoomOut(rect,size);
219 i.value()->zoomOut(rect,size);
220 }
220 }
221 domain->zoomOut(rect,size);
221 domain->zoomOut(rect,size);
222 }
222 }
223
223
224 int ChartDataSet::seriesCount(QAbstractSeries::SeriesType type)
224 int ChartDataSet::seriesCount(QAbstractSeries::SeriesType type)
225 {
225 {
226 int count=0;
226 int count=0;
227 QMapIterator<QAbstractSeries*, QAxis*> i(m_seriesAxisMap);
227 QMapIterator<QAbstractSeries*, QAxis*> i(m_seriesAxisMap);
228 while (i.hasNext()) {
228 while (i.hasNext()) {
229 i.next();
229 i.next();
230 if(i.key()->type()==type) count++;
230 if(i.key()->type()==type) count++;
231 }
231 }
232 return count;
232 return count;
233 }
233 }
234
234
235 int ChartDataSet::seriesIndex(QAbstractSeries *series)
235 int ChartDataSet::seriesIndex(QAbstractSeries *series)
236 {
236 {
237 QMapIterator<int, QAbstractSeries*> i(m_indexSeriesMap);
237 QMapIterator<int, QAbstractSeries*> i(m_indexSeriesMap);
238 while (i.hasNext()) {
238 while (i.hasNext()) {
239 i.next();
239 i.next();
240 if (i.value() == series)
240 if (i.value() == series)
241 return i.key();
241 return i.key();
242 }
242 }
243 return -1;
243 return -1;
244 }
244 }
245
245
246 QAxis* ChartDataSet::axisY(QAbstractSeries *series) const
246 QAxis* ChartDataSet::axisY(QAbstractSeries *series) const
247 {
247 {
248 if(series == 0) return m_axisY;
248 if(series == 0) return m_axisY;
249 return m_seriesAxisMap.value(series);
249 return m_seriesAxisMap.value(series);
250 }
250 }
251
251
252 Domain* ChartDataSet::domain(QAbstractSeries *series) const
252 Domain* ChartDataSet::domain(QAbstractSeries *series) const
253 {
253 {
254 QAxis* axis = m_seriesAxisMap.value(series);
254 QAxis* axis = m_seriesAxisMap.value(series);
255 if(axis){
255 if(axis){
256 return m_axisDomainMap.value(axis);
256 return m_axisDomainMap.value(axis);
257 }else
257 }else
258 return 0;
258 return 0;
259 }
259 }
260
260
261 Domain* ChartDataSet::domain(QAxis* axis) const
261 Domain* ChartDataSet::domain(QAxis* axis) const
262 {
262 {
263 if(!axis || axis==axisX()) {
263 if(!axis || axis==axisX()) {
264 return m_axisDomainMap.value(axisY());
264 return m_axisDomainMap.value(axisY());
265 }
265 }
266 else {
266 else {
267 return m_axisDomainMap.value(axis);
267 return m_axisDomainMap.value(axis);
268 }
268 }
269 }
269 }
270
270
271 void ChartDataSet::scrollDomain(int dx,int dy,const QSizeF& size)
271 void ChartDataSet::scrollDomain(int dx,int dy,const QSizeF& size)
272 {
272 {
273 QMapIterator<QAxis*, Domain*> i( m_axisDomainMap);
273 QMapIterator<QAxis*, Domain*> i( m_axisDomainMap);
274 //main domain has to be the last one;
274 //main domain has to be the last one;
275 Domain *domain = m_axisDomainMap.value(axisY());
275 Domain *domain = m_axisDomainMap.value(axisY());
276 while (i.hasNext()) {
276 while (i.hasNext()) {
277 i.next();
277 i.next();
278 if(i.value()==domain) continue;
278 if(i.value()==domain) continue;
279 i.value()->move(dx,dy,size);
279 i.value()->move(dx,dy,size);
280 }
280 }
281 domain->move(dx,dy,size);
281 domain->move(dx,dy,size);
282 }
282 }
283
283
284 QList<QAbstractSeries*> ChartDataSet::series() const
284 QList<QAbstractSeries*> ChartDataSet::series() const
285 {
285 {
286 return m_seriesAxisMap.keys();
286 return m_seriesAxisMap.keys();
287 }
287 }
288
288
289 void ChartDataSet::updateSeries(QAbstractSeries *series)
290 {
291 emit seriesUpdated(series);
292 }
293
289 #include "moc_chartdataset_p.cpp"
294 #include "moc_chartdataset_p.cpp"
290
295
291 QTCOMMERCIALCHART_END_NAMESPACE
296 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,93 +1,95
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 CHARTDATASET_P_H
30 #ifndef CHARTDATASET_P_H
31 #define CHARTDATASET_P_H
31 #define CHARTDATASET_P_H
32
32
33 #include "qabstractseries.h"
33 #include "qabstractseries.h"
34 #include "domain_p.h"
34 #include "domain_p.h"
35 #include <QVector>
35 #include <QVector>
36
36
37 QTCOMMERCIALCHART_BEGIN_NAMESPACE
37 QTCOMMERCIALCHART_BEGIN_NAMESPACE
38
38
39 class QAxis;
39 class QAxis;
40 class QBarSeries;
40 class QBarSeries;
41
41
42 class QTCOMMERCIALCHART_AUTOTEST_EXPORT ChartDataSet : public QObject
42 class QTCOMMERCIALCHART_AUTOTEST_EXPORT ChartDataSet : public QObject
43 {
43 {
44 Q_OBJECT
44 Q_OBJECT
45 public:
45 public:
46 ChartDataSet(QObject* parent=0);
46 ChartDataSet(QObject* parent=0);
47 virtual ~ChartDataSet();
47 virtual ~ChartDataSet();
48
48
49 void addSeries(QAbstractSeries* series,QAxis *axisY = 0);
49 void addSeries(QAbstractSeries* series,QAxis *axisY = 0);
50 QAxis* removeSeries(QAbstractSeries* series);
50 QAxis* removeSeries(QAbstractSeries* series);
51 void removeAllSeries();
51 void removeAllSeries();
52 void updateSeries(QAbstractSeries* series);
52
53
53 void zoomInDomain(const QRectF& rect, const QSizeF& size);
54 void zoomInDomain(const QRectF& rect, const QSizeF& size);
54 void zoomOutDomain(const QRectF& rect, const QSizeF& size);
55 void zoomOutDomain(const QRectF& rect, const QSizeF& size);
55 void scrollDomain(int dx,int dy,const QSizeF& size);
56 void scrollDomain(int dx,int dy,const QSizeF& size);
56
57
57 int seriesCount(QAbstractSeries::SeriesType type);
58 int seriesCount(QAbstractSeries::SeriesType type);
58 int seriesIndex(QAbstractSeries *series);
59 int seriesIndex(QAbstractSeries *series);
59
60
60 Domain* domain(QAbstractSeries* series) const;
61 Domain* domain(QAbstractSeries* series) const;
61 Domain* domain(QAxis* axis) const;
62 Domain* domain(QAxis* axis) const;
62
63
63 QAxis* axisX() const { return m_axisX; }
64 QAxis* axisX() const { return m_axisX; }
64 QAxis* axisY(QAbstractSeries *series = 0) const;
65 QAxis* axisY(QAbstractSeries *series = 0) const;
65
66
66 QList<QAbstractSeries*> series() const;
67 QList<QAbstractSeries*> series() const;
67
68
68 Q_SIGNALS:
69 Q_SIGNALS:
69 void seriesAdded(QAbstractSeries* series, Domain* domain);
70 void seriesAdded(QAbstractSeries* series, Domain* domain);
70 void seriesRemoved(QAbstractSeries* series);
71 void seriesRemoved(QAbstractSeries* series);
72 void seriesUpdated(QAbstractSeries* series);
71 void axisAdded(QAxis* axis,Domain* domain);
73 void axisAdded(QAxis* axis,Domain* domain);
72 void axisRemoved(QAxis* axis);
74 void axisRemoved(QAxis* axis);
73
75
74 private:
76 private:
75 QStringList createLabels(QAxis* axis,qreal min, qreal max);
77 QStringList createLabels(QAxis* axis,qreal min, qreal max);
76 void calculateDomain(QAbstractSeries* series,Domain* domain);
78 void calculateDomain(QAbstractSeries* series,Domain* domain);
77 void setupCategories(QBarSeries* series);
79 void setupCategories(QBarSeries* series);
78
80
79 private:
81 private:
80 QMap<QAbstractSeries *, QAxis *> m_seriesAxisMap;
82 QMap<QAbstractSeries *, QAxis *> m_seriesAxisMap;
81 QMap<QAxis*, Domain *> m_axisDomainMap;
83 QMap<QAxis*, Domain *> m_axisDomainMap;
82 QMap<int, QAbstractSeries *> m_indexSeriesMap;
84 QMap<int, QAbstractSeries *> m_indexSeriesMap;
83 QAxis* m_axisX;
85 QAxis* m_axisX;
84 QAxis* m_axisY;
86 QAxis* m_axisY;
85
87
86 int m_domainIndex;
88 int m_domainIndex;
87 bool m_axisXInitialized;
89 bool m_axisXInitialized;
88 bool m_axisYInitialized;
90 bool m_axisYInitialized;
89 };
91 };
90
92
91 QTCOMMERCIALCHART_END_NAMESPACE
93 QTCOMMERCIALCHART_END_NAMESPACE
92
94
93 #endif /* CHARTENGINE_P_H_ */
95 #endif /* CHARTENGINE_P_H_ */
@@ -1,459 +1,469
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,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 }
97 }
97
98
98 /*!
99 /*!
99 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.
100 */
101 */
101 QLegend::~QLegend()
102 QLegend::~QLegend()
102 {
103 {
103 }
104 }
104
105
105 /*!
106 /*!
106 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.
107 */
108 */
108
109
109 void QLegend::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
110 void QLegend::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
110 {
111 {
111 Q_UNUSED(option)
112 Q_UNUSED(option)
112 Q_UNUSED(widget)
113 Q_UNUSED(widget)
113 if(!d_ptr->m_backgroundVisible) return;
114 if(!d_ptr->m_backgroundVisible) return;
114
115
115 painter->setOpacity(opacity());
116 painter->setOpacity(opacity());
116 painter->setPen(d_ptr->m_pen);
117 painter->setPen(d_ptr->m_pen);
117 painter->setBrush(d_ptr->m_brush);
118 painter->setBrush(d_ptr->m_brush);
118 painter->drawRect(boundingRect());
119 painter->drawRect(boundingRect());
119 }
120 }
120
121
121 /*!
122 /*!
122 Bounding rect of legend.
123 Bounding rect of legend.
123 */
124 */
124
125
125 QRectF QLegend::boundingRect() const
126 QRectF QLegend::boundingRect() const
126 {
127 {
127 return d_ptr->m_rect;
128 return d_ptr->m_rect;
128 }
129 }
129
130
130 /*!
131 /*!
131 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.
132 */
133 */
133 void QLegend::setBrush(const QBrush &brush)
134 void QLegend::setBrush(const QBrush &brush)
134 {
135 {
135 if (d_ptr->m_brush != brush) {
136 if (d_ptr->m_brush != brush) {
136 d_ptr->m_brush = brush;
137 d_ptr->m_brush = brush;
137 update();
138 update();
138 }
139 }
139 }
140 }
140
141
141 /*!
142 /*!
142 Returns the brush used by legend.
143 Returns the brush used by legend.
143 */
144 */
144 QBrush QLegend::brush() const
145 QBrush QLegend::brush() const
145 {
146 {
146 return d_ptr->m_brush;
147 return d_ptr->m_brush;
147 }
148 }
148
149
149 /*!
150 /*!
150 Sets the \a pen of legend. Pen affects the legend borders.
151 Sets the \a pen of legend. Pen affects the legend borders.
151 */
152 */
152 void QLegend::setPen(const QPen &pen)
153 void QLegend::setPen(const QPen &pen)
153 {
154 {
154 if (d_ptr->m_pen != pen) {
155 if (d_ptr->m_pen != pen) {
155 d_ptr->m_pen = pen;
156 d_ptr->m_pen = pen;
156 update();
157 update();
157 }
158 }
158 }
159 }
159
160
160 /*!
161 /*!
161 Returns the pen used by legend
162 Returns the pen used by legend
162 */
163 */
163
164
164 QPen QLegend::pen() const
165 QPen QLegend::pen() const
165 {
166 {
166 return d_ptr->m_pen;
167 return d_ptr->m_pen;
167 }
168 }
168
169
169 /*!
170 /*!
170 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.
171 \sa QLegend::Alignment
172 \sa QLegend::Alignment
172 */
173 */
173 void QLegend::setAlignment(QLegend::Alignments alignment)
174 void QLegend::setAlignment(QLegend::Alignments alignment)
174 {
175 {
175 if(d_ptr->m_alignment!=alignment && d_ptr->m_attachedToChart) {
176 if(d_ptr->m_alignment!=alignment && d_ptr->m_attachedToChart) {
176 d_ptr->m_alignment = alignment;
177 d_ptr->m_alignment = alignment;
177 d_ptr->updateLayout();
178 d_ptr->updateLayout();
178 }
179 }
179 }
180 }
180
181
181 /*!
182 /*!
182 Returns the preferred layout for legend
183 Returns the preferred layout for legend
183 */
184 */
184 QLegend::Alignments QLegend::alignment() const
185 QLegend::Alignments QLegend::alignment() const
185 {
186 {
186 return d_ptr->m_alignment;
187 return d_ptr->m_alignment;
187 }
188 }
188
189
189 /*!
190 /*!
190 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.
191 */
192 */
192 void QLegend::detachFromChart()
193 void QLegend::detachFromChart()
193 {
194 {
194 d_ptr->m_attachedToChart = false;
195 d_ptr->m_attachedToChart = false;
195 }
196 }
196
197
197 /*!
198 /*!
198 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.
199 */
200 */
200 void QLegend::attachToChart()
201 void QLegend::attachToChart()
201 {
202 {
202 d_ptr->m_attachedToChart = true;
203 d_ptr->m_attachedToChart = true;
203 }
204 }
204
205
205 /*!
206 /*!
206 Returns true, if legend is attached to chart.
207 Returns true, if legend is attached to chart.
207 */
208 */
208 bool QLegend::isAttachedToChart()
209 bool QLegend::isAttachedToChart()
209 {
210 {
210 return d_ptr->m_attachedToChart;
211 return d_ptr->m_attachedToChart;
211 }
212 }
212
213
213 /*!
214 /*!
214 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.
215 */
216 */
216 void QLegend::setOffset(const QPointF& point)
217 void QLegend::setOffset(const QPointF& point)
217 {
218 {
218 d_ptr->setOffset(point.x(),point.y());
219 d_ptr->setOffset(point.x(),point.y());
219 }
220 }
220
221
221 /*!
222 /*!
222 Returns the legend's scrolling offset.
223 Returns the legend's scrolling offset.
223 */
224 */
224 QPointF QLegend::offset() const
225 QPointF QLegend::offset() const
225 {
226 {
226 return QPointF(d_ptr->m_offsetX,d_ptr->m_offsetY);
227 return QPointF(d_ptr->m_offsetX,d_ptr->m_offsetY);
227 }
228 }
228
229
229 /*!
230 /*!
230 Sets the visibility of legend background to \a visible
231 Sets the visibility of legend background to \a visible
231 */
232 */
232 void QLegend::setBackgroundVisible(bool visible)
233 void QLegend::setBackgroundVisible(bool visible)
233 {
234 {
234 if(d_ptr->m_backgroundVisible!=visible)
235 if(d_ptr->m_backgroundVisible!=visible)
235 {
236 {
236 d_ptr->m_backgroundVisible=visible;
237 d_ptr->m_backgroundVisible=visible;
237 update();
238 update();
238 }
239 }
239 }
240 }
240
241
241 /*!
242 /*!
242 Returns the visibility of legend background
243 Returns the visibility of legend background
243 */
244 */
244 bool QLegend::isBackgroundVisible() const
245 bool QLegend::isBackgroundVisible() const
245 {
246 {
246 return d_ptr->m_backgroundVisible;
247 return d_ptr->m_backgroundVisible;
247 }
248 }
248
249
249 /*!
250 /*!
250 \internal \a event see QGraphicsWidget for details
251 \internal \a event see QGraphicsWidget for details
251 */
252 */
252 void QLegend::resizeEvent(QGraphicsSceneResizeEvent *event)
253 void QLegend::resizeEvent(QGraphicsSceneResizeEvent *event)
253 {
254 {
254 const QRectF& rect = QRectF(QPoint(0,0),event->newSize());
255 const QRectF& rect = QRectF(QPoint(0,0),event->newSize());
255 QGraphicsWidget::resizeEvent(event);
256 QGraphicsWidget::resizeEvent(event);
256 if(d_ptr->m_rect != rect) {
257 if(d_ptr->m_rect != rect) {
257 d_ptr->m_rect = rect;
258 d_ptr->m_rect = rect;
258 d_ptr->updateLayout();
259 d_ptr->updateLayout();
259 }
260 }
260 }
261 }
261
262
262 /*!
263 /*!
263 \internal \a event see QGraphicsWidget for details
264 \internal \a event see QGraphicsWidget for details
264 */
265 */
265 void QLegend::hideEvent(QHideEvent *event)
266 void QLegend::hideEvent(QHideEvent *event)
266 {
267 {
267 QGraphicsWidget::hideEvent(event);
268 QGraphicsWidget::hideEvent(event);
268 setEnabled(false);
269 setEnabled(false);
269 d_ptr->updateLayout();
270 d_ptr->updateLayout();
270 }
271 }
271
272
272 /*!
273 /*!
273 \internal \a event see QGraphicsWidget for details
274 \internal \a event see QGraphicsWidget for details
274 */
275 */
275 void QLegend::showEvent(QShowEvent *event)
276 void QLegend::showEvent(QShowEvent *event)
276 {
277 {
277 QGraphicsWidget::showEvent(event);
278 QGraphicsWidget::showEvent(event);
278 setEnabled(true);
279 setEnabled(true);
279 d_ptr->updateLayout();
280 d_ptr->updateLayout();
280 }
281 }
281
282
282 qreal QLegend::minWidth() const
283 qreal QLegend::minWidth() const
283 {
284 {
284 return d_ptr->m_minWidth;
285 return d_ptr->m_minWidth;
285 }
286 }
286
287
287 qreal QLegend::minHeight() const
288 qreal QLegend::minHeight() const
288 {
289 {
289 return d_ptr->m_minHeight;
290 return d_ptr->m_minHeight;
290 }
291 }
291
292
292 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
293 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
293
294
294 QLegendPrivate::QLegendPrivate(ChartPresenter* presenter,QLegend *q):
295 QLegendPrivate::QLegendPrivate(ChartPresenter* presenter,QLegend *q):
295 q_ptr(q),
296 q_ptr(q),
296 m_presenter(presenter),
297 m_presenter(presenter),
297 m_markers(new QGraphicsItemGroup(q)),
298 m_markers(new QGraphicsItemGroup(q)),
298 m_alignment(QLegend::AlignmentTop),
299 m_alignment(QLegend::AlignmentTop),
299 m_offsetX(0),
300 m_offsetX(0),
300 m_offsetY(0),
301 m_offsetY(0),
301 m_minWidth(0),
302 m_minWidth(0),
302 m_minHeight(0),
303 m_minHeight(0),
303 m_width(0),
304 m_width(0),
304 m_height(0),
305 m_height(0),
305 m_attachedToChart(true),
306 m_attachedToChart(true),
306 m_backgroundVisible(false)
307 m_backgroundVisible(false)
307 {
308 {
308
309
309 }
310 }
310
311
311 QLegendPrivate::~QLegendPrivate()
312 QLegendPrivate::~QLegendPrivate()
312 {
313 {
313
314
314 }
315 }
315
316
316 void QLegendPrivate::setOffset(qreal x, qreal y)
317 void QLegendPrivate::setOffset(qreal x, qreal y)
317 {
318 {
318
319
319 switch(m_alignment) {
320 switch(m_alignment) {
320
321
321 case QLegend::AlignmentTop:
322 case QLegend::AlignmentTop:
322 case QLegend::AlignmentBottom: {
323 case QLegend::AlignmentBottom: {
323 if(m_width<=m_rect.width()) return;
324 if(m_width<=m_rect.width()) return;
324
325
325 if (x != m_offsetX) {
326 if (x != m_offsetX) {
326 m_offsetX = qBound(qreal(0), x, m_width - m_rect.width());
327 m_offsetX = qBound(qreal(0), x, m_width - m_rect.width());
327 m_markers->setPos(-m_offsetX,m_rect.top());
328 m_markers->setPos(-m_offsetX,m_rect.top());
328 }
329 }
329 break;
330 break;
330 }
331 }
331 case QLegend::AlignmentLeft:
332 case QLegend::AlignmentLeft:
332 case QLegend::AlignmentRight: {
333 case QLegend::AlignmentRight: {
333
334
334 if(m_height<=m_rect.height()) return;
335 if(m_height<=m_rect.height()) return;
335
336
336 if (y != m_offsetY) {
337 if (y != m_offsetY) {
337 m_offsetY = qBound(qreal(0), y, m_height - m_rect.height());
338 m_offsetY = qBound(qreal(0), y, m_height - m_rect.height());
338 m_markers->setPos(m_rect.left(),-m_offsetY);
339 m_markers->setPos(m_rect.left(),-m_offsetY);
339 }
340 }
340 break;
341 break;
341 }
342 }
342 }
343 }
343 }
344 }
344
345
345
346
346 void QLegendPrivate::updateLayout()
347 void QLegendPrivate::updateLayout()
347 {
348 {
348 m_offsetX=0;
349 m_offsetX=0;
349 QList<QGraphicsItem *> items = m_markers->childItems();
350 QList<QGraphicsItem *> items = m_markers->childItems();
350
351
351 if(items.isEmpty()) return;
352 if(items.isEmpty()) return;
352
353
353 m_minWidth=0;
354 m_minWidth=0;
354 m_minHeight=0;
355 m_minHeight=0;
355
356
356 switch(m_alignment) {
357 switch(m_alignment) {
357
358
358 case QLegend::AlignmentTop:
359 case QLegend::AlignmentTop:
359 case QLegend::AlignmentBottom: {
360 case QLegend::AlignmentBottom: {
360 QPointF point = m_rect.topLeft();
361 QPointF point = m_rect.topLeft();
361 m_width = 0;
362 m_width = 0;
362 foreach (QGraphicsItem *item, items) {
363 foreach (QGraphicsItem *item, items) {
363 item->setPos(point.x(),m_rect.height()/2 -item->boundingRect().height()/2);
364 item->setPos(point.x(),m_rect.height()/2 -item->boundingRect().height()/2);
364 const QRectF& rect = item->boundingRect();
365 const QRectF& rect = item->boundingRect();
365 qreal w = rect.width();
366 qreal w = rect.width();
366 m_minWidth=qMax(m_minWidth,w);
367 m_minWidth=qMax(m_minWidth,w);
367 m_minHeight=qMax(m_minHeight,rect.height());
368 m_minHeight=qMax(m_minHeight,rect.height());
368 m_width+=w;
369 m_width+=w;
369 point.setX(point.x() + w);
370 point.setX(point.x() + w);
370 }
371 }
371 if(m_width<m_rect.width()) {
372 if(m_width<m_rect.width()) {
372 m_markers->setPos(m_rect.width()/2-m_width/2,m_rect.top());
373 m_markers->setPos(m_rect.width()/2-m_width/2,m_rect.top());
373 }
374 }
374 else {
375 else {
375 m_markers->setPos(m_rect.topLeft());
376 m_markers->setPos(m_rect.topLeft());
376 }
377 }
377 m_height=m_minHeight;
378 m_height=m_minHeight;
378 }
379 }
379 break;
380 break;
380 case QLegend::AlignmentLeft:
381 case QLegend::AlignmentLeft:
381 case QLegend::AlignmentRight: {
382 case QLegend::AlignmentRight: {
382 QPointF point = m_rect.topLeft();
383 QPointF point = m_rect.topLeft();
383 m_height = 0;
384 m_height = 0;
384 foreach (QGraphicsItem *item, items) {
385 foreach (QGraphicsItem *item, items) {
385 item->setPos(point);
386 item->setPos(point);
386 const QRectF& rect = item->boundingRect();
387 const QRectF& rect = item->boundingRect();
387 qreal h = rect.height();
388 qreal h = rect.height();
388 m_minWidth=qMax(m_minWidth,rect.width());
389 m_minWidth=qMax(m_minWidth,rect.width());
389 m_minHeight=qMax(m_minHeight,h);
390 m_minHeight=qMax(m_minHeight,h);
390 m_height+=h;
391 m_height+=h;
391 point.setY(point.y() + h);
392 point.setY(point.y() + h);
392 }
393 }
393 if(m_height<m_rect.height()) {
394 if(m_height<m_rect.height()) {
394 m_markers->setPos(m_rect.left(),m_rect.height()/2-m_height/2);
395 m_markers->setPos(m_rect.left(),m_rect.height()/2-m_height/2);
395 }
396 }
396 else {
397 else {
397 m_markers->setPos(m_rect.topLeft());
398 m_markers->setPos(m_rect.topLeft());
398 }
399 }
399 m_width=m_minWidth;
400 m_width=m_minWidth;
400 }
401 }
401 break;
402 break;
402 }
403 }
403
404
404 m_presenter->updateLayout();
405 m_presenter->updateLayout();
405 }
406 }
406
407
407 void QLegendPrivate::handleSeriesAdded(QAbstractSeries *series, Domain *domain)
408 void QLegendPrivate::handleSeriesAdded(QAbstractSeries *series, Domain *domain)
408 {
409 {
409 Q_UNUSED(domain)
410 Q_UNUSED(domain)
410
411
411 QList<LegendMarker*> markers = series->d_ptr->createLegendMarker(q_ptr);
412 QList<LegendMarker*> markers = series->d_ptr->createLegendMarker(q_ptr);
412 foreach(LegendMarker* marker , markers)
413 foreach(LegendMarker* marker , markers)
413 m_markers->addToGroup(marker);
414 m_markers->addToGroup(marker);
414
415
415 if(series->type() == QAbstractSeries::SeriesTypePie)
416 if(series->type() == QAbstractSeries::SeriesTypePie)
416 {
417 {
417 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
418 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
418 QObject::connect(pieSeries, SIGNAL(added(QList<QPieSlice*>)), this, SLOT(handleUpdatePieSeries()));
419 QObject::connect(pieSeries, SIGNAL(added(QList<QPieSlice*>)), this, SLOT(handleUpdatePieSeries()));
419 QObject::connect(pieSeries, SIGNAL(removed(QList<QPieSlice*>)), this, SLOT(handleUpdatePieSeries()));
420 QObject::connect(pieSeries, SIGNAL(removed(QList<QPieSlice*>)), this, SLOT(handleUpdatePieSeries()));
420 }
421 }
421
422
422 updateLayout();
423 updateLayout();
423 }
424 }
424
425
425 void QLegendPrivate::handleSeriesRemoved(QAbstractSeries *series)
426 void QLegendPrivate::handleSeriesRemoved(QAbstractSeries *series)
426 {
427 {
427
428
428 QList<QGraphicsItem *> items = m_markers->childItems();
429 QList<QGraphicsItem *> items = m_markers->childItems();
429
430
430 foreach (QGraphicsItem *markers, items) {
431 foreach (QGraphicsItem *markers, items) {
431 LegendMarker *marker = static_cast<LegendMarker*>(markers);
432 LegendMarker *marker = static_cast<LegendMarker*>(markers);
432 if (marker->series() == series) {
433 if (marker->series() == series) {
433 delete marker;
434 delete marker;
434 }
435 }
435 }
436 }
436
437
437 if(series->type() == QAbstractSeries::SeriesTypePie)
438 if(series->type() == QAbstractSeries::SeriesTypePie)
438 {
439 {
439 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
440 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
440 QObject::disconnect(pieSeries, SIGNAL(added(QList<QPieSlice*>)), this, SLOT(handleUpdatePieSeries()));
441 QObject::disconnect(pieSeries, SIGNAL(added(QList<QPieSlice*>)), this, SLOT(handleUpdatePieSeries()));
441 QObject::disconnect(pieSeries, SIGNAL(removed(QList<QPieSlice*>)), this, SLOT(handleUpdatePieSeries()));
442 QObject::disconnect(pieSeries, SIGNAL(removed(QList<QPieSlice*>)), this, SLOT(handleUpdatePieSeries()));
442 }
443 }
443
444
444 updateLayout();
445 updateLayout();
445 }
446 }
446
447
448 void QLegendPrivate::handleSeriesUpdated(QAbstractSeries *series)
449 {
450 // TODO: find out which markers are are added or removed. Update them
451 // TODO: better implementation
452 handleSeriesRemoved(series);
453 Domain domain;
454 handleSeriesAdded(series, &domain);
455 }
456
447 void QLegendPrivate::handleUpdatePieSeries()
457 void QLegendPrivate::handleUpdatePieSeries()
448 {
458 {
449 //TODO: reimplement to be optimal
459 //TODO: reimplement to be optimal
450 QPieSeries* series = qobject_cast<QPieSeries *> (sender());
460 QPieSeries* series = qobject_cast<QPieSeries *> (sender());
451 Q_ASSERT(series);
461 Q_ASSERT(series);
452 handleSeriesRemoved(series);
462 handleSeriesRemoved(series);
453 handleSeriesAdded(series, 0);
463 handleSeriesAdded(series, 0);
454 }
464 }
455
465
456 #include "moc_qlegend.cpp"
466 #include "moc_qlegend.cpp"
457 #include "moc_qlegend_p.cpp"
467 #include "moc_qlegend_p.cpp"
458
468
459 QTCOMMERCIALCHART_END_NAMESPACE
469 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,78 +1,79
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 ChartPresenter;
37 class ChartPresenter;
38 class QAbstractSeries;
38 class QAbstractSeries;
39
39
40 class QLegendPrivate : public QObject
40 class QLegendPrivate : public QObject
41 {
41 {
42 Q_OBJECT
42 Q_OBJECT
43 public:
43 public:
44 QLegendPrivate(ChartPresenter *chart,QLegend *q);
44 QLegendPrivate(ChartPresenter *chart,QLegend *q);
45 ~QLegendPrivate();
45 ~QLegendPrivate();
46
46
47 void setOffset(qreal x, qreal y);
47 void setOffset(qreal x, qreal y);
48 void updateLayout();
48 void updateLayout();
49
49
50 public Q_SLOTS:
50 public Q_SLOTS:
51 void handleSeriesAdded(QAbstractSeries *series, Domain *domain);
51 void handleSeriesAdded(QAbstractSeries *series, Domain *domain);
52 void handleSeriesRemoved(QAbstractSeries *series);
52 void handleSeriesRemoved(QAbstractSeries *series);
53 void handleSeriesUpdated(QAbstractSeries *series);
53 void handleUpdatePieSeries(); //TODO remove this function
54 void handleUpdatePieSeries(); //TODO remove this function
54
55
55 private:
56 private:
56 QLegend *q_ptr;
57 QLegend *q_ptr;
57 ChartPresenter *m_presenter;
58 ChartPresenter *m_presenter;
58 QGraphicsItemGroup* m_markers;
59 QGraphicsItemGroup* m_markers;
59 QLegend::Alignments m_alignment;
60 QLegend::Alignments m_alignment;
60 QBrush m_brush;
61 QBrush m_brush;
61 QPen m_pen;
62 QPen m_pen;
62 QRectF m_rect;
63 QRectF m_rect;
63 qreal m_offsetX;
64 qreal m_offsetX;
64 qreal m_offsetY;
65 qreal m_offsetY;
65 qreal m_minWidth;
66 qreal m_minWidth;
66 qreal m_minHeight;
67 qreal m_minHeight;
67 qreal m_width;
68 qreal m_width;
68 qreal m_height;
69 qreal m_height;
69 bool m_attachedToChart;
70 bool m_attachedToChart;
70 bool m_backgroundVisible;
71 bool m_backgroundVisible;
71
72
72 friend class QLegend;
73 friend class QLegend;
73
74
74 };
75 };
75
76
76 QTCOMMERCIALCHART_END_NAMESPACE
77 QTCOMMERCIALCHART_END_NAMESPACE
77
78
78 #endif
79 #endif
General Comments 0
You need to be logged in to leave comments. Login now