##// END OF EJS Templates
fixed bug in category implementation. model now owns the category and sets
sauimone -
r173:5bd6f6e4373b
parent child
Show More
@@ -1,49 +1,49
1 1 #include <QApplication>
2 2 #include <QMainWindow>
3 3 #include <QStandardItemModel>
4 4 #include <barchartseries.h>
5 5 #include <qbarcategory.h>
6 6 #include <qbarset.h>
7 7 #include "chartwidget.h"
8 8
9 9 QTCOMMERCIALCHART_USE_NAMESPACE
10 10
11 11 int main(int argc, char *argv[])
12 12 {
13 13 QApplication a(argc, argv);
14 14 QMainWindow window;
15 15
16 QBarCategory category;
17 category << "Jan" << "Feb" << "Mar" << "Apr" << "May" << "June" << "Jul" << "Aug" << "Sep" << "Oct" << "Nov" << "Dec";
16 QBarCategory *category = new QBarCategory;
17 *category << "Jan" << "Feb" << "Mar" << "Apr" << "May" << "June" << "Jul" << "Aug" << "Sep" << "Oct" << "Nov" << "Dec";
18 18
19 19 BarChartSeries* series0 = new BarChartSeries(category);
20 20
21 QBarSet barSet0;
22 QBarSet barSet1;
23 QBarSet barSet2;
24 QBarSet barSet3;
25 QBarSet barSet4;
21 QBarSet *set0 = new QBarSet;
22 QBarSet *set1 = new QBarSet;
23 QBarSet *set2 = new QBarSet;
24 QBarSet *set3 = new QBarSet;
25 QBarSet *set4 = new QBarSet;
26 26
27 27 // Create some test data to chart
28 barSet0 << 1 << 2 << 3 << 4 << 5 << 6 << 7 << 8 << 9 << 10 << 11 << 12;
29 barSet1 << 5 << 0 << 0 << 4 << 0 << 7 << 8 << 9 << 9 << 0 << 4 << 2;
30 barSet2 << 3 << 5 << 8 << 13 << 8 << 5 << 3 << 2 << 1 << 1 << 3 << 5;
31 barSet3 << 5 << 6 << 7 << 3 << 4 << 5 << 8 << 9 << 10 << 5 << 2 << 7;
32 barSet4 << 9 << 7 << 5 << 3 << 1 << 2 << 4 << 6 << 8 << 10 << 1 << 6;
33
34 series0->addBarSet(barSet0);
35 series0->addBarSet(barSet1);
36 series0->addBarSet(barSet2);
37 series0->addBarSet(barSet3);
38 series0->addBarSet(barSet4);
28 *set0 << 1 << 2 << 3 << 4 << 5 << 6 << 7 << 8 << 9 << 10 << 11 << 12;
29 *set1 << 5 << 0 << 0 << 4 << 0 << 7 << 8 << 9 << 9 << 0 << 4 << 2;
30 *set2 << 3 << 5 << 8 << 13 << 8 << 5 << 3 << 2 << 1 << 1 << 3 << 5;
31 *set3 << 5 << 6 << 7 << 3 << 4 << 5 << 8 << 9 << 10 << 5 << 2 << 7;
32 *set4 << 9 << 7 << 5 << 3 << 1 << 2 << 4 << 6 << 8 << 10 << 1 << 6;
33
34 series0->addBarSet(set0);
35 series0->addBarSet(set1);
36 series0->addBarSet(set2);
37 series0->addBarSet(set3);
38 series0->addBarSet(set4);
39 39
40 40 ChartWidget* chartWidget = new ChartWidget(&window);
41 41 chartWidget->addSeries(series0);
42 42
43 43 window.setCentralWidget(chartWidget);
44 44 window.resize(400, 300);
45 45 window.show();
46 46
47 47 return a.exec();
48 48 }
49 49
@@ -1,49 +1,49
1 1 #include <QApplication>
2 2 #include <QMainWindow>
3 3 #include <QStandardItemModel>
4 4 #include <percentbarchartseries.h>
5 5 #include "chartwidget.h"
6 6 #include <qbarcategory.h>
7 7 #include <qbarset.h>
8 8
9 9 QTCOMMERCIALCHART_USE_NAMESPACE
10 10
11 11 int main(int argc, char *argv[])
12 12 {
13 13 QApplication a(argc, argv);
14 14 QMainWindow window;
15 15
16 QBarCategory category;
17 category << "Jan" << "Feb" << "Mar" << "Apr" << "May" << "June" << "Jul" << "Aug" << "Sep" << "Oct" << "Nov" << "Dec";
16 QBarCategory *category = new QBarCategory;
17 *category << "Jan" << "Feb" << "Mar" << "Apr" << "May" << "June" << "Jul" << "Aug" << "Sep" << "Oct" << "Nov" << "Dec";
18 18
19 19 PercentBarChartSeries* series0 = new PercentBarChartSeries(category);
20 20
21 QBarSet barSet0;
22 QBarSet barSet1;
23 QBarSet barSet2;
24 QBarSet barSet3;
25 QBarSet barSet4;
21 QBarSet *set0 = new QBarSet;
22 QBarSet *set1 = new QBarSet;
23 QBarSet *set2 = new QBarSet;
24 QBarSet *set3 = new QBarSet;
25 QBarSet *set4 = new QBarSet;
26 26
27 27 // Create some test data to chart
28 barSet0 << 1 << 2 << 3 << 4 << 5 << 6 << 7 << 8 << 9 << 10 << 11 << 12;
29 barSet1 << 5 << 0 << 0 << 4 << 0 << 7 << 8 << 9 << 9 << 0 << 4 << 2;
30 barSet2 << 3 << 5 << 8 << 13 << 8 << 5 << 3 << 2 << 1 << 1 << 3 << 5;
31 barSet3 << 5 << 6 << 7 << 3 << 4 << 5 << 8 << 9 << 10 << 5 << 2 << 7;
32 barSet4 << 9 << 7 << 5 << 3 << 1 << 2 << 4 << 6 << 8 << 10 << 1 << 6;
33
34 series0->addBarSet(barSet0);
35 series0->addBarSet(barSet1);
36 series0->addBarSet(barSet2);
37 series0->addBarSet(barSet3);
38 series0->addBarSet(barSet4);
28 *set0 << 1 << 2 << 3 << 4 << 5 << 6 << 7 << 8 << 9 << 10 << 11 << 12;
29 *set1 << 5 << 0 << 0 << 4 << 0 << 7 << 8 << 9 << 9 << 0 << 4 << 2;
30 *set2 << 3 << 5 << 8 << 13 << 8 << 5 << 3 << 2 << 1 << 1 << 3 << 5;
31 *set3 << 5 << 6 << 7 << 3 << 4 << 5 << 8 << 9 << 10 << 5 << 2 << 7;
32 *set4 << 9 << 7 << 5 << 3 << 1 << 2 << 4 << 6 << 8 << 10 << 1 << 6;
33
34 series0->addBarSet(set0);
35 series0->addBarSet(set1);
36 series0->addBarSet(set2);
37 series0->addBarSet(set3);
38 series0->addBarSet(set4);
39 39
40 40 ChartWidget* chartWidget = new ChartWidget(&window);
41 41 chartWidget->addSeries(series0);
42 42
43 43 window.setCentralWidget(chartWidget);
44 44 window.resize(400, 300);
45 45 window.show();
46 46
47 47 return a.exec();
48 48 }
49 49
@@ -1,49 +1,49
1 1 #include <QApplication>
2 2 #include <QMainWindow>
3 3 #include <QStandardItemModel>
4 4 #include <stackedbarchartseries.h>
5 5 #include "chartwidget.h"
6 6 #include <qbarset.h>
7 7 #include <qbarcategory.h>
8 8
9 9 QTCOMMERCIALCHART_USE_NAMESPACE
10 10
11 11 int main(int argc, char *argv[])
12 12 {
13 13 QApplication a(argc, argv);
14 14 QMainWindow window;
15 15
16 QBarCategory category;
17 category << "Jan" << "Feb" << "Mar" << "Apr" << "May" << "June" << "Jul" << "Aug" << "Sep" << "Oct" << "Nov" << "Dec";
16 QBarCategory *category = new QBarCategory;
17 *category << "Jan" << "Feb" << "Mar" << "Apr" << "May" << "June" << "Jul" << "Aug" << "Sep" << "Oct" << "Nov" << "Dec";
18 18
19 19 StackedBarChartSeries* series0 = new StackedBarChartSeries(category);
20 20
21 QBarSet barSet0;
22 QBarSet barSet1;
23 QBarSet barSet2;
24 QBarSet barSet3;
25 QBarSet barSet4;
21 QBarSet *set0 = new QBarSet;
22 QBarSet *set1 = new QBarSet;
23 QBarSet *set2 = new QBarSet;
24 QBarSet *set3 = new QBarSet;
25 QBarSet *set4 = new QBarSet;
26 26
27 27 // Create some test data to chart
28 barSet0 << 1 << 2 << 3 << 4 << 5 << 6 << 7 << 8 << 9 << 10 << 11 << 12;
29 barSet1 << 5 << 0 << 0 << 4 << 0 << 7 << 8 << 9 << 9 << 0 << 4 << 2;
30 barSet2 << 3 << 5 << 8 << 13 << 8 << 5 << 3 << 2 << 1 << 1 << 3 << 5;
31 barSet3 << 5 << 6 << 7 << 3 << 4 << 5 << 8 << 9 << 10 << 5 << 2 << 7;
32 barSet4 << 9 << 7 << 5 << 3 << 1 << 2 << 4 << 6 << 8 << 10 << 1 << 6;
33
34 series0->addBarSet(barSet0);
35 series0->addBarSet(barSet1);
36 series0->addBarSet(barSet2);
37 series0->addBarSet(barSet3);
38 series0->addBarSet(barSet4);
28 *set0 << 1 << 2 << 3 << 4 << 5 << 6 << 7 << 8 << 9 << 10 << 11 << 12;
29 *set1 << 5 << 0 << 0 << 4 << 0 << 7 << 8 << 9 << 9 << 0 << 4 << 2;
30 *set2 << 3 << 5 << 8 << 13 << 8 << 5 << 3 << 2 << 1 << 1 << 3 << 5;
31 *set3 << 5 << 6 << 7 << 3 << 4 << 5 << 8 << 9 << 10 << 5 << 2 << 7;
32 *set4 << 9 << 7 << 5 << 3 << 1 << 2 << 4 << 6 << 8 << 10 << 1 << 6;
33
34 series0->addBarSet(set0);
35 series0->addBarSet(set1);
36 series0->addBarSet(set2);
37 series0->addBarSet(set3);
38 series0->addBarSet(set4);
39 39
40 40 ChartWidget* chartWidget = new ChartWidget(&window);
41 41 chartWidget->addSeries(series0);
42 42
43 43 window.setCentralWidget(chartWidget);
44 44 window.resize(400, 300);
45 45 window.show();
46 46
47 47 return a.exec();
48 48 }
49 49
@@ -1,143 +1,151
1 1 #include <limits.h>
2 2 #include <QVector>
3 3 #include <QDebug>
4 4 #include "barchartmodel_p.h"
5 5 #include "qbarcategory.h"
6 6 #include "qbarset.h"
7 7
8 8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9 9
10 BarChartModel::BarChartModel(QBarCategory &category, QObject *parent) :
10 BarChartModel::BarChartModel(QBarCategory *category, QObject *parent) :
11 11 QObject(parent)
12 12 ,mCategory(category)
13 13 {
14 14 }
15 15
16 QBarCategory& BarChartModel::category()
16 BarChartModel::~BarChartModel()
17 17 {
18 return mCategory;
18 delete mCategory;
19 19 }
20 20
21 void BarChartModel::addBarSet(QBarSet &set)
21
22 QBarCategory& BarChartModel::category()
22 23 {
23 mDataModel.append(&set);
24 return *mCategory;
24 25 }
25 26
26 void BarChartModel::removeBarSet(QBarSet &set)
27 void BarChartModel::addBarSet(QBarSet *set)
27 28 {
28 mDataModel.removeOne(&set);
29 mDataModel.append(set);
29 30 }
30 31
32 void BarChartModel::removeBarSet(QBarSet *set)
33 {
34 if (mDataModel.contains(set)) {
35 mDataModel.removeOne(set);
36 delete set;
37 }
38 }
31 39
32 40 int BarChartModel::countSets()
33 41 {
34 42 return mDataModel.count();
35 43 }
36 44
37 45 int BarChartModel::countCategories()
38 46 {
39 47 int count(0);
40 48 for (int i=0; i<mDataModel.count(); i++){
41 49 // TODO: can we assume that all series have same number of values? If not. then which values are empty?
42 50 int temp = mDataModel.at(i)->count();
43 51 if (temp > count) {
44 52 count = temp;
45 53 }
46 54 }
47 55 return count;
48 56 }
49 57
50 58 int BarChartModel::countTotalItems()
51 59 {
52 60 int total = mDataModel.count() * countCategories();
53 61 return total;
54 62 }
55 63
56 64 qreal BarChartModel::min()
57 65 {
58 66 Q_ASSERT(mDataModel.count() > 0);
59 67 // TODO: make min and max members and update them when data changes.
60 68 // This is slower since they are checked every time, even if data is same since previous call.
61 69 qreal min = INT_MAX;
62 70
63 71 for (int i=0; i <mDataModel.count(); i++) {
64 72 int itemCount = mDataModel.at(i)->count();
65 73 for (int j=0; j<itemCount; j++) {
66 74 qreal temp = mDataModel.at(i)->valueAt(j);
67 75 if (temp < min) {
68 76 min = temp;
69 77 }
70 78 }
71 79 }
72 80 return min;
73 81 }
74 82
75 83 qreal BarChartModel::max()
76 84 {
77 85 Q_ASSERT(mDataModel.count() > 0);
78 86
79 87 // TODO: make min and max members and update them when data changes.
80 88 // This is slower since they are checked every time, even if data is same since previous call.
81 89 qreal max = INT_MIN;
82 90
83 91 for (int i=0; i <mDataModel.count(); i++) {
84 92 int itemCount = mDataModel.at(i)->count();
85 93 for (int j=0; j<itemCount; j++) {
86 94 qreal temp = mDataModel.at(i)->valueAt(j);
87 95 if (temp > max) {
88 96 max = temp;
89 97 }
90 98 }
91 99 }
92 100
93 101 return max;
94 102 }
95 103
96 104 qreal BarChartModel::valueAt(int set, int category)
97 105 {
98 106 if ((set < 0) || (set >= mDataModel.count())) {
99 107 // No set, no value.
100 108 return 0;
101 109 } else if ((category < 0) || (category >= mDataModel.at(set)->count())) {
102 110 // No category, no value.
103 111 return 0;
104 112 }
105 113
106 114 return mDataModel.at(set)->valueAt(category);
107 115 }
108 116
109 117 qreal BarChartModel::categorySum(int column)
110 118 {
111 119 qreal sum(0);
112 120 int count = mDataModel.count(); // Count rows
113 121
114 122 for (int row = 0; row < count; row++) {
115 123 if (column < mDataModel.at(row)->count()) {
116 124 sum += mDataModel.at(row)->valueAt(column);
117 125 }
118 126 }
119 127 return sum;
120 128 }
121 129
122 130 qreal BarChartModel::maxCategorySum()
123 131 {
124 132 qreal max = INT_MIN;
125 133 int count = countCategories();
126 134
127 135 for (int col=0; col<count; col++) {
128 136 qreal sum = categorySum(col);
129 137 if (sum > max) {
130 138 max = sum;
131 139 }
132 140 }
133 141 return max;
134 142 }
135 143
136 144 QString BarChartModel::label(int category)
137 145 {
138 return mCategory.label(category);
146 return mCategory->label(category);
139 147 }
140 148
141 149 #include "moc_barchartmodel_p.cpp"
142 150
143 151 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,52 +1,53
1 1 #ifndef BARCHARTMODEL_H
2 2 #define BARCHARTMODEL_H
3 3
4 4 #include <QObject>
5 5 #include "qchartglobal.h"
6 6
7 7 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8 8
9 9 // Model for bar chart. Internal class.
10 10 // TODO: Implement as QAbstractItemModel?
11 11
12 12 class QBarSet;
13 13 class QBarCategory;
14 14
15 15 class BarChartModel : public QObject //, public QAbstractItemModel
16 16 {
17 17 Q_OBJECT
18 18 public:
19 explicit BarChartModel(QBarCategory &category, QObject *parent = 0);
19 explicit BarChartModel(QBarCategory *category, QObject *parent = 0);
20 ~BarChartModel();
20 21
21 22 QBarCategory& category();
22 void addBarSet(QBarSet &set);
23 void removeBarSet(QBarSet &set);
23 void addBarSet(QBarSet *set);
24 void removeBarSet(QBarSet *set);
24 25
25 26 int countSets(); // Number of sets in model
26 27 int countCategories(); // Number of categories
27 28 int countTotalItems(); // Total items in all sets. Includes empty items.
28 29
29 30 qreal max(); // Maximum value of all sets
30 31 qreal min(); // Minimum value of all sets
31 32 qreal valueAt(int set, int category);
32 33
33 34 qreal categorySum(int column);
34 35 qreal maxCategorySum(); // returns maximum sum of sets in all categories.
35 36
36 37 QString label(int category);
37 38
38 39 signals:
39 40 void modelUpdated();
40 41
41 42 public slots:
42 43
43 44 private:
44 45
45 46 QList<QBarSet*> mDataModel;
46 QBarCategory& mCategory;
47 QBarCategory* mCategory; // Owned
47 48
48 49 };
49 50
50 51 QTCOMMERCIALCHART_END_NAMESPACE
51 52
52 53 #endif // BARCHARTMODEL_H
@@ -1,59 +1,59
1 1 #include <QDebug>
2 2 #include "barchartseries.h"
3 3 #include "qbarcategory.h"
4 4 #include "qbarset.h"
5 5 #include "barchartmodel_p.h"
6 6
7 7
8 8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9 9
10 BarChartSeries::BarChartSeries(QBarCategory &category, QObject *parent)
10 BarChartSeries::BarChartSeries(QBarCategory *category, QObject *parent)
11 11 : QChartSeries(parent)
12 12 ,mModel(new BarChartModel(category, this))
13 13 {
14 14 }
15 15
16 void BarChartSeries::addBarSet(QBarSet &set)
16 void BarChartSeries::addBarSet(QBarSet *set)
17 17 {
18 18 mModel->addBarSet(set);
19 19 }
20 20
21 void BarChartSeries::removeBarSet(QBarSet &set)
21 void BarChartSeries::removeBarSet(QBarSet *set)
22 22 {
23 23 mModel->removeBarSet(set);
24 24 }
25 25
26 26 int BarChartSeries::countCategories()
27 27 {
28 28 return mModel->countCategories();
29 29 }
30 30
31 31 qreal BarChartSeries::min()
32 32 {
33 33 return mModel->min();
34 34 }
35 35
36 36 qreal BarChartSeries::max()
37 37 {
38 38 return mModel->max();
39 39 }
40 40
41 41 qreal BarChartSeries::valueAt(int set, int category)
42 42 {
43 43 return mModel->valueAt(set,category);
44 44 }
45 45
46 46 qreal BarChartSeries::maxCategorySum()
47 47 {
48 48 return mModel->maxCategorySum();
49 49 }
50 50
51 51 BarChartModel& BarChartSeries::model()
52 52 {
53 53 return *mModel;
54 54 }
55 55
56 56
57 57 #include "moc_barchartseries.cpp"
58 58
59 59 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,50 +1,54
1 1 #ifndef BARCHARTSERIES_H
2 2 #define BARCHARTSERIES_H
3 3
4 4 #include <QList>
5 5 #include <QAbstractItemModel>
6 6 #include "qchartseries.h"
7 7
8 8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9 9
10 10 class QBarCategory;
11 11 class QBarSet;
12 12 class BarGroup;
13 13 class BarChartModel;
14 14
15 15 // Container for series
16 16 class QTCOMMERCIALCHART_EXPORT BarChartSeries : public QChartSeries
17 17 {
18 18 Q_OBJECT
19 19 public:
20 BarChartSeries(QBarCategory &category, QObject* parent=0);
20 BarChartSeries(QBarCategory *category, QObject* parent=0);
21 21
22 // from BarChartSeriesBase
23 22 virtual QChartSeriesType type() const { return QChartSeries::SeriesTypeBar; }
24 23
25 void addBarSet(QBarSet &set);
26 void removeBarSet(QBarSet &set);
24 void addBarSet(QBarSet *set); // Takes ownership
25 void removeBarSet(QBarSet *set); // Also deletes the set, if set is owned.
27 26
27 //TODO:
28 //QList<QString> legend(); // Returns legend of series (ie. names of all sets in series)
29
30 // TODO: Functions below this are not part of api and will be moved
31 // to private implementation, when we start using it (not part of api)
28 32 int countCategories();
29 33 qreal min();
30 34 qreal max();
31 35 qreal valueAt(int set, int category);
32 36 qreal maxCategorySum();
33 37
34 38 BarChartModel& model();
35 39
36 40 signals:
37 41 void changed(int index);
38 42
39 43 public Q_SLOTS:
40 44
41 45 private:
42 46
43 47 BarGroup* mBarGroup;
44 48 BarChartModel* mModel;
45 49
46 50 };
47 51
48 52 QTCOMMERCIALCHART_END_NAMESPACE
49 53
50 54 #endif // BARCHARTSERIES_H
@@ -1,69 +1,70
1 1 #include "bargroup.h"
2 2 #include "bar_p.h"
3 3 #include "barlabel_p.h"
4 4 #include <QDebug>
5 5
6 6 QTCOMMERCIALCHART_BEGIN_NAMESPACE
7 7
8 8 BarGroup::BarGroup(BarChartModel& model, QGraphicsItem *parent) :
9 9 BarGroupBase(model,parent)
10 10 {
11 mBarDefaultWidth = 10;
11 mBarDefaultWidth = 5;
12 12 }
13 13
14 14 void BarGroup::layoutChanged()
15 15 {
16 16 // qDebug() << "BarGroup::layoutChanged";
17 17 // Scale bars to new layout
18 18 // Layout for bars:
19 19 if (mModel.countSets() <= 0) {
20 qDebug() << "No sets in model!";
20 21 return;
21 22 }
22 23
23 24 if (childItems().count() == 0) {
24 25 qDebug() << "WARNING: BarGroup::layoutChanged called before graphics items are created!";
25 26 return;
26 27 }
27 28
28 29 // TODO: better way to auto-layout?
29 30 // Use reals for accurancy (we might get some compiler warnings... :)
30 31 int itemCount = mModel.countCategories();
31 32 int seriesCount = mModel.countSets();
32 33
33 34 qreal tW = mWidth;
34 35 qreal tH = mHeight;
35 36 qreal tM = mModel.max();
36 37 qreal scale = (tH/tM);
37 38 qreal tC = itemCount+1;
38 39 qreal xStepPerSeries = (tW/tC);
39 40
40 41 // Scaling.
41 42 int itemIndex(0);
42 43 int labelIndex = itemCount * seriesCount;
43 44
44 45 for (int item=0; item < itemCount; item++) {
45 46 qreal xPos = xStepPerSeries * item + ((tW + mBarDefaultWidth*seriesCount)/(itemCount*2));
46 47 qreal yPos = mHeight;
47 48 for (int series = 0; series < seriesCount; series++) {
48 49 qreal barHeight = mModel.valueAt(series, item) * scale;
49 50 Bar* bar = reinterpret_cast<Bar*> (childItems().at(itemIndex));
50 51
51 52 // TODO: width settable per bar?
52 53 bar->resize(mBarDefaultWidth, barHeight);
53 54 bar->setColor(mColors.at(series));
54 55 bar->setPos(xPos, yPos-barHeight); // item*posStep+startPos + series * mBarDefaultWidth, mHeight);
55 56 itemIndex++;
56 57 xPos += mBarDefaultWidth;
57 58 }
58 59
59 60 // TODO: Layout for labels, remove magic number
60 61 xPos = xStepPerSeries * item + ((tW + mBarDefaultWidth*seriesCount)/(itemCount*2));
61 62 BarLabel* label = reinterpret_cast<BarLabel*> (childItems().at(labelIndex));
62 63 label->setPos(xPos, mHeight + 20);
63 64 labelIndex++;
64 65 }
65 66
66 67 mLayoutDirty = true;
67 68 }
68 69
69 70 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,128 +1,125
1 1 #include "bargroupbase.h"
2 2 #include "bar_p.h"
3 3 #include "barlabel_p.h"
4 4 #include "separator_p.h"
5 5 #include <QDebug>
6 6
7 7 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8 8
9 9 BarGroupBase::BarGroupBase(BarChartModel& model, QGraphicsItem *parent)
10 10 : ChartItem(parent)
11 11 ,mBarDefaultWidth(20) // TODO: remove hard coding, when we have layout code ready
12 12 ,mLayoutSet(false)
13 13 ,mLayoutDirty(true)
14 14 ,mSeparatorsVisible(true)
15 15 ,mModel(model)
16 // ,mSeries(series)
17 16 {
18 17 dataChanged();
19 18 }
20 19
21 20 void BarGroupBase::setSeparatorsVisible(bool visible)
22 21 {
23 22 mSeparatorsVisible = visible;
24 23 }
25 24
26 25 void BarGroupBase::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
27 26 {
28 27 // qDebug() << "BarGroupBase::paint" << childItems().count();
29 28 if (!mLayoutSet) {
30 29 qDebug() << "BarGroupBase::paint called without layout set. Aborting.";
31 30 return;
32 31 }
33 32 // if (mLayoutDirty) {
34 33 // Layout or data has changed. Need to redraw.
35 34 foreach(QGraphicsItem* i, childItems()) {
36 35 i->paint(painter,option,widget);
37 36 }
38 37 // }
39 38 }
40 39
41 40 QRectF BarGroupBase::boundingRect() const
42 41 {
43 42 return QRectF(0,0,mWidth,mHeight);
44 43 }
45 44
46 45 void BarGroupBase::setBarWidth( int w )
47 46 {
48 47 mBarDefaultWidth = w;
49 48 }
50 49
51 50 int BarGroupBase::addColor( QColor color )
52 51 {
53 52 // qDebug() << "BarGroupBase::addColor";
54 53 int colorIndex = mColors.count();
55 54 mColors.append(color);
56 55 return colorIndex;
57 56 }
58 57
59 58 void BarGroupBase::resetColors()
60 59 {
61 60 // qDebug() << "BarGroupBase::resetColors";
62 61 mColors.clear();
63 62 }
64 63
65 64 void BarGroupBase::dataChanged()
66 65 {
67 66 // TODO: performance optimizations. Do we really need to delete and create items every time data is changed or can we reuse them?
68 67
69 68 // Delete old bars
70 69 foreach (QGraphicsItem* item, childItems()) {
71 70 delete item;
72 71 }
73 72
74 73 // Create new graphic items for bars
75 int totalItems = mModel.countTotalItems(); // mSeries.countTotalItems();
74 int totalItems = mModel.countTotalItems();
76 75 for (int i=0; i<totalItems; i++) {
77 76 Bar *bar = new Bar(this);
78 77 childItems().append(bar);
79 78 }
80 79
81 int count = mModel.countCategories(); // mSeries.countColumns();
80 int count = mModel.countCategories();
82 81 for (int i=0; i<count; i++) {
83 82 BarLabel* label = new BarLabel(this);
84 83 label->set(mModel.label(i));
85 84 childItems().append(label);
86 85 }
87 86
88 count = mModel.countCategories() - 1; // mSeries.countColumns() - 1; // There is one less separator than columns
87 count = mModel.countCategories() - 1; // There is one less separator than columns
89 88 for (int i=0; i<count; i++) {
90 89 Separator* sep = new Separator(this);
91 90 sep->setColor(QColor(255,0,0,255)); // TODO: color for separations from theme
92 91 childItems().append(sep);
93 92 }
94 93
95 94 // TODO: if (autolayout) { layoutChanged() } or something
96 95 mLayoutDirty = true;
97 96 }
98 97
99 98 //handlers
100 99
101 100 void BarGroupBase::handleModelChanged(int index)
102 101 {
103 qDebug() << "BarGroupBase::handleModelChanged" << index;
102 // qDebug() << "BarGroupBase::handleModelChanged" << index;
104 103 dataChanged();
105 104 }
106 105
107 106 void BarGroupBase::handleDomainChanged(const Domain& domain)
108 107 {
109 108 // qDebug() << "BarGroupBase::handleDomainChanged";
110
111 109 // TODO: Figure out the use case for this.
112 110 // Affects the size of visible item, so layout is changed.
113 111 // layoutChanged();
114 112 }
115 113
116 114 void BarGroupBase::handleGeometryChanged(const QRectF& rect)
117 115 {
118 // qDebug() << "BarGroupBase::handleGeometryChanged";
119 116 mWidth = rect.width();
120 117 mHeight = rect.height();
121 118 layoutChanged();
122 119 mLayoutSet = true;
123 120 setPos(rect.topLeft());
124 121 }
125 122
126 123 #include "moc_bargroupbase.cpp"
127 124
128 125 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,62 +1,62
1 1 #include "percentbarchartseries.h"
2 2
3 3 #include <limits.h>
4 4 #include <QDebug>
5 5 #include "percentbarchartseries.h"
6 6 #include "qbarset.h"
7 7 #include "qbarcategory.h"
8 8 #include "barchartmodel_p.h"
9 9
10 10 QTCOMMERCIALCHART_BEGIN_NAMESPACE
11 11
12 PercentBarChartSeries::PercentBarChartSeries(QBarCategory &category, QObject *parent)
12 PercentBarChartSeries::PercentBarChartSeries(QBarCategory *category, QObject *parent)
13 13 : QChartSeries(parent)
14 14 ,mModel(new BarChartModel(category, this))
15 15 {
16 16 }
17 17
18 void PercentBarChartSeries::addBarSet(QBarSet &set)
18 void PercentBarChartSeries::addBarSet(QBarSet *set)
19 19 {
20 20 mModel->addBarSet(set);
21 21 }
22 22
23 void PercentBarChartSeries::removeBarSet(QBarSet &set)
23 void PercentBarChartSeries::removeBarSet(QBarSet *set)
24 24 {
25 25 mModel->removeBarSet(set);
26 26 }
27 27
28 28 int PercentBarChartSeries::countCategories()
29 29 {
30 30 return mModel->countCategories();
31 31 }
32 32
33 33 qreal PercentBarChartSeries::min()
34 34 {
35 35 return mModel->min();
36 36 }
37 37
38 38 qreal PercentBarChartSeries::max()
39 39 {
40 40 return mModel->max();
41 41 }
42 42
43 43 qreal PercentBarChartSeries::valueAt(int set, int category)
44 44 {
45 45 return mModel->valueAt(set,category);
46 46 }
47 47
48 48 qreal PercentBarChartSeries::maxCategorySum()
49 49 {
50 50 return mModel->maxCategorySum();
51 51 }
52 52
53 53 BarChartModel& PercentBarChartSeries::model()
54 54 {
55 55 return *mModel;
56 56 }
57 57
58 58
59 59 #include "moc_percentbarchartseries.cpp"
60 60
61 61 QTCOMMERCIALCHART_END_NAMESPACE
62 62
@@ -1,51 +1,56
1 1 #ifndef PERCENTBARCHARTSERIES_H
2 2 #define PERCENTBARCHARTSERIES_H
3 3
4 4 #include <QList>
5 5 #include <QAbstractItemModel>
6 6 #include "qchartseries.h"
7 7
8 8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9 9
10 10 class PercentBarGroup;
11 11 class QBarCategory;
12 12 class QBarSet;
13 13 class BarChartModel;
14 14
15 15 class QTCOMMERCIALCHART_EXPORT PercentBarChartSeries : public QChartSeries
16 16 {
17 17 Q_OBJECT
18 18 public:
19 PercentBarChartSeries(QBarCategory &category, QObject* parent=0);
19 PercentBarChartSeries(QBarCategory *category, QObject* parent=0);
20 20
21 21 // from BarChartSeriesBase
22 22 virtual QChartSeriesType type() const { return QChartSeries::SeriesTypePercentBar; }
23 23
24 void addBarSet(QBarSet &set);
25 void removeBarSet(QBarSet &set);
24 void addBarSet(QBarSet *set); // Takes ownership
25 void removeBarSet(QBarSet *set); // Also deletes the set, if set is owned.
26 26
27 //TODO:
28 //QList<QString> legend(); // Returns legend of series (ie. names of all sets in series)
29
30 // TODO: Functions below this are not part of api and will be moved
31 // to private implementation, when we start using it (not part of api)
27 32 int countCategories();
28 33 qreal min();
29 34 qreal max();
30 35 qreal valueAt(int set, int category);
31 36 qreal maxCategorySum();
32 37
33 38 BarChartModel& model();
34 39
35 40 signals:
36 41 void changed(int index);
37 42
38 43 public Q_SLOTS:
39 44
40 45
41 46 private:
42 47
43 48 PercentBarGroup* mPercentBarGroup;
44 49 BarChartModel* mModel;
45 50
46 51 };
47 52
48 53 QTCOMMERCIALCHART_END_NAMESPACE
49 54
50 55
51 56 #endif // PERCENTBARCHARTSERIES_H
@@ -1,77 +1,79
1 1 #include "percentbargroup.h"
2 2 #include "bar_p.h"
3 3 #include "barlabel_p.h"
4 4 #include "separator_p.h"
5 5 #include <QDebug>
6 6
7 7 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8 8
9 9
10 10 PercentBarGroup::PercentBarGroup(BarChartModel& model, QGraphicsItem *parent) :
11 11 BarGroupBase(model, parent)
12 12 {
13 13 }
14 14
15 15 void PercentBarGroup::layoutChanged()
16 16 {
17 // qDebug() << "PercentBarGroup::layoutChanged";
17 18 // Scale bars to new layout
18 19 // Layout for bars:
19 20 if (mModel.countSets() <= 0) {
21 qDebug() << "No sets in model!";
20 22 // Nothing to do.
21 23 return;
22 24 }
23 25
24 26 if (childItems().count() == 0) {
25 27 qDebug() << "WARNING: PercentBarGroup::layoutChanged called before graphics items are created!";
26 28 return;
27 29 }
28 30
29 31 // TODO: better way to auto-layout
30 32 // Use reals for accurancy (we might get some compiler warnings... :)
31 33 int count = mModel.countCategories();
32 34 int itemIndex(0);
33 35 qreal tW = mWidth;
34 36 qreal tC = count+1;
35 37 qreal xStep = (tW/tC);
36 38 qreal xPos = ((tW/tC) - mBarDefaultWidth / 2);
37 39 int labelIndex = mModel.countCategories() * mModel.countSets();
38 40
39 41 for (int column = 0; column < mModel.countCategories(); column++) {
40 42 qreal colSum = mModel.categorySum(column);
41 43 qreal h = mHeight;
42 44 qreal scale = (h / colSum);
43 45 qreal yPos = h;
44 46 for (int row=0; row < mModel.countSets(); row++) {
45 47 qreal barHeight = mModel.valueAt(row, column) * scale;
46 48 Bar* bar = reinterpret_cast<Bar*> (childItems().at(itemIndex));
47 49
48 50 // TODO: width settable per bar?
49 51 bar->resize(mBarDefaultWidth, barHeight);
50 52 bar->setColor(mColors.at(row));
51 53 bar->setPos(xPos, yPos-barHeight);
52 54 itemIndex++;
53 55 yPos -= barHeight;
54 56 }
55 57
56 58 // TODO: Layout for labels, remove magic number
57 59 BarLabel* label = reinterpret_cast<BarLabel*> (childItems().at(labelIndex));
58 60 label->setPos(xPos, mHeight + 20);
59 61 labelIndex++;
60 62 xPos += xStep;
61 63 }
62 64
63 65 // Position separators
64 66 int separatorIndex = labelIndex; // Separators are after labels in childItems(). TODO: better way to store these?
65 67 xPos = xStep + xStep/2; // Initial position is between first and second group. ie one and half steps from left.
66 68 for (int s=0; s < mModel.countCategories() - 1; s++) {
67 69 Separator* sep = reinterpret_cast<Separator*> (childItems().at(separatorIndex));
68 70 sep->setPos(xPos,0);
69 71 sep->setSize(QSizeF(1,mHeight));
70 72 xPos += xStep;
71 73 separatorIndex++;
72 74 }
73 75
74 76 mLayoutDirty = true;
75 77 }
76 78
77 79 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,26 +1,27
1 1 #include "qbarcategory.h"
2 2
3 3 QTCOMMERCIALCHART_BEGIN_NAMESPACE
4 4
5 5 QBarCategory::QBarCategory()
6 6 {
7 7 }
8 8
9 9 QBarCategory& QBarCategory::operator << (const QString &label)
10 10 {
11 11 mList.append(label);
12 12 return *this;
13 13 }
14 14
15 15 int QBarCategory::count()
16 16 {
17 17 return mList.count();
18 18 }
19 19
20 20 QString QBarCategory::label(int category)
21 21 {
22 22 return mList.at(category);
23 23 }
24 24
25
25 // TODO?:
26 //#include "moc_qbarcategory.cpp"
26 27 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,27 +1,28
1 1 #ifndef QBARCATEGORY_H
2 2 #define QBARCATEGORY_H
3 3
4 4 #include "qchartglobal.h"
5 5
6 6 QTCOMMERCIALCHART_BEGIN_NAMESPACE
7 7
8 class QTCOMMERCIALCHART_EXPORT QBarCategory // TODO? : pubclic QObject
8 class QTCOMMERCIALCHART_EXPORT QBarCategory // TODO?: : public QObject
9 9 {
10 // Q_OBJECT;
10 11 public:
11 12 QBarCategory();
12 13
13 14 QBarCategory& operator << (const QString &label);
14 15
15 16 // Number of items in category
16 17 int count();
17 18 QString label(int category);
18 19
19 20 public:
20 21
21 22 QList<QString> mList;
22 23
23 24 };
24 25
25 26 QTCOMMERCIALCHART_END_NAMESPACE
26 27
27 28 #endif // QBARCATEGORY_H
@@ -1,35 +1,36
1 1 #include "qbarset.h"
2 2
3 3 QTCOMMERCIALCHART_BEGIN_NAMESPACE
4 4
5 5 QBarSet::QBarSet()
6 6 {
7 7 }
8 8
9 9 void QBarSet::setName(QString name)
10 10 {
11 11 mName = name;
12 12 }
13 13 QString QBarSet::name()
14 14 {
15 15 return mName;
16 16 }
17 17
18 18 QBarSet& QBarSet::operator << (const qreal &value)
19 19 {
20 20 mValues.append(value);
21 21 return *this;
22 22 }
23 23
24 24 int QBarSet::count()
25 25 {
26 26 return mValues.count();
27 27 }
28 28
29 29 qreal QBarSet::valueAt(int index)
30 30 {
31 31 return mValues.at(index);
32 32 }
33 33
34
34 //TODO?:
35 //#include "moc_qbarset.cpp"
35 36 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,31 +1,32
1 1 #ifndef QBARSET_H
2 2 #define QBARSET_H
3 3
4 4 #include "qchartglobal.h"
5 5
6 6 QTCOMMERCIALCHART_BEGIN_NAMESPACE
7 7
8 class QTCOMMERCIALCHART_EXPORT QBarSet // : pubclic QObject // TODO: Need for this?
8 class QTCOMMERCIALCHART_EXPORT QBarSet // TODO? : public QObject
9 9 {
10 //Q_OBJECT;
10 11 public:
11 12 QBarSet();
12 13
13 14 void setName(QString name);
14 15 QString name();
15 16 QBarSet& operator << (const qreal &value);
16 17
17 18 //TODO: What is the way to set a single value to n:th item? Is there need for such functionality?
18 19
19 20 int count();
20 21 qreal valueAt(int index);
21 22
22 23 private:
23 24
24 25 QString mName;
25 26 QList<qreal> mValues;
26 27
27 28 };
28 29
29 30 QTCOMMERCIALCHART_END_NAMESPACE
30 31
31 32 #endif // QBARSET_H
@@ -1,60 +1,60
1 1 #include <limits.h>
2 2 #include <QDebug>
3 3 #include "stackedbarchartseries.h"
4 4 #include "qbarcategory.h"
5 5 #include "qbarset.h"
6 6 #include "barchartmodel_p.h"
7 7
8 8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9 9
10 StackedBarChartSeries::StackedBarChartSeries(QBarCategory &category, QObject *parent)
10 StackedBarChartSeries::StackedBarChartSeries(QBarCategory *category, QObject *parent)
11 11 : QChartSeries(parent)
12 12 ,mModel(new BarChartModel(category, this))
13 13 {
14 14 }
15 15
16 void StackedBarChartSeries::addBarSet(QBarSet &set)
16 void StackedBarChartSeries::addBarSet(QBarSet *set)
17 17 {
18 18 mModel->addBarSet(set);
19 19 }
20 20
21 void StackedBarChartSeries::removeBarSet(QBarSet &set)
21 void StackedBarChartSeries::removeBarSet(QBarSet *set)
22 22 {
23 23 mModel->removeBarSet(set);
24 24 }
25 25
26 26 int StackedBarChartSeries::countCategories()
27 27 {
28 28 return mModel->countCategories();
29 29 }
30 30
31 31 qreal StackedBarChartSeries::min()
32 32 {
33 33 return mModel->min();
34 34 }
35 35
36 36 qreal StackedBarChartSeries::max()
37 37 {
38 38 return mModel->max();
39 39 }
40 40
41 41 qreal StackedBarChartSeries::valueAt(int set, int category)
42 42 {
43 43 return mModel->valueAt(set,category);
44 44 }
45 45
46 46 qreal StackedBarChartSeries::maxCategorySum()
47 47 {
48 48 return mModel->maxCategorySum();
49 49 }
50 50
51 51 BarChartModel& StackedBarChartSeries::model()
52 52 {
53 53 return *mModel;
54 54 }
55 55
56 56
57 57 #include "moc_stackedbarchartseries.cpp"
58 58
59 59 QTCOMMERCIALCHART_END_NAMESPACE
60 60
@@ -1,48 +1,53
1 1 #ifndef STACKEDBARCHARTSERIES_H
2 2 #define STACKEDBARCHARTSERIES_H
3 3
4 4 #include <QList>
5 5 #include <QAbstractItemModel>
6 6 #include "qchartseries.h"
7 7
8 8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9 9
10 10 class StackedBarGroup;
11 11 class QBarCategory;
12 12 class QBarSet;
13 13 class BarChartModel;
14 14
15 15 class QTCOMMERCIALCHART_EXPORT StackedBarChartSeries : public QChartSeries
16 16 {
17 17 Q_OBJECT
18 18 public:
19 StackedBarChartSeries(QBarCategory &category, QObject* parent=0);
19 StackedBarChartSeries(QBarCategory *category, QObject* parent=0);
20 20
21 21 // from QChartSeries
22 22 virtual QChartSeriesType type() const { return QChartSeries::SeriesTypeStackedBar; }
23 23
24 void addBarSet(QBarSet &set);
25 void removeBarSet(QBarSet &set);
24 void addBarSet(QBarSet *set); // Takes ownership
25 void removeBarSet(QBarSet *set); // Also deletes the set, if set is owned.
26 26
27 //TODO:
28 //QList<QString> legend(); // Returns legend of series (ie. names of all sets in series)
29
30 // TODO: Functions below this are not part of api and will be moved
31 // to private implementation, when we start using it (not part of api)
27 32 int countCategories();
28 33 qreal min();
29 34 qreal max();
30 35 qreal valueAt(int set, int category);
31 36 qreal maxCategorySum();
32 37
33 38 BarChartModel& model();
34 39
35 40 signals:
36 41 void changed(int index);
37 42
38 43 public Q_SLOTS:
39 44
40 45 private:
41 46
42 47 StackedBarGroup* mStackedBarGroup;
43 48 BarChartModel* mModel;
44 49 };
45 50
46 51 QTCOMMERCIALCHART_END_NAMESPACE
47 52
48 53 #endif // STACKEDBARCHARTSERIES_H
@@ -1,83 +1,84
1 1 #include "stackedbargroup.h"
2 2 #include "bar_p.h"
3 3 #include "barlabel_p.h"
4 4 #include "separator_p.h"
5 5 #include <QDebug>
6 6
7 7 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8 8
9 9 StackedBarGroup::StackedBarGroup(BarChartModel& model, QGraphicsItem *parent) :
10 10 BarGroupBase(model,parent)
11 11 {
12 12 }
13 13
14 14 void StackedBarGroup::layoutChanged()
15 15 {
16 16 // qDebug() << "StackedBarGroup::layoutChanged";
17 17 // Scale bars to new layout
18 18 // Layout for bars:
19 19 if (mModel.countSets() <= 0) {
20 qDebug() << "No sets in model!";
20 21 // Nothing to do.
21 22 return;
22 23 }
23 24
24 25 if (mModel.countCategories() == 0) {
26 qDebug() << "No categories in model!";
25 27 // Nothing to do
26 28 return;
27 29 }
28 30
29 31 if (childItems().count() == 0) {
30 32 qDebug() << "WARNING: StackedBarGroup::layoutChanged called before graphics items are created!";
31 33 return;
32 34 }
33 35
34 36 // TODO: better way to auto-layout
35 37 // Use reals for accurancy (we might get some compiler warnings... :)
36 38 // TODO: use temp variable for column count...
37 39 qreal maxSum = mModel.maxCategorySum();
38 40 qreal h = mHeight;
39 41 qreal scale = (h / maxSum);
40 42
41 43 int itemIndex(0);
42 44 qreal tW = mWidth;
43 45 qreal tC = mModel.countCategories() + 1;
44 46 qreal xStep = (tW/tC);
45 47 qreal xPos = ((tW/tC) - mBarDefaultWidth / 2);
46 48 int labelIndex = mModel.countSets() * mModel.countCategories();
47 49
48 50 for (int column = 0; column < mModel.countCategories(); column++) {
49 51 qreal yPos = h;
50 52 for (int row=0; row < mModel.countSets(); row++) {
51 53 qreal barHeight = mModel.valueAt(row, column) * scale;
52 54 Bar* bar = reinterpret_cast<Bar*> (childItems().at(itemIndex));
53 55
54 56 bar->resize(mBarDefaultWidth, barHeight);
55 57 bar->setColor(mColors.at(row));
56 58 bar->setPos(xPos, yPos-barHeight);
57 59 itemIndex++;
58 60 yPos -= barHeight;
59 61 }
60 62
61 63 // TODO: Layout for labels, remove magic number
62 64 BarLabel* label = reinterpret_cast<BarLabel*> (childItems().at(labelIndex));
63 65 label->setPos(xPos, mHeight + 20);
64 66 labelIndex++;
65 67 xPos += xStep;
66 68 }
67 69
68
69 70 // Position separators
70 71 int separatorIndex = labelIndex; // Separators are after labels in childItems(). TODO: better way to store these?
71 72 xPos = xStep + xStep/2; // Initial position is between first and second group. ie one and half steps from left.
72 73 for (int s=0; s < mModel.countCategories() - 1; s++) {
73 74 Separator* sep = reinterpret_cast<Separator*> (childItems().at(separatorIndex));
74 75 sep->setPos(xPos,0);
75 76 sep->setSize(QSizeF(1,mHeight));
76 77 xPos += xStep;
77 78 separatorIndex++;
78 79 }
79 80
80 81 mLayoutDirty = true;
81 82 }
82 83
83 84 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,160 +1,162
1 1 #include "chartdataset_p.h"
2 2 //series
3 3 #include "qlinechartseries.h"
4 4 #include "barchartseries.h"
5 5 #include "stackedbarchartseries.h"
6 6 #include "percentbarchartseries.h"
7 7 #include "qpieseries.h"
8 8 #include "qscatterseries.h"
9 9
10 10 QTCOMMERCIALCHART_BEGIN_NAMESPACE
11 11
12 12 ChartDataSet::ChartDataSet(QObject *parent):QObject(parent)
13 13 {
14 14 Domain domain;
15 15 m_domains<<domain;
16 16 }
17 17
18 18 ChartDataSet::~ChartDataSet()
19 19 {
20 20 // TODO Auto-generated destructor stub
21 21 }
22 22
23 23 const Domain& ChartDataSet::domain() const
24 24 {
25 25 return m_domains[m_domainIndex];
26 26 }
27 27
28 28 void ChartDataSet::addSeries(QChartSeries* series)
29 29 {
30 30 // TODO: we should check the series not already added
31 31 m_chartSeries << series;
32 32 m_domainIndex = 0;
33 33 m_domains.resize(1);
34 34
35 35 Domain& domain = m_domains[m_domainIndex];
36 36
37 37 switch(series->type())
38 38 {
39 39 case QChartSeries::SeriesTypeLine: {
40 40
41 41 QLineChartSeries* xyseries = static_cast<QLineChartSeries*>(series);
42 42
43 43 for (int i = 0; i < xyseries->count(); i++)
44 44 {
45 45 qreal x = xyseries->x(i);
46 46 qreal y = xyseries->y(i);
47 47 domain.m_minX = qMin(domain.m_minX,x);
48 48 domain.m_minY = qMin(domain.m_minY,y);
49 49 domain.m_maxX = qMax(domain.m_maxX,x);
50 50 domain.m_maxY = qMax(domain.m_maxY,y);
51 51 }
52 52 break;
53 53 }
54 54 case QChartSeries::SeriesTypeBar: {
55
55 qDebug() << "QChartSeries::SeriesTypeBar";
56 56 BarChartSeries* barSeries = static_cast<BarChartSeries*>(series);
57 57 qreal x = barSeries->countCategories();
58 58 qreal y = barSeries->max();
59 59 domain.m_minX = qMin(domain.m_minX,x);
60 60 domain.m_minY = qMin(domain.m_minY,y);
61 61 domain.m_maxX = qMax(domain.m_maxX,x);
62 62 domain.m_maxY = qMax(domain.m_maxY,y);
63 63 break;
64 64 }
65 65 case QChartSeries::SeriesTypeStackedBar: {
66 qDebug() << "QChartSeries::SeriesTypeStackedBar";
66 67
67 68 StackedBarChartSeries* stackedBarSeries = static_cast<StackedBarChartSeries*>(series);
68 69 qreal x = stackedBarSeries->countCategories();
69 70 qreal y = stackedBarSeries->maxCategorySum();
70 71 domain.m_minX = qMin(domain.m_minX,x);
71 72 domain.m_minY = qMin(domain.m_minY,y);
72 73 domain.m_maxX = qMax(domain.m_maxX,x);
73 74 domain.m_maxY = qMax(domain.m_maxY,y);
74 75 break;
75 76 }
76 77 case QChartSeries::SeriesTypePercentBar: {
78 qDebug() << "QChartSeries::SeriesTypePercentBar";
77 79
78 80 PercentBarChartSeries* percentBarSeries = static_cast<PercentBarChartSeries*>(series);
79 81 qreal x = percentBarSeries->countCategories();
80 82 domain.m_minX = qMin(domain.m_minX,x);
81 83 domain.m_minY = 0;
82 84 domain.m_maxX = qMax(domain.m_maxX,x);
83 85 domain.m_maxY = 100;
84 86 break;
85 87 }
86 88
87 89 case QChartSeries::SeriesTypePie: {
88 90 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
89 91 // TODO: domain stuff
90 92 break;
91 93 }
92 94
93 95 case QChartSeries::SeriesTypeScatter: {
94 96 QScatterSeries *scatterSeries = qobject_cast<QScatterSeries *>(series);
95 97 Q_ASSERT(scatterSeries);
96 98 foreach (QPointF point, scatterSeries->data()) {
97 99 domain.m_minX = qMin(domain.m_minX, point.x());
98 100 domain.m_maxX = qMax(domain.m_maxX, point.x());
99 101 domain.m_minY = qMin(domain.m_minY, point.y());
100 102 domain.m_maxY = qMax(domain.m_maxY, point.y());
101 103 }
102 104 break;
103 105 }
104 106
105 107 default: {
106 108 qDebug()<<__FUNCTION__<<"type" << series->type()<<"not supported";
107 109 return;
108 110 break;
109 111 }
110 112
111 113 }
112 114
113 115 emit seriesAdded(series);
114 116 emit domainChanged(domain);
115 117 }
116 118
117 119 bool ChartDataSet::nextDomain()
118 120 {
119 121 if (m_domainIndex < m_domains.count() - 1) {
120 122 m_domainIndex++;
121 123 emit domainChanged(m_domains[m_domainIndex]);
122 124 return true;
123 125 }
124 126 else {
125 127 return false;
126 128 }
127 129 }
128 130
129 131 bool ChartDataSet::previousDomain()
130 132 {
131 133 if (m_domainIndex > 0) {
132 134 m_domainIndex--;
133 135 emit domainChanged(m_domains[m_domainIndex]);
134 136 return true;
135 137 }
136 138 else {
137 139 return false;
138 140 }
139 141 }
140 142
141 143 void ChartDataSet::clearDomains()
142 144 {
143 145 if (m_domainIndex > 0) {
144 146 m_domainIndex = 0;
145 147 emit domainChanged(m_domains[m_domainIndex]);
146 148 }
147 149 }
148 150
149 151 void ChartDataSet::addDomain(const Domain& domain)
150 152 {
151 153 m_domains.resize(m_domainIndex + 1);
152 154 m_domains << domain;
153 155 m_domainIndex++;
154 156
155 157 emit domainChanged(domain);
156 158 }
157 159
158 160 #include "moc_chartdataset_p.cpp"
159 161
160 162 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,264 +1,265
1 1 #include "qchart.h"
2 2 #include "qchartaxis.h"
3 3 #include "chartpresenter_p.h"
4 4 #include "chartdataset_p.h"
5 5 #include "charttheme_p.h"
6 6 //series
7 7 #include "barchartseries.h"
8 8 #include "stackedbarchartseries.h"
9 9 #include "percentbarchartseries.h"
10 10 #include "qlinechartseries.h"
11 11 #include "qpieseries.h"
12 12 #include "qscatterseries.h"
13 13 //items
14 14 #include "axisitem_p.h"
15 15 #include "bargroup.h"
16 16 #include "stackedbargroup.h"
17 17 #include "linechartitem_p.h"
18 18 #include "percentbargroup.h"
19 19 #include "linechartanimationitem_p.h"
20 20 #include "piepresenter.h"
21 21 #include "scatterpresenter.h"
22 22
23 23 QTCOMMERCIALCHART_BEGIN_NAMESPACE
24 24
25 25 ChartPresenter::ChartPresenter(QChart* chart,ChartDataSet* dataset):QObject(chart),
26 26 m_chart(chart),
27 27 m_dataset(dataset),
28 28 m_chartTheme(0),
29 29 m_domainIndex(0),
30 30 m_marginSize(0),
31 31 m_axisX(new QChartAxis(this)),
32 32 m_axisY(new QChartAxis(this)),
33 33 m_rect(QRectF(QPoint(0,0),m_chart->size()))
34 34 {
35 35 setChartTheme(QChart::ChartThemeDefault);
36 36 m_axisItems[m_axisX] = new AxisItem(m_axisX,AxisItem::X_AXIS,m_chart);
37 37 m_axisItems[m_axisY] = new AxisItem(m_axisY,AxisItem::Y_AXIS,m_chart);
38 38 createConnections();
39 39 }
40 40
41 41 ChartPresenter::~ChartPresenter()
42 42 {
43 43 }
44 44
45 45 void ChartPresenter::createConnections()
46 46 {
47 47 QObject::connect(m_chart,SIGNAL(geometryChanged()),this,SLOT(handleGeometryChanged()));
48 48 QObject::connect(m_dataset,SIGNAL(seriesAdded(QChartSeries*)),this,SLOT(handleSeriesAdded(QChartSeries*)));
49 49
50 50 QMapIterator<QChartAxis*,AxisItem*> i(m_axisItems);
51 51
52 52 while (i.hasNext()) {
53 53 i.next();
54 54 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),i.value(),SLOT(handleGeometryChanged(const QRectF&)));
55 55 QObject::connect(m_dataset,SIGNAL(domainChanged(const Domain&)),i.value(),SLOT(handleDomainChanged(const Domain&)));
56 56 }
57 57 }
58 58
59 59 void ChartPresenter::handleGeometryChanged()
60 60 {
61 61 m_rect = QRectF(QPoint(0,0),m_chart->size());
62 62 m_rect.adjust(m_marginSize,m_marginSize, -m_marginSize, -m_marginSize);
63 63 Q_ASSERT(m_rect.isValid());
64 64 emit geometryChanged(m_rect);
65 65 }
66 66
67 67 int ChartPresenter::margin() const
68 68 {
69 69 return m_marginSize;
70 70 }
71 71
72 72 void ChartPresenter::setMargin(int margin)
73 73 {
74 74 m_marginSize = margin;
75 75 }
76 76
77 77 void ChartPresenter::handleSeriesAdded(QChartSeries* series)
78 78 {
79 qDebug() << " ChartPresenter::handleSeriesAdded";
79 80 switch(series->type())
80 81 {
81 82 case QChartSeries::SeriesTypeLine: {
82 83 QLineChartSeries* lineSeries = static_cast<QLineChartSeries*>(series);
83 84 LineChartItem* item = new LineChartAnimationItem(this,lineSeries,m_chart);
84 85 m_chartTheme->decorate(item,lineSeries,m_chartItems.count());
85 86 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
86 87 QObject::connect(m_dataset,SIGNAL(domainChanged(const Domain&)),item,SLOT(handleDomainChanged(const Domain&)));
87 88 QObject::connect(lineSeries,SIGNAL(changed(int)),item,SLOT(handleModelChanged(int)));
88 89 m_chartItems.insert(series,item);
89 90 break;
90 91 }
91 92
92 93 case QChartSeries::SeriesTypeBar: {
93 94 BarChartSeries* barSeries = static_cast<BarChartSeries*>(series);
94 95 BarGroup* item = new BarGroup(barSeries->model(),m_chart);
95 96 m_chartTheme->decorate(item,barSeries,m_chartItems.count());
96 97 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
97 98 QObject::connect(m_dataset,SIGNAL(domainChanged(const Domain&)),item,SLOT(handleDomainChanged(const Domain&)));
98 99 QObject::connect(barSeries,SIGNAL(changed(int)),item,SLOT(handleModelChanged(int)));
99 100 m_chartItems.insert(series,item);
100 101 // m_axisXItem->setVisible(false);
101 102 break;
102 103 }
103 104
104 105 case QChartSeries::SeriesTypeStackedBar: {
105 106
106 107 StackedBarChartSeries* stackedBarSeries = static_cast<StackedBarChartSeries*>(series);
107 108 StackedBarGroup* item = new StackedBarGroup(stackedBarSeries->model(),m_chart);
108 109 m_chartTheme->decorate(item,stackedBarSeries,m_chartItems.count());
109 110 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
110 111 QObject::connect(m_dataset,SIGNAL(domainChanged(const Domain&)),item,SLOT(handleDomainChanged(const Domain&)));
111 112 QObject::connect(stackedBarSeries,SIGNAL(changed(int)),item,SLOT(handleModelChanged(int)));
112 113 m_chartItems.insert(series,item);
113 114 break;
114 115 }
115 116
116 117 case QChartSeries::SeriesTypePercentBar: {
117 118
118 119 PercentBarChartSeries* percentBarSeries = static_cast<PercentBarChartSeries*>(series);
119 120 PercentBarGroup* item = new PercentBarGroup(percentBarSeries->model(),m_chart);
120 121 m_chartTheme->decorate(item,percentBarSeries ,m_chartItems.count());
121 122 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
122 123 QObject::connect(m_dataset,SIGNAL(domainChanged(const Domain&)),item,SLOT(handleDomainChanged(const Domain&)));
123 124 QObject::connect(percentBarSeries,SIGNAL(changed(int)),item,SLOT(handleModelChanged(int)));
124 125 m_chartItems.insert(series,item);
125 126 break;
126 127 }
127 128 case QChartSeries::SeriesTypeScatter: {
128 129 QScatterSeries *scatterSeries = qobject_cast<QScatterSeries *>(series);
129 130 ScatterPresenter *scatterPresenter = new ScatterPresenter(scatterSeries, m_chart);
130 131 QObject::connect(this, SIGNAL(geometryChanged(const QRectF&)),
131 132 scatterPresenter, SLOT(handleGeometryChanged(const QRectF&)));
132 133 QObject::connect(m_dataset, SIGNAL(domainChanged(const Domain&)),
133 134 scatterPresenter, SLOT(handleDomainChanged(const Domain&)));
134 135 // scatterSeries->d->m_theme = m_chartTheme->themeForSeries();
135 136 // scatterSeries->d->setParentItem(this);
136 137 // scatterSeries->d->m_boundingRect = m_rect.adjusted(margin(),margin(), -margin(), -margin());
137 138 m_chartItems.insert(scatterSeries, scatterPresenter);
138 139 break;
139 140 }
140 141 case QChartSeries::SeriesTypePie: {
141 142 QPieSeries *s = qobject_cast<QPieSeries *>(series);
142 143 PiePresenter* pie = new PiePresenter(m_chart, s);
143 144 m_chartTheme->decorate(pie, s, m_chartItems.count());
144 145 QObject::connect(this, SIGNAL(geometryChanged(const QRectF&)), pie, SLOT(handleGeometryChanged(const QRectF&)));
145 146 QObject::connect(m_dataset, SIGNAL(domainChanged(const Domain&)), pie, SLOT(handleDomainChanged(const Domain&)));
146 147 m_chartItems.insert(series, pie);
147 148 break;
148 149 }
149 150 default: {
150 151 qDebug()<< "Series type" << series->type() << "not implemented.";
151 152 break;
152 153 }
153 154 }
154 155
155 156 if(m_rect.isValid()) emit geometryChanged(m_rect);
156 157 }
157 158
158 159 void ChartPresenter::handleSeriesChanged(QChartSeries* series)
159 160 {
160 161 //TODO:
161 162 }
162 163
163 164 void ChartPresenter::zoomInToRect(const QRectF& rect)
164 165 {
165 166 if(!rect.isValid()) return;
166 167 QRectF r = rect.normalized();
167 168 r.translate(-m_marginSize, -m_marginSize);
168 169 Domain domain (m_dataset->domain().subDomain(r,m_rect.width(),m_rect.height()));
169 170 m_dataset->addDomain(domain);
170 171 }
171 172
172 173 void ChartPresenter::zoomIn()
173 174 {
174 175 if (!m_dataset->nextDomain()) {
175 176 QRectF rect = m_rect;
176 177 rect.setWidth(rect.width()/2);
177 178 rect.setHeight(rect.height()/2);
178 179 rect.moveCenter(m_rect.center());
179 180 Domain domain (m_dataset->domain().subDomain(rect,m_rect.width(),m_rect.height()));
180 181 m_dataset->addDomain(domain);
181 182 }
182 183 }
183 184
184 185 void ChartPresenter::zoomOut()
185 186 {
186 187 m_dataset->previousDomain();
187 188 }
188 189
189 190 void ChartPresenter::zoomReset()
190 191 {
191 192 m_dataset->clearDomains();
192 193 }
193 194
194 195 void ChartPresenter::setChartTheme(QChart::ChartTheme theme)
195 196 {
196 197 delete m_chartTheme;
197 198
198 199 m_chartTheme = ChartTheme::createTheme(theme);
199 200
200 201 m_chartTheme->decorate(m_chart);
201 202 QMapIterator<QChartSeries*,ChartItem*> i(m_chartItems);
202 203
203 204 int index=0;
204 205 while (i.hasNext()) {
205 206 i.next();
206 207 index++;
207 208 m_chartTheme->decorate(i.value(),i.key(),index);
208 209 }
209 210 }
210 211
211 212
212 213 QChart::ChartTheme ChartPresenter::chartTheme()
213 214 {
214 215 return m_chartTheme->id();
215 216 }
216 217
217 218 QChartAxis* ChartPresenter::axisX()
218 219 {
219 220 return m_axisX;
220 221 }
221 222
222 223 QChartAxis* ChartPresenter::axisY()
223 224 {
224 225 return m_axisY;
225 226 }
226 227
227 228 QChartAxis* ChartPresenter::addAxisX()
228 229 {
229 230 //only one axis
230 231 if(m_axisX==0){
231 232 m_axisX = new QChartAxis(this);
232 233 m_axisItems[m_axisX] = new AxisItem(m_axisX,AxisItem::X_AXIS,m_chart);
233 234 }
234 235 return m_axisX;
235 236 }
236 237
237 238 QChartAxis* ChartPresenter::addAxisY()
238 239 {
239 240 if(m_axisY==0){
240 241 m_axisY = new QChartAxis(this);
241 242 m_axisItems[m_axisY] = new AxisItem(m_axisY,AxisItem::Y_AXIS,m_chart);
242 243 return m_axisY;
243 244 }
244 245
245 246 QChartAxis* axis = new QChartAxis(this);
246 247 m_axisItems[axis] = new AxisItem(axis,AxisItem::Y_AXIS,m_chart);
247 248 return axis;
248 249 }
249 250
250 251 void ChartPresenter::removeAxis(QChartAxis* axis)
251 252 {
252 253 AxisItem* item = m_axisItems.take(axis);
253 254 if(item){
254 255 delete item;
255 256 delete axis;
256 257 }
257 258 //reset pointers to default ones
258 259 if(axis == m_axisX) m_axisX=0;
259 260 else if(axis == m_axisY) m_axisY=0;
260 261 }
261 262
262 263 #include "moc_chartpresenter_p.cpp"
263 264
264 265 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,425 +1,425
1 1 #include "mainwidget.h"
2 2 #include "dataseriedialog.h"
3 3 #include "qchartseries.h"
4 4 #include "qpieseries.h"
5 5 #include <qlinechartseries.h>
6 6 #include <qbarset.h>
7 7 #include <qbarcategory.h>
8 8 #include <barchartseries.h>
9 9 #include <stackedbarchartseries.h>
10 10 #include <percentbarchartseries.h>
11 11 #include <QPushButton>
12 12 #include <QComboBox>
13 13 #include <QSpinBox>
14 14 #include <QCheckBox>
15 15 #include <QGridLayout>
16 16 #include <QHBoxLayout>
17 17 #include <QLabel>
18 18 #include <QSpacerItem>
19 19 #include <QMessageBox>
20 20 #include <cmath>
21 21 #include <QDebug>
22 22 #include <QStandardItemModel>
23 23
24 24
25 25 QTCOMMERCIALCHART_USE_NAMESPACE
26 26
27 27 MainWidget::MainWidget(QWidget *parent) :
28 28 QWidget(parent)
29 29 {
30 30 m_chartWidget = new QChartView(this);
31 31 m_chartWidget->setRubberBandPolicy(QChartView::HorizonalRubberBand);
32 32
33 33 // Grid layout for the controls for configuring the chart widget
34 34 QGridLayout *grid = new QGridLayout();
35 35 QPushButton *addSeriesButton = new QPushButton("Add series");
36 36 connect(addSeriesButton, SIGNAL(clicked()), this, SLOT(addSeries()));
37 37 grid->addWidget(addSeriesButton, 0, 1);
38 38 initBackroundCombo(grid);
39 39 initScaleControls(grid);
40 40 initThemeCombo(grid);
41 41 QCheckBox *zoomCheckBox = new QCheckBox("Drag'n drop Zoom");
42 42 connect(zoomCheckBox, SIGNAL(toggled(bool)), m_chartWidget, SLOT(setZoomEnabled(bool)));
43 43 zoomCheckBox->setChecked(true);
44 44 grid->addWidget(zoomCheckBox, grid->rowCount(), 0);
45 45 // add row with empty label to make all the other rows static
46 46 grid->addWidget(new QLabel(""), grid->rowCount(), 0);
47 47 grid->setRowStretch(grid->rowCount() - 1, 1);
48 48
49 49 // Another grid layout as a main layout
50 50 QGridLayout *mainLayout = new QGridLayout();
51 51 mainLayout->addLayout(grid, 0, 0);
52 52
53 53 // Init series type specific controls
54 54 initPieControls();
55 55 mainLayout->addLayout(m_pieLayout, 2, 0);
56 56 // Scatter series specific settings
57 57 // m_scatterLayout = new QGridLayout();
58 58 // m_scatterLayout->addWidget(new QLabel("scatter"), 0, 0);
59 59 // m_scatterLayout->setEnabled(false);
60 60 // mainLayout->addLayout(m_scatterLayout, 1, 0);
61 61
62 62 // Add layouts and the chart widget to the main layout
63 63 mainLayout->addWidget(m_chartWidget, 0, 1, 3, 1);
64 64 setLayout(mainLayout);
65 65
66 66 // force an update to test data
67 67 testDataChanged(0);
68 68 }
69 69
70 70 // Combo box for selecting the chart's background
71 71 void MainWidget::initBackroundCombo(QGridLayout *grid)
72 72 {
73 73 QComboBox *backgroundCombo = new QComboBox(this);
74 74 backgroundCombo->addItem("Color");
75 75 backgroundCombo->addItem("Gradient");
76 76 backgroundCombo->addItem("Image");
77 77 connect(backgroundCombo, SIGNAL(currentIndexChanged(int)),
78 78 this, SLOT(backgroundChanged(int)));
79 79
80 80 grid->addWidget(new QLabel("Background:"), grid->rowCount(), 0);
81 81 grid->addWidget(backgroundCombo, grid->rowCount() - 1, 1);
82 82 }
83 83
84 84 // Scale related controls (auto-scale vs. manual min-max values)
85 85 void MainWidget::initScaleControls(QGridLayout *grid)
86 86 {
87 87 m_autoScaleCheck = new QCheckBox("Automatic scaling");
88 88 connect(m_autoScaleCheck, SIGNAL(stateChanged(int)), this, SLOT(autoScaleChanged(int)));
89 89 // Allow setting also non-sense values (like -2147483648 and 2147483647)
90 90 m_xMinSpin = new QSpinBox();
91 91 m_xMinSpin->setMinimum(INT_MIN);
92 92 m_xMinSpin->setMaximum(INT_MAX);
93 93 m_xMinSpin->setValue(0);
94 94 connect(m_xMinSpin, SIGNAL(valueChanged(int)), this, SLOT(xMinChanged(int)));
95 95 m_xMaxSpin = new QSpinBox();
96 96 m_xMaxSpin->setMinimum(INT_MIN);
97 97 m_xMaxSpin->setMaximum(INT_MAX);
98 98 m_xMaxSpin->setValue(10);
99 99 connect(m_xMaxSpin, SIGNAL(valueChanged(int)), this, SLOT(xMaxChanged(int)));
100 100 m_yMinSpin = new QSpinBox();
101 101 m_yMinSpin->setMinimum(INT_MIN);
102 102 m_yMinSpin->setMaximum(INT_MAX);
103 103 m_yMinSpin->setValue(0);
104 104 connect(m_yMinSpin, SIGNAL(valueChanged(int)), this, SLOT(yMinChanged(int)));
105 105 m_yMaxSpin = new QSpinBox();
106 106 m_yMaxSpin->setMinimum(INT_MIN);
107 107 m_yMaxSpin->setMaximum(INT_MAX);
108 108 m_yMaxSpin->setValue(10);
109 109 connect(m_yMaxSpin, SIGNAL(valueChanged(int)), this, SLOT(yMaxChanged(int)));
110 110
111 111 grid->addWidget(m_autoScaleCheck, grid->rowCount(), 0);
112 112 grid->addWidget(new QLabel("x min:"), grid->rowCount(), 0);
113 113 grid->addWidget(m_xMinSpin, grid->rowCount() - 1, 1);
114 114 grid->addWidget(new QLabel("x max:"), grid->rowCount(), 0);
115 115 grid->addWidget(m_xMaxSpin, grid->rowCount() - 1, 1);
116 116 grid->addWidget(new QLabel("y min:"), grid->rowCount(), 0);
117 117 grid->addWidget(m_yMinSpin, grid->rowCount() - 1, 1);
118 118 grid->addWidget(new QLabel("y max:"), grid->rowCount(), 0);
119 119 grid->addWidget(m_yMaxSpin, grid->rowCount() - 1, 1);
120 120
121 121 m_autoScaleCheck->setChecked(true);
122 122 }
123 123
124 124 // Combo box for selecting theme
125 125 void MainWidget::initThemeCombo(QGridLayout *grid)
126 126 {
127 127 QComboBox *chartTheme = new QComboBox();
128 128 chartTheme->addItem("Default");
129 129 chartTheme->addItem("Vanilla");
130 130 chartTheme->addItem("Icy");
131 131 chartTheme->addItem("Grayscale");
132 132 chartTheme->addItem("Scientific");
133 133 chartTheme->addItem("Unnamed1");
134 134 connect(chartTheme, SIGNAL(currentIndexChanged(int)),
135 135 this, SLOT(changeChartTheme(int)));
136 136 grid->addWidget(new QLabel("Chart theme:"), 8, 0);
137 137 grid->addWidget(chartTheme, 8, 1);
138 138 }
139 139
140 140 void MainWidget::initPieControls()
141 141 {
142 142 // Pie series specific settings
143 143 // Pie size factory
144 144 QDoubleSpinBox *pieSizeSpin = new QDoubleSpinBox();
145 145 pieSizeSpin->setMinimum(LONG_MIN);
146 146 pieSizeSpin->setMaximum(LONG_MAX);
147 147 pieSizeSpin->setValue(1.0);
148 148 pieSizeSpin->setSingleStep(0.1);
149 149 connect(pieSizeSpin, SIGNAL(valueChanged(double)), this, SLOT(setPieSizeFactor(double)));
150 150 // Pie position
151 151 QComboBox *piePosCombo = new QComboBox(this);
152 152 piePosCombo->addItem("Maximized");
153 153 piePosCombo->addItem("Top left");
154 154 piePosCombo->addItem("Top right");
155 155 piePosCombo->addItem("Bottom left");
156 156 piePosCombo->addItem("Bottom right");
157 157 connect(piePosCombo, SIGNAL(currentIndexChanged(int)),
158 158 this, SLOT(setPiePosition(int)));
159 159 m_pieLayout = new QGridLayout();
160 160 m_pieLayout->setEnabled(false);
161 161 m_pieLayout->addWidget(new QLabel("Pie size factor"), 0, 0);
162 162 m_pieLayout->addWidget(pieSizeSpin, 0, 1);
163 163 m_pieLayout->addWidget(new QLabel("Pie position"), 1, 0);
164 164 m_pieLayout->addWidget(piePosCombo, 1, 1);
165 165 }
166 166
167 167 void MainWidget::addSeries()
168 168 {
169 169 DataSerieDialog dialog(m_defaultSeriesName, this);
170 170 connect(&dialog, SIGNAL(accepted(QString, QString)), this, SLOT(addSeries(QString, QString)));
171 171 dialog.exec();
172 172 }
173 173
174 174 void MainWidget::addSeries(QString series, QString data)
175 175 {
176 176 qDebug() << "addSeries: " << series << " data: " << data;
177 177 m_defaultSeriesName = series;
178 178
179 179 // TODO: a dedicated data class for storing x and y values
180 180 QList<qreal> x;
181 181 QList<qreal> y;
182 182
183 QBarSet set0;
184 QBarSet set1;
185 QBarSet set2;
186 QBarSet set3;
187 QBarSet set4;
183 QBarSet *set0 = new QBarSet;
184 QBarSet *set1 = new QBarSet;
185 QBarSet *set2 = new QBarSet;
186 QBarSet *set3 = new QBarSet;
187 QBarSet *set4 = new QBarSet;
188 188
189 189 if (data == "linear") {
190 190 for (int i = 0; i < 20; i++) {
191 191 x.append(i);
192 192 y.append(i);
193 193 }
194 194 } else if (data == "linear, 1M") {
195 195 // 1 million data points from 0.0001 to 100
196 196 // TODO: What is the requirement? Should we be able to show this kind of data with
197 197 // reasonable performance, or can we expect the application developer to do "data mining"
198 198 // for us, so that the count of data points given to QtCommercial Chart is always
199 199 // reasonable?
200 200 for (qreal i = 0; i < 100; i += 0.0001) {
201 201 x.append(i);
202 202 y.append(20);
203 203 }
204 204 } else if (data == "SIN") {
205 205 for (int i = 0; i < 100; i++) {
206 206 x.append(i);
207 207 y.append(abs(sin(3.14159265358979 / 50 * i) * 100));
208 208 }
209 209 } else if (data == "SIN + random") {
210 210 for (qreal i = 0; i < 100; i += 0.1) {
211 211 x.append(i + (rand() % 5));
212 212 y.append(abs(sin(3.14159265358979 / 50 * i) * 100) + (rand() % 5));
213 213 }
214 214 } else if (data == "Table, 5 series"){
215 215 // Create some test data to chart
216 set0 << 1 << 2 << 3 << 4 << 5 << 6 << 7 << 8 << 9 << 10 << 11 << 12;
217 set1 << 5 << 0 << 0 << 4 << 0 << 7 << 8 << 9 << 9 << 0 << 4 << 2;
218 set2 << 3 << 5 << 8 << 13 << 8 << 5 << 3 << 2 << 1 << 1 << 3 << 5;
219 set3 << 5 << 6 << 7 << 3 << 4 << 5 << 8 << 9 << 10 << 5 << 2 << 7;
220 set4 << 9 << 7 << 5 << 3 << 1 << 2 << 4 << 6 << 8 << 10 << 1 << 6;
216 *set0 << 1 << 2 << 3 << 4 << 5 << 6 << 7 << 8 << 9 << 10 << 11 << 12;
217 *set1 << 5 << 0 << 0 << 4 << 0 << 7 << 8 << 9 << 9 << 0 << 4 << 2;
218 *set2 << 3 << 5 << 8 << 13 << 8 << 5 << 3 << 2 << 1 << 1 << 3 << 5;
219 *set3 << 5 << 6 << 7 << 3 << 4 << 5 << 8 << 9 << 10 << 5 << 2 << 7;
220 *set4 << 9 << 7 << 5 << 3 << 1 << 2 << 4 << 6 << 8 << 10 << 1 << 6;
221 221 } else {
222 222 // TODO: check if data has a valid file name
223 223 Q_ASSERT(false);
224 224 }
225 225
226 226 // TODO: color of the series
227 227 QChartSeries *newSeries = 0;
228 228 if (series == "Scatter") {
229 229 newSeries = m_chartWidget->createSeries(QChartSeries::SeriesTypeScatter);
230 230 Q_ASSERT(newSeries->setData(x, y));
231 231 } else if (series == "Pie") {
232 232 newSeries = m_chartWidget->createSeries(QChartSeries::SeriesTypePie);
233 233 Q_ASSERT(newSeries->setData(y));
234 234 } else if (series == "Line") {
235 235 // TODO: adding data to an existing line series does not give any visuals for some reason
236 236 // newSeries = m_chartWidget->createSeries(QChartSeries::SeriesTypeLine);
237 237 // QXYChartSeries *lineSeries = static_cast<QXYChartSeries *>(newSeries);
238 238 // lineSeries->setColor(Qt::blue);
239 239 // for (int i(0); i < x.count() && i < y.count(); i++) {
240 240 // lineSeries->add(x.at(i), y.at(i));
241 241 // }
242 242 //Q_ASSERT(newSeries->setData(x, y));
243 243 QLineChartSeries* series0 = new QLineChartSeries();
244 244 for (int i(0); i < x.count() && i < y.count(); i++)
245 245 series0->add(x.at(i), y.at(i));
246 246 m_chartWidget->addSeries(series0);
247 247 newSeries = series0;
248 248 } else if (series == "Bar") {
249 249 qDebug() << "Bar chart series";
250 250
251 QBarCategory category;
252 category << "Jan" << "Feb" << "Mar" << "Apr" << "May" << "June" << "Jul" << "Aug" << "Sep" << "Oct" << "Nov" << "Dec";
251 QBarCategory *category = new QBarCategory;
252 *category << "Jan" << "Feb" << "Mar" << "Apr" << "May" << "June" << "Jul" << "Aug" << "Sep" << "Oct" << "Nov" << "Dec";
253 253
254 254 BarChartSeries* series0 = new BarChartSeries(category, this);
255 255
256 256 series0->addBarSet(set0);
257 257 series0->addBarSet(set1);
258 258 series0->addBarSet(set2);
259 259 series0->addBarSet(set3);
260 260 series0->addBarSet(set4);
261 261
262 262 m_chartWidget->addSeries(series0);
263 263 newSeries = series0;
264 264 } else if (series == "StackedBar") {
265 265 qDebug() << "Stacked bar chart series";
266 266
267 QBarCategory category;
268 category << "Jan" << "Feb" << "Mar" << "Apr" << "May" << "June" << "Jul" << "Aug" << "Sep" << "Oct" << "Nov" << "Dec";
267 QBarCategory *category = new QBarCategory;
268 *category << "Jan" << "Feb" << "Mar" << "Apr" << "May" << "June" << "Jul" << "Aug" << "Sep" << "Oct" << "Nov" << "Dec";
269 269
270 270 StackedBarChartSeries* series0 = new StackedBarChartSeries(category, this);
271 271
272 272 series0->addBarSet(set0);
273 273 series0->addBarSet(set1);
274 274 series0->addBarSet(set2);
275 275 series0->addBarSet(set3);
276 276 series0->addBarSet(set4);
277 277
278 278 m_chartWidget->addSeries(series0);
279 279 newSeries = series0;
280 280 } else if (series == "PercentBar") {
281 281 qDebug() << "Percent bar chart series";
282 282
283 QBarCategory category;
284 category << "Jan" << "Feb" << "Mar" << "Apr" << "May" << "June" << "Jul" << "Aug" << "Sep" << "Oct" << "Nov" << "Dec";
283 QBarCategory *category = new QBarCategory;
284 *category << "Jan" << "Feb" << "Mar" << "Apr" << "May" << "June" << "Jul" << "Aug" << "Sep" << "Oct" << "Nov" << "Dec";
285 285
286 286 PercentBarChartSeries* series0 = new PercentBarChartSeries(category, this);
287 287
288 288 series0->addBarSet(set0);
289 289 series0->addBarSet(set1);
290 290 series0->addBarSet(set2);
291 291 series0->addBarSet(set3);
292 292 series0->addBarSet(set4);
293 293
294 294 m_chartWidget->addSeries(series0);
295 295 newSeries = series0;
296 296 } else {
297 297 qDebug() << "Something weird going on in MainWidget::addSeries";
298 298 }
299 299
300 300 setCurrentSeries(newSeries);
301 301 }
302 302
303 303 void MainWidget::setCurrentSeries(QChartSeries *series)
304 304 {
305 305 m_currentSeries = series;
306 306 switch (m_currentSeries->type()) {
307 307 case QChartSeries::SeriesTypeLine:
308 308 break;
309 309 case QChartSeries::SeriesTypeScatter:
310 310 break;
311 311 case QChartSeries::SeriesTypePie:
312 312 break;
313 313 case QChartSeries::SeriesTypeBar:
314 314 qDebug() << "setCurrentSeries (bar)";
315 315 break;
316 316 case QChartSeries::SeriesTypeStackedBar:
317 317 qDebug() << "setCurrentSeries (Stackedbar)";
318 318 break;
319 319 case QChartSeries::SeriesTypePercentBar:
320 320 qDebug() << "setCurrentSeries (Percentbar)";
321 321 break;
322 322 default:
323 323 Q_ASSERT(false);
324 324 break;
325 325 }
326 326 }
327 327
328 328 void MainWidget::testDataChanged(int itemIndex)
329 329 {
330 330 qDebug() << "testDataChanged: " << itemIndex;
331 331
332 332 // switch (itemIndex) {
333 333 // case 0: {
334 334 // QList<QChartDataPoint> data;
335 335 // for (int x = 0; x < 20; x++) {
336 336 // data.append(QChartDataPoint() << x << x / 2);
337 337 // }
338 338 // m_chartWidget->setData(data);
339 339 // break;
340 340 // }
341 341 // case 1: {
342 342 // QList<QChartDataPoint> data;
343 343 // for (int x = 0; x < 100; x++) {
344 344 // data.append(QChartDataPoint() << x - 200 << 2 * (uint(sin(3.14159/50*x)*80) % 100));
345 345 // }
346 346 // m_chartWidget->setData(data);
347 347 // break;
348 348 // }
349 349 // case 2: {
350 350 // QList<QChartDataPoint> data;
351 351 // for (int x = 0; x < 1000; x++) {
352 352 // data.append(QChartDataPoint() << x - 200 << 2 * (uint(sin(3.14159/50*x)*80) % 100) + (rand() % 100 * 0.2));
353 353 // data.append(QChartDataPoint() << x - 200 << 2 * (uint(sin(3.14159/50*x)*80) % 100) + (rand() % 100 * 0.2));
354 354 // data.append(QChartDataPoint() << x - 200 << 2 * (uint(sin(3.14159/50*x)*80) % 100) + (rand() % 100 * 0.2));
355 355 // }
356 356 // m_chartWidget->setData(data);
357 357 // break;
358 358 // }
359 359 // default:
360 360 // break;
361 361 // }
362 362 }
363 363
364 364 void MainWidget::backgroundChanged(int itemIndex)
365 365 {
366 366 qDebug() << "backgroundChanged: " << itemIndex;
367 367 }
368 368
369 369 void MainWidget::autoScaleChanged(int value)
370 370 {
371 371 if (value) {
372 372 // TODO: enable auto scaling
373 373 } else {
374 374 // TODO: set scaling manually (and disable auto scaling)
375 375 }
376 376
377 377 m_xMinSpin->setEnabled(!value);
378 378 m_xMaxSpin->setEnabled(!value);
379 379 m_yMinSpin->setEnabled(!value);
380 380 m_yMaxSpin->setEnabled(!value);
381 381 }
382 382
383 383 void MainWidget::xMinChanged(int value)
384 384 {
385 385 qDebug() << "xMinChanged: " << value;
386 386 }
387 387
388 388 void MainWidget::xMaxChanged(int value)
389 389 {
390 390 qDebug() << "xMaxChanged: " << value;
391 391 }
392 392
393 393 void MainWidget::yMinChanged(int value)
394 394 {
395 395 qDebug() << "yMinChanged: " << value;
396 396 }
397 397
398 398 void MainWidget::yMaxChanged(int value)
399 399 {
400 400 qDebug() << "yMaxChanged: " << value;
401 401 }
402 402
403 403 void MainWidget::changeChartTheme(int themeIndex)
404 404 {
405 405 qDebug() << "changeChartTheme: " << themeIndex;
406 406 m_chartWidget->setChartTheme((QChart::ChartTheme) themeIndex);
407 407 //TODO: remove this hack. This is just to make it so that theme change is seen immediately.
408 408 QSize s = size();
409 409 s.setWidth(s.width()+1);
410 410 resize(s);
411 411 }
412 412
413 413 void MainWidget::setPieSizeFactor(double size)
414 414 {
415 415 QPieSeries *pie = qobject_cast<QPieSeries *>(m_currentSeries);
416 416 if (pie)
417 417 pie->setSizeFactor(qreal(size));
418 418 }
419 419
420 420 void MainWidget::setPiePosition(int position)
421 421 {
422 422 QPieSeries *pie = qobject_cast<QPieSeries *>(m_currentSeries);
423 423 if (pie)
424 424 pie->setPosition((QPieSeries::PiePosition) position);
425 425 }
General Comments 0
You need to be logged in to leave comments. Login now