##// END OF EJS Templates
bar chart layout fixing
sauimone -
r99:f2e3978c70a1
parent child
Show More
@@ -1,79 +1,79
1 #include <QDebug>
1 #include <QDebug>
2 #include "barchartseries.h"
2 #include "barchartseries.h"
3 #include "bargroup.h"
3 #include "bargroup.h"
4 QTCOMMERCIALCHART_BEGIN_NAMESPACE
4 QTCOMMERCIALCHART_BEGIN_NAMESPACE
5
5
6 BarChartSeries::BarChartSeries(QObject *parent)
6 BarChartSeries::BarChartSeries(QObject *parent)
7 : QChartSeries(parent)
7 : QChartSeries(parent)
8 {
8 {
9 }
9 }
10
10
11 bool BarChartSeries::setData(QAbstractItemModel* model)
11 bool BarChartSeries::setData(QAbstractItemModel* model)
12 {
12 {
13 mModel = model;
13 mModel = model;
14 }
14 }
15
15
16 int BarChartSeries::min()
16 int BarChartSeries::min()
17 {
17 {
18 Q_ASSERT(mModel->rowCount() > 0);
18 Q_ASSERT(mModel->rowCount() > 0);
19 Q_ASSERT(mModel->columnCount() > 0);
19 Q_ASSERT(mModel->columnCount() > 0);
20
20
21 // TODO: make min and max members and update them when data changes.
21 // TODO: make min and max members and update them when data changes.
22 // This is slower since they are checked every time, even if data is same since previous call.
22 // This is slower since they are checked every time, even if data is same since previous call.
23 int min = INT_MAX;
23 int min = INT_MAX;
24
24
25 for (int i=0; i <mModel->rowCount(); i++) {
25 for (int i=0; i <mModel->rowCount(); i++) {
26 for(int j=0; j<mModel->columnCount(); j++) {
26 for(int j=0; j<mModel->columnCount(); j++) {
27 int temp = mModel->data(mModel->index(i,j)).toInt();
27 int temp = mModel->data(mModel->index(i,j)).toInt();
28 if (temp < min) {
28 if (temp < min) {
29 min = temp;
29 min = temp;
30 }
30 }
31 }
31 }
32 }
32 }
33 return min;
33 return min;
34 }
34 }
35
35
36 int BarChartSeries::max()
36 int BarChartSeries::max()
37 {
37 {
38 Q_ASSERT(mModel->rowCount() > 0);
38 Q_ASSERT(mModel->rowCount() > 0);
39 Q_ASSERT(mModel->columnCount() > 0);
39 Q_ASSERT(mModel->columnCount() > 0);
40
40
41 // TODO: make min and max members and update them when data changes.
41 // TODO: make min and max members and update them when data changes.
42 // This is slower since they are checked every time, even if data is same since previous call.
42 // This is slower since they are checked every time, even if data is same since previous call.
43 int max = INT_MIN;
43 int max = INT_MIN;
44
44
45 for (int i=0; i <mModel->rowCount(); i++) {
45 for (int i=0; i <mModel->rowCount(); i++) {
46 for(int j=0; j<mModel->columnCount(); j++) {
46 for(int j=0; j<mModel->columnCount(); j++) {
47 int temp = mModel->data(mModel->index(i,j)).toInt();
47 int temp = mModel->data(mModel->index(i,j)).toInt();
48 if (temp > max) {
48 if (temp > max) {
49 max = temp;
49 max = temp;
50 }
50 }
51 }
51 }
52 }
52 }
53 return max;
53 return max;
54 }
54 }
55
55
56
56
57 int BarChartSeries::countSeries()
57 int BarChartSeries::countRows()
58 {
58 {
59 return mModel->rowCount();
59 return mModel->rowCount();
60 }
60 }
61
61
62 int BarChartSeries::countColumns()
62 int BarChartSeries::countColumns()
63 {
63 {
64 return mModel->columnCount();
64 return mModel->columnCount();
65 }
65 }
66
66
67 int BarChartSeries::countTotalItems()
67 int BarChartSeries::countTotalItems()
68 {
68 {
69 return mModel->rowCount() * mModel->columnCount();
69 return mModel->rowCount() * mModel->columnCount();
70 }
70 }
71
71
72 int BarChartSeries::valueAt(int row, int column)
72 int BarChartSeries::valueAt(int row, int column)
73 {
73 {
74 return mModel->data(mModel->index(row,column)).toInt();
74 return mModel->data(mModel->index(row,column)).toInt();
75 }
75 }
76
76
77 #include "moc_barchartseries.cpp"
77 #include "moc_barchartseries.cpp"
78
78
79 QTCOMMERCIALCHART_END_NAMESPACE
79 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,45 +1,45
1 #ifndef BARCHARTSERIES_H
1 #ifndef BARCHARTSERIES_H
2 #define BARCHARTSERIES_H
2 #define BARCHARTSERIES_H
3
3
4 #include <QList>
4 #include <QList>
5 #include <QAbstractItemModel>
5 #include <QAbstractItemModel>
6 #include "qchartseries.h"
6 #include "qchartseries.h"
7 #include "qchartglobal.h"
7 #include "qchartglobal.h"
8
8
9 // TODO: Can this class be combined with series?
9 // TODO: Can this class be combined with series?
10 class BarGroup;
10 class BarGroup;
11
11
12 QTCOMMERCIALCHART_BEGIN_NAMESPACE
12 QTCOMMERCIALCHART_BEGIN_NAMESPACE
13
13
14 // Container for series
14 // Container for series
15 class QTCOMMERCIALCHART_EXPORT BarChartSeries : public QChartSeries
15 class QTCOMMERCIALCHART_EXPORT BarChartSeries : public QChartSeries
16 {
16 {
17 Q_OBJECT
17 Q_OBJECT
18 public:
18 public:
19 BarChartSeries(QObject* parent=0);
19 BarChartSeries(QObject* parent=0);
20
20
21 // from QChartSeries
21 // from QChartSeries
22 virtual QChartSeriesType type() const { return QChartSeries::SeriesTypeBar; }
22 virtual QChartSeriesType type() const { return QChartSeries::SeriesTypeBar; }
23
23
24 // TODO: Better data model?
24 // TODO: Better data model?
25 virtual bool setData(QAbstractItemModel* model);
25 virtual bool setData(QAbstractItemModel* model);
26
26
27 // Methods to find out minimum and maximum values of data
27 // Methods to find out minimum and maximum values of data
28 int min();
28 int min();
29 int max();
29 int max();
30 int countSeries();
30 int countRows();
31 int countColumns(); // Count items in one series.
31 int countColumns(); // Count items in one series.
32 int countTotalItems();
32 int countTotalItems();
33 int valueAt(int row, int column);
33 int valueAt(int row, int column);
34
34
35 public Q_SLOTS:
35 public Q_SLOTS:
36
36
37 private:
37 private:
38
38
39 QAbstractItemModel* mModel;
39 QAbstractItemModel* mModel;
40 BarGroup* mBarGroup;
40 BarGroup* mBarGroup;
41 };
41 };
42
42
43 QTCOMMERCIALCHART_END_NAMESPACE
43 QTCOMMERCIALCHART_END_NAMESPACE
44
44
45 #endif // BARCHARTSERIES_H
45 #endif // BARCHARTSERIES_H
@@ -1,127 +1,159
1 #include "bargroup.h"
1 #include "bargroup.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 BarGroup::BarGroup(BarChartSeries& series, QGraphicsItem *parent) :
7 BarGroup::BarGroup(BarChartSeries& 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(10)
12 ,mBarDefaultWidth(10)
13 {
13 {
14 dataChanged();
14 dataChanged();
15 }
15 }
16
16
17
17
18 void BarGroup::setSize(const QSize& size)
18 void BarGroup::setSize(const QSize& size)
19 {
19 {
20 qDebug() << "BarGroup::setSize";
20 qDebug() << "BarGroup::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 BarGroup::setPlotDomain(const PlotDomain& data)
27 void BarGroup::setPlotDomain(const PlotDomain& data)
28 {
28 {
29 qDebug() << "BarGroup::setPlotDomain";
29 qDebug() << "BarGroup::setPlotDomain";
30 // TODO:
30 // TODO:
31 }
31 }
32
32
33 void BarGroup::setBarWidth( int w )
33 void BarGroup::setBarWidth( int w )
34 {
34 {
35 mBarDefaultWidth = w;
35 mBarDefaultWidth = w;
36 }
36 }
37
37
38 int BarGroup::addColor( QColor color )
38 int BarGroup::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 BarGroup::resetColors()
45 void BarGroup::resetColors()
46 {
46 {
47 mColors.clear();
47 mColors.clear();
48 }
48 }
49
49
50 void BarGroup::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
50 void BarGroup::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 BarGroup::boundingRect() const
64 QRectF BarGroup::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 BarGroup::dataChanged()
70 void BarGroup::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 BarGroup::layoutChanged()
94 void BarGroup::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.countSeries() <= 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 int count = mSeries.countColumns();
104 // Use reals for accurancy (we might get some compiler warnings... :)
105 int posStep = (mWidth / (count+1));
105 int columnCount = mSeries.countColumns();
106 int startPos = (mWidth / (count+1)) - mSeries.countSeries() * mBarDefaultWidth /2;
106 int rowCount = mSeries.countRows();
107 qDebug() << "startpos" << startPos;
108
107
108 qreal tW = mWidth;
109 qreal tH = mHeight;
110 qreal tM = mMax;
111 qreal scale = (tH/tM);
112
113 qreal tC = columnCount+1;
114 qreal xStepPerSeries = (tW/tC);
115
116 //qint startPos = (mWidth / (count+1)) - mSeries.countSeries() * mBarDefaultWidth /2;
117 // qDebug() << "XPOS:" << xPos;
118
119 qDebug() << "XSTEP:" << xStepPerSeries;
120
121 // TODO: Correct the calculations...
109 // Scaling.
122 // Scaling.
110 int itemIndex(0);
123 int itemIndex(0);
111 for (int series = 0; series < mSeries.countSeries(); series++) {
124 for (int column=0; column < columnCount; column++) {
125 qreal xPos = xStepPerSeries * column + ((tW + mBarDefaultWidth*rowCount)/(columnCount*2));
126 qDebug() << "XPOS:" << xPos;
127 for (int row = 0; row < rowCount; row++) {
128 qreal barHeight = mSeries.valueAt(row, column) * scale;
129 Bar* bar = reinterpret_cast<Bar*> (childItems().at(itemIndex));
130
131 // TODO: width settable per bar?
132 bar->resize(mBarDefaultWidth, barHeight);
133 bar->setColor(mColors.at(row));
134 bar->setPos(xPos, mHeight); // item*posStep+startPos + series * mBarDefaultWidth, mHeight);
135 itemIndex++;
136 xPos += mBarDefaultWidth;
137 }
138 }
139
140 /*
141 for (int series = 0; series < mSeries.countRows(); series++) {
112 for (int item=0; item < mSeries.countColumns(); item++) {
142 for (int item=0; item < mSeries.countColumns(); item++) {
113 qDebug() << itemIndex;
143 qreal barHeight = mSeries.valueAt(series, item) * scale;
114 int barHeight = mSeries.valueAt(series, item) * mHeight / mMax;
115 Bar* bar = reinterpret_cast<Bar*> (childItems().at(itemIndex));
144 Bar* bar = reinterpret_cast<Bar*> (childItems().at(itemIndex));
116
145
117 // TODO: width settable per bar?
146 // TODO: width settable per bar?
118 bar->resize(mBarDefaultWidth, barHeight);
147 bar->resize(mBarDefaultWidth, barHeight);
119 bar->setColor(mColors.at(series));
148 bar->setColor(mColors.at(series));
120 bar->setPos(item*posStep+startPos + series * mBarDefaultWidth, mHeight);
149 bar->setPos(xPos, mHeight); // item*posStep+startPos + series * mBarDefaultWidth, mHeight);
121 itemIndex++;
150 itemIndex++;
151 xPos += mBarDefaultWidth;
122 }
152 }
153 xPos = xStepPerSeries * series;
123 }
154 }
155 */
124 mLayoutDirty = true;
156 mLayoutDirty = true;
125 }
157 }
126
158
127 QTCOMMERCIALCHART_END_NAMESPACE
159 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,134 +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 (we might get some compiler warnings... :)
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 itemIndex(0);
110 int itemIndex(0);
111 qreal tW = mWidth;
111 qreal tW = mWidth;
112 qreal tC = count+1;
112 qreal tC = count+1;
113 qreal xStep = (tW/tC);
113 qreal xStep = (tW/tC);
114 qreal xPos = ((tW/tC) + mBarDefaultWidth / 2);
114 qreal xPos = ((tW/tC) + mBarDefaultWidth / 2);
115
115
116 for (int column = 0; column < mSeries.countColumns(); column++) {
116 for (int column = 0; column < mSeries.countColumns(); column++) {
117 qreal yPos = h;
117 qreal yPos = h;
118 for (int row=0; row < mSeries.countRows(); row++) {
118 for (int row=0; row < mSeries.countRows(); row++) {
119 qreal barHeight = mSeries.valueAt(row, column) * scale;
119 qreal barHeight = mSeries.valueAt(row, column) * scale;
120 Bar* bar = reinterpret_cast<Bar*> (childItems().at(itemIndex));
120 Bar* bar = reinterpret_cast<Bar*> (childItems().at(itemIndex));
121
121
122 // TODO: width settable per bar?
122 // TODO: width settable per bar?
123 bar->resize(mBarDefaultWidth, barHeight);
123 bar->resize(mBarDefaultWidth, barHeight);
124 bar->setColor(mColors.at(row));
124 bar->setColor(mColors.at(row));
125 bar->setPos(xPos, yPos);
125 bar->setPos(xPos, yPos);
126 itemIndex++;
126 itemIndex++;
127 yPos -= barHeight;
127 yPos -= barHeight;
128 }
128 }
129 xPos += xStep;
129 xPos += xStep;
130 }
130 }
131 mLayoutDirty = true;
131 mLayoutDirty = true;
132 }
132 }
133
133
134 QTCOMMERCIALCHART_END_NAMESPACE
134 QTCOMMERCIALCHART_END_NAMESPACE
General Comments 0
You need to be logged in to leave comments. Login now