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