##// END OF EJS Templates
Floating values to bar charts
sauimone -
r263:b057123ac417
parent child
Show More
@@ -0,0 +1,58
1 #include "barvalue_p.h"
2 #include <QPainter>
3 #include <QPen>
4
5 QTCOMMERCIALCHART_BEGIN_NAMESPACE
6
7 BarValue::BarValue(QGraphicsItem *parent)
8 : QGraphicsItem(parent)
9 {
10 // setVisible(false);
11 }
12
13 void BarValue::setValueString(QString str)
14 {
15 mValueString = str;
16 }
17
18 QString BarValue::valueString()
19 {
20 return mValueString;
21 }
22
23 void BarValue::setPen(const QPen& pen)
24 {
25 mPen = pen;
26 }
27
28 const QPen& BarValue::pen()
29 {
30 return mPen;
31 }
32
33 void BarValue::resize(qreal w, qreal h)
34 {
35 mWidth = w;
36 mHeight = h;
37 }
38
39 void BarValue::setPos(qreal x, qreal y)
40 {
41 mXpos = x;
42 mYpos = y;
43 }
44
45 void BarValue::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
46 {
47 painter->setPen(mPen);
48 painter->drawText(boundingRect(),mValueString);
49 }
50
51 QRectF BarValue::boundingRect() const
52 {
53 QRectF r(mXpos, mYpos, mXpos + mWidth, mYpos + mHeight);
54 return r;
55 }
56
57
58 QTCOMMERCIALCHART_END_NAMESPACE
@@ -0,0 +1,45
1 #ifndef BARVALUE_P_H
2 #define BARVALUE_P_H
3
4 #include "qchartglobal.h"
5 #include <QGraphicsItem>
6 #include <QPen>
7
8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9
10
11 // Visual class for floating bar values
12 // TODO: fonts, colors etc.
13 // By default these are not visible.
14 class BarValue : public QGraphicsItem
15 {
16 public:
17 BarValue(QGraphicsItem *parent = 0);
18
19 void setValueString(QString str);
20 QString valueString();
21
22 void setPen(const QPen& pen);
23 const QPen& pen();
24
25 void resize(qreal w, qreal h);
26 void setPos(qreal x, qreal y);
27
28 // From QGraphicsItem
29 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
30 QRectF boundingRect() const;
31
32 private:
33
34 QPen mPen;
35 QString mValueString;
36
37 qreal mXpos;
38 qreal mYpos;
39 qreal mWidth;
40 qreal mHeight;
41 };
42
43 QTCOMMERCIALCHART_END_NAMESPACE
44
45 #endif // BARVALUE_P_H
@@ -1,35 +1,38
1 INCLUDEPATH += $$PWD
1 INCLUDEPATH += $$PWD
2 DEPENDPATH += $$PWD
2 DEPENDPATH += $$PWD
3
3
4 SOURCES += \
4 SOURCES += \
5 $$PWD/bar.cpp \
5 $$PWD/bar.cpp \
6 $$PWD/barchartmodel.cpp \
6 $$PWD/barchartmodel.cpp \
7 $$PWD/barlabel.cpp \
7 $$PWD/barlabel.cpp \
8 $$PWD/barpresenter.cpp \
8 $$PWD/barpresenter.cpp \
9 $$PWD/barpresenterbase.cpp \
9 $$PWD/barpresenterbase.cpp \
10 $$PWD/percentbarpresenter.cpp \
10 $$PWD/percentbarpresenter.cpp \
11 $$PWD/qbarcategory.cpp \
11 $$PWD/qbarcategory.cpp \
12 $$PWD/qbarchartseries.cpp \
12 $$PWD/qbarchartseries.cpp \
13 $$PWD/qbarset.cpp \
13 $$PWD/qbarset.cpp \
14 $$PWD/qpercentbarchartseries.cpp \
14 $$PWD/qpercentbarchartseries.cpp \
15 $$PWD/qstackedbarchartseries.cpp \
15 $$PWD/qstackedbarchartseries.cpp \
16 $$PWD/separator.cpp \
16 $$PWD/separator.cpp \
17 $$PWD/stackedbarpresenter.cpp
17 $$PWD/stackedbarpresenter.cpp \
18 $$PWD/barvalue.cpp
18
19
19 PRIVATE_HEADERS += \
20 PRIVATE_HEADERS += \
20 $$PWD/bar_p.h \
21 $$PWD/bar_p.h \
21 $$PWD/barchartmodel_p.h \
22 $$PWD/barchartmodel_p.h \
22 $$PWD/barlabel_p.h \
23 $$PWD/barlabel_p.h \
23 $$PWD/barpresenter.h \
24 $$PWD/barpresenter.h \
24 $$PWD/barpresenterbase.h \
25 $$PWD/barpresenterbase.h \
25 $$PWD/percentbarpresenter.h \
26 $$PWD/percentbarpresenter.h \
26 $$PWD/separator_p.h \
27 $$PWD/separator_p.h \
27 $$PWD/stackedbarpresenter.h
28 $$PWD/stackedbarpresenter.h \
28
29 $$PWD/barvalue_p.h
30
29 PUBLIC_HEADERS += \
31 PUBLIC_HEADERS += \
30 $$PWD/qbarcategory.h \
32 $$PWD/qbarcategory.h \
31 $$PWD/qbarchartseries.h \
33 $$PWD/qbarchartseries.h \
32 $$PWD/qbarset.h \
34 $$PWD/qbarset.h \
33 $$PWD/qpercentbarchartseries.h \
35 $$PWD/qpercentbarchartseries.h \
34 $$PWD/qstackedbarchartseries.h
36 $$PWD/qstackedbarchartseries.h
35 No newline at end of file
37
38
@@ -1,171 +1,191
1 #include <limits.h>
1 #include <limits.h>
2 #include <QVector>
2 #include <QVector>
3 #include <QDebug>
3 #include <QDebug>
4 #include "barchartmodel_p.h"
4 #include "barchartmodel_p.h"
5 #include "qbarcategory.h"
5 #include "qbarcategory.h"
6 #include "qbarset.h"
6 #include "qbarset.h"
7
7
8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9
9
10 BarChartModel::BarChartModel(QBarCategory *category, QObject *parent) :
10 BarChartModel::BarChartModel(QBarCategory *category, QObject *parent) :
11 QObject(parent)
11 QObject(parent)
12 ,mCategory(category)
12 ,mCategory(category)
13 {
13 {
14 }
14 }
15
15
16 BarChartModel::~BarChartModel()
16 BarChartModel::~BarChartModel()
17 {
17 {
18 delete mCategory;
18 delete mCategory;
19 }
19 }
20
20
21
21
22 QBarCategory& BarChartModel::category()
22 QBarCategory& BarChartModel::category()
23 {
23 {
24 return *mCategory;
24 return *mCategory;
25 }
25 }
26
26
27 void BarChartModel::addBarSet(QBarSet *set)
27 void BarChartModel::addBarSet(QBarSet *set)
28 {
28 {
29 mDataModel.append(set);
29 mDataModel.append(set);
30 }
30 }
31
31
32 void BarChartModel::removeBarSet(QBarSet *set)
32 void BarChartModel::removeBarSet(QBarSet *set)
33 {
33 {
34 if (mDataModel.contains(set)) {
34 if (mDataModel.contains(set)) {
35 mDataModel.removeOne(set);
35 mDataModel.removeOne(set);
36 }
36 }
37 }
37 }
38
38
39 QBarSet* BarChartModel::nextSet(bool getFirst)
39 QBarSet* BarChartModel::nextSet(bool getFirst)
40 {
40 {
41 if (getFirst) {
41 if (getFirst) {
42 mCurrentSet = 0;
42 mCurrentSet = 0;
43 }
43 }
44
44
45 if ((mDataModel.count() <= 0) || (mDataModel.count() <= mCurrentSet)) {
45 if ((mDataModel.count() <= 0) || (mDataModel.count() <= mCurrentSet)) {
46 return 0;
46 return 0;
47 }
47 }
48
48
49 QBarSet* set = mDataModel.at(mCurrentSet);
49 QBarSet* set = mDataModel.at(mCurrentSet);
50 mCurrentSet++;
50 mCurrentSet++;
51 return set;
51 return set;
52 }
52 }
53
53
54
54
55 QBarSet& BarChartModel::setAt(int index)
55 QBarSet& BarChartModel::setAt(int index)
56 {
56 {
57 return *mDataModel.at(index);
57 return *mDataModel.at(index);
58 }
58 }
59
59
60 int BarChartModel::countSets()
60 int BarChartModel::countSets()
61 {
61 {
62 return mDataModel.count();
62 return mDataModel.count();
63 }
63 }
64
64
65 int BarChartModel::countCategories()
65 int BarChartModel::countCategories()
66 {
66 {
67 int count(0);
67 int count(0);
68 for (int i=0; i<mDataModel.count(); i++){
68 for (int i=0; i<mDataModel.count(); i++){
69 // TODO: can we assume that all series have same number of values? If not. then which values are empty?
69 // TODO: can we assume that all series have same number of values? If not. then which values are empty?
70 int temp = mDataModel.at(i)->count();
70 int temp = mDataModel.at(i)->count();
71 if (temp > count) {
71 if (temp > count) {
72 count = temp;
72 count = temp;
73 }
73 }
74 }
74 }
75 return count;
75 return count;
76 }
76 }
77
77
78 int BarChartModel::countTotalItems()
78 int BarChartModel::countTotalItems()
79 {
79 {
80 int total = mDataModel.count() * countCategories();
80 int total = mDataModel.count() * countCategories();
81 return total;
81 return total;
82 }
82 }
83
83
84 qreal BarChartModel::min()
84 qreal BarChartModel::min()
85 {
85 {
86 Q_ASSERT(mDataModel.count() > 0);
86 Q_ASSERT(mDataModel.count() > 0);
87 // TODO: make min and max members and update them when data changes.
87 // TODO: make min and max members and update them when data changes.
88 // This is slower since they are checked every time, even if data is same since previous call.
88 // This is slower since they are checked every time, even if data is same since previous call.
89 qreal min = INT_MAX;
89 qreal min = INT_MAX;
90
90
91 for (int i=0; i <mDataModel.count(); i++) {
91 for (int i=0; i <mDataModel.count(); i++) {
92 int itemCount = mDataModel.at(i)->count();
92 int itemCount = mDataModel.at(i)->count();
93 for (int j=0; j<itemCount; j++) {
93 for (int j=0; j<itemCount; j++) {
94 qreal temp = mDataModel.at(i)->valueAt(j);
94 qreal temp = mDataModel.at(i)->valueAt(j);
95 if (temp < min) {
95 if (temp < min) {
96 min = temp;
96 min = temp;
97 }
97 }
98 }
98 }
99 }
99 }
100 return min;
100 return min;
101 }
101 }
102
102
103 qreal BarChartModel::max()
103 qreal BarChartModel::max()
104 {
104 {
105 Q_ASSERT(mDataModel.count() > 0);
105 Q_ASSERT(mDataModel.count() > 0);
106
106
107 // TODO: make min and max members and update them when data changes.
107 // TODO: make min and max members and update them when data changes.
108 // This is slower since they are checked every time, even if data is same since previous call.
108 // This is slower since they are checked every time, even if data is same since previous call.
109 qreal max = INT_MIN;
109 qreal max = INT_MIN;
110
110
111 for (int i=0; i <mDataModel.count(); i++) {
111 for (int i=0; i <mDataModel.count(); i++) {
112 int itemCount = mDataModel.at(i)->count();
112 int itemCount = mDataModel.at(i)->count();
113 for (int j=0; j<itemCount; j++) {
113 for (int j=0; j<itemCount; j++) {
114 qreal temp = mDataModel.at(i)->valueAt(j);
114 qreal temp = mDataModel.at(i)->valueAt(j);
115 if (temp > max) {
115 if (temp > max) {
116 max = temp;
116 max = temp;
117 }
117 }
118 }
118 }
119 }
119 }
120
120
121 return max;
121 return max;
122 }
122 }
123
123
124 qreal BarChartModel::valueAt(int set, int category)
124 qreal BarChartModel::valueAt(int set, int category)
125 {
125 {
126 if ((set < 0) || (set >= mDataModel.count())) {
126 if ((set < 0) || (set >= mDataModel.count())) {
127 // No set, no value.
127 // No set, no value.
128 return 0;
128 return 0;
129 } else if ((category < 0) || (category >= mDataModel.at(set)->count())) {
129 } else if ((category < 0) || (category >= mDataModel.at(set)->count())) {
130 // No category, no value.
130 // No category, no value.
131 return 0;
131 return 0;
132 }
132 }
133
133
134 return mDataModel.at(set)->valueAt(category);
134 return mDataModel.at(set)->valueAt(category);
135 }
135 }
136
136
137 qreal BarChartModel::categorySum(int column)
137 qreal BarChartModel::percentageAt(int set, int category)
138 {
139 if ((set < 0) || (set >= mDataModel.count())) {
140 // No set, no value.
141 return 0;
142 } else if ((category < 0) || (category >= mDataModel.at(set)->count())) {
143 // No category, no value.
144 return 0;
145 }
146
147 qreal value = mDataModel.at(set)->valueAt(category);
148 qreal total = categorySum(category);
149 if (0 == total) {
150 return 100.0;
151 }
152
153 return value / total;
154 }
155
156
157 qreal BarChartModel::categorySum(int category)
138 {
158 {
139 qreal sum(0);
159 qreal sum(0);
140 int count = mDataModel.count(); // Count rows
160 int count = mDataModel.count(); // Count sets
141
161
142 for (int row = 0; row < count; row++) {
162 for (int set = 0; set < count; set++) {
143 if (column < mDataModel.at(row)->count()) {
163 if (category < mDataModel.at(set)->count()) {
144 sum += mDataModel.at(row)->valueAt(column);
164 sum += mDataModel.at(set)->valueAt(category);
145 }
165 }
146 }
166 }
147 return sum;
167 return sum;
148 }
168 }
149
169
150 qreal BarChartModel::maxCategorySum()
170 qreal BarChartModel::maxCategorySum()
151 {
171 {
152 qreal max = INT_MIN;
172 qreal max = INT_MIN;
153 int count = countCategories();
173 int count = countCategories();
154
174
155 for (int col=0; col<count; col++) {
175 for (int col=0; col<count; col++) {
156 qreal sum = categorySum(col);
176 qreal sum = categorySum(col);
157 if (sum > max) {
177 if (sum > max) {
158 max = sum;
178 max = sum;
159 }
179 }
160 }
180 }
161 return max;
181 return max;
162 }
182 }
163
183
164 QString BarChartModel::label(int category)
184 QString BarChartModel::label(int category)
165 {
185 {
166 return mCategory->label(category);
186 return mCategory->label(category);
167 }
187 }
168
188
169 #include "moc_barchartmodel_p.cpp"
189 #include "moc_barchartmodel_p.cpp"
170
190
171 QTCOMMERCIALCHART_END_NAMESPACE
191 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,58 +1,59
1 #ifndef BARCHARTMODEL_H
1 #ifndef BARCHARTMODEL_H
2 #define BARCHARTMODEL_H
2 #define BARCHARTMODEL_H
3
3
4 #include <QObject>
4 #include <QObject>
5 #include "qchartglobal.h"
5 #include "qchartglobal.h"
6
6
7 QTCOMMERCIALCHART_BEGIN_NAMESPACE
7 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8
8
9 // Model for bar chart. Internal class.
9 // Model for bar chart. Internal class.
10 // TODO: Implement as QAbstractItemModel?
10 // TODO: Implement as QAbstractItemModel?
11
11
12 class QBarSet;
12 class QBarSet;
13 class QBarCategory;
13 class QBarCategory;
14
14
15 class BarChartModel : public QObject //, public QAbstractItemModel
15 class BarChartModel : public QObject //, public QAbstractItemModel
16 {
16 {
17 Q_OBJECT
17 Q_OBJECT
18 public:
18 public:
19 explicit BarChartModel(QBarCategory *category, QObject *parent = 0);
19 explicit BarChartModel(QBarCategory *category, QObject *parent = 0);
20 ~BarChartModel();
20 ~BarChartModel();
21
21
22 QBarCategory& category();
22 QBarCategory& category();
23 void addBarSet(QBarSet *set);
23 void addBarSet(QBarSet *set);
24 void removeBarSet(QBarSet *set);
24 void removeBarSet(QBarSet *set);
25 QBarSet* nextSet(bool getFirst);
25 QBarSet* nextSet(bool getFirst);
26
26
27 QBarSet& setAt(int index); // Internal
27 QBarSet& setAt(int index); // Internal
28
28
29 int countSets(); // Number of sets in model
29 int countSets(); // Number of sets in model
30 int countCategories(); // Number of categories
30 int countCategories(); // Number of categories
31 int countTotalItems(); // Total items in all sets. Includes empty items.
31 int countTotalItems(); // Total items in all sets. Includes empty items.
32
32
33 qreal max(); // Maximum value of all sets
33 qreal max(); // Maximum value of all sets
34 qreal min(); // Minimum value of all sets
34 qreal min(); // Minimum value of all sets
35 qreal valueAt(int set, int category);
35 qreal valueAt(int set, int category);
36 qreal percentageAt(int set, int category);
36
37
37 qreal categorySum(int column);
38 qreal categorySum(int category);
38 qreal maxCategorySum(); // returns maximum sum of sets in all categories.
39 qreal maxCategorySum(); // returns maximum sum of sets in all categories.
39
40
40 QString label(int category);
41 QString label(int category);
41
42
42 signals:
43 signals:
43 void modelUpdated();
44 void modelUpdated();
44
45
45 public slots:
46 public slots:
46
47
47 private:
48 private:
48
49
49 QList<QBarSet*> mDataModel;
50 QList<QBarSet*> mDataModel;
50 QBarCategory* mCategory; // Owned
51 QBarCategory* mCategory; // Owned
51
52
52 int mCurrentSet;
53 int mCurrentSet;
53
54
54 };
55 };
55
56
56 QTCOMMERCIALCHART_END_NAMESPACE
57 QTCOMMERCIALCHART_END_NAMESPACE
57
58
58 #endif // BARCHARTMODEL_H
59 #endif // BARCHARTMODEL_H
@@ -1,70 +1,92
1 #include "barpresenter.h"
1 #include "barpresenter.h"
2 #include "bar_p.h"
2 #include "bar_p.h"
3 #include "barlabel_p.h"
3 #include "barlabel_p.h"
4 #include "barvalue_p.h"
4 #include "qbarset.h"
5 #include "qbarset.h"
5 #include <QDebug>
6 #include <QDebug>
6
7
7 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8
9
9 BarPresenter::BarPresenter(BarChartModel& model, QGraphicsItem *parent) :
10 BarPresenter::BarPresenter(BarChartModel& model, QGraphicsItem *parent) :
10 BarPresenterBase(model,parent)
11 BarPresenterBase(model,parent)
11 {
12 {
12 mBarDefaultWidth = 5;
13 mBarDefaultWidth = 15;
13 }
14 }
14
15
15 void BarPresenter::layoutChanged()
16 void BarPresenter::layoutChanged()
16 {
17 {
17 // Scale bars to new layout
18 // Scale bars to new layout
18 // Layout for bars:
19 // Layout for bars:
19 if (mModel.countSets() <= 0) {
20 if (mModel.countSets() <= 0) {
20 qDebug() << "No sets in model!";
21 qDebug() << "No sets in model!";
21 return;
22 return;
22 }
23 }
23
24
24 if (childItems().count() == 0) {
25 if (childItems().count() == 0) {
25 qDebug() << "WARNING: BarPresenter::layoutChanged called before graphics items are created!";
26 qDebug() << "WARNING: BarPresenter::layoutChanged called before graphics items are created!";
26 return;
27 return;
27 }
28 }
28
29
29 // TODO: better way to auto-layout?
30 // TODO: better way to auto-layout?
30 // Use reals for accurancy (we might get some compiler warnings... :)
31 // Use reals for accurancy (we might get some compiler warnings... :)
31 int itemCount = mModel.countCategories();
32 int categoryCount = mModel.countCategories();
32 int setCount = mModel.countSets();
33 int setCount = mModel.countSets();
33
34
34 qreal tW = mWidth;
35 qreal tW = mWidth;
35 qreal tH = mHeight;
36 qreal tH = mHeight;
36 qreal tM = mModel.max();
37 qreal tM = mModel.max();
37 qreal scale = (tH/tM);
38 qreal scale = (tH/tM);
38 qreal tC = itemCount+1;
39 qreal tC = categoryCount+1;
39 qreal xStepPerSet = (tW/tC);
40 qreal xStepPerSet = (tW/tC);
40
41
41 // Scaling.
42 // Scaling.
42 int itemIndex(0);
43 int itemIndex(0);
43 int labelIndex(0);
44 int labelIndex(0);
44
45
45 for (int item=0; item < itemCount; item++) {
46 for (int category=0; category < categoryCount; category++) {
46 qreal xPos = xStepPerSet * item + ((tW + mBarDefaultWidth*setCount)/(itemCount*2));
47 qreal xPos = xStepPerSet * category + ((tW + mBarDefaultWidth*setCount)/(categoryCount*2));
47 qreal yPos = mHeight;
48 qreal yPos = mHeight;
48 for (int set = 0; set < setCount; set++) {
49 for (int set = 0; set < setCount; set++) {
49 qreal barHeight = mModel.valueAt(set, item) * scale;
50 qreal barHeight = mModel.valueAt(set, category) * scale;
50 Bar* bar = mBars.at(itemIndex);
51 Bar* bar = mBars.at(itemIndex);
51
52
52 // TODO: width settable per bar?
53 // TODO: width settable per bar?
53 bar->resize(mBarDefaultWidth, barHeight);
54 bar->resize(mBarDefaultWidth, barHeight);
54 bar->setBrush(mModel.setAt(set).brush());
55 bar->setBrush(mModel.setAt(set).brush());
55 bar->setPos(xPos, yPos-barHeight); // item*posStep+startPos + set * mBarDefaultWidth, mHeight);
56 bar->setPos(xPos, yPos-barHeight); // item*posStep+startPos + set * mBarDefaultWidth, mHeight);
56 itemIndex++;
57 itemIndex++;
57 xPos += mBarDefaultWidth;
58 xPos += mBarDefaultWidth;
58 }
59 }
59
60
60 // TODO: Layout for labels, remove magic number
61 // TODO: Layout for labels, remove magic number
61 xPos = xStepPerSet * item + ((tW + mBarDefaultWidth*setCount)/(itemCount*2));
62 xPos = xStepPerSet * category + ((tW + mBarDefaultWidth*setCount)/(categoryCount*2));
62 BarLabel* label = mLabels.at(labelIndex);
63 BarLabel* label = mLabels.at(labelIndex);
63 label->setPos(xPos, mHeight + 20);
64 label->setPos(xPos, mHeight + 20);
64 labelIndex++;
65 labelIndex++;
65 }
66 }
66
67
68 // Position floating values
69 itemIndex = 0;
70 for (int category=0; category < mModel.countCategories(); category++) {
71 qreal xPos = xStepPerSet * category + ((tW + mBarDefaultWidth*setCount)/(categoryCount*2));
72 qreal yPos = mHeight;
73 for (int set=0; set < mModel.countSets(); set++) {
74 qreal barHeight = mModel.valueAt(set,category) * scale;
75 BarValue* value = mFloatingValues.at(itemIndex);
76
77 // TODO: remove hard coding, apply layout
78 value->resize(100,50);
79 value->setPos(xPos + mBarDefaultWidth/2, yPos-barHeight/2);
80 value->setPen(QPen(QColor(255,255,255,255)));
81
82 QString vString(QString::number(mModel.valueAt(set,category)));
83 value->setValueString(vString);
84
85 itemIndex++;
86 xPos += mBarDefaultWidth;
87 }
88 }
67 mLayoutDirty = true;
89 mLayoutDirty = true;
68 }
90 }
69
91
70 QTCOMMERCIALCHART_END_NAMESPACE
92 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,121 +1,134
1 #include "barpresenterbase.h"
1 #include "barpresenterbase.h"
2 #include "bar_p.h"
2 #include "bar_p.h"
3 #include "barvalue_p.h"
3 #include "barlabel_p.h"
4 #include "barlabel_p.h"
4 #include "separator_p.h"
5 #include "separator_p.h"
5 #include "qbarset.h"
6 #include "qbarset.h"
6 #include <QDebug>
7 #include <QDebug>
7
8
8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9
10
10 BarPresenterBase::BarPresenterBase(BarChartModel& model, QGraphicsItem *parent)
11 BarPresenterBase::BarPresenterBase(BarChartModel& model, QGraphicsItem *parent)
11 : ChartItem(parent)
12 : ChartItem(parent)
12 ,mBarDefaultWidth(20) // TODO: remove hard coding, when we have layout code ready
13 ,mBarDefaultWidth(20) // TODO: remove hard coding, when we have layout code ready
13 ,mLayoutSet(false)
14 ,mLayoutSet(false)
14 ,mLayoutDirty(true)
15 ,mLayoutDirty(true)
15 ,mSeparatorsVisible(true)
16 ,mSeparatorsVisible(false)
16 ,mModel(model)
17 ,mModel(model)
17 {
18 {
18 dataChanged();
19 dataChanged();
19 }
20 }
20
21
21 void BarPresenterBase::setSeparatorsVisible(bool visible)
22 void BarPresenterBase::setSeparatorsVisible(bool visible)
22 {
23 {
23 mSeparatorsVisible = visible;
24 mSeparatorsVisible = visible;
24 }
25 }
25
26
26 void BarPresenterBase::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
27 void BarPresenterBase::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
27 {
28 {
28 if (!mLayoutSet) {
29 if (!mLayoutSet) {
29 qDebug() << "BarPresenterBase::paint called without layout set. Aborting.";
30 qDebug() << "BarPresenterBase::paint called without layout set. Aborting.";
30 return;
31 return;
31 }
32 }
32 // if (mLayoutDirty) {
33 // if (mLayoutDirty) {
33 // Layout or data has changed. Need to redraw.
34 // Layout or data has changed. Need to redraw.
34 foreach(QGraphicsItem* i, childItems()) {
35 foreach(QGraphicsItem* i, childItems()) {
35 i->paint(painter,option,widget);
36 i->paint(painter,option,widget);
36 }
37 }
37 // }
38 // }
38 }
39 }
39
40
40 QRectF BarPresenterBase::boundingRect() const
41 QRectF BarPresenterBase::boundingRect() const
41 {
42 {
42 return QRectF(0,0,mWidth,mHeight);
43 return QRectF(0,0,mWidth,mHeight);
43 }
44 }
44
45
45 void BarPresenterBase::setBarWidth( int w )
46 void BarPresenterBase::setBarWidth( int w )
46 {
47 {
47 mBarDefaultWidth = w;
48 mBarDefaultWidth = w;
48 }
49 }
49
50
50 void BarPresenterBase::dataChanged()
51 void BarPresenterBase::dataChanged()
51 {
52 {
52 // TODO: performance optimizations. Do we really need to delete and create items every time data is changed or can we reuse them?
53 // TODO: performance optimizations. Do we really need to delete and create items every time data is changed or can we reuse them?
53 qDebug() << "datachanged";
54 qDebug() << "datachanged";
54 // Delete old bars
55 // Delete old bars
55 foreach (QGraphicsItem* item, childItems()) {
56 foreach (QGraphicsItem* item, childItems()) {
56 delete item;
57 delete item;
57 }
58 }
58
59
59 mBars.clear();
60 mBars.clear();
60 mLabels.clear();
61 mLabels.clear();
61 mSeparators.clear();
62 mSeparators.clear();
63 mFloatingValues.clear();
62
64
63 // Create new graphic items for bars
65 // Create new graphic items for bars
64 for (int s=0; s<mModel.countSets(); s++) {
66 for (int s=0; s<mModel.countSets(); s++) {
65 QBarSet *set = mModel.nextSet(0==s);
67 QBarSet *set = mModel.nextSet(0==s);
66 for (int c=0; c<mModel.countCategories(); c++) {
68 for (int c=0; c<mModel.countCategories(); c++) {
67 Bar *bar = new Bar(this);
69 Bar *bar = new Bar(this);
68 childItems().append(bar);
70 childItems().append(bar);
69 mBars.append(bar);
71 mBars.append(bar);
70 connect(bar,SIGNAL(clicked()),set,SLOT(barClicked()));
72 connect(bar,SIGNAL(clicked()),set,SLOT(barClicked()));
71 }
73 }
72 }
74 }
73
75
76 // Create labels
74 int count = mModel.countCategories();
77 int count = mModel.countCategories();
75 for (int i=0; i<count; i++) {
78 for (int i=0; i<count; i++) {
76 BarLabel* label = new BarLabel(this);
79 BarLabel* label = new BarLabel(this);
77 label->set(mModel.label(i));
80 label->set(mModel.label(i));
78 childItems().append(label);
81 childItems().append(label);
79 mLabels.append(label);
82 mLabels.append(label);
80 }
83 }
81
84
85 // Create separators
82 count = mModel.countCategories() - 1; // There is one less separator than columns
86 count = mModel.countCategories() - 1; // There is one less separator than columns
83 for (int i=0; i<count; i++) {
87 for (int i=0; i<count; i++) {
84 Separator* sep = new Separator(this);
88 Separator* sep = new Separator(this);
85 sep->setColor(QColor(255,0,0,255)); // TODO: color for separations from theme
89 sep->setColor(QColor(255,0,0,255)); // TODO: color for separations from theme
86 childItems().append(sep);
90 childItems().append(sep);
87 mSeparators.append(sep);
91 mSeparators.append(sep);
88 }
92 }
89
93
94 // Create floating values
95 for (int s=0; s<mModel.countSets(); s++) {
96 for (int category=0; category<mModel.countCategories(); category++) {
97 BarValue *value = new BarValue(this);
98 childItems().append(value);
99 mFloatingValues.append(value);
100 }
101 }
102
90 // TODO: if (autolayout) { layoutChanged() } or something
103 // TODO: if (autolayout) { layoutChanged() } or something
91 mLayoutDirty = true;
104 mLayoutDirty = true;
92 }
105 }
93
106
94 //handlers
107 //handlers
95
108
96 void BarPresenterBase::handleModelChanged(int index)
109 void BarPresenterBase::handleModelChanged(int index)
97 {
110 {
98 // qDebug() << "BarPresenterBase::handleModelChanged" << index;
111 // qDebug() << "BarPresenterBase::handleModelChanged" << index;
99 dataChanged();
112 dataChanged();
100 }
113 }
101
114
102 void BarPresenterBase::handleDomainChanged(const Domain& domain)
115 void BarPresenterBase::handleDomainChanged(const Domain& domain)
103 {
116 {
104 // qDebug() << "BarPresenterBase::handleDomainChanged";
117 // qDebug() << "BarPresenterBase::handleDomainChanged";
105 // TODO: Figure out the use case for this.
118 // TODO: Figure out the use case for this.
106 // Affects the size of visible item, so layout is changed.
119 // Affects the size of visible item, so layout is changed.
107 // layoutChanged();
120 // layoutChanged();
108 }
121 }
109
122
110 void BarPresenterBase::handleGeometryChanged(const QRectF& rect)
123 void BarPresenterBase::handleGeometryChanged(const QRectF& rect)
111 {
124 {
112 mWidth = rect.width();
125 mWidth = rect.width();
113 mHeight = rect.height();
126 mHeight = rect.height();
114 layoutChanged();
127 layoutChanged();
115 mLayoutSet = true;
128 mLayoutSet = true;
116 setPos(rect.topLeft());
129 setPos(rect.topLeft());
117 }
130 }
118
131
119 #include "moc_barpresenterbase.cpp"
132 #include "moc_barpresenterbase.cpp"
120
133
121 QTCOMMERCIALCHART_END_NAMESPACE
134 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,71 +1,73
1 #ifndef BARPRESENTERBASE_H
1 #ifndef BARPRESENTERBASE_H
2 #define BARPRESENTERBASE_H
2 #define BARPRESENTERBASE_H
3
3
4 #include "chartitem_p.h"
4 #include "chartitem_p.h"
5 #include "barchartmodel_p.h"
5 #include "barchartmodel_p.h"
6 #include <QPen>
6 #include <QPen>
7 #include <QBrush>
7 #include <QBrush>
8 #include <QGraphicsItem>
8 #include <QGraphicsItem>
9
9
10 QTCOMMERCIALCHART_BEGIN_NAMESPACE
10 QTCOMMERCIALCHART_BEGIN_NAMESPACE
11
11
12 class Bar;
12 class Bar;
13 class BarLabel;
13 class BarLabel;
14 class Separator;
14 class Separator;
15 class BarValue;
15
16
16 // Common implemantation of different presenters. Not to be instantiated.
17 // Common implemantation of different presenters. Not to be instantiated.
17 class BarPresenterBase : public QObject, public ChartItem
18 class BarPresenterBase : public QObject, public ChartItem
18 {
19 {
19 Q_OBJECT
20 Q_OBJECT
20 public:
21 public:
21 BarPresenterBase(BarChartModel& model, QGraphicsItem *parent = 0);
22 BarPresenterBase(BarChartModel& model, QGraphicsItem *parent = 0);
22 void setSeparatorsVisible(bool visible = true);
23 void setSeparatorsVisible(bool visible = true);
23
24
24 public:
25 public:
25
26
26 // From QGraphicsItem
27 // From QGraphicsItem
27 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
28 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
28 QRectF boundingRect() const;
29 QRectF boundingRect() const;
29
30
30 // TODO: these may change with layout awarness.
31 // TODO: these may change with layout awarness.
31 void setBarWidth( int w );
32 void setBarWidth( int w );
32
33
33 void setPen(QPen pen);
34 void setPen(QPen pen);
34 QPen pen();
35 QPen pen();
35
36
36 void setBrush(QBrush brush);
37 void setBrush(QBrush brush);
37 QBrush brush();
38 QBrush brush();
38
39
39 // TODO: Consider the domain for layoutChanged. May be use case, may not be. If it is, then the derived classes need to implement it
40 // TODO: Consider the domain for layoutChanged. May be use case, may not be. If it is, then the derived classes need to implement it
40 virtual void dataChanged(); // data of series has changed -> need to recalculate bar sizes
41 virtual void dataChanged(); // data of series has changed -> need to recalculate bar sizes
41 virtual void layoutChanged() = 0; // layout has changed -> need to recalculate bar sizes
42 virtual void layoutChanged() = 0; // layout has changed -> need to recalculate bar sizes
42
43
43 protected slots:
44 protected slots:
44 void handleModelChanged(int index);
45 void handleModelChanged(int index);
45 void handleDomainChanged(const Domain& domain);
46 void handleDomainChanged(const Domain& domain);
46 void handleGeometryChanged(const QRectF& size);
47 void handleGeometryChanged(const QRectF& size);
47
48
48 protected:
49 protected:
49
50
50 // TODO: consider these.
51 // TODO: consider these.
51 int mHeight; // Layout spesific
52 int mHeight; // Layout spesific
52 int mWidth;
53 int mWidth;
53 int mBarDefaultWidth;
54 int mBarDefaultWidth;
54
55
55 bool mLayoutSet; // True, if component has been laid out.
56 bool mLayoutSet; // True, if component has been laid out.
56 bool mLayoutDirty;
57 bool mLayoutDirty;
57
58
58 bool mSeparatorsVisible;
59 bool mSeparatorsVisible;
59 BarChartModel& mModel;
60 BarChartModel& mModel;
60
61
61 // Not owned.
62 // Not owned.
62 QList<Bar*> mBars;
63 QList<Bar*> mBars;
63 QList<BarLabel*> mLabels;
64 QList<BarLabel*> mLabels;
64 QList<Separator*> mSeparators;
65 QList<Separator*> mSeparators;
66 QList<BarValue*> mFloatingValues;
65
67
66 QPen mPen;
68 QPen mPen;
67 };
69 };
68
70
69 QTCOMMERCIALCHART_END_NAMESPACE
71 QTCOMMERCIALCHART_END_NAMESPACE
70
72
71 #endif // BARPRESENTERBASE_H
73 #endif // BARPRESENTERBASE_H
@@ -1,79 +1,103
1 #include "percentbarpresenter.h"
1 #include "percentbarpresenter.h"
2 #include "bar_p.h"
2 #include "bar_p.h"
3 #include "barlabel_p.h"
3 #include "barlabel_p.h"
4 #include "barvalue_p.h"
4 #include "separator_p.h"
5 #include "separator_p.h"
5 #include "qbarset.h"
6 #include "qbarset.h"
6 #include <QDebug>
7 #include <QDebug>
7
8
8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9
10
10
11
11 PercentBarPresenter::PercentBarPresenter(BarChartModel& model, QGraphicsItem *parent) :
12 PercentBarPresenter::PercentBarPresenter(BarChartModel& model, QGraphicsItem *parent) :
12 BarPresenterBase(model, parent)
13 BarPresenterBase(model, parent)
13 {
14 {
14 }
15 }
15
16
16 void PercentBarPresenter::layoutChanged()
17 void PercentBarPresenter::layoutChanged()
17 {
18 {
18 // Scale bars to new layout
19 // Scale bars to new layout
19 // Layout for bars:
20 // Layout for bars:
20 if (mModel.countSets() <= 0) {
21 if (mModel.countSets() <= 0) {
21 qDebug() << "No sets in model!";
22 qDebug() << "No sets in model!";
22 // Nothing to do.
23 // Nothing to do.
23 return;
24 return;
24 }
25 }
25
26
26 if (childItems().count() == 0) {
27 if (childItems().count() == 0) {
27 qDebug() << "WARNING: PercentBarPresenter::layoutChanged called before graphics items are created!";
28 qDebug() << "WARNING: PercentBarPresenter::layoutChanged called before graphics items are created!";
28 return;
29 return;
29 }
30 }
30
31
31 // TODO: better way to auto-layout
32 // TODO: better way to auto-layout
32 // Use reals for accurancy (we might get some compiler warnings... :)
33 // Use reals for accurancy (we might get some compiler warnings... :)
33 int count = mModel.countCategories();
34 int count = mModel.countCategories();
34 int itemIndex(0);
35 int itemIndex(0);
35 int labelIndex(0);
36 int labelIndex(0);
36 qreal tW = mWidth;
37 qreal tW = mWidth;
37 qreal tC = count+1;
38 qreal tC = count+1;
38 qreal xStep = (tW/tC);
39 qreal xStep = (tW/tC);
39 qreal xPos = ((tW/tC) - mBarDefaultWidth / 2);
40 qreal xPos = ((tW/tC) - mBarDefaultWidth / 2);
41 qreal h = mHeight;
40
42
41 for (int category = 0; category < mModel.countCategories(); category++) {
43 for (int category = 0; category < mModel.countCategories(); category++) {
42 qreal colSum = mModel.categorySum(category);
44 qreal colSum = mModel.categorySum(category);
43 qreal h = mHeight;
44 qreal scale = (h / colSum);
45 qreal scale = (h / colSum);
45 qreal yPos = h;
46 qreal yPos = h;
46 for (int set=0; set < mModel.countSets(); set++) {
47 for (int set=0; set < mModel.countSets(); set++) {
47 qreal barHeight = mModel.valueAt(set, category) * scale;
48 qreal barHeight = mModel.valueAt(set, category) * scale;
48 Bar* bar = mBars.at(itemIndex);
49 Bar* bar = mBars.at(itemIndex);
49
50
50 // TODO: width settable per bar?
51 // TODO: width settable per bar?
51 bar->resize(mBarDefaultWidth, barHeight);
52 bar->resize(mBarDefaultWidth, barHeight);
52 bar->setBrush(mModel.setAt(set).brush());
53 bar->setBrush(mModel.setAt(set).brush());
53 bar->setPos(xPos, yPos-barHeight);
54 bar->setPos(xPos, yPos-barHeight);
54 itemIndex++;
55 itemIndex++;
55 yPos -= barHeight;
56 yPos -= barHeight;
56 }
57 }
57
58
58 // TODO: Layout for labels, remove magic number
59 // TODO: Layout for labels, remove magic number
59 BarLabel* label = mLabels.at(labelIndex);
60 BarLabel* label = mLabels.at(labelIndex);
60 label->setPos(xPos, mHeight + 20);
61 label->setPos(xPos, mHeight + 20);
61 labelIndex++;
62 labelIndex++;
62 xPos += xStep;
63 xPos += xStep;
63 }
64 }
64
65
65 // Position separators
66 // Position separators
66 int separatorIndex(0);
67 xPos = xStep + xStep/2;
67 xPos = xStep + xStep/2;
68 for (int s=0; s < mModel.countCategories() - 1; s++) {
68 for (int s=0; s < mModel.countCategories() - 1; s++) {
69 Separator* sep = mSeparators.at(separatorIndex);
69 Separator* sep = mSeparators.at(s);
70 sep->setPos(xPos,0);
70 sep->setPos(xPos,0);
71 sep->setSize(QSizeF(1,mHeight));
71 sep->setSize(QSizeF(1,mHeight));
72 xPos += xStep;
72 xPos += xStep;
73 separatorIndex++;
73 }
74
75 // Position floating values
76 itemIndex = 0;
77 xPos = ((tW/tC) - mBarDefaultWidth / 2);
78 for (int category=0; category < mModel.countCategories(); category++) {
79 qreal yPos = h;
80 qreal colSum = mModel.categorySum(category);
81 qreal scale = (h / colSum);
82 for (int set=0; set < mModel.countSets(); set++) {
83 qreal barHeight = mModel.valueAt(set,category) * scale;
84 BarValue* value = mFloatingValues.at(itemIndex);
85
86 // TODO: remove hard coding, apply layout
87 value->setPos(xPos + mBarDefaultWidth/2, yPos-barHeight/2);
88 value->setPen(QPen(QColor(255,255,255,255)));
89
90 QString vString(QString::number(mModel.percentageAt(set,category) * 100));
91 vString.append("%");
92 value->setValueString(vString);
93
94 itemIndex++;
95 yPos -= barHeight;
96 }
97 xPos += xStep;
74 }
98 }
75
99
76 mLayoutDirty = true;
100 mLayoutDirty = true;
77 }
101 }
78
102
79 QTCOMMERCIALCHART_END_NAMESPACE
103 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,69 +1,70
1 #include "qbarset.h"
1 #include "qbarset.h"
2 #include <QDebug>
2 #include <QDebug>
3
3
4 QTCOMMERCIALCHART_BEGIN_NAMESPACE
4 QTCOMMERCIALCHART_BEGIN_NAMESPACE
5
5
6 QBarSet::QBarSet()
6 QBarSet::QBarSet()
7 {
7 {
8 }
8 }
9
9
10 void QBarSet::setName(QString name)
10 void QBarSet::setName(QString name)
11 {
11 {
12 mName = name;
12 mName = name;
13 }
13 }
14 QString QBarSet::name()
14 QString QBarSet::name()
15 {
15 {
16 return mName;
16 return mName;
17 }
17 }
18
18
19 QBarSet& QBarSet::operator << (const qreal &value)
19 QBarSet& QBarSet::operator << (const qreal &value)
20 {
20 {
21 mValues.append(value);
21 mValues.append(value);
22 return *this;
22 return *this;
23 }
23 }
24
24
25 int QBarSet::count()
25 int QBarSet::count()
26 {
26 {
27 return mValues.count();
27 return mValues.count();
28 }
28 }
29
29
30 qreal QBarSet::valueAt(int index)
30 qreal QBarSet::valueAt(int index)
31 {
31 {
32 return mValues.at(index);
32 return mValues.at(index);
33 }
33 }
34
34
35 void QBarSet::setValue(int index, qreal value)
35 void QBarSet::setValue(int index, qreal value)
36 {
36 {
37 mValues.replace(index,value);
37 mValues.replace(index,value);
38 }
38 }
39
39
40 void QBarSet::setPen(const QPen& pen)
40 void QBarSet::setPen(const QPen& pen)
41 {
41 {
42 mPen = pen;
42 mPen = pen;
43 }
43 }
44
44
45 const QPen& QBarSet::pen() const
45 const QPen& QBarSet::pen() const
46 {
46 {
47 return mPen;
47 return mPen;
48 }
48 }
49
49
50 void QBarSet::setBrush(const QBrush& brush)
50 void QBarSet::setBrush(const QBrush& brush)
51 {
51 {
52 mBrush = brush;
52 mBrush = brush;
53 }
53 }
54
54
55 const QBrush& QBarSet::brush() const
55 const QBrush& QBarSet::brush() const
56 {
56 {
57 return mBrush;
57 return mBrush;
58 }
58 }
59
59
60 void QBarSet::barClicked()
60 void QBarSet::barClicked()
61 {
61 {
62 qDebug() << "QBarset::barClicked";
62 // Some bar of this set has been clicked
63 // Some bar of this set has been clicked
63 // TODO: What happens then?
64 // TODO: What happens then?
64 qDebug() << "bar Clicked";
65 emit clicked(); // Notify that set has been clicked
65 }
66 }
66
67
67
68
68 #include "moc_qbarset.cpp"
69 #include "moc_qbarset.cpp"
69 QTCOMMERCIALCHART_END_NAMESPACE
70 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,50 +1,51
1 #ifndef QBARSET_H
1 #ifndef QBARSET_H
2 #define QBARSET_H
2 #define QBARSET_H
3
3
4 #include "qchartglobal.h"
4 #include "qchartglobal.h"
5 #include <QPen>
5 #include <QPen>
6 #include <QBrush>
6 #include <QBrush>
7
7
8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9
9
10 class QTCOMMERCIALCHART_EXPORT QBarSet : public QObject
10 class QTCOMMERCIALCHART_EXPORT QBarSet : public QObject
11 {
11 {
12 Q_OBJECT
12 Q_OBJECT
13 public:
13 public:
14 QBarSet();
14 QBarSet();
15
15
16 void setName(QString name);
16 void setName(QString name);
17 QString name();
17 QString name();
18 QBarSet& operator << (const qreal &value); // appends new value to set
18 QBarSet& operator << (const qreal &value); // appends new value to set
19
19
20 int count(); // count of values in set
20 int count(); // count of values in set
21 qreal valueAt(int index); // for modifying individual values
21 qreal valueAt(int index); // for modifying individual values
22 void setValue(int index, qreal value); //
22 void setValue(int index, qreal value); //
23
23
24 void setPen(const QPen& pen);
24 void setPen(const QPen& pen);
25 const QPen& pen() const;
25 const QPen& pen() const;
26
26
27 void setBrush(const QBrush& brush);
27 void setBrush(const QBrush& brush);
28 const QBrush& brush() const;
28 const QBrush& brush() const;
29
29
30 // void clicked();
30 Q_SIGNALS:
31 void clicked();
31 /*
32 /*
32 void hoverEnter();
33 void hoverEnter();
33 void hoverLeave();
34 void hoverLeave();
34 */
35 */
35
36
36 public Q_SLOTS:
37 public Q_SLOTS:
37 void barClicked();
38 void barClicked();
38
39
39 private:
40 private:
40
41
41 QString mName;
42 QString mName;
42 QList<qreal> mValues;
43 QList<qreal> mValues;
43 QPen mPen;
44 QPen mPen;
44 QBrush mBrush;
45 QBrush mBrush;
45
46
46 };
47 };
47
48
48 QTCOMMERCIALCHART_END_NAMESPACE
49 QTCOMMERCIALCHART_END_NAMESPACE
49
50
50 #endif // QBARSET_H
51 #endif // QBARSET_H
@@ -1,84 +1,106
1 #include "stackedbarpresenter.h"
1 #include "stackedbarpresenter.h"
2 #include "bar_p.h"
2 #include "bar_p.h"
3 #include "barlabel_p.h"
3 #include "barlabel_p.h"
4 #include "barvalue_p.h"
4 #include "separator_p.h"
5 #include "separator_p.h"
5 #include "qbarset.h"
6 #include "qbarset.h"
6 #include <QDebug>
7 #include <QDebug>
7
8
8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9
10
10 StackedBarPresenter::StackedBarPresenter(BarChartModel& model, QGraphicsItem *parent) :
11 StackedBarPresenter::StackedBarPresenter(BarChartModel& model, QGraphicsItem *parent) :
11 BarPresenterBase(model,parent)
12 BarPresenterBase(model,parent)
12 {
13 {
13 }
14 }
14
15
15 void StackedBarPresenter::layoutChanged()
16 void StackedBarPresenter::layoutChanged()
16 {
17 {
17 // Scale bars to new layout
18 // Scale bars to new layout
18 // Layout for bars:
19 // Layout for bars:
19 if (mModel.countSets() <= 0) {
20 if (mModel.countSets() <= 0) {
20 qDebug() << "No sets in model!";
21 qDebug() << "No sets in model!";
21 // Nothing to do.
22 // Nothing to do.
22 return;
23 return;
23 }
24 }
24
25
25 if (mModel.countCategories() == 0) {
26 if (mModel.countCategories() == 0) {
26 qDebug() << "No categories in model!";
27 qDebug() << "No categories in model!";
27 // Nothing to do
28 // Nothing to do
28 return;
29 return;
29 }
30 }
30
31
31 if (childItems().count() == 0) {
32 if (childItems().count() == 0) {
32 qDebug() << "WARNING: StackedBarPresenter::layoutChanged called before graphics items are created!";
33 qDebug() << "WARNING: StackedBarPresenter::layoutChanged called before graphics items are created!";
33 return;
34 return;
34 }
35 }
35
36
36 // TODO: better way to auto-layout
37 // TODO: better way to auto-layout
37 // Use reals for accurancy (we might get some compiler warnings... :)
38 // Use reals for accurancy (we might get some compiler warnings... :)
38 // TODO: use temp variable for category count...
39 // TODO: use temp variable for category count...
39 qreal maxSum = mModel.maxCategorySum();
40 qreal maxSum = mModel.maxCategorySum();
40 qreal h = mHeight;
41 qreal h = mHeight;
41 qreal scale = (h / maxSum);
42 qreal scale = (h / maxSum);
42
43
43 int itemIndex(0);
44 int itemIndex(0);
44 int labelIndex(0);
45 int labelIndex(0);
45 qreal tW = mWidth;
46 qreal tW = mWidth;
46 qreal tC = mModel.countCategories() + 1;
47 qreal tC = mModel.countCategories() + 1;
47 qreal xStep = (tW/tC);
48 qreal xStep = (tW/tC);
48 qreal xPos = ((tW/tC) - mBarDefaultWidth / 2);
49 qreal xPos = ((tW/tC) - mBarDefaultWidth / 2);
49
50
50 for (int category = 0; category < mModel.countCategories(); category++) {
51 for (int category = 0; category < mModel.countCategories(); category++) {
51 qreal yPos = h;
52 qreal yPos = h;
52 for (int set=0; set < mModel.countSets(); set++) {
53 for (int set=0; set < mModel.countSets(); set++) {
53 qreal barHeight = mModel.valueAt(set, category) * scale;
54 qreal barHeight = mModel.valueAt(set, category) * scale;
54 Bar* bar = mBars.at(itemIndex);
55 Bar* bar = mBars.at(itemIndex);
55
56
56 bar->resize(mBarDefaultWidth, barHeight);
57 bar->resize(mBarDefaultWidth, barHeight);
57 bar->setBrush(mModel.setAt(set).brush());
58 bar->setBrush(mModel.setAt(set).brush());
58 bar->setPos(xPos, yPos-barHeight);
59 bar->setPos(xPos, yPos-barHeight);
59 itemIndex++;
60 itemIndex++;
60 yPos -= barHeight;
61 yPos -= barHeight;
61 }
62 }
62
63
63 // TODO: Layout for labels, remove magic number
64 // TODO: Layout for labels, remove magic number
64 BarLabel* label = mLabels.at(labelIndex);
65 BarLabel* label = mLabels.at(labelIndex);
65 label->setPos(xPos, mHeight + 20);
66 label->setPos(xPos, mHeight + 20);
66 labelIndex++;
67 labelIndex++;
67 xPos += xStep;
68 xPos += xStep;
68 }
69 }
69
70
70 // Position separators
71 // Position separators
71 int separatorIndex(0);
72 xPos = xStep + xStep/2;
72 xPos = xStep + xStep/2;
73 for (int s=0; s < mModel.countCategories() - 1; s++) {
73 for (int s=0; s < mModel.countCategories() - 1; s++) {
74 Separator* sep = mSeparators.at(separatorIndex);
74 Separator* sep = mSeparators.at(s);
75 sep->setPos(xPos,0);
75 sep->setPos(xPos,0);
76 sep->setSize(QSizeF(1,mHeight));
76 sep->setSize(QSizeF(1,mHeight));
77 xPos += xStep;
77 xPos += xStep;
78 separatorIndex++;
78 }
79
80 // Position floating values
81 itemIndex = 0;
82 xPos = ((tW/tC) - mBarDefaultWidth / 2);
83 for (int category=0; category < mModel.countCategories(); category++) {
84 qreal yPos = h;
85 for (int set=0; set < mModel.countSets(); set++) {
86 qreal barHeight = mModel.valueAt(set,category) * scale;
87 BarValue* value = mFloatingValues.at(itemIndex);
88
89 // TODO: remove hard coding, apply layout
90 value->resize(100,50);
91 value->setPos(xPos + mBarDefaultWidth/2, yPos-barHeight/2);
92 value->setPen(QPen(QColor(255,255,255,255)));
93
94 QString vString(QString::number(mModel.valueAt(set,category)));
95 value->setValueString(vString);
96
97 itemIndex++;
98 yPos -= barHeight;
99 }
100 xPos += xStep;
79 }
101 }
80
102
81 mLayoutDirty = true;
103 mLayoutDirty = true;
82 }
104 }
83
105
84 QTCOMMERCIALCHART_END_NAMESPACE
106 QTCOMMERCIALCHART_END_NAMESPACE
General Comments 0
You need to be logged in to leave comments. Login now