##// END OF EJS Templates
fixing layout bug on stacked bar chart
sauimone -
r98:e7f551f0831b
parent child
Show More
@@ -1,110 +1,108
1 #include <limits.h>
1 #include <limits.h>
2 #include <QDebug>
2 #include <QDebug>
3 #include "stackedbarchartseries.h"
3 #include "stackedbarchartseries.h"
4
4
5 QTCOMMERCIALCHART_BEGIN_NAMESPACE
5 QTCOMMERCIALCHART_BEGIN_NAMESPACE
6
6
7 StackedBarChartSeries::StackedBarChartSeries(QObject *parent) :
7 StackedBarChartSeries::StackedBarChartSeries(QObject *parent) :
8 QChartSeries(parent)
8 QChartSeries(parent)
9 {
9 {
10 }
10 }
11
11
12 bool StackedBarChartSeries::setData(QAbstractItemModel* model)
12 bool StackedBarChartSeries::setData(QAbstractItemModel* model)
13 {
13 {
14 mModel = model;
14 mModel = model;
15 }
15 }
16
16
17 int StackedBarChartSeries::min()
17 int StackedBarChartSeries::min()
18 {
18 {
19 Q_ASSERT(mModel->rowCount() > 0);
19 Q_ASSERT(mModel->rowCount() > 0);
20 Q_ASSERT(mModel->columnCount() > 0);
20 Q_ASSERT(mModel->columnCount() > 0);
21
21
22 // TODO: make min and max members and update them when data changes.
22 // TODO: make min and max members and update them when data changes.
23 // This is slower since they are checked every time, even if data is same since previous call.
23 // This is slower since they are checked every time, even if data is same since previous call.
24 int min = INT_MAX;
24 int min = INT_MAX;
25
25
26 for (int i=0; i <mModel->rowCount(); i++) {
26 for (int i=0; i <mModel->rowCount(); i++) {
27 for(int j=0; j<mModel->columnCount(); j++) {
27 for(int j=0; j<mModel->columnCount(); j++) {
28 int temp = mModel->data(mModel->index(i,j)).toInt();
28 int temp = mModel->data(mModel->index(i,j)).toInt();
29 if (temp < min) {
29 if (temp < min) {
30 min = temp;
30 min = temp;
31 }
31 }
32 }
32 }
33 }
33 }
34 return min;
34 return min;
35 }
35 }
36
36
37 int StackedBarChartSeries::max()
37 int StackedBarChartSeries::max()
38 {
38 {
39 Q_ASSERT(mModel->rowCount() > 0);
39 Q_ASSERT(mModel->rowCount() > 0);
40 Q_ASSERT(mModel->columnCount() > 0);
40 Q_ASSERT(mModel->columnCount() > 0);
41
41
42 // TODO: make min and max members and update them when data changes.
42 // TODO: make min and max members and update them when data changes.
43 // This is slower since they are checked every time, even if data is same since previous call.
43 // This is slower since they are checked every time, even if data is same since previous call.
44 int max = INT_MIN;
44 int max = INT_MIN;
45
45
46 for (int i=0; i <mModel->rowCount(); i++) {
46 for (int i=0; i <mModel->rowCount(); i++) {
47 for(int j=0; j<mModel->columnCount(); j++) {
47 for(int j=0; j<mModel->columnCount(); j++) {
48 int temp = mModel->data(mModel->index(i,j)).toInt();
48 int temp = mModel->data(mModel->index(i,j)).toInt();
49 if (temp > max) {
49 if (temp > max) {
50 max = temp;
50 max = temp;
51 }
51 }
52 }
52 }
53 }
53 }
54 return max;
54 return max;
55 }
55 }
56
56
57 int StackedBarChartSeries::maxColumnSum()
57 int StackedBarChartSeries::maxColumnSum()
58 {
58 {
59 Q_ASSERT(mModel->rowCount() > 0);
59 Q_ASSERT(mModel->rowCount() > 0);
60 Q_ASSERT(mModel->columnCount() > 0);
60 Q_ASSERT(mModel->columnCount() > 0);
61
61
62 int max = INT_MIN;
62 int max = INT_MIN;
63
63
64 for (int col=0; col <mModel->columnCount(); col++) {
64 for (int col=0; col <mModel->columnCount(); col++) {
65 int sum = columnSum(col);
65 int sum = columnSum(col);
66 if (sum > max) {
66 if (sum > max) {
67 max = sum;
67 max = sum;
68 }
68 }
69 }
69 }
70 qDebug() << "maxColumnSum" << max;
71 return max;
70 return max;
72 }
71 }
73
72
74 int StackedBarChartSeries::countRows()
73 int StackedBarChartSeries::countRows()
75 {
74 {
76 return mModel->rowCount();
75 return mModel->rowCount();
77 }
76 }
78
77
79 int StackedBarChartSeries::countColumns()
78 int StackedBarChartSeries::countColumns()
80 {
79 {
81 return mModel->columnCount();
80 return mModel->columnCount();
82 }
81 }
83
82
84 int StackedBarChartSeries::countTotalItems()
83 int StackedBarChartSeries::countTotalItems()
85 {
84 {
86 return mModel->rowCount() * mModel->columnCount();
85 return mModel->rowCount() * mModel->columnCount();
87 }
86 }
88
87
89 int StackedBarChartSeries::valueAt(int row, int column)
88 int StackedBarChartSeries::valueAt(int row, int column)
90 {
89 {
91 QModelIndex index = mModel->index(row,column);
90 QModelIndex index = mModel->index(row,column);
92 return mModel->data(index).toInt();
91 return mModel->data(index).toInt();
93 }
92 }
94
93
95 int StackedBarChartSeries::columnSum(int column)
94 int StackedBarChartSeries::columnSum(int column)
96 {
95 {
97 int sum(0);
96 int sum(0);
98 int count = mModel->rowCount();
97 int count = mModel->rowCount();
99
98
100 for (int row = 0; row < count; row++) {
99 for (int row = 0; row < count; row++) {
101 sum += mModel->data(mModel->index(row,column)).toInt();
100 sum += mModel->data(mModel->index(row,column)).toInt();
102 }
101 }
103 qDebug() << "sum for column" << column << "=" << sum;
104 return sum;
102 return sum;
105 }
103 }
106
104
107 #include "moc_stackedbarchartseries.cpp"
105 #include "moc_stackedbarchartseries.cpp"
108
106
109 QTCOMMERCIALCHART_END_NAMESPACE
107 QTCOMMERCIALCHART_END_NAMESPACE
110
108
@@ -1,133 +1,134
1 #include "stackedbargroup.h"
1 #include "stackedbargroup.h"
2 #include "bar.h"
2 #include "bar.h"
3 #include <QDebug>
3 #include <QDebug>
4
4
5 QTCOMMERCIALCHART_BEGIN_NAMESPACE
5 QTCOMMERCIALCHART_BEGIN_NAMESPACE
6
6
7 StackedBarGroup::StackedBarGroup(StackedBarChartSeries& series, QGraphicsItem *parent) :
7 StackedBarGroup::StackedBarGroup(StackedBarChartSeries& series, QGraphicsItem *parent) :
8 ChartItem(parent)
8 ChartItem(parent)
9 ,mSeries(series)
9 ,mSeries(series)
10 ,mLayoutSet(false)
10 ,mLayoutSet(false)
11 ,mLayoutDirty(true)
11 ,mLayoutDirty(true)
12 ,mBarDefaultWidth(20) // TODO: remove hard coding, when we have layout code ready
12 ,mBarDefaultWidth(20) // TODO: remove hard coding, when we have layout code ready
13 {
13 {
14 dataChanged();
14 dataChanged();
15 }
15 }
16
16
17
17
18 void StackedBarGroup::setSize(const QSize& size)
18 void StackedBarGroup::setSize(const QSize& size)
19 {
19 {
20 qDebug() << "StackedBarGroup::setSize";
20 qDebug() << "StackedBarGroup::setSize";
21 mWidth = size.width();
21 mWidth = size.width();
22 mHeight = size.height();
22 mHeight = size.height();
23 layoutChanged();
23 layoutChanged();
24 mLayoutSet = true;
24 mLayoutSet = true;
25 }
25 }
26
26
27 void StackedBarGroup::setPlotDomain(const PlotDomain& data)
27 void StackedBarGroup::setPlotDomain(const PlotDomain& data)
28 {
28 {
29 qDebug() << "StackedBarGroup::setPlotDomain";
29 qDebug() << "StackedBarGroup::setPlotDomain";
30 // TODO:
30 // TODO:
31 }
31 }
32
32
33 void StackedBarGroup::setBarWidth( int w )
33 void StackedBarGroup::setBarWidth( int w )
34 {
34 {
35 mBarDefaultWidth = w;
35 mBarDefaultWidth = w;
36 }
36 }
37
37
38 int StackedBarGroup::addColor( QColor color )
38 int StackedBarGroup::addColor( QColor color )
39 {
39 {
40 int colorIndex = mColors.count();
40 int colorIndex = mColors.count();
41 mColors.append(color);
41 mColors.append(color);
42 return colorIndex;
42 return colorIndex;
43 }
43 }
44
44
45 void StackedBarGroup::resetColors()
45 void StackedBarGroup::resetColors()
46 {
46 {
47 mColors.clear();
47 mColors.clear();
48 }
48 }
49
49
50 void StackedBarGroup::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
50 void StackedBarGroup::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
51 {
51 {
52 if (!mLayoutSet) {
52 if (!mLayoutSet) {
53 qDebug() << "QBarChart::paint called without layout set. Aborting.";
53 qDebug() << "QBarChart::paint called without layout set. Aborting.";
54 return;
54 return;
55 }
55 }
56 if (mLayoutDirty) {
56 if (mLayoutDirty) {
57 // Layout or data has changed. Need to redraw.
57 // Layout or data has changed. Need to redraw.
58 foreach(QGraphicsItem* i, childItems()) {
58 foreach(QGraphicsItem* i, childItems()) {
59 i->paint(painter,option,widget);
59 i->paint(painter,option,widget);
60 }
60 }
61 }
61 }
62 }
62 }
63
63
64 QRectF StackedBarGroup::boundingRect() const
64 QRectF StackedBarGroup::boundingRect() const
65 {
65 {
66 return QRectF(0,0,mWidth,mHeight);
66 return QRectF(0,0,mWidth,mHeight);
67 }
67 }
68
68
69
69
70 void StackedBarGroup::dataChanged()
70 void StackedBarGroup::dataChanged()
71 {
71 {
72 qDebug() << "QBarChart::dataChanged mSeries";
72 qDebug() << "QBarChart::dataChanged mSeries";
73
73
74 // Find out maximum and minimum of all series
74 // Find out maximum and minimum of all series
75 mMax = mSeries.max();
75 mMax = mSeries.max();
76 mMin = mSeries.min();
76 mMin = mSeries.min();
77
77
78 // Delete old bars
78 // Delete old bars
79 // Is this correct way to delete childItems?
79 // Is this correct way to delete childItems?
80 foreach (QGraphicsItem* item, childItems()) {
80 foreach (QGraphicsItem* item, childItems()) {
81 delete item;
81 delete item;
82 }
82 }
83
83
84 // Create new graphic items for bars
84 // Create new graphic items for bars
85 int totalItems = mSeries.countTotalItems();
85 int totalItems = mSeries.countTotalItems();
86 for (int i=0; i<totalItems; i++) {
86 for (int i=0; i<totalItems; i++) {
87 Bar *bar = new Bar(this);
87 Bar *bar = new Bar(this);
88 childItems().append(bar);
88 childItems().append(bar);
89 }
89 }
90
90
91 mLayoutDirty = true;
91 mLayoutDirty = true;
92 }
92 }
93
93
94 void StackedBarGroup::layoutChanged()
94 void StackedBarGroup::layoutChanged()
95 {
95 {
96 // Scale bars to new layout
96 // Scale bars to new layout
97 // Layout for bars:
97 // Layout for bars:
98 if (mSeries.countRows() <= 0) {
98 if (mSeries.countRows() <= 0) {
99 // Nothing to do.
99 // Nothing to do.
100 return;
100 return;
101 }
101 }
102
102
103 // TODO: better way to auto-layout
103 // TODO: better way to auto-layout
104 // Use reals for accurancy (implicit casting here, we get a warning)
104 // Use reals for accurancy (implicit casting here, we get a warning)
105 qreal maxSum = mSeries.maxColumnSum();
105 qreal maxSum = mSeries.maxColumnSum();
106 qreal h = mHeight;
106 qreal h = mHeight;
107 qreal scale = (h / maxSum);
107 qreal scale = (h / maxSum);
108
108
109 int count = mSeries.countColumns();
109 int count = mSeries.countColumns();
110 int posStepX = (mWidth / (count+1));
111
112 int itemIndex(0);
110 int itemIndex(0);
113 int xPos = (mWidth / (count+1)) - mSeries.countRows() * mBarDefaultWidth /2;
111 qreal tW = mWidth;
112 qreal tC = count+1;
113 qreal xStep = (tW/tC);
114 qreal xPos = ((tW/tC) + mBarDefaultWidth / 2);
115
114 for (int column = 0; column < mSeries.countColumns(); column++) {
116 for (int column = 0; column < mSeries.countColumns(); column++) {
115 int yPos = mHeight;
117 qreal yPos = h;
116 for (int row=0; row < mSeries.countRows(); row++) {
118 for (int row=0; row < mSeries.countRows(); row++) {
117 int barHeight = mSeries.valueAt(row, column) * scale;
119 qreal barHeight = mSeries.valueAt(row, column) * scale;
118 Bar* bar = reinterpret_cast<Bar*> (childItems().at(itemIndex));
120 Bar* bar = reinterpret_cast<Bar*> (childItems().at(itemIndex));
119
121
120 // TODO: width settable per bar?
122 // TODO: width settable per bar?
121 bar->resize(mBarDefaultWidth, barHeight);
123 bar->resize(mBarDefaultWidth, barHeight);
122 bar->setColor(mColors.at(row));
124 bar->setColor(mColors.at(row));
123 bar->setPos(xPos, yPos);
125 bar->setPos(xPos, yPos);
124 qDebug() << itemIndex << "pos" << xPos << yPos;
125 itemIndex++;
126 itemIndex++;
126 yPos -= barHeight;
127 yPos -= barHeight;
127 }
128 }
128 xPos += posStepX;
129 xPos += xStep;
129 }
130 }
130 mLayoutDirty = true;
131 mLayoutDirty = true;
131 }
132 }
132
133
133 QTCOMMERCIALCHART_END_NAMESPACE
134 QTCOMMERCIALCHART_END_NAMESPACE
General Comments 0
You need to be logged in to leave comments. Login now