##// END OF EJS Templates
Some fixes to bar charts. Now bars draw almost correctly
sauimone -
r97:f3d03f051601
parent child
Show More
@@ -1,64 +1,58
1 #include "bar.h"
1 #include "bar.h"
2 #include <QDebug>
2 #include <QDebug>
3 #include <QPainter>
3 #include <QPainter>
4
4
5 QTCOMMERCIALCHART_BEGIN_NAMESPACE
5 QTCOMMERCIALCHART_BEGIN_NAMESPACE
6
6
7 Bar::Bar(ChartItem *parent)
7 Bar::Bar(ChartItem *parent)
8 : ChartItem(parent)
8 : ChartItem(parent)
9 {
9 {
10 }
10 }
11
11
12 void Bar::setSize(const QSize& size)
12 void Bar::setSize(const QSize& size)
13 {
13 {
14 //mSize = size;
15 mWidth = size.width();
14 mWidth = size.width();
16 mHeight = size.height();
15 mHeight = size.height();
17 }
16 }
18
17
19 void Bar::setPlotDomain(const PlotDomain& data)
18 void Bar::setPlotDomain(const PlotDomain& data)
20 {
19 {
21 mPlotDomain = data;
20 mPlotDomain = data;
22 }
21 }
23
22
24 void Bar::resize( int w, int h )
23 void Bar::resize( int w, int h )
25 {
24 {
26 qDebug() << "bar::resize" << w << h;
25 // qDebug() << "bar::resize" << w << h;
27 mWidth = w;
26 mWidth = w;
28 mHeight = h;
27 mHeight = h;
29 }
28 }
30
29
31 void Bar::setColor( QColor col )
30 void Bar::setColor( QColor col )
32 {
31 {
33 mColor = col;
32 mColor = col;
34 }
33 }
35 void Bar::setPos(qreal x, qreal y)
34 void Bar::setPos(qreal x, qreal y)
36 {
35 {
37 qDebug() << "Bar::setpos" << x << y;
36 // qDebug() << "Bar::setpos" << x << y;
38 mXpos = x;
37 mXpos = x;
39 mYpos = y;
38 mYpos = y;
40 }
39 }
41
40
42 void Bar::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
41 void Bar::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
43 {
42 {
44 if (0 == mHeight) {
43 if (0 == mHeight) {
45 return;
44 return;
46 }
45 }
47 // Set color for bar. TODO: gradients, textures etc
46 // TODO: accept brush instead of color
48 QPen pen = painter->pen();
47 QBrush brush(mColor);
49 pen.setColor( mColor );
48 painter->setBrush(brush);
50 pen.setWidth( mWidth );
49 painter->drawRect(mXpos-mWidth, mYpos-mHeight ,mWidth ,mHeight); // Evil inverse rect, because we want bars to grow from bottom to top :)
51 painter->setPen(pen);
52
53 // Draw bar
54 painter->drawLine(mXpos, mYpos,
55 mXpos, mYpos - mHeight);
56 }
50 }
57
51
58 QRectF Bar::boundingRect() const
52 QRectF Bar::boundingRect() const
59 {
53 {
60 QRectF r(mXpos, mYpos, mXpos + mWidth, mYpos + mHeight);
54 QRectF r(mXpos, mYpos, mXpos + mWidth, mYpos + mHeight);
61 return r;
55 return r;
62 }
56 }
63
57
64 QTCOMMERCIALCHART_END_NAMESPACE
58 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,107 +1,110
1 #include <limits.h>
1 #include <limits.h>
2 #include <QDebug>
2 #include "stackedbarchartseries.h"
3 #include "stackedbarchartseries.h"
3
4
4 QTCOMMERCIALCHART_BEGIN_NAMESPACE
5 QTCOMMERCIALCHART_BEGIN_NAMESPACE
5
6
6 StackedBarChartSeries::StackedBarChartSeries(QObject *parent) :
7 StackedBarChartSeries::StackedBarChartSeries(QObject *parent) :
7 QChartSeries(parent)
8 QChartSeries(parent)
8 {
9 {
9 }
10 }
10
11
11 bool StackedBarChartSeries::setData(QAbstractItemModel* model)
12 bool StackedBarChartSeries::setData(QAbstractItemModel* model)
12 {
13 {
13 mModel = model;
14 mModel = model;
14 }
15 }
15
16
16 int StackedBarChartSeries::min()
17 int StackedBarChartSeries::min()
17 {
18 {
18 Q_ASSERT(mModel->rowCount() > 0);
19 Q_ASSERT(mModel->rowCount() > 0);
19 Q_ASSERT(mModel->columnCount() > 0);
20 Q_ASSERT(mModel->columnCount() > 0);
20
21
21 // 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.
22 // 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.
23 int min = INT_MAX;
24 int min = INT_MAX;
24
25
25 for (int i=0; i <mModel->rowCount(); i++) {
26 for (int i=0; i <mModel->rowCount(); i++) {
26 for(int j=0; j<mModel->columnCount(); j++) {
27 for(int j=0; j<mModel->columnCount(); j++) {
27 int temp = mModel->data(mModel->index(i,j)).toInt();
28 int temp = mModel->data(mModel->index(i,j)).toInt();
28 if (temp < min) {
29 if (temp < min) {
29 min = temp;
30 min = temp;
30 }
31 }
31 }
32 }
32 }
33 }
33 return min;
34 return min;
34 }
35 }
35
36
36 int StackedBarChartSeries::max()
37 int StackedBarChartSeries::max()
37 {
38 {
38 Q_ASSERT(mModel->rowCount() > 0);
39 Q_ASSERT(mModel->rowCount() > 0);
39 Q_ASSERT(mModel->columnCount() > 0);
40 Q_ASSERT(mModel->columnCount() > 0);
40
41
41 // 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.
42 // 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.
43 int max = INT_MIN;
44 int max = INT_MIN;
44
45
45 for (int i=0; i <mModel->rowCount(); i++) {
46 for (int i=0; i <mModel->rowCount(); i++) {
46 for(int j=0; j<mModel->columnCount(); j++) {
47 for(int j=0; j<mModel->columnCount(); j++) {
47 int temp = mModel->data(mModel->index(i,j)).toInt();
48 int temp = mModel->data(mModel->index(i,j)).toInt();
48 if (temp > max) {
49 if (temp > max) {
49 max = temp;
50 max = temp;
50 }
51 }
51 }
52 }
52 }
53 }
53 return max;
54 return max;
54 }
55 }
55
56
56 int StackedBarChartSeries::maxColumnSum()
57 int StackedBarChartSeries::maxColumnSum()
57 {
58 {
58 Q_ASSERT(mModel->rowCount() > 0);
59 Q_ASSERT(mModel->rowCount() > 0);
59 Q_ASSERT(mModel->columnCount() > 0);
60 Q_ASSERT(mModel->columnCount() > 0);
60
61
61 int max = INT_MIN;
62 int max = INT_MIN;
62
63
63 for (int col=0; col <mModel->rowCount(); col++) {
64 for (int col=0; col <mModel->columnCount(); col++) {
64 int sum = columnSum(col);
65 int sum = columnSum(col);
65 if (sum > max) {
66 if (sum > max) {
66 max = sum;
67 max = sum;
67 }
68 }
68 }
69 }
70 qDebug() << "maxColumnSum" << max;
69 return max;
71 return max;
70 }
72 }
71
73
72 int StackedBarChartSeries::countRows()
74 int StackedBarChartSeries::countRows()
73 {
75 {
74 return mModel->rowCount();
76 return mModel->rowCount();
75 }
77 }
76
78
77 int StackedBarChartSeries::countColumns()
79 int StackedBarChartSeries::countColumns()
78 {
80 {
79 return mModel->columnCount();
81 return mModel->columnCount();
80 }
82 }
81
83
82 int StackedBarChartSeries::countTotalItems()
84 int StackedBarChartSeries::countTotalItems()
83 {
85 {
84 return mModel->rowCount() * mModel->columnCount();
86 return mModel->rowCount() * mModel->columnCount();
85 }
87 }
86
88
87 int StackedBarChartSeries::valueAt(int row, int column)
89 int StackedBarChartSeries::valueAt(int row, int column)
88 {
90 {
89 QModelIndex index = mModel->index(row,column);
91 QModelIndex index = mModel->index(row,column);
90 return mModel->data(index).toInt();
92 return mModel->data(index).toInt();
91 }
93 }
92
94
93 int StackedBarChartSeries::columnSum(int column)
95 int StackedBarChartSeries::columnSum(int column)
94 {
96 {
95 int sum(0);
97 int sum(0);
96 int count = mModel->rowCount();
98 int count = mModel->rowCount();
97
99
98 for (int row = 0; row < count; row++) {
100 for (int row = 0; row < count; row++) {
99 sum += mModel->data(mModel->index(row,column)).toInt();
101 sum += mModel->data(mModel->index(row,column)).toInt();
100 }
102 }
103 qDebug() << "sum for column" << column << "=" << sum;
101 return sum;
104 return sum;
102 }
105 }
103
106
104 #include "moc_stackedbarchartseries.cpp"
107 #include "moc_stackedbarchartseries.cpp"
105
108
106 QTCOMMERCIALCHART_END_NAMESPACE
109 QTCOMMERCIALCHART_END_NAMESPACE
107
110
@@ -1,133 +1,133
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(10) // 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));
110 int posStepX = (mWidth / (count+1));
111
111
112 int itemIndex(0);
112 int itemIndex(0);
113 int xPos = (mWidth / (count+1)) - mSeries.countColumns() * mBarDefaultWidth /2;
113 int xPos = (mWidth / (count+1)) - mSeries.countRows() * mBarDefaultWidth /2;
114 for (int column = 0; column < mSeries.countColumns(); column++) {
114 for (int column = 0; column < mSeries.countColumns(); column++) {
115 int yPos = mHeight;
115 int yPos = mHeight;
116 for (int row=0; row < mSeries.countRows(); row++) {
116 for (int row=0; row < mSeries.countRows(); row++) {
117 qDebug() << itemIndex;
118 int barHeight = mSeries.valueAt(row, column) * scale;
117 int barHeight = mSeries.valueAt(row, column) * scale;
119 Bar* bar = reinterpret_cast<Bar*> (childItems().at(itemIndex));
118 Bar* bar = reinterpret_cast<Bar*> (childItems().at(itemIndex));
120
119
121 // TODO: width settable per bar?
120 // TODO: width settable per bar?
122 bar->resize(mBarDefaultWidth, barHeight);
121 bar->resize(mBarDefaultWidth, barHeight);
123 bar->setColor(mColors.at(row));
122 bar->setColor(mColors.at(row));
124 bar->setPos(xPos, yPos);
123 bar->setPos(xPos, yPos);
124 qDebug() << itemIndex << "pos" << xPos << yPos;
125 itemIndex++;
125 itemIndex++;
126 yPos += barHeight;
126 yPos -= barHeight;
127 }
127 }
128 xPos += posStepX;
128 xPos += posStepX;
129 }
129 }
130 mLayoutDirty = true;
130 mLayoutDirty = true;
131 }
131 }
132
132
133 QTCOMMERCIALCHART_END_NAMESPACE
133 QTCOMMERCIALCHART_END_NAMESPACE
General Comments 0
You need to be logged in to leave comments. Login now