##// END OF EJS Templates
Code review: Fixed simple issues in Bar and Legend
Tero Ahola -
r737:e81beeb51921
parent child
Show More
@@ -1,37 +1,38
1 #include "bar_p.h"
1 #include "bar_p.h"
2 #include <QDebug>
2 #include <QDebug>
3 #include <QPainter>
3 #include <QPainter>
4 #include <QGraphicsSceneEvent>
4 #include <QGraphicsSceneEvent>
5
5
6 QTCOMMERCIALCHART_BEGIN_NAMESPACE
6 QTCOMMERCIALCHART_BEGIN_NAMESPACE
7
7
8 Bar::Bar(QString category, QGraphicsItem *parent)
8 Bar::Bar(QString category, QGraphicsItem *parent)
9 : QGraphicsRectItem(parent),
9 : QGraphicsRectItem(parent),
10 mCategory(category)
10 mCategory(category)
11 {
11 {
12 setAcceptedMouseButtons(Qt::LeftButton|Qt::RightButton);
12 setAcceptedMouseButtons(Qt::LeftButton | Qt::RightButton);
13 setAcceptHoverEvents(true);
13 setAcceptHoverEvents(true);
14 }
14 }
15
15
16 void Bar::mousePressEvent(QGraphicsSceneMouseEvent* event)
16 void Bar::mousePressEvent(QGraphicsSceneMouseEvent *event)
17 {
17 {
18 if (event->button() == Qt::LeftButton) {
18 if (event->button() == Qt::LeftButton) {
19 emit clicked(mCategory);
19 emit clicked(mCategory);
20 } else if (event->button() == Qt::RightButton) {
20 } else if (event->button() == Qt::RightButton) {
21 emit rightClicked(mCategory);
21 emit rightClicked(mCategory);
22 }
22 }
23 }
23 }
24
24
25 void Bar::hoverEnterEvent(QGraphicsSceneHoverEvent* event)
25 void Bar::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
26 {
26 {
27 emit hoverEntered(event->lastScreenPos());
27 emit hoverEntered(event->lastScreenPos());
28 }
28 }
29
29
30 void Bar::hoverLeaveEvent(QGraphicsSceneHoverEvent* /*event*/)
30 void Bar::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
31 {
31 {
32 Q_UNUSED(event)
32 emit hoverLeaved();
33 emit hoverLeaved();
33 }
34 }
34
35
35 #include "moc_bar_p.cpp"
36 #include "moc_bar_p.cpp"
36
37
37 QTCOMMERCIALCHART_END_NAMESPACE
38 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,33 +1,33
1 #ifndef BAR_H
1 #ifndef BAR_H
2 #define BAR_H
2 #define BAR_H
3
3
4 #include "qchartglobal.h"
4 #include "qchartglobal.h"
5 #include <QGraphicsRectItem>
5 #include <QGraphicsRectItem>
6
6
7 QTCOMMERCIALCHART_BEGIN_NAMESPACE
7 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8
8
9 // Single visual bar item of chart
9 // Single visual bar item of chart
10 class Bar : public QObject, public QGraphicsRectItem
10 class Bar : public QObject, public QGraphicsRectItem
11 {
11 {
12 Q_OBJECT
12 Q_OBJECT
13 public:
13 public:
14 Bar(QString category, QGraphicsItem *parent=0);
14 Bar(QString category, QGraphicsItem *parent = 0);
15
15
16 public:
16 public:
17 void mousePressEvent(QGraphicsSceneMouseEvent *event);
17 void mousePressEvent(QGraphicsSceneMouseEvent *event);
18 void hoverEnterEvent(QGraphicsSceneHoverEvent *event);
18 void hoverEnterEvent(QGraphicsSceneHoverEvent *event);
19 void hoverLeaveEvent(QGraphicsSceneHoverEvent *event);
19 void hoverLeaveEvent(QGraphicsSceneHoverEvent *event);
20
20
21 Q_SIGNALS:
21 Q_SIGNALS:
22 void clicked(QString category);
22 void clicked(QString category);
23 void rightClicked(QString category);
23 void rightClicked(QString category);
24 void hoverEntered(QPoint pos);
24 void hoverEntered(QPoint pos);
25 void hoverLeaved();
25 void hoverLeaved();
26
26
27 private:
27 private:
28 QString mCategory;
28 QString mCategory;
29 };
29 };
30
30
31 QTCOMMERCIALCHART_END_NAMESPACE
31 QTCOMMERCIALCHART_END_NAMESPACE
32
32
33 #endif // BAR_H
33 #endif // BAR_H
@@ -1,217 +1,215
1 #include "barchartitem_p.h"
1 #include "barchartitem_p.h"
2 #include "bar_p.h"
2 #include "bar_p.h"
3 #include "barvalue_p.h"
3 #include "barvalue_p.h"
4 #include "qbarset.h"
4 #include "qbarset.h"
5 #include "qbarseries.h"
5 #include "qbarseries.h"
6 #include "qchart.h"
6 #include "qchart.h"
7 #include "qchartaxis.h"
7 #include "qchartaxis.h"
8 #include "qchartaxiscategories.h"
8 #include "qchartaxiscategories.h"
9 #include "chartpresenter_p.h"
9 #include "chartpresenter_p.h"
10 #include "chartanimator_p.h"
10 #include "chartanimator_p.h"
11 #include "chartdataset_p.h"
11 #include "chartdataset_p.h"
12 #include <QDebug>
12 #include <QDebug>
13 #include <QToolTip>
13 #include <QToolTip>
14
14
15 QTCOMMERCIALCHART_BEGIN_NAMESPACE
15 QTCOMMERCIALCHART_BEGIN_NAMESPACE
16
16
17 BarChartItem::BarChartItem(QBarSeries *series, ChartPresenter *presenter) :
17 BarChartItem::BarChartItem(QBarSeries *series, ChartPresenter *presenter) :
18 ChartItem(presenter),
18 ChartItem(presenter),
19 mLayoutSet(false),
19 mLayoutSet(false),
20 mSeries(series)
20 mSeries(series)
21 {
21 {
22 connect(series,SIGNAL(showToolTip(QPoint,QString)),this,SLOT(showToolTip(QPoint,QString)));
22 connect(series, SIGNAL(showToolTip(QPoint,QString)), this, SLOT(showToolTip(QPoint,QString)));
23 connect(series, SIGNAL(updatedBars()), this, SLOT(handleLayoutChanged()));
23 connect(series, SIGNAL(updatedBars()), this, SLOT(handleLayoutChanged()));
24 //TODO: connect(series,SIGNAL("position or size has changed"), this, SLOT(handleLayoutChanged()));
24 //TODO: connect(series,SIGNAL("position or size has changed"), this, SLOT(handleLayoutChanged()));
25 connect(series, SIGNAL(restructuredBar(int)), this, SLOT(handleModelChanged(int)));
25 connect(series, SIGNAL(restructuredBar(int)), this, SLOT(handleModelChanged(int)));
26 setZValue(ChartPresenter::BarSeriesZValue);
26 setZValue(ChartPresenter::BarSeriesZValue);
27 dataChanged();
27 dataChanged();
28 }
28 }
29
29
30 BarChartItem::~BarChartItem()
30 BarChartItem::~BarChartItem()
31 {
31 {
32 disconnect(this,SLOT(showToolTip(QPoint,QString)));
32 disconnect(this,SLOT(showToolTip(QPoint,QString)));
33 }
33 }
34
34
35 void BarChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
35 void BarChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
36 {
36 {
37 if (!mLayoutSet) {
37 if (!mLayoutSet) {
38 qDebug() << "BarChartItem::paint called without layout set. Aborting.";
38 qDebug() << "BarChartItem::paint called without layout set. Aborting.";
39 return;
39 return;
40 }
40 }
41 foreach(QGraphicsItem* i, childItems()) {
41
42 foreach(QGraphicsItem* i, childItems())
42 i->paint(painter,option,widget);
43 i->paint(painter,option,widget);
43 }
44 }
44 }
45
45
46 QRectF BarChartItem::boundingRect() const
46 QRectF BarChartItem::boundingRect() const
47 {
47 {
48 return m_rect;
48 return m_rect;
49 }
49 }
50
50
51 void BarChartItem::dataChanged()
51 void BarChartItem::dataChanged()
52 {
52 {
53 // 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?
54 // Delete old bars
54 // Delete old bars
55 foreach (QGraphicsItem* item, childItems()) {
55 foreach (QGraphicsItem *item, childItems())
56 delete item;
56 delete item;
57 }
58
57
59 mBars.clear();
58 mBars.clear();
60 mFloatingValues.clear();
59 mFloatingValues.clear();
61 mLayout.clear();
60 mLayout.clear();
62
61
63 // Create new graphic items for bars
62 // Create new graphic items for bars
64 for (int c=0; c<mSeries->categoryCount(); c++) {
63 for (int c = 0; c < mSeries->categoryCount(); c++) {
65 QString category = mSeries->categoryName(c);
64 QString category = mSeries->categoryName(c);
66 for (int s=0; s<mSeries->barsetCount(); s++) {
65 for (int s = 0; s < mSeries->barsetCount(); s++) {
67 QBarSet *set = mSeries->barsetAt(s);
66 QBarSet *set = mSeries->barsetAt(s);
68 Bar *bar = new Bar(category,this);
67 Bar *bar = new Bar(category,this);
69 childItems().append(bar);
68 childItems().append(bar);
70 mBars.append(bar);
69 mBars.append(bar);
71 connect(bar,SIGNAL(clicked(QString)),set,SIGNAL(clicked(QString)));
70 connect(bar, SIGNAL(clicked(QString)), set, SIGNAL(clicked(QString)));
72 connect(bar,SIGNAL(rightClicked(QString)),set,SIGNAL(rightClicked(QString)));
71 connect(bar, SIGNAL(rightClicked(QString)), set, SIGNAL(rightClicked(QString)));
73 connect(bar,SIGNAL(hoverEntered(QPoint)),set,SLOT(barHoverEnterEvent(QPoint)));
72 connect(bar, SIGNAL(hoverEntered(QPoint)), set, SLOT(barHoverEnterEvent(QPoint)));
74 connect(bar,SIGNAL(hoverLeaved()),set,SLOT(barHoverLeaveEvent()));
73 connect(bar, SIGNAL(hoverLeaved()), set, SLOT(barHoverLeaveEvent()));
75 mLayout.append(QRectF(0,0,0,0));
74 mLayout.append(QRectF(0, 0, 0, 0));
76 }
75 }
77 }
76 }
78
77
79 // Create floating values
78 // Create floating values
80 for (int category=0; category<mSeries->categoryCount(); category++) {
79 for (int category = 0; category < mSeries->categoryCount(); category++) {
81 for (int s=0; s<mSeries->barsetCount(); s++) {
80 for (int s = 0; s < mSeries->barsetCount(); s++) {
82 QBarSet *set = mSeries->barsetAt(s);
81 QBarSet *set = mSeries->barsetAt(s);
83 BarValue *value = new BarValue(*set, this);
82 BarValue *value = new BarValue(*set, this);
84 childItems().append(value);
83 childItems().append(value);
85 mFloatingValues.append(value);
84 mFloatingValues.append(value);
86 connect(set,SIGNAL(toggleFloatingValues()),value,SLOT(toggleVisible()));
85 connect(set, SIGNAL(toggleFloatingValues()), value, SLOT(toggleVisible()));
87 }
86 }
88 }
87 }
89 }
88 }
90 QVector<QRectF> BarChartItem::calculateLayout()
89 QVector<QRectF> BarChartItem::calculateLayout()
91 {
90 {
92 QVector<QRectF> layout;
91 QVector<QRectF> layout;
93
92
94 // Use temporary qreals for accurancy (we might get some compiler warnings... :)
93 // Use temporary qreals for accurancy (we might get some compiler warnings... :)
95 qreal categoryCount = mSeries->categoryCount();
94 qreal categoryCount = mSeries->categoryCount();
96 qreal setCount = mSeries->barsetCount();
95 qreal setCount = mSeries->barsetCount();
97
96
98 qreal width = geometry().width();
97 qreal width = geometry().width();
99 qreal height = geometry().height();
98 qreal height = geometry().height();
100
99
101 qreal max = mSeries->max();
100 qreal max = mSeries->max();
102
101
103 // Domain:
102 // Domain:
104 if (mDomainMaxY > max) {
103 if (mDomainMaxY > max) {
105 max = mDomainMaxY;
104 max = mDomainMaxY;
106 }
105 }
107
106
108 qreal scale = (height/max);
107 qreal scale = (height / max);
109 qreal categoryWidth = width/categoryCount;
108 qreal categoryWidth = width / categoryCount;
110 qreal barWidth = categoryWidth / (setCount+1);
109 qreal barWidth = categoryWidth / (setCount+1);
111
110
112 int itemIndex(0);
111 int itemIndex(0);
113 for (int category=0; category < categoryCount; category++) {
112 for (int category = 0; category < categoryCount; category++) {
114 qreal xPos = categoryWidth * category + barWidth/2;
113 qreal xPos = categoryWidth * category + barWidth / 2;
115 qreal yPos = height;
114 qreal yPos = height;
116 for (int set = 0; set < setCount; set++) {
115 for (int set = 0; set < setCount; set++) {
117 qreal barHeight = mSeries->valueAt(set,category) * scale;
116 qreal barHeight = mSeries->valueAt(set, category) * scale;
118 Bar* bar = mBars.at(itemIndex);
117 Bar* bar = mBars.at(itemIndex);
119
118
120 QRectF rect(xPos,yPos-barHeight,barWidth,barHeight);
119 QRectF rect(xPos, yPos - barHeight, barWidth, barHeight);
121 layout.append(rect);
120 layout.append(rect);
122 bar->setPen(mSeries->barsetAt(set)->pen());
121 bar->setPen(mSeries->barsetAt(set)->pen());
123 bar->setBrush(mSeries->barsetAt(set)->brush());
122 bar->setBrush(mSeries->barsetAt(set)->brush());
124 itemIndex++;
123 itemIndex++;
125 xPos += barWidth;
124 xPos += barWidth;
126 }
125 }
127 }
126 }
128
127
129 // Position floating values
128 // Position floating values
130 itemIndex = 0;
129 itemIndex = 0;
131 for (int category=0; category < mSeries->categoryCount(); category++) {
130 for (int category = 0; category < mSeries->categoryCount(); category++) {
132 qreal xPos = categoryWidth * category + barWidth;
131 qreal xPos = categoryWidth * category + barWidth;
133 qreal yPos = height;
132 qreal yPos = height;
134 for (int set=0; set < mSeries->barsetCount(); set++) {
133 for (int set=0; set < mSeries->barsetCount(); set++) {
135 qreal barHeight = mSeries->valueAt(set,category) * scale;
134 qreal barHeight = mSeries->valueAt(set, category) * scale;
136 BarValue* value = mFloatingValues.at(itemIndex);
135 BarValue* value = mFloatingValues.at(itemIndex);
137
136
138 QBarSet* barSet = mSeries->barsetAt(set);
137 QBarSet* barSet = mSeries->barsetAt(set);
139 value->resize(100,50); // TODO: proper layout for this.
138 value->resize(100, 50); // TODO: proper layout for this.
140 value->setPos(xPos, yPos-barHeight/2);
139 value->setPos(xPos, yPos-barHeight / 2);
141 value->setPen(barSet->floatingValuePen());
140 value->setPen(barSet->floatingValuePen());
142
141
143 if (mSeries->valueAt(set,category) != 0) {
142 if (mSeries->valueAt(set,category) != 0) {
144 value->setValueString(QString::number(mSeries->valueAt(set,category)));
143 value->setValueString(QString::number(mSeries->valueAt(set, category)));
145 } else {
144 } else {
146 value->setValueString(QString(""));
145 value->setValueString(QString(""));
147 }
146 }
148
147
149 itemIndex++;
148 itemIndex++;
150 xPos += barWidth;
149 xPos += barWidth;
151 }
150 }
152 }
151 }
153
152
154 return layout;
153 return layout;
155 }
154 }
156
155
157 void BarChartItem::applyLayout(const QVector<QRectF> &layout)
156 void BarChartItem::applyLayout(const QVector<QRectF> &layout)
158 {
157 {
159 if (animator())
158 if (animator())
160 animator()->updateLayout(this, mLayout, layout);
159 animator()->updateLayout(this, mLayout, layout);
161 else
160 else
162 setLayout(layout);
161 setLayout(layout);
163 }
162 }
164
163
165 void BarChartItem::setLayout(const QVector<QRectF> &layout)
164 void BarChartItem::setLayout(const QVector<QRectF> &layout)
166 {
165 {
167 mLayout = layout;
166 mLayout = layout;
168
167
169 for (int i=0; i<mBars.count(); i++) {
168 for (int i=0; i < mBars.count(); i++)
170 mBars.at(i)->setRect(layout.at(i));
169 mBars.at(i)->setRect(layout.at(i));
171 }
172
170
173 update();
171 update();
174 }
172 }
175
173
176 //handlers
174 //handlers
177
175
178 void BarChartItem::handleModelChanged(int index)
176 void BarChartItem::handleModelChanged(int index)
179 {
177 {
180 Q_UNUSED(index)
178 Q_UNUSED(index)
181 dataChanged();
179 dataChanged();
182 }
180 }
183
181
184 void BarChartItem::handleDomainChanged(qreal minX, qreal maxX, qreal minY, qreal maxY)
182 void BarChartItem::handleDomainChanged(qreal minX, qreal maxX, qreal minY, qreal maxY)
185 {
183 {
186 mDomainMinX = minX;
184 mDomainMinX = minX;
187 mDomainMaxX = maxX;
185 mDomainMaxX = maxX;
188 mDomainMinY = minY;
186 mDomainMinY = minY;
189 mDomainMaxY = maxY;
187 mDomainMaxY = maxY;
190 handleLayoutChanged();
188 handleLayoutChanged();
191 }
189 }
192
190
193 void BarChartItem::handleGeometryChanged(const QRectF& rect)
191 void BarChartItem::handleGeometryChanged(const QRectF &rect)
194 {
192 {
195 m_rect=rect;
193 m_rect = rect;
196 handleLayoutChanged();
194 handleLayoutChanged();
197 mLayoutSet = true;
195 mLayoutSet = true;
198 setPos(rect.topLeft());
196 setPos(rect.topLeft());
199 }
197 }
200
198
201 void BarChartItem::handleLayoutChanged()
199 void BarChartItem::handleLayoutChanged()
202 {
200 {
203 QVector<QRectF> layout = calculateLayout();
201 QVector<QRectF> layout = calculateLayout();
204 applyLayout(layout);
202 applyLayout(layout);
205 update();
203 update();
206 }
204 }
207
205
208
206
209 void BarChartItem::showToolTip(QPoint pos, QString tip)
207 void BarChartItem::showToolTip(QPoint pos, QString tip)
210 {
208 {
211 // TODO: cool tooltip instead of default
209 // TODO: cool tooltip instead of default
212 QToolTip::showText(pos,tip);
210 QToolTip::showText(pos, tip);
213 }
211 }
214
212
215 #include "moc_barchartitem_p.cpp"
213 #include "moc_barchartitem_p.cpp"
216
214
217 QTCOMMERCIALCHART_END_NAMESPACE
215 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,75 +1,75
1 #ifndef BARCHARTITEM_H
1 #ifndef BARCHARTITEM_H
2 #define BARCHARTITEM_H
2 #define BARCHARTITEM_H
3
3
4 #include "chartitem_p.h"
4 #include "chartitem_p.h"
5 #include "qbarseries.h"
5 #include "qbarseries.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 BarValue;
13 class BarValue;
14 class QChartAxisCategories;
14 class QChartAxisCategories;
15 class QChart;
15 class QChart;
16
16
17 //typedef QVector<QRectF> BarLayout;
17 //typedef QVector<QRectF> BarLayout;
18
18
19 class BarChartItem : public ChartItem
19 class BarChartItem : public ChartItem
20 {
20 {
21 Q_OBJECT
21 Q_OBJECT
22 public:
22 public:
23 BarChartItem(QBarSeries *series, ChartPresenter *presenter);
23 BarChartItem(QBarSeries *series, ChartPresenter *presenter);
24 virtual ~BarChartItem();
24 virtual ~BarChartItem();
25
25
26 // Common implemantation of different presenters. Not to be instantiated.
26 // Common implemantation of different presenters. Not to be instantiated.
27 // TODO: combine this with BarPresenter and derive other presenters from it?
27 // TODO: combine this with BarPresenter and derive other presenters from it?
28
28
29 public:
29 public:
30 // From QGraphicsItem
30 // From QGraphicsItem
31 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
31 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
32 QRectF boundingRect() const;
32 QRectF boundingRect() const;
33
33
34 // TODO: Consider the domain for layoutChanged. May be use case, may not be. If it is, then the derived classes need to implement it
34 // TODO: Consider the domain for layoutChanged. May be use case, may not be. If it is, then the derived classes need to implement it
35 virtual void dataChanged(); // data of series has changed -> need to recalculate bar sizes
35 virtual void dataChanged(); // data of series has changed -> need to recalculate bar sizes
36 private slots:
36 private slots:
37
37
38 public:
38 public:
39 virtual QVector<QRectF> calculateLayout();
39 virtual QVector<QRectF> calculateLayout();
40 void applyLayout(const QVector<QRectF> &layout);
40 void applyLayout(const QVector<QRectF> &layout);
41 void setLayout(const QVector<QRectF> &layout);
41 void setLayout(const QVector<QRectF> &layout);
42 void updateLayout(const QVector<QRectF> &layout);
42 void updateLayout(const QVector<QRectF> &layout);
43
43
44 QRectF geometry() const { return m_rect;}
44 QRectF geometry() const { return m_rect;}
45
45
46 public slots:
46 public slots:
47 void handleModelChanged(int index);
47 void handleModelChanged(int index);
48 void handleDomainChanged(qreal minX, qreal maxX, qreal minY, qreal maxY);
48 void handleDomainChanged(qreal minX, qreal maxX, qreal minY, qreal maxY);
49 void handleGeometryChanged(const QRectF& size);
49 void handleGeometryChanged(const QRectF &size);
50 void handleLayoutChanged();
50 void handleLayoutChanged();
51
51
52 // Internal slots
52 // Internal slots
53 void showToolTip(QPoint pos, QString tip); // shows tooltip (if enabled)
53 void showToolTip(QPoint pos, QString tip); // shows tooltip (if enabled)
54
54
55 protected:
55 protected:
56
56
57 // TODO: consider these.
57 // TODO: consider these.
58 qreal mDomainMinX;
58 qreal mDomainMinX;
59 qreal mDomainMaxX;
59 qreal mDomainMaxX;
60 qreal mDomainMinY;
60 qreal mDomainMinY;
61 qreal mDomainMaxY;
61 qreal mDomainMaxY;
62
62
63 QRectF m_rect;
63 QRectF m_rect;
64 bool mLayoutSet; // True, if component has been laid out.
64 bool mLayoutSet; // True, if component has been laid out.
65 QVector<QRectF> mLayout;
65 QVector<QRectF> mLayout;
66
66
67 // Not owned.
67 // Not owned.
68 QBarSeries* mSeries;
68 QBarSeries *mSeries;
69 QList<Bar*> mBars;
69 QList<Bar *> mBars;
70 QList<BarValue*> mFloatingValues;
70 QList<BarValue *> mFloatingValues;
71 };
71 };
72
72
73 QTCOMMERCIALCHART_END_NAMESPACE
73 QTCOMMERCIALCHART_END_NAMESPACE
74
74
75 #endif // BARCHARTITEM_H
75 #endif // BARCHARTITEM_H
@@ -1,174 +1,169
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 "qbarset.h"
5 #include "qbarset.h"
6
6
7 QTCOMMERCIALCHART_BEGIN_NAMESPACE
7 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8
8
9 BarChartModel::BarChartModel(QStringList categories, QObject *parent) :
9 BarChartModel::BarChartModel(QStringList categories, QObject *parent) :
10 QObject(parent)
10 QObject(parent)
11 ,mCategory(categories)
11 ,mCategory(categories)
12 {
12 {
13 }
13 }
14
14
15 QStringList BarChartModel::category()
15 QStringList BarChartModel::category()
16 {
16 {
17 return mCategory;
17 return mCategory;
18 }
18 }
19
19
20 void BarChartModel::addBarSet(QBarSet *set)
20 void BarChartModel::addBarSet(QBarSet *set)
21 {
21 {
22 mDataModel.append(set);
22 mDataModel.append(set);
23 }
23 }
24
24
25 void BarChartModel::removeBarSet(QBarSet *set)
25 void BarChartModel::removeBarSet(QBarSet *set)
26 {
26 {
27 if (mDataModel.contains(set)) {
27 if (mDataModel.contains(set)) {
28 mDataModel.removeOne(set);
28 mDataModel.removeOne(set);
29 }
29 }
30 }
30 }
31
31
32 void BarChartModel::insertBarSet(int i, QBarSet *set)
32 void BarChartModel::insertBarSet(int i, QBarSet *set)
33 {
33 {
34 mDataModel.insert(i, set);
34 mDataModel.insert(i, set);
35 }
35 }
36
36
37 void BarChartModel::insertCategory(int i, QString category)
37 void BarChartModel::insertCategory(int i, QString category)
38 {
38 {
39 mCategory.insert(i, category);
39 mCategory.insert(i, category);
40 }
40 }
41
41
42 void BarChartModel::removeCategory(int i)
42 void BarChartModel::removeCategory(int i)
43 {
43 {
44 mCategory.removeAt(i);
44 mCategory.removeAt(i);
45 }
45 }
46
46
47 QBarSet* BarChartModel::setAt(int index)
47 QBarSet* BarChartModel::setAt(int index)
48 {
48 {
49 return mDataModel.at(index);
49 return mDataModel.at(index);
50 }
50 }
51
51
52 QList<QBarSet*> BarChartModel::barSets()
52 QList<QBarSet*> BarChartModel::barSets()
53 {
53 {
54 return mDataModel;
54 return mDataModel;
55 }
55 }
56
56
57 int BarChartModel::barsetCount()
57 int BarChartModel::barsetCount()
58 {
58 {
59 return mDataModel.count();
59 return mDataModel.count();
60 }
60 }
61
61
62 int BarChartModel::categoryCount()
62 int BarChartModel::categoryCount()
63 {
63 {
64 return mCategory.count();
64 return mCategory.count();
65 }
65 }
66
66
67 qreal BarChartModel::min()
67 qreal BarChartModel::min()
68 {
68 {
69 Q_ASSERT(mDataModel.count() > 0);
69 Q_ASSERT(mDataModel.count() > 0);
70 // TODO: make min and max members and update them when data changes.
70 // TODO: make min and max members and update them when data changes.
71 // This is slower since they are checked every time, even if data is same since previous call.
71 // This is slower since they are checked every time, even if data is same since previous call.
72 qreal min = INT_MAX;
72 qreal min = INT_MAX;
73
73
74 for (int i=0; i <mDataModel.count(); i++) {
74 for (int i = 0; i < mDataModel.count(); i++) {
75 int itemCount = mDataModel.at(i)->count();
75 int itemCount = mDataModel.at(i)->count();
76 for (int j=0; j<itemCount; j++) {
76 for (int j = 0; j < itemCount; j++) {
77 qreal temp = mDataModel.at(i)->valueAt(j);
77 qreal temp = mDataModel.at(i)->valueAt(j);
78 if (temp < min) {
78 if (temp < min)
79 min = temp;
79 min = temp;
80 }
81 }
80 }
82 }
81 }
83 return min;
82 return min;
84 }
83 }
85
84
86 qreal BarChartModel::max()
85 qreal BarChartModel::max()
87 {
86 {
88 Q_ASSERT(mDataModel.count() > 0);
87 Q_ASSERT(mDataModel.count() > 0);
89
88
90 // TODO: make min and max members and update them when data changes.
89 // TODO: make min and max members and update them when data changes.
91 // This is slower since they are checked every time, even if data is same since previous call.
90 // This is slower since they are checked every time, even if data is same since previous call.
92 qreal max = INT_MIN;
91 qreal max = INT_MIN;
93
92
94 for (int i=0; i <mDataModel.count(); i++) {
93 for (int i = 0; i < mDataModel.count(); i++) {
95 int itemCount = mDataModel.at(i)->count();
94 int itemCount = mDataModel.at(i)->count();
96 for (int j=0; j<itemCount; j++) {
95 for (int j = 0; j < itemCount; j++) {
97 qreal temp = mDataModel.at(i)->valueAt(j);
96 qreal temp = mDataModel.at(i)->valueAt(j);
98 if (temp > max) {
97 if (temp > max)
99 max = temp;
98 max = temp;
100 }
101 }
99 }
102 }
100 }
103
101
104 return max;
102 return max;
105 }
103 }
106
104
107 qreal BarChartModel::valueAt(int set, int category)
105 qreal BarChartModel::valueAt(int set, int category)
108 {
106 {
109 if ((set < 0) || (set >= mDataModel.count())) {
107 if ((set < 0) || (set >= mDataModel.count())) {
110 // No set, no value.
108 // No set, no value.
111 return 0;
109 return 0;
112 } else if ((category < 0) || (category >= mDataModel.at(set)->count())) {
110 } else if ((category < 0) || (category >= mDataModel.at(set)->count())) {
113 // No category, no value.
111 // No category, no value.
114 return 0;
112 return 0;
115 }
113 }
116
114
117 return mDataModel.at(set)->valueAt(category);
115 return mDataModel.at(set)->valueAt(category);
118 }
116 }
119
117
120 qreal BarChartModel::percentageAt(int set, int category)
118 qreal BarChartModel::percentageAt(int set, int category)
121 {
119 {
122 if ((set < 0) || (set >= mDataModel.count())) {
120 if ((set < 0) || (set >= mDataModel.count())) {
123 // No set, no value.
121 // No set, no value.
124 return 0;
122 return 0;
125 } else if ((category < 0) || (category >= mDataModel.at(set)->count())) {
123 } else if ((category < 0) || (category >= mDataModel.at(set)->count())) {
126 // No category, no value.
124 // No category, no value.
127 return 0;
125 return 0;
128 }
126 }
129
127
130 qreal value = mDataModel.at(set)->valueAt(category);
128 qreal value = mDataModel.at(set)->valueAt(category);
131 qreal total = categorySum(category);
129 qreal total = categorySum(category);
132 if (0 == total) {
130 if (0 == total)
133 return 100.0;
131 return 100.0;
134 }
135
132
136 return value / total;
133 return value / total;
137 }
134 }
138
135
139
136
140 qreal BarChartModel::categorySum(int category)
137 qreal BarChartModel::categorySum(int category)
141 {
138 {
142 qreal sum(0);
139 qreal sum(0);
143 int count = mDataModel.count(); // Count sets
140 int count = mDataModel.count(); // Count sets
144
141
145 for (int set = 0; set < count; set++) {
142 for (int set = 0; set < count; set++) {
146 if (category < mDataModel.at(set)->count()) {
143 if (category < mDataModel.at(set)->count())
147 sum += mDataModel.at(set)->valueAt(category);
144 sum += mDataModel.at(set)->valueAt(category);
148 }
149 }
145 }
150 return sum;
146 return sum;
151 }
147 }
152
148
153 qreal BarChartModel::maxCategorySum()
149 qreal BarChartModel::maxCategorySum()
154 {
150 {
155 qreal max = INT_MIN;
151 qreal max = INT_MIN;
156 int count = categoryCount();
152 int count = categoryCount();
157
153
158 for (int col=0; col<count; col++) {
154 for (int col = 0; col < count; col++) {
159 qreal sum = categorySum(col);
155 qreal sum = categorySum(col);
160 if (sum > max) {
156 if (sum > max)
161 max = sum;
157 max = sum;
162 }
163 }
158 }
164 return max;
159 return max;
165 }
160 }
166
161
167 QString BarChartModel::categoryName(int category)
162 QString BarChartModel::categoryName(int category)
168 {
163 {
169 return mCategory.at(category);
164 return mCategory.at(category);
170 }
165 }
171
166
172 #include "moc_barchartmodel_p.cpp"
167 #include "moc_barchartmodel_p.cpp"
173
168
174 QTCOMMERCIALCHART_END_NAMESPACE
169 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,60 +1,58
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 <QStringList>
5 #include <QStringList>
6 #include "qchartglobal.h"
6 #include "qchartglobal.h"
7 #include <qseries.h>
7 #include <qseries.h>
8
8
9 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9 QTCOMMERCIALCHART_BEGIN_NAMESPACE
10
10
11 // Model for bar chart. Internal class.
11 // Model for bar chart. Internal class.
12 // TODO: Implement as QAbstractItemModel?
12 // TODO: Implement as QAbstractItemModel?
13
13
14 class QBarSet;
14 class QBarSet;
15
15
16 class BarChartModel : public QObject //, public QAbstractItemModel
16 class BarChartModel : public QObject //, public QAbstractItemModel
17 {
17 {
18 Q_OBJECT
18 Q_OBJECT
19 public:
19 public:
20 explicit BarChartModel(QStringList categories, QObject *parent = 0);
20 explicit BarChartModel(QStringList categories, QObject *parent = 0);
21
21
22 QStringList category();
22 QStringList category();
23 void addBarSet(QBarSet *set);
23 void addBarSet(QBarSet *set);
24 void removeBarSet(QBarSet *set);
24 void removeBarSet(QBarSet *set);
25 void insertBarSet(int i, QBarSet *set);
25 void insertBarSet(int i, QBarSet *set);
26 void insertCategory(int i, QString category);
26 void insertCategory(int i, QString category);
27 void removeCategory(int i);
27 void removeCategory(int i);
28 QBarSet *setAt(int index);
28 QBarSet *setAt(int index);
29 QList<QBarSet*> barSets();
29 QList<QBarSet *> barSets();
30
30
31 int barsetCount(); // Number of sets in model
31 int barsetCount(); // Number of sets in model
32 int categoryCount(); // Number of categories
32 int categoryCount(); // Number of categories
33
33
34 qreal max(); // Maximum value of all sets
34 qreal max(); // Maximum value of all sets
35 qreal min(); // Minimum value of all sets
35 qreal min(); // Minimum value of all sets
36 qreal valueAt(int set, int category);
36 qreal valueAt(int set, int category);
37 qreal percentageAt(int set, int category);
37 qreal percentageAt(int set, int category);
38
38
39 qreal categorySum(int category);
39 qreal categorySum(int category);
40 qreal maxCategorySum(); // returns maximum sum of sets in all categories.
40 qreal maxCategorySum(); // returns maximum sum of sets in all categories.
41
41
42 QString categoryName(int category);
42 QString categoryName(int category);
43
43
44 signals:
44 signals:
45 void modelUpdated();
45 void modelUpdated();
46
46
47 public slots:
47 public slots:
48
48
49 private:
49 private:
50
50
51 QList<QBarSet*> mDataModel;
51 QList<QBarSet *> mDataModel;
52 QStringList mCategory;
52 QStringList mCategory;
53
54 int mCurrentSet;
53 int mCurrentSet;
55
56 };
54 };
57
55
58 QTCOMMERCIALCHART_END_NAMESPACE
56 QTCOMMERCIALCHART_END_NAMESPACE
59
57
60 #endif // BARCHARTMODEL_H
58 #endif // BARCHARTMODEL_H
@@ -1,73 +1,73
1 #include "barvalue_p.h"
1 #include "barvalue_p.h"
2 #include <QPainter>
2 #include <QPainter>
3 #include <QPen>
3 #include <QPen>
4
4
5 QTCOMMERCIALCHART_BEGIN_NAMESPACE
5 QTCOMMERCIALCHART_BEGIN_NAMESPACE
6
6
7 BarValue::BarValue(QBarSet &set, QGraphicsItem *parent)
7 BarValue::BarValue(QBarSet &set, QGraphicsItem *parent)
8 : QGraphicsObject(parent),
8 : QGraphicsObject(parent),
9 mBarSet(set),
9 mBarSet(set),
10 mXpos(0),
10 mXpos(0),
11 mYpos(0),
11 mYpos(0),
12 mWidth(0),
12 mWidth(0),
13 mHeight(0)
13 mHeight(0)
14 {
14 {
15 setVisible(false);
15 setVisible(false);
16 }
16 }
17
17
18 void BarValue::setValueString(QString str)
18 void BarValue::setValueString(QString str)
19 {
19 {
20 mValueString = str;
20 mValueString = str;
21 }
21 }
22
22
23 QString BarValue::valueString()
23 QString BarValue::valueString()
24 {
24 {
25 return mValueString;
25 return mValueString;
26 }
26 }
27
27
28 void BarValue::setPen(const QPen pen)
28 void BarValue::setPen(const QPen pen)
29 {
29 {
30 mPen = pen;
30 mPen = pen;
31 }
31 }
32
32
33 QPen BarValue::pen() const
33 QPen BarValue::pen() const
34 {
34 {
35 return mPen;
35 return mPen;
36 }
36 }
37
37
38 void BarValue::resize(qreal w, qreal h)
38 void BarValue::resize(qreal w, qreal h)
39 {
39 {
40 mWidth = w;
40 mWidth = w;
41 mHeight = h;
41 mHeight = h;
42 }
42 }
43
43
44 void BarValue::setPos(qreal x, qreal y)
44 void BarValue::setPos(qreal x, qreal y)
45 {
45 {
46 mXpos = x;
46 mXpos = x;
47 mYpos = y;
47 mYpos = y;
48 }
48 }
49
49
50 void BarValue::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
50 void BarValue::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
51 {
51 {
52 Q_UNUSED(option)
52 Q_UNUSED(option)
53 Q_UNUSED(widget)
53 Q_UNUSED(widget)
54
54
55 if (isVisible()) {
55 if (isVisible()) {
56 painter->setPen(mPen);
56 painter->setPen(mPen);
57 painter->drawText(boundingRect(),mValueString);
57 painter->drawText(boundingRect(), mValueString);
58 }
58 }
59 }
59 }
60
60
61 QRectF BarValue::boundingRect() const
61 QRectF BarValue::boundingRect() const
62 {
62 {
63 QRectF r(mXpos, mYpos, mWidth, mHeight);
63 QRectF r(mXpos, mYpos, mWidth, mHeight);
64 return r;
64 return r;
65 }
65 }
66
66
67 void BarValue::toggleVisible()
67 void BarValue::toggleVisible()
68 {
68 {
69 setVisible(!isVisible());
69 setVisible(!isVisible());
70 }
70 }
71
71
72 #include "moc_barvalue_p.cpp"
72 #include "moc_barvalue_p.cpp"
73 QTCOMMERCIALCHART_END_NAMESPACE
73 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,50 +1,50
1 #ifndef BARVALUE_P_H
1 #ifndef BARVALUE_P_H
2 #define BARVALUE_P_H
2 #define BARVALUE_P_H
3
3
4 #include "qchartglobal.h"
4 #include "qchartglobal.h"
5 #include <QGraphicsObject>
5 #include <QGraphicsObject>
6 #include <QPen>
6 #include <QPen>
7
7
8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9
9
10 class QBarSet;
10 class QBarSet;
11
11
12 // Visual class for floating bar values
12 // Visual class for floating bar values
13 // By default these are not visible.
13 // By default these are not visible.
14 class BarValue : public QGraphicsObject
14 class BarValue : public QGraphicsObject
15 {
15 {
16 Q_OBJECT
16 Q_OBJECT
17 public:
17 public:
18 BarValue(QBarSet &set, QGraphicsItem *parent = 0);
18 BarValue(QBarSet &set, QGraphicsItem *parent = 0);
19
19
20 void setValueString(QString str);
20 void setValueString(QString str);
21 QString valueString();
21 QString valueString();
22
22
23 void setPen(const QPen pen);
23 void setPen(const QPen pen);
24 QPen pen() const;
24 QPen pen() const;
25
25
26 void resize(qreal w, qreal h);
26 void resize(qreal w, qreal h);
27 void setPos(qreal x, qreal y);
27 void setPos(qreal x, qreal y);
28
28
29 // From QGraphicsItem
29 // From QGraphicsItem
30 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
30 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
31 QRectF boundingRect() const;
31 QRectF boundingRect() const;
32
32
33 public Q_SLOTS:
33 public Q_SLOTS:
34 void toggleVisible();
34 void toggleVisible();
35
35
36 private:
36 private:
37
37
38 QBarSet& mBarSet;
38 QBarSet &mBarSet;
39 QPen mPen;
39 QPen mPen;
40 QString mValueString;
40 QString mValueString;
41
41
42 qreal mXpos;
42 qreal mXpos;
43 qreal mYpos;
43 qreal mYpos;
44 qreal mWidth;
44 qreal mWidth;
45 qreal mHeight;
45 qreal mHeight;
46 };
46 };
47
47
48 QTCOMMERCIALCHART_END_NAMESPACE
48 QTCOMMERCIALCHART_END_NAMESPACE
49
49
50 #endif // BARVALUE_P_H
50 #endif // BARVALUE_P_H
@@ -1,81 +1,81
1 #include "percentbarchartitem_p.h"
1 #include "percentbarchartitem_p.h"
2 #include "bar_p.h"
2 #include "bar_p.h"
3 #include "barvalue_p.h"
3 #include "barvalue_p.h"
4 #include "qbarset.h"
4 #include "qbarset.h"
5 #include <QDebug>
5 #include <QDebug>
6
6
7 QTCOMMERCIALCHART_BEGIN_NAMESPACE
7 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8
8
9 PercentBarChartItem::PercentBarChartItem(QBarSeries *series, ChartPresenter* presenter) :
9 PercentBarChartItem::PercentBarChartItem(QBarSeries *series, ChartPresenter *presenter) :
10 BarChartItem(series, presenter)
10 BarChartItem(series, presenter)
11 {
11 {
12 }
12 }
13
13
14 QVector<QRectF> PercentBarChartItem::calculateLayout()
14 QVector<QRectF> PercentBarChartItem::calculateLayout()
15 {
15 {
16 QVector<QRectF> layout;
16 QVector<QRectF> layout;
17
17
18 // Use temporary qreals for accurancy (we might get some compiler warnings... :)
18 // Use temporary qreals for accurancy (we might get some compiler warnings... :)
19 qreal width = geometry().width();
19 qreal width = geometry().width();
20 qreal height = geometry().height();
20 qreal height = geometry().height();
21
21
22 qreal categoryCount = mSeries->categoryCount();
22 qreal categoryCount = mSeries->categoryCount();
23 qreal barWidth = width / (mSeries->categoryCount() * 2);
23 qreal barWidth = width / (mSeries->categoryCount() * 2);
24 qreal xStep = width/categoryCount;
24 qreal xStep = width / categoryCount;
25 qreal xPos = xStep/2 - barWidth / 2;
25 qreal xPos = xStep / 2 - barWidth / 2;
26
26
27 int itemIndex(0);
27 int itemIndex(0);
28 for (int category = 0; category < categoryCount ; category++) {
28 for (int category = 0; category < categoryCount; category++) {
29 qreal colSum = mSeries->categorySum(category);
29 qreal colSum = mSeries->categorySum(category);
30 qreal scale = (height / colSum);
30 qreal scale = (height / colSum);
31 qreal yPos = height;
31 qreal yPos = height;
32 for (int set=0; set < mSeries->barsetCount(); set++) {
32 for (int set=0; set < mSeries->barsetCount(); set++) {
33 qreal barHeight = mSeries->valueAt(set, category) * scale;
33 qreal barHeight = mSeries->valueAt(set, category) * scale;
34 Bar* bar = mBars.at(itemIndex);
34 Bar* bar = mBars.at(itemIndex);
35 bar->setPen(mSeries->barsetAt(set)->pen());
35 bar->setPen(mSeries->barsetAt(set)->pen());
36 bar->setBrush(mSeries->barsetAt(set)->brush());
36 bar->setBrush(mSeries->barsetAt(set)->brush());
37 QRectF rect(xPos, yPos-barHeight,barWidth, barHeight);
37 QRectF rect(xPos, yPos-barHeight, barWidth, barHeight);
38 layout.append(rect);
38 layout.append(rect);
39 itemIndex++;
39 itemIndex++;
40 yPos -= barHeight;
40 yPos -= barHeight;
41 }
41 }
42 xPos += xStep;
42 xPos += xStep;
43 }
43 }
44
44
45 // Position floating values
45 // Position floating values
46 itemIndex = 0;
46 itemIndex = 0;
47 xPos = (width/categoryCount);
47 xPos = (width/categoryCount);
48 for (int category=0; category < mSeries->categoryCount(); category++) {
48 for (int category=0; category < mSeries->categoryCount(); category++) {
49 qreal yPos = height;
49 qreal yPos = height;
50 qreal colSum = mSeries->categorySum(category);
50 qreal colSum = mSeries->categorySum(category);
51 qreal scale = (height / colSum);
51 qreal scale = (height / colSum);
52 for (int set=0; set < mSeries->barsetCount(); set++) {
52 for (int set=0; set < mSeries->barsetCount(); set++) {
53 qreal barHeight = mSeries->valueAt(set,category) * scale;
53 qreal barHeight = mSeries->valueAt(set,category) * scale;
54 BarValue* value = mFloatingValues.at(itemIndex);
54 BarValue* value = mFloatingValues.at(itemIndex);
55
55
56 QBarSet* barSet = mSeries->barsetAt(set);
56 QBarSet* barSet = mSeries->barsetAt(set);
57 value->resize(100,50); // TODO: proper layout for this.
57 value->resize(100, 50); // TODO: proper layout for this.
58 value->setPos(xPos, yPos-barHeight/2);
58 value->setPos(xPos, yPos-barHeight / 2);
59 value->setPen(barSet->floatingValuePen());
59 value->setPen(barSet->floatingValuePen());
60
60
61 if (mSeries->valueAt(set,category) != 0) {
61 if (mSeries->valueAt(set,category) != 0) {
62 int p = mSeries->percentageAt(set,category) * 100;
62 int p = mSeries->percentageAt(set,category) * 100;
63 QString vString(QString::number(p));
63 QString vString(QString::number(p));
64 vString.truncate(3);
64 vString.truncate(3);
65 vString.append("%");
65 vString.append("%");
66 value->setValueString(vString);
66 value->setValueString(vString);
67 } else {
67 } else {
68 value->setValueString(QString(""));
68 value->setValueString(QString(""));
69 }
69 }
70
70
71 itemIndex++;
71 itemIndex++;
72 yPos -= barHeight;
72 yPos -= barHeight;
73 }
73 }
74 xPos += xStep;
74 xPos += xStep;
75 }
75 }
76 return layout;
76 return layout;
77 }
77 }
78
78
79 #include "moc_percentbarchartitem_p.cpp"
79 #include "moc_percentbarchartitem_p.cpp"
80
80
81 QTCOMMERCIALCHART_END_NAMESPACE
81 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,391 +1,388
1 #include <QDebug>
1 #include <QDebug>
2 #include "qbarseries.h"
2 #include "qbarseries.h"
3 #include "qbarset.h"
3 #include "qbarset.h"
4 #include "barchartmodel_p.h"
4 #include "barchartmodel_p.h"
5
5
6 QTCOMMERCIALCHART_BEGIN_NAMESPACE
6 QTCOMMERCIALCHART_BEGIN_NAMESPACE
7
7
8 /*!
8 /*!
9 \class QBarSeries
9 \class QBarSeries
10 \brief part of QtCommercial chart API.
10 \brief part of QtCommercial chart API.
11
11
12 QBarSeries represents a series of data shown as bars. One QBarSeries can contain multible
12 QBarSeries represents a series of data shown as bars. One QBarSeries can contain multible
13 QBarSet data sets. QBarSeries groups the data from sets to categories, which are defined
13 QBarSet data sets. QBarSeries groups the data from sets to categories, which are defined
14 by QStringList.
14 by QStringList.
15
15
16 \mainclass
16 \mainclass
17
17
18 \sa QBarSet, QStackedBarSeries, QPercentBarSeries
18 \sa QBarSet, QStackedBarSeries, QPercentBarSeries
19 */
19 */
20
20
21 /*!
21 /*!
22 \fn virtual QSeriesType QBarSeries::type() const
22 \fn virtual QSeriesType QBarSeries::type() const
23 \brief Returns type of series.
23 \brief Returns type of series.
24 \sa QSeries, QSeriesType
24 \sa QSeries, QSeriesType
25 */
25 */
26
26
27 /*!
27 /*!
28 \fn void QBarSeries::showToolTip(QPoint pos, QString tip)
28 \fn void QBarSeries::showToolTip(QPoint pos, QString tip)
29 \brief \internal \a pos \a tip
29 \brief \internal \a pos \a tip
30 */
30 */
31
31
32 /*!
32 /*!
33 Constructs empty QBarSeries. Parameter \a categories defines the categories for chart.
33 Constructs empty QBarSeries. Parameter \a categories defines the categories for chart.
34 QBarSeries is QObject which is a child of a \a parent.
34 QBarSeries is QObject which is a child of a \a parent.
35 */
35 */
36 QBarSeries::QBarSeries(QBarCategories categories, QObject *parent)
36 QBarSeries::QBarSeries(QBarCategories categories, QObject *parent)
37 : QSeries(parent)
37 : QSeries(parent)
38 ,mModel(new BarChartModel(categories, this))
38 ,mModel(new BarChartModel(categories, this))
39 {
39 {
40 m_model = NULL;
40 m_model = NULL;
41 m_mapCategories = -1;
41 m_mapCategories = -1;
42 m_mapBarBottom = -1;
42 m_mapBarBottom = -1;
43 m_mapBarTop = -1;
43 m_mapBarTop = -1;
44 m_mapFirst = 0;
44 m_mapFirst = 0;
45 m_mapCount = 0;
45 m_mapCount = 0;
46 m_mapOrientation = Qt::Vertical;
46 m_mapOrientation = Qt::Vertical;
47 }
47 }
48
48
49 /*!
49 /*!
50 Adds a set of bars to series. Takes ownership of \a set.
50 Adds a set of bars to series. Takes ownership of \a set.
51 Connects the clicked(QString) and rightClicked(QString) signals
51 Connects the clicked(QString) and rightClicked(QString) signals
52 of \a set to this series
52 of \a set to this series
53 */
53 */
54 void QBarSeries::addBarSet(QBarSet *set)
54 void QBarSeries::addBarSet(QBarSet *set)
55 {
55 {
56 mModel->addBarSet(set);
56 mModel->addBarSet(set);
57 connect(set,SIGNAL(clicked(QString)),this,SLOT(barsetClicked(QString)));
57 connect(set, SIGNAL(clicked(QString)), this, SLOT(barsetClicked(QString)));
58 connect(set,SIGNAL(rightClicked(QString)),this,SLOT(barsetRightClicked(QString)));
58 connect(set, SIGNAL(rightClicked(QString)), this, SLOT(barsetRightClicked(QString)));
59 connect(set, SIGNAL(valueChanged()), this, SLOT(barsetChanged()));
59 connect(set, SIGNAL(valueChanged()), this, SLOT(barsetChanged()));
60 emit updatedBars();
60 emit updatedBars();
61 }
61 }
62
62
63 /*!
63 /*!
64 Removes a set of bars from series. Releases ownership of \a set. Doesnt delete \a set.
64 Removes a set of bars from series. Releases ownership of \a set. Doesnt delete \a set.
65 Disconnects the clicked(QString) and rightClicked(QString) signals
65 Disconnects the clicked(QString) and rightClicked(QString) signals
66 of \a set from this series
66 of \a set from this series
67 */
67 */
68 void QBarSeries::removeBarSet(QBarSet *set)
68 void QBarSeries::removeBarSet(QBarSet *set)
69 {
69 {
70 disconnect(set,SIGNAL(clicked(QString)),this,SLOT(barsetClicked(QString)));
70 disconnect(set, SIGNAL(clicked(QString)), this, SLOT(barsetClicked(QString)));
71 disconnect(set,SIGNAL(rightClicked(QString)),this,SLOT(barsetRightClicked(QString)));
71 disconnect(set, SIGNAL(rightClicked(QString)), this, SLOT(barsetRightClicked(QString)));
72 mModel->removeBarSet(set);
72 mModel->removeBarSet(set);
73 emit updatedBars();
73 emit updatedBars();
74 }
74 }
75
75
76 void QBarSeries::insertBarSet(int i, QBarSet *set)
76 void QBarSeries::insertBarSet(int i, QBarSet *set)
77 {
77 {
78 mModel->insertBarSet(i, set);
78 mModel->insertBarSet(i, set);
79 // emit barsetChanged();
79 // emit barsetChanged();
80 }
80 }
81
81
82 void QBarSeries::insertCategory(int i, QString category)
82 void QBarSeries::insertCategory(int i, QString category)
83 {
83 {
84 mModel->insertCategory(i, category);
84 mModel->insertCategory(i, category);
85 }
85 }
86
86
87 void QBarSeries::removeCategory(int i)
87 void QBarSeries::removeCategory(int i)
88 {
88 {
89 mModel->removeCategory(i);
89 mModel->removeCategory(i);
90 }
90 }
91
91
92 /*!
92 /*!
93 Returns number of sets in series.
93 Returns number of sets in series.
94 */
94 */
95 int QBarSeries::barsetCount()
95 int QBarSeries::barsetCount()
96 {
96 {
97 // if(m_model)
97 // if(m_model)
98 // return m_mapBarTop - m_mapBarBottom;
98 // return m_mapBarTop - m_mapBarBottom;
99 // else
99 // else
100 return mModel->barsetCount();
100 return mModel->barsetCount();
101 }
101 }
102
102
103 /*!
103 /*!
104 Returns number of categories in series
104 Returns number of categories in series
105 */
105 */
106 int QBarSeries::categoryCount()
106 int QBarSeries::categoryCount()
107 {
107 {
108 return mModel->categoryCount();
108 return mModel->categoryCount();
109 }
109 }
110
110
111 /*!
111 /*!
112 Returns a list of sets in series. Keeps ownership of sets.
112 Returns a list of sets in series. Keeps ownership of sets.
113 */
113 */
114 QList<QBarSet*> QBarSeries::barSets()
114 QList<QBarSet*> QBarSeries::barSets()
115 {
115 {
116 return mModel->barSets();
116 return mModel->barSets();
117 }
117 }
118
118
119 /*!
119 /*!
120 \internal \a index
120 \internal \a index
121 */
121 */
122 QBarSet* QBarSeries::barsetAt(int index)
122 QBarSet* QBarSeries::barsetAt(int index)
123 {
123 {
124 return mModel->setAt(index);
124 return mModel->setAt(index);
125 }
125 }
126
126
127 /*!
127 /*!
128 \internal \a category
128 \internal \a category
129 */
129 */
130 QString QBarSeries::categoryName(int category)
130 QString QBarSeries::categoryName(int category)
131 {
131 {
132 return mModel->categoryName(category);
132 return mModel->categoryName(category);
133 }
133 }
134
134
135 /*!
135 /*!
136 Enables or disables tooltip depending on parameter \a enabled.
136 Enables or disables tooltip depending on parameter \a enabled.
137 Tooltip shows the name of set, when mouse is hovering on top of bar.
137 Tooltip shows the name of set, when mouse is hovering on top of bar.
138 Calling without parameter \a enabled, enables the tooltip
138 Calling without parameter \a enabled, enables the tooltip
139 */
139 */
140 void QBarSeries::setToolTipEnabled(bool enabled)
140 void QBarSeries::setToolTipEnabled(bool enabled)
141 {
141 {
142 // TODO: what if we add sets after call to this function? Those sets won't have tooltip enabled.
142 // TODO: what if we add sets after call to this function? Those sets won't have tooltip enabled.
143 if (enabled) {
143 if (enabled) {
144 for (int i=0; i<mModel->barsetCount(); i++) {
144 for (int i=0; i<mModel->barsetCount(); i++) {
145 QBarSet *set = mModel->setAt(i);
145 QBarSet *set = mModel->setAt(i);
146 connect(set,SIGNAL(showToolTip(QPoint,QString)),this,SIGNAL(showToolTip(QPoint,QString)));
146 connect(set, SIGNAL(showToolTip(QPoint,QString)), this, SIGNAL(showToolTip(QPoint,QString)));
147 }
147 }
148 } else {
148 } else {
149 for (int i=0; i<mModel->barsetCount(); i++) {
149 for (int i=0; i<mModel->barsetCount(); i++) {
150 QBarSet *set = mModel->setAt(i);
150 QBarSet *set = mModel->setAt(i);
151 disconnect(set,SIGNAL(showToolTip(QPoint,QString)),this,SIGNAL(showToolTip(QPoint,QString)));
151 disconnect(set, SIGNAL(showToolTip(QPoint,QString)), this, SIGNAL(showToolTip(QPoint,QString)));
152 }
152 }
153 }
153 }
154 }
154 }
155
155
156
156
157 /*!
157 /*!
158 \internal \a category
158 \internal \a category
159 */
159 */
160 void QBarSeries::barsetClicked(QString category)
160 void QBarSeries::barsetClicked(QString category)
161 {
161 {
162 emit clicked(qobject_cast<QBarSet*>(sender()), category);
162 emit clicked(qobject_cast<QBarSet*>(sender()), category);
163 }
163 }
164
164
165 /*!
165 /*!
166 \internal \a category
166 \internal \a category
167 */
167 */
168 void QBarSeries::barsetRightClicked(QString category)
168 void QBarSeries::barsetRightClicked(QString category)
169 {
169 {
170 emit rightClicked(qobject_cast<QBarSet*>(sender()), category);
170 emit rightClicked(qobject_cast<QBarSet*>(sender()), category);
171 }
171 }
172
172
173
173
174 /*!
174 /*!
175 \internal
175 \internal
176 */
176 */
177 qreal QBarSeries::min()
177 qreal QBarSeries::min()
178 {
178 {
179 return mModel->min();
179 return mModel->min();
180 }
180 }
181
181
182 /*!
182 /*!
183 \internal
183 \internal
184 */
184 */
185 qreal QBarSeries::max()
185 qreal QBarSeries::max()
186 {
186 {
187 return mModel->max();
187 return mModel->max();
188 }
188 }
189
189
190 /*!
190 /*!
191 \internal \a set \a category
191 \internal \a set \a category
192 */
192 */
193 qreal QBarSeries::valueAt(int set, int category)
193 qreal QBarSeries::valueAt(int set, int category)
194 {
194 {
195 return mModel->valueAt(set,category);
195 return mModel->valueAt(set, category);
196 }
196 }
197
197
198 /*!
198 /*!
199 \internal \a set \a category
199 \internal \a set \a category
200 */
200 */
201 qreal QBarSeries::percentageAt(int set, int category)
201 qreal QBarSeries::percentageAt(int set, int category)
202 {
202 {
203 return mModel->percentageAt(set,category);
203 return mModel->percentageAt(set, category);
204 }
204 }
205
205
206 /*!
206 /*!
207 \internal \a category
207 \internal \a category
208 */
208 */
209 qreal QBarSeries::categorySum(int category)
209 qreal QBarSeries::categorySum(int category)
210 {
210 {
211 return mModel->categorySum(category);
211 return mModel->categorySum(category);
212 }
212 }
213
213
214 /*!
214 /*!
215 \internal
215 \internal
216 */
216 */
217 qreal QBarSeries::maxCategorySum()
217 qreal QBarSeries::maxCategorySum()
218 {
218 {
219 return mModel->maxCategorySum();
219 return mModel->maxCategorySum();
220 }
220 }
221
221
222 /*!
222 /*!
223 \internal
223 \internal
224 */
224 */
225 BarChartModel& QBarSeries::model()
225 BarChartModel& QBarSeries::model()
226 {
226 {
227 return *mModel;
227 return *mModel;
228 }
228 }
229
229
230 bool QBarSeries::setModel(QAbstractItemModel* model)
230 bool QBarSeries::setModel(QAbstractItemModel *model)
231 {
231 {
232 // disconnect signals from old model
232 // disconnect signals from old model
233 if(m_model)
233 if(m_model)
234 {
234 {
235 disconnect(m_model, 0, this, 0);
235 disconnect(m_model, 0, this, 0);
236 m_mapCategories = -1;
236 m_mapCategories = -1;
237 m_mapBarBottom = -1;
237 m_mapBarBottom = -1;
238 m_mapBarTop = -1;
238 m_mapBarTop = -1;
239 m_mapFirst = 0;
239 m_mapFirst = 0;
240 m_mapCount = 0;
240 m_mapCount = 0;
241 m_mapOrientation = Qt::Vertical;
241 m_mapOrientation = Qt::Vertical;
242 }
242 }
243
243
244 // set new model
244 // set new model
245 if(model)
245 if(model)
246 {
246 {
247 m_model = model;
247 m_model = model;
248 return true;
248 return true;
249 }
249 }
250 else
250 else
251 {
251 {
252 m_model = NULL;
252 m_model = NULL;
253 return false;
253 return false;
254 }
254 }
255 }
255 }
256
256
257 // TODO
257 // TODO
258 void QBarSeries::setModelMapping(int categories, int bottomBoundry, int topBoundry, Qt::Orientation orientation)
258 void QBarSeries::setModelMapping(int categories, int bottomBoundry, int topBoundry, Qt::Orientation orientation)
259 {
259 {
260 if (m_model == NULL)
260 if (m_model == NULL)
261 return;
261 return;
262
262 m_mapCategories = categories;
263 m_mapCategories = categories;
263 m_mapBarBottom = bottomBoundry;
264 m_mapBarBottom = bottomBoundry;
264 m_mapBarTop = topBoundry;
265 m_mapBarTop = topBoundry;
265 // m_mapFirst = 1;
266 // m_mapFirst = 1;
266 m_mapOrientation = orientation;
267 m_mapOrientation = orientation;
267
268
268 // connect the signals
269 // connect the signals
269 if (m_mapOrientation == Qt::Vertical)
270 if (m_mapOrientation == Qt::Vertical) {
270 {
271 m_mapCount = m_model->rowCount() - m_mapFirst;
271 m_mapCount = m_model->rowCount() - m_mapFirst;
272 connect(m_model,SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(modelUpdated(QModelIndex, QModelIndex)));
272 connect(m_model,SIGNAL(dataChanged(QModelIndex,QModelIndex)),
273 connect(m_model,SIGNAL(rowsInserted(QModelIndex, int, int)), this, SLOT(modelDataAdded(QModelIndex,int,int)));
273 this, SLOT(modelUpdated(QModelIndex, QModelIndex)));
274 connect(m_model, SIGNAL(rowsRemoved(QModelIndex, int, int)), this, SLOT(modelDataRemoved(QModelIndex,int,int)));
274 connect(m_model,SIGNAL(rowsInserted(QModelIndex, int, int)),
275 }
275 this, SLOT(modelDataAdded(QModelIndex,int,int)));
276 else
276 connect(m_model, SIGNAL(rowsRemoved(QModelIndex, int, int)),
277 {
277 this, SLOT(modelDataRemoved(QModelIndex,int,int)));
278 } else {
278 m_mapCount = m_model->columnCount() - m_mapFirst;
279 m_mapCount = m_model->columnCount() - m_mapFirst;
279 connect(m_model,SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(modelUpdated(QModelIndex, QModelIndex)));
280 connect(m_model,SIGNAL(dataChanged(QModelIndex,QModelIndex)),
280 connect(m_model,SIGNAL(columnsInserted(QModelIndex, int, int)), this, SLOT(modelDataAdded(QModelIndex,int,int)));
281 this, SLOT(modelUpdated(QModelIndex, QModelIndex)));
281 connect(m_model, SIGNAL(columnsRemoved(QModelIndex, int, int)), this, SLOT(modelDataRemoved(QModelIndex,int,int)));
282 connect(m_model,SIGNAL(columnsInserted(QModelIndex, int, int)),
283 this, SLOT(modelDataAdded(QModelIndex,int,int)));
284 connect(m_model, SIGNAL(columnsRemoved(QModelIndex, int, int)),
285 this, SLOT(modelDataRemoved(QModelIndex,int,int)));
282 }
286 }
283
287
284
288
285 // create the initial bars
289 // create the initial bars
286 delete mModel;
290 delete mModel;
287 if (m_mapOrientation == Qt::Vertical)
291 if (m_mapOrientation == Qt::Vertical) {
288 {
289 QStringList categories;
292 QStringList categories;
290 for (int k = m_mapFirst; k < m_mapFirst + m_mapCount; k++)
293 for (int k = m_mapFirst; k < m_mapFirst + m_mapCount; k++)
291 categories << m_model->data(m_model->index(k, m_mapCategories), Qt::DisplayRole).toString();
294 categories << m_model->data(m_model->index(k, m_mapCategories), Qt::DisplayRole).toString();
292 mModel = new BarChartModel(categories, this);
295 mModel = new BarChartModel(categories, this);
293
296
294 for (int i = m_mapBarBottom; i <= m_mapBarTop; i++)
297 for (int i = m_mapBarBottom; i <= m_mapBarTop; i++) {
295 {
296 QBarSet* barSet = new QBarSet(QString("Column: %1").arg(i + 1));
298 QBarSet* barSet = new QBarSet(QString("Column: %1").arg(i + 1));
297 for(int m = m_mapFirst; m < m_mapFirst + m_mapCount; m++)
299 for(int m = m_mapFirst; m < m_mapFirst + m_mapCount; m++)
298 *barSet << m_model->data(m_model->index(m, i), Qt::DisplayRole).toDouble();
300 *barSet << m_model->data(m_model->index(m, i), Qt::DisplayRole).toDouble();
299 addBarSet(barSet);
301 addBarSet(barSet);
300 }
302 }
301 }
303 } else {
302 else
303 {
304 QStringList categories;
304 QStringList categories;
305 for (int k = m_mapFirst; k < m_mapFirst + m_mapCount; k++)
305 for (int k = m_mapFirst; k < m_mapFirst + m_mapCount; k++)
306 categories << m_model->data(m_model->index(m_mapCategories, k), Qt::DisplayRole).toString();
306 categories << m_model->data(m_model->index(m_mapCategories, k), Qt::DisplayRole).toString();
307 mModel = new BarChartModel(categories, this);
307 mModel = new BarChartModel(categories, this);
308
308
309 for (int i = m_mapBarBottom; i <= m_mapBarTop; i++)
309 for (int i = m_mapBarBottom; i <= m_mapBarTop; i++) {
310 {
311 QBarSet* barSet = new QBarSet(QString("Row: %1").arg(i + 1));
310 QBarSet* barSet = new QBarSet(QString("Row: %1").arg(i + 1));
312 for(int m = m_mapFirst; m < m_mapFirst + m_mapCount; m++)
311 for(int m = m_mapFirst; m < m_mapFirst + m_mapCount; m++)
313 *barSet << m_model->data(m_model->index(i, m), Qt::DisplayRole).toDouble();
312 *barSet << m_model->data(m_model->index(i, m), Qt::DisplayRole).toDouble();
314 addBarSet(barSet);
313 addBarSet(barSet);
315 }
314 }
316 }
315 }
317 }
316 }
318
317
319 void QBarSeries::setModelMappingShift(int first, int count)
318 void QBarSeries::setModelMappingShift(int first, int count)
320 {
319 {
321 m_mapFirst = first;
320 m_mapFirst = first;
322 m_mapCount = count;
321 m_mapCount = count;
323 }
322 }
324
323
325 void QBarSeries::modelUpdated(QModelIndex topLeft, QModelIndex bottomRight)
324 void QBarSeries::modelUpdated(QModelIndex topLeft, QModelIndex bottomRight)
326 {
325 {
327 Q_UNUSED(bottomRight)
326 Q_UNUSED(bottomRight)
328
327
329 if (m_mapOrientation == Qt::Vertical)
328 if (m_mapOrientation == Qt::Vertical)
330 {
329 {
331 // model update is relevant to BarSeries if the change was made to the part of the model that was mapped to BarSeries
330 // model update is relevant to BarSeries if the change was made to the part of the model that was mapped to BarSeries
332 if (topLeft.column() >= m_mapBarBottom && topLeft.column() <= m_mapBarTop && topLeft.row() >= m_mapFirst && topLeft.row() < m_mapFirst + m_mapCount)
331 if (topLeft.column() >= m_mapBarBottom && topLeft.column() <= m_mapBarTop && topLeft.row() >= m_mapFirst && topLeft.row() < m_mapFirst + m_mapCount)
333 barsetAt(topLeft.column() - m_mapBarBottom)->setValue(topLeft.row() - m_mapFirst, m_model->data(topLeft, Qt::DisplayRole).toDouble());
332 barsetAt(topLeft.column() - m_mapBarBottom)->setValue(topLeft.row() - m_mapFirst, m_model->data(topLeft, Qt::DisplayRole).toDouble());
334 }
333 }
335 else
334 else
336 {
335 {
337 // model update is relevant to BarSeries if the change was made to the part of the model that was mapped to BarSeries
336 // model update is relevant to BarSeries if the change was made to the part of the model that was mapped to BarSeries
338 if (topLeft.row() >= m_mapBarBottom && topLeft.row() <= m_mapBarTop && topLeft.column() >= m_mapFirst && topLeft.column() < m_mapFirst + m_mapCount)
337 if (topLeft.row() >= m_mapBarBottom && topLeft.row() <= m_mapBarTop && topLeft.column() >= m_mapFirst && topLeft.column() < m_mapFirst + m_mapCount)
339 barsetAt(topLeft.row() - m_mapBarBottom)->setValue(topLeft.column() - m_mapFirst, m_model->data(topLeft, Qt::DisplayRole).toDouble());
338 barsetAt(topLeft.row() - m_mapBarBottom)->setValue(topLeft.column() - m_mapFirst, m_model->data(topLeft, Qt::DisplayRole).toDouble());
340 }
339 }
341 }
340 }
342
341
343 void QBarSeries::modelDataAdded(QModelIndex /*parent*/, int start, int /*end*/)
342 void QBarSeries::modelDataAdded(QModelIndex /*parent*/, int start, int /*end*/)
344 {
343 {
345 if (m_mapOrientation == Qt::Vertical)
344 if (m_mapOrientation == Qt::Vertical) {
346 {
347 insertCategory(start - m_mapFirst, QString("Row: %1").arg(start + 1));
345 insertCategory(start - m_mapFirst, QString("Row: %1").arg(start + 1));
348 for (int i = 0; i <= m_mapBarTop - m_mapBarBottom; i++)
346 for (int i = 0; i <= m_mapBarTop - m_mapBarBottom; i++) {
349 {
350 barsetAt(i)->insertValue(start - m_mapFirst, m_model->data(m_model->index(start, i), Qt::DisplayRole).toDouble());
347 barsetAt(i)->insertValue(start - m_mapFirst, m_model->data(m_model->index(start, i), Qt::DisplayRole).toDouble());
351 }
348 }
352 }
349 } else {
353 else
354 {
355 insertCategory(start - m_mapFirst, QString("Column: %1").arg(start + 1));
350 insertCategory(start - m_mapFirst, QString("Column: %1").arg(start + 1));
356 for (int i = 0; i <= m_mapBarTop - m_mapBarBottom; i++)
351 for (int i = 0; i <= m_mapBarTop - m_mapBarBottom; i++) {
357 {
358 barsetAt(i)->insertValue(start - m_mapFirst, m_model->data(m_model->index(i, start), Qt::DisplayRole).toDouble());
352 barsetAt(i)->insertValue(start - m_mapFirst, m_model->data(m_model->index(i, start), Qt::DisplayRole).toDouble());
359 }
353 }
360 }
354 }
361 emit restructuredBar(1);
355 emit restructuredBar(1);
362 }
356 }
363
357
364 void QBarSeries::modelDataRemoved(QModelIndex /*parent*/, int start, int /*end*/)
358 void QBarSeries::modelDataRemoved(QModelIndex parent, int start, int end)
365 {
359 {
360 Q_UNUSED(parent)
361 Q_UNUSED(end)
362
366 removeCategory(start - m_mapFirst);
363 removeCategory(start - m_mapFirst);
367 for (int i = 0; i <= m_mapBarTop - m_mapBarBottom; i++)
364 for (int i = 0; i <= m_mapBarTop - m_mapBarBottom; i++)
368 {
365 {
369 barsetAt(i)->removeValue(start - m_mapFirst);
366 barsetAt(i)->removeValue(start - m_mapFirst);
370 }
367 }
371 emit restructuredBar(1);
368 emit restructuredBar(1);
372 }
369 }
373
370
374 void QBarSeries::barsetChanged()
371 void QBarSeries::barsetChanged()
375 {
372 {
376 emit updatedBars();
373 emit updatedBars();
377 }
374 }
378
375
379 QBarCategories QBarSeries::categories() const
376 QBarCategories QBarSeries::categories() const
380 {
377 {
381 QBarCategories categories;
378 QBarCategories categories;
382 int count = mModel->categoryCount();
379 int count = mModel->categoryCount();
383 for (int i=1; i<=count; i++) {
380 for (int i=1; i <= count; i++) {
384 categories.insert(i, mModel->categoryName(i-1));
381 categories.insert(i, mModel->categoryName(i - 1));
385 }
382 }
386 return categories;
383 return categories;
387 }
384 }
388
385
389 #include "moc_qbarseries.cpp"
386 #include "moc_qbarseries.cpp"
390
387
391 QTCOMMERCIALCHART_END_NAMESPACE
388 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,98 +1,97
1 #ifndef BARSERIES_H
1 #ifndef BARSERIES_H
2 #define BARSERIES_H
2 #define BARSERIES_H
3
3
4 #include <qseries.h>
4 #include <qseries.h>
5 #include <QStringList>
5 #include <QStringList>
6
6
7 QTCOMMERCIALCHART_BEGIN_NAMESPACE
7 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8
8
9 typedef QStringList QBarCategories;
9 typedef QStringList QBarCategories;
10
10
11 class QBarSet;
11 class QBarSet;
12 class BarChartModel;
12 class BarChartModel;
13 class BarCategory;
13 class BarCategory;
14
14
15 // Container for series
15 // Container for series
16 class QTCOMMERCIALCHART_EXPORT QBarSeries : public QSeries
16 class QTCOMMERCIALCHART_EXPORT QBarSeries : public QSeries
17 {
17 {
18 Q_OBJECT
18 Q_OBJECT
19 public:
19 public:
20 QBarSeries(QStringList categories, QObject* parent=0);
20 QBarSeries(QStringList categories, QObject *parent = 0);
21
21
22 virtual QSeriesType type() const { return QSeries::SeriesTypeBar; }
22 virtual QSeriesType type() const { return QSeries::SeriesTypeBar; }
23
23
24 void addBarSet(QBarSet *set); // Takes ownership of set
24 void addBarSet(QBarSet *set); // Takes ownership of set
25 void removeBarSet(QBarSet *set); // Releases ownership, doesn't delete set
25 void removeBarSet(QBarSet *set); // Releases ownership, doesn't delete set
26 void insertBarSet(int i, QBarSet *set);
26 void insertBarSet(int i, QBarSet *set);
27 void insertCategory(int i, QString category);
27 void insertCategory(int i, QString category);
28 void removeCategory(int i);
28 void removeCategory(int i);
29 int barsetCount();
29 int barsetCount();
30 int categoryCount();
30 int categoryCount();
31 QList<QBarSet*> barSets();
31 QList<QBarSet*> barSets();
32 QBarCategories categories() const;
32 QBarCategories categories() const;
33
33
34
34 bool setModel(QAbstractItemModel *model);
35 bool setModel(QAbstractItemModel* model);
35 QAbstractItemModel *modelExt() { return m_model; }
36 QAbstractItemModel* modelExt() {return m_model;}
37 void setModelMapping(int categories, int bottomBoundry, int topBoundry, Qt::Orientation orientation = Qt::Vertical);
36 void setModelMapping(int categories, int bottomBoundry, int topBoundry, Qt::Orientation orientation = Qt::Vertical);
38 void setModelMappingShift(int first, int count);
37 void setModelMappingShift(int first, int count);
39
38
40 public:
39 public:
41 // TODO: Functions below this are not part of api and will be moved
40 // TODO: Functions below this are not part of api and will be moved
42 // to private implementation, when we start using it
41 // to private implementation, when we start using it
43 // TODO: TO PIMPL --->
42 // TODO: TO PIMPL --->
44 QBarSet* barsetAt(int index);
43 QBarSet* barsetAt(int index);
45 QString categoryName(int category);
44 QString categoryName(int category);
46 qreal min();
45 qreal min();
47 qreal max();
46 qreal max();
48 qreal valueAt(int set, int category);
47 qreal valueAt(int set, int category);
49 qreal percentageAt(int set, int category);
48 qreal percentageAt(int set, int category);
50 qreal categorySum(int category);
49 qreal categorySum(int category);
51 qreal maxCategorySum();
50 qreal maxCategorySum();
52 BarChartModel& model();
51 BarChartModel& model();
53 // <--- TO PIMPL
52 // <--- TO PIMPL
54
53
55 signals:
54 signals:
56 //void changed(int index);
55 //void changed(int index);
57 void clicked(QBarSet* barset, QString category); // Up to user of api, what to do with these signals
56 void clicked(QBarSet *barset, QString category); // Up to user of api, what to do with these signals
58 void rightClicked(QBarSet* barset, QString category);
57 void rightClicked(QBarSet *barset, QString category);
59
58
60 //
59 //
61 void updatedBars();
60 void updatedBars();
62 void restructuredBar(int);
61 void restructuredBar(int);
63
62
64 // TODO: internal signals, these to private implementation.
63 // TODO: internal signals, these to private implementation.
65 // TODO: TO PIMPL --->
64 // TODO: TO PIMPL --->
66 void showToolTip(QPoint pos, QString tip);
65 void showToolTip(QPoint pos, QString tip);
67 // <--- TO PIMPL
66 // <--- TO PIMPL
68
67
69 public Q_SLOTS:
68 public Q_SLOTS:
70 void setToolTipEnabled(bool enabled=true); // enables tooltips
69 void setToolTipEnabled(bool enabled = true); // enables tooltips
71
70
72 // TODO: TO PIMPL --->
71 // TODO: TO PIMPL --->
73 void barsetClicked(QString category);
72 void barsetClicked(QString category);
74 void barsetRightClicked(QString category);
73 void barsetRightClicked(QString category);
75 // <--- TO PIMPL
74 // <--- TO PIMPL
76
75
77 private Q_SLOTS:
76 private Q_SLOTS:
78 // slots for updating bars when data in model changes
77 // slots for updating bars when data in model changes
79 void modelUpdated(QModelIndex topLeft, QModelIndex bottomRight);
78 void modelUpdated(QModelIndex topLeft, QModelIndex bottomRight);
80 void modelDataAdded(QModelIndex parent, int start, int end);
79 void modelDataAdded(QModelIndex parent, int start, int end);
81 void modelDataRemoved(QModelIndex parent, int start, int end);
80 void modelDataRemoved(QModelIndex parent, int start, int end);
82 void barsetChanged();
81 void barsetChanged();
83
82
84 protected:
83 protected:
85 BarChartModel* mModel;
84 BarChartModel *mModel;
86
85
87 // QAbstractItemModel* m_model;
86 // QAbstractItemModel* m_model;
88 int m_mapCategories;
87 int m_mapCategories;
89 int m_mapBarBottom;
88 int m_mapBarBottom;
90 int m_mapBarTop;
89 int m_mapBarTop;
91 int m_mapFirst;
90 int m_mapFirst;
92 int m_mapCount;
91 int m_mapCount;
93 Qt::Orientation m_mapOrientation;
92 Qt::Orientation m_mapOrientation;
94 };
93 };
95
94
96 QTCOMMERCIALCHART_END_NAMESPACE
95 QTCOMMERCIALCHART_END_NAMESPACE
97
96
98 #endif // BARSERIES_H
97 #endif // BARSERIES_H
@@ -1,205 +1,206
1 #include "qbarset.h"
1 #include "qbarset.h"
2 #include <QDebug>
2 #include <QDebug>
3 #include <QToolTip>
3 #include <QToolTip>
4
4
5 QTCOMMERCIALCHART_BEGIN_NAMESPACE
5 QTCOMMERCIALCHART_BEGIN_NAMESPACE
6
6
7 /*!
7 /*!
8 \class QBarSet
8 \class QBarSet
9 \brief part of QtCommercial chart API.
9 \brief part of QtCommercial chart API.
10
10
11 QBarSet represents one set of bars. Set of bars contains one data value for each category.
11 QBarSet represents one set of bars. Set of bars contains one data value for each category.
12 First value of set is assumed to belong to first category, second to second category and so on.
12 First value of set is assumed to belong to first category, second to second category and so on.
13 If set has fewer values than there are categories, then the missing values are assumed to be
13 If set has fewer values than there are categories, then the missing values are assumed to be
14 at the end of set. For missing values in middle of a set, numerical value of zero is used.
14 at the end of set. For missing values in middle of a set, numerical value of zero is used.
15
15
16 \mainclass
16 \mainclass
17
17
18 \sa QBarSeries, QStackedBarSeries, QPercentBarSeries
18 \sa QBarSeries, QStackedBarSeries, QPercentBarSeries
19 */
19 */
20
20
21 /*!
21 /*!
22 \fn void QBarSet::clicked(QString category)
22 \fn void QBarSet::clicked(QString category)
23 \brief signals that set has been clicked
23 \brief signals that set has been clicked
24 Parameter \a category describes on which category was clicked
24 Parameter \a category describes on which category was clicked
25 */
25 */
26
26
27 /*!
27 /*!
28 \fn void QBarSet::rightClicked(QString category)
28 \fn void QBarSet::rightClicked(QString category)
29 \brief signals that set has been clicked with right mouse button
29 \brief signals that set has been clicked with right mouse button
30 Parameter \a category describes on which category was clicked
30 Parameter \a category describes on which category was clicked
31 */
31 */
32
32
33 /*!
33 /*!
34 \fn void QBarSet::hoverEnter(QPoint pos)
34 \fn void QBarSet::hoverEnter(QPoint pos)
35 \brief signals that mouse has entered over the set at position \a pos.
35 \brief signals that mouse has entered over the set at position \a pos.
36 */
36 */
37
37
38 /*!
38 /*!
39 \fn void QBarSet::hoverLeave()
39 \fn void QBarSet::hoverLeave()
40 \brief signals that mouse has left from the set.
40 \brief signals that mouse has left from the set.
41 */
41 */
42
42
43 /*!
43 /*!
44 \fn void QBarSet::toggleFloatingValues()
44 \fn void QBarSet::toggleFloatingValues()
45 \brief \internal
45 \brief \internal
46 */
46 */
47
47
48 /*!
48 /*!
49 \fn void QBarSet::showToolTip(QPoint pos, QString tip)
49 \fn void QBarSet::showToolTip(QPoint pos, QString tip)
50 \brief \internal \a pos \a tip
50 \brief \internal \a pos \a tip
51 */
51 */
52
52
53
53
54 /*!
54 /*!
55 Constructs QBarSet with a name of \a name and with parent of \a parent
55 Constructs QBarSet with a name of \a name and with parent of \a parent
56 */
56 */
57 QBarSet::QBarSet(QString name, QObject *parent)
57 QBarSet::QBarSet(QString name, QObject *parent)
58 : QObject(parent)
58 : QObject(parent)
59 ,mName(name)
59 ,mName(name)
60 {
60 {
61 }
61 }
62
62
63 /*!
63 /*!
64 Sets new \a name for set.
64 Sets new \a name for set.
65 */
65 */
66 void QBarSet::setName(QString name)
66 void QBarSet::setName(QString name)
67 {
67 {
68 mName = name;
68 mName = name;
69 }
69 }
70
70
71 /*!
71 /*!
72 Returns name of the set.
72 Returns name of the set.
73 */
73 */
74 QString QBarSet::name()
74 QString QBarSet::name()
75 {
75 {
76 return mName;
76 return mName;
77 }
77 }
78
78
79 /*!
79 /*!
80 Appends new value \a value to the end of set.
80 Appends new value \a value to the end of set.
81 */
81 */
82 QBarSet& QBarSet::operator << (const qreal &value)
82 QBarSet& QBarSet::operator << (const qreal &value)
83 {
83 {
84 mValues.append(value);
84 mValues.append(value);
85 emit structureChanged();
85 emit structureChanged();
86 return *this;
86 return *this;
87 }
87 }
88
88
89 void QBarSet::insertValue(int i, qreal value)
89 void QBarSet::insertValue(int i, qreal value)
90 {
90 {
91 mValues.insert(i, value);
91 mValues.insert(i, value);
92 }
92 }
93
93
94 void QBarSet::removeValue(int i)
94 void QBarSet::removeValue(int i)
95 {
95 {
96 mValues.removeAt(i);
96 mValues.removeAt(i);
97 }
97 }
98
98
99 /*!
99 /*!
100 Returns count of values in set.
100 Returns count of values in set.
101 */
101 */
102 int QBarSet::count()
102 int QBarSet::count()
103 {
103 {
104 return mValues.count();
104 return mValues.count();
105 }
105 }
106
106
107 /*!
107 /*!
108 Returns value of set indexed by \a index
108 Returns value of set indexed by \a index
109 */
109 */
110 qreal QBarSet::valueAt(int index)
110 qreal QBarSet::valueAt(int index)
111 {
111 {
112 return mValues.at(index);
112 return mValues.at(index);
113 }
113 }
114
114
115 /*!
115 /*!
116 Sets a new value \a value to set, indexed by \a index
116 Sets a new value \a value to set, indexed by \a index
117 */
117 */
118 void QBarSet::setValue(int index, qreal value)
118 void QBarSet::setValue(int index, qreal value)
119 {
119 {
120 mValues.replace(index,value);
120 mValues.replace(index,value);
121 emit valueChanged();
121 emit valueChanged();
122 }
122 }
123
123
124 /*!
124 /*!
125 Returns total sum of all values in barset.
125 Returns total sum of all values in barset.
126 */
126 */
127 qreal QBarSet::total()
127 qreal QBarSet::total()
128 {
128 {
129 qreal total(0);
129 qreal total(0);
130 for (int i=0; i<mValues.count(); i++) {
130 for (int i=0; i < mValues.count(); i++) {
131 total += mValues.at(i);
131 total += mValues.at(i);
132 }
132 }
133 return total;
133 return total;
134 }
134 }
135
135
136 /*!
136 /*!
137 Sets pen for set. Bars of this set are drawn using \a pen
137 Sets pen for set. Bars of this set are drawn using \a pen
138 */
138 */
139 void QBarSet::setPen(const QPen pen)
139 void QBarSet::setPen(const QPen pen)
140 {
140 {
141 mPen = pen;
141 mPen = pen;
142 emit valueChanged();
142 emit valueChanged();
143 }
143 }
144
144
145 /*!
145 /*!
146 Returns pen of the set.
146 Returns pen of the set.
147 */
147 */
148 QPen QBarSet::pen() const
148 QPen QBarSet::pen() const
149 {
149 {
150 return mPen;
150 return mPen;
151 }
151 }
152
152
153 /*!
153 /*!
154 Sets brush for the set. Bars of this set are drawn using \a brush
154 Sets brush for the set. Bars of this set are drawn using \a brush
155 */
155 */
156 void QBarSet::setBrush(const QBrush brush)
156 void QBarSet::setBrush(const QBrush brush)
157 {
157 {
158 mBrush = brush;
158 mBrush = brush;
159 emit valueChanged();
159 emit valueChanged();
160 }
160 }
161
161
162 /*!
162 /*!
163 Returns brush of the set.
163 Returns brush of the set.
164 */
164 */
165 QBrush QBarSet::brush() const
165 QBrush QBarSet::brush() const
166 {
166 {
167 return mBrush;
167 return mBrush;
168 }
168 }
169
169
170 /*!
170 /*!
171 Sets the pen for floating values that are drawn on top of this set
171 Sets the pen for floating values that are drawn on top of this set
172 */
172 */
173 void QBarSet::setFloatingValuePen(const QPen pen)
173 void QBarSet::setFloatingValuePen(const QPen pen)
174 {
174 {
175 mFloatingValuePen = pen;
175 mFloatingValuePen = pen;
176 }
176 }
177
177
178 /*!
178 /*!
179 Returns the pen for floating values that are drawn on top of this set
179 Returns the pen for floating values that are drawn on top of this set
180 */
180 */
181 QPen QBarSet::floatingValuePen() const
181 QPen QBarSet::floatingValuePen() const
182 {
182 {
183 return mFloatingValuePen;
183 return mFloatingValuePen;
184 }
184 }
185
185
186 /*!
186 /*!
187 \internal \a pos
187 \internal \a pos
188 */
188 */
189 void QBarSet::barHoverEnterEvent(QPoint pos)
189 void QBarSet::barHoverEnterEvent(QPoint pos)
190 {
190 {
191 emit showToolTip(pos, mName);
191 emit showToolTip(pos, mName);
192 emit hoverEnter(pos);
192 emit hoverEnter(pos);
193 }
193 }
194
194
195 /*!
195 /*!
196 \internal
196 \internal
197 */
197 */
198 void QBarSet::barHoverLeaveEvent()
198 void QBarSet::barHoverLeaveEvent()
199 {
199 {
200 // Emit signal to user of charts
200 // Emit signal to user of charts
201 emit hoverLeave();
201 emit hoverLeave();
202 }
202 }
203
203
204 #include "moc_qbarset.cpp"
204 #include "moc_qbarset.cpp"
205
205 QTCOMMERCIALCHART_END_NAMESPACE
206 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,74 +1,74
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(QString name, QObject *parent = 0);
14 QBarSet(QString name, QObject *parent = 0);
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 void insertValue(int i, qreal value);
19 void insertValue(int i, qreal value);
20 void removeValue(int i);
20 void removeValue(int i);
21
21
22 // TODO: remove indices eventually. Use as internal?
22 // TODO: remove indices eventually. Use as internal?
23 int count(); // count of values in set
23 int count(); // count of values in set
24 qreal valueAt(int index); // for modifying individual values
24 qreal valueAt(int index); // for modifying individual values
25 void setValue(int index, qreal value); // setter for individual value
25 void setValue(int index, qreal value); // setter for individual value
26 qreal total(); // total values in the set
26 qreal total(); // total values in the set
27
27
28 // TODO:
28 // TODO:
29 //qreal value(QString category);
29 //qreal value(QString category);
30 //void setValue(QString category, qreal value);
30 //void setValue(QString category, qreal value);
31
31
32 void setPen(const QPen pen);
32 void setPen(const QPen pen);
33 QPen pen() const;
33 QPen pen() const;
34
34
35 void setBrush(const QBrush brush);
35 void setBrush(const QBrush brush);
36 QBrush brush() const;
36 QBrush brush() const;
37
37
38 void setFloatingValuePen(const QPen pen);
38 void setFloatingValuePen(const QPen pen);
39 QPen floatingValuePen() const;
39 QPen floatingValuePen() const;
40
40
41 Q_SIGNALS:
41 Q_SIGNALS:
42 void clicked(QString category); // Clicked and hover signals exposed to user
42 void clicked(QString category); // Clicked and hover signals exposed to user
43 void rightClicked(QString category);
43 void rightClicked(QString category);
44 void toggleFloatingValues();
44 void toggleFloatingValues();
45
45
46 // TODO: Expose this to user or not?
46 // TODO: Expose this to user or not?
47 // TODO: TO PIMPL --->
47 // TODO: TO PIMPL --->
48 void structureChanged();
48 void structureChanged();
49 void valueChanged();
49 void valueChanged();
50 void hoverEnter(QPoint pos);
50 void hoverEnter(QPoint pos);
51 void hoverLeave();
51 void hoverLeave();
52 void showToolTip(QPoint pos, QString tip); // Private signal
52 void showToolTip(QPoint pos, QString tip); // Private signal
53 // <--- TO PIMPL
53 // <--- TO PIMPL
54
54
55 public Q_SLOTS:
55 public Q_SLOTS:
56 // These are for internal communication
56 // These are for internal communication
57 // TODO: TO PIMPL --->
57 // TODO: TO PIMPL --->
58 void barHoverEnterEvent(QPoint pos);
58 void barHoverEnterEvent(QPoint pos);
59 void barHoverLeaveEvent();
59 void barHoverLeaveEvent();
60 // <--- TO PIMPL
60 // <--- TO PIMPL
61
61
62 private:
62 private:
63
63
64 QString mName;
64 QString mName;
65 QList<qreal> mValues; // TODO: replace with map (category, value)
65 QList<qreal> mValues; // TODO: replace with map (category, value)
66 QMap<QString,qreal> mMappedValues;
66 QMap<QString, qreal> mMappedValues;
67 QPen mPen;
67 QPen mPen;
68 QBrush mBrush;
68 QBrush mBrush;
69 QPen mFloatingValuePen;
69 QPen mFloatingValuePen;
70 };
70 };
71
71
72 QTCOMMERCIALCHART_END_NAMESPACE
72 QTCOMMERCIALCHART_END_NAMESPACE
73
73
74 #endif // QBARSET_H
74 #endif // QBARSET_H
@@ -1,21 +1,19
1 #ifndef PERCENTBARSERIES_H
1 #ifndef PERCENTBARSERIES_H
2 #define PERCENTBARSERIES_H
2 #define PERCENTBARSERIES_H
3
3
4 #include <QStringList>
4 #include <QStringList>
5 #include <qbarseries.h>
5 #include <qbarseries.h>
6
6
7 QTCOMMERCIALCHART_BEGIN_NAMESPACE
7 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8
8
9 class QTCOMMERCIALCHART_EXPORT QPercentBarSeries : public QBarSeries
9 class QTCOMMERCIALCHART_EXPORT QPercentBarSeries : public QBarSeries
10 {
10 {
11 Q_OBJECT
11 Q_OBJECT
12 public:
12 public:
13 QPercentBarSeries(QStringList categories, QObject* parent=0);
13 QPercentBarSeries(QStringList categories, QObject *parent = 0);
14
15 virtual QSeriesType type() const { return QSeries::SeriesTypePercentBar; }
14 virtual QSeriesType type() const { return QSeries::SeriesTypePercentBar; }
16 };
15 };
17
16
18 QTCOMMERCIALCHART_END_NAMESPACE
17 QTCOMMERCIALCHART_END_NAMESPACE
19
18
20
21 #endif // PERCENTBARSERIES_H
19 #endif // PERCENTBARSERIES_H
@@ -1,20 +1,19
1 #ifndef STACKEDBARSERIES_H
1 #ifndef STACKEDBARSERIES_H
2 #define STACKEDBARSERIES_H
2 #define STACKEDBARSERIES_H
3
3
4 #include <QStringList>
4 #include <QStringList>
5 #include <qbarseries.h>
5 #include <qbarseries.h>
6
6
7 QTCOMMERCIALCHART_BEGIN_NAMESPACE
7 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8
8
9 class QTCOMMERCIALCHART_EXPORT QStackedBarSeries : public QBarSeries
9 class QTCOMMERCIALCHART_EXPORT QStackedBarSeries : public QBarSeries
10 {
10 {
11 Q_OBJECT
11 Q_OBJECT
12 public:
12 public:
13 QStackedBarSeries(QStringList categories, QObject* parent=0);
13 QStackedBarSeries(QStringList categories, QObject *parent = 0);
14
15 virtual QSeriesType type() const { return QSeries::SeriesTypeStackedBar; }
14 virtual QSeriesType type() const { return QSeries::SeriesTypeStackedBar; }
16 };
15 };
17
16
18 QTCOMMERCIALCHART_END_NAMESPACE
17 QTCOMMERCIALCHART_END_NAMESPACE
19
18
20 #endif // STACKEDBARSERIES_H
19 #endif // STACKEDBARSERIES_H
@@ -1,84 +1,83
1 #include "stackedbarchartitem_p.h"
1 #include "stackedbarchartitem_p.h"
2 #include "bar_p.h"
2 #include "bar_p.h"
3 #include "barvalue_p.h"
3 #include "barvalue_p.h"
4 #include "qbarset.h"
4 #include "qbarset.h"
5 #include <QDebug>
5 #include <QDebug>
6
6
7 QTCOMMERCIALCHART_BEGIN_NAMESPACE
7 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8
8
9 StackedBarChartItem::StackedBarChartItem(QBarSeries *series, ChartPresenter *presenter) :
9 StackedBarChartItem::StackedBarChartItem(QBarSeries *series, ChartPresenter *presenter) :
10 BarChartItem(series,presenter)
10 BarChartItem(series, presenter)
11 {
11 {
12 }
12 }
13
13
14 StackedBarChartItem::~StackedBarChartItem()
14 StackedBarChartItem::~StackedBarChartItem()
15 {
15 {
16 }
16 }
17
17
18
19 QVector<QRectF> StackedBarChartItem::calculateLayout()
18 QVector<QRectF> StackedBarChartItem::calculateLayout()
20 {
19 {
21 QVector<QRectF> layout;
20 QVector<QRectF> layout;
22 // Use temporary qreals for accurancy (we might get some compiler warnings... :)
21 // Use temporary qreals for accurancy (we might get some compiler warnings... :)
23
22
24 qreal maxSum = mSeries->maxCategorySum();
23 qreal maxSum = mSeries->maxCategorySum();
25 // Domain:
24 // Domain:
26 if (mDomainMaxY > maxSum) {
25 if (mDomainMaxY > maxSum) {
27 maxSum = mDomainMaxY;
26 maxSum = mDomainMaxY;
28 }
27 }
29
28
30 qreal height = geometry().height();
29 qreal height = geometry().height();
31 qreal width = geometry().width();
30 qreal width = geometry().width();
32 qreal scale = (height / mSeries->maxCategorySum());
31 qreal scale = (height / mSeries->maxCategorySum());
33 qreal categotyCount = mSeries->categoryCount();
32 qreal categotyCount = mSeries->categoryCount();
34 qreal barWidth = width / (categotyCount *2);
33 qreal barWidth = width / (categotyCount * 2);
35 qreal xStep = width/categotyCount;
34 qreal xStep = width / categotyCount;
36 qreal xPos = xStep/2 - barWidth/2;
35 qreal xPos = xStep / 2 - barWidth / 2;
37
36
38 int itemIndex(0);
37 int itemIndex(0);
39 for (int category = 0; category < categotyCount; category++) {
38 for (int category = 0; category < categotyCount; category++) {
40 qreal yPos = height;
39 qreal yPos = height;
41 for (int set=0; set < mSeries->barsetCount(); set++) {
40 for (int set=0; set < mSeries->barsetCount(); set++) {
42 qreal barHeight = mSeries->valueAt(set, category) * scale;
41 qreal barHeight = mSeries->valueAt(set, category) * scale;
43 Bar* bar = mBars.at(itemIndex);
42 Bar* bar = mBars.at(itemIndex);
44 bar->setPen(mSeries->barsetAt(set)->pen());
43 bar->setPen(mSeries->barsetAt(set)->pen());
45 bar->setBrush(mSeries->barsetAt(set)->brush());
44 bar->setBrush(mSeries->barsetAt(set)->brush());
46 QRectF rect(xPos,yPos-barHeight,barWidth,barHeight);
45 QRectF rect(xPos, yPos-barHeight, barWidth, barHeight);
47 layout.append(rect);
46 layout.append(rect);
48 itemIndex++;
47 itemIndex++;
49 yPos -= barHeight;
48 yPos -= barHeight;
50 }
49 }
51 xPos += xStep;
50 xPos += xStep;
52 }
51 }
53
52
54 // Position floating values
53 // Position floating values
55 itemIndex = 0;
54 itemIndex = 0;
56 xPos = (width/categotyCount);
55 xPos = (width/categotyCount);
57 for (int category=0; category < mSeries->categoryCount(); category++) {
56 for (int category=0; category < mSeries->categoryCount(); category++) {
58 qreal yPos = height;
57 qreal yPos = height;
59 for (int set=0; set < mSeries->barsetCount(); set++) {
58 for (int set=0; set < mSeries->barsetCount(); set++) {
60 qreal barHeight = mSeries->valueAt(set,category) * scale;
59 qreal barHeight = mSeries->valueAt(set, category) * scale;
61 BarValue* value = mFloatingValues.at(itemIndex);
60 BarValue* value = mFloatingValues.at(itemIndex);
62
61
63 QBarSet* barSet = mSeries->barsetAt(set);
62 QBarSet* barSet = mSeries->barsetAt(set);
64 value->resize(100,50); // TODO: proper layout for this.
63 value->resize(100, 50); // TODO: proper layout for this.
65 value->setPos(xPos, yPos-barHeight/2);
64 value->setPos(xPos, yPos-barHeight / 2);
66 value->setPen(barSet->floatingValuePen());
65 value->setPen(barSet->floatingValuePen());
67
66
68 if (mSeries->valueAt(set,category) != 0) {
67 if (mSeries->valueAt(set, category) != 0) {
69 value->setValueString(QString::number(mSeries->valueAt(set,category)));
68 value->setValueString(QString::number(mSeries->valueAt(set,category)));
70 } else {
69 } else {
71 value->setValueString(QString(""));
70 value->setValueString(QString(""));
72 }
71 }
73
72
74 itemIndex++;
73 itemIndex++;
75 yPos -= barHeight;
74 yPos -= barHeight;
76 }
75 }
77 xPos += xStep;
76 xPos += xStep;
78 }
77 }
79 return layout;
78 return layout;
80 }
79 }
81
80
82 #include "moc_stackedbarchartitem_p.cpp"
81 #include "moc_stackedbarchartitem_p.cpp"
83
82
84 QTCOMMERCIALCHART_END_NAMESPACE
83 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,789 +1,793
1 #include "qchartglobal.h"
1 #include "qchartglobal.h"
2 #include "qlegend.h"
2 #include "qlegend.h"
3 #include "qseries.h"
3 #include "qseries.h"
4 #include "legendmarker_p.h"
4 #include "legendmarker_p.h"
5 #include "legendscrollbutton_p.h"
5 #include "legendscrollbutton_p.h"
6 #include "qxyseries.h"
6 #include "qxyseries.h"
7 #include "qlineseries.h"
7 #include "qlineseries.h"
8 #include "qareaseries.h"
8 #include "qareaseries.h"
9 #include "qscatterseries.h"
9 #include "qscatterseries.h"
10 #include "qsplineseries.h"
10 #include "qsplineseries.h"
11 #include "qbarseries.h"
11 #include "qbarseries.h"
12 #include "qstackedbarseries.h"
12 #include "qstackedbarseries.h"
13 #include "qpercentbarseries.h"
13 #include "qpercentbarseries.h"
14 #include "qbarset.h"
14 #include "qbarset.h"
15 #include "qpieseries.h"
15 #include "qpieseries.h"
16 #include "qpieslice.h"
16 #include "qpieslice.h"
17 #include "chartpresenter_p.h"
17 #include "chartpresenter_p.h"
18 #include <QPainter>
18 #include <QPainter>
19 #include <QPen>
19 #include <QPen>
20
20
21 #include <QGraphicsSceneEvent>
21 #include <QGraphicsSceneEvent>
22
22
23 QTCOMMERCIALCHART_BEGIN_NAMESPACE
23 QTCOMMERCIALCHART_BEGIN_NAMESPACE
24
24
25 /*!
25 /*!
26 \class QLegend
26 \class QLegend
27 \brief part of QtCommercial chart API.
27 \brief part of QtCommercial chart API.
28
28
29 QLegend is a graphical object, whics displays legend of the chart. Legend state is updated by QChart, when
29 QLegend is a graphical object, whics displays legend of the chart. Legend state is updated by QChart, when
30 series have been changed. By default, legend is drawn by QChart, but user can set a new parent to legend and
30 series have been changed. By default, legend is drawn by QChart, but user can set a new parent to legend and
31 handle the drawing manually.
31 handle the drawing manually.
32 User isn't supposed to create or delete legend objects, but can reference it via QChart class.
32 User isn't supposed to create or delete legend objects, but can reference it via QChart class.
33
33
34 \mainclass
34 \mainclass
35
35
36 \sa QChart, QSeries
36 \sa QChart, QSeries
37 */
37 */
38
38
39 /*!
39 /*!
40 \enum QLegend::PreferredLayout
40 \enum QLegend::PreferredLayout
41
41
42 This enum describes the possible position for legend inside chart.
42 This enum describes the possible position for legend inside chart.
43
43
44 \value PreferredLayoutTop
44 \value PreferredLayoutTop
45 \value PreferredLayoutBottom
45 \value PreferredLayoutBottom
46 \value PreferredLayoutLeft
46 \value PreferredLayoutLeft
47 \value PreferredLayoutRight
47 \value PreferredLayoutRight
48 */
48 */
49
49
50
50
51 /*!
51 /*!
52 \fn void QLegend::clicked(QSeries* series, Qt::MouseButton button)
52 \fn void QLegend::clicked(QSeries* series, Qt::MouseButton button)
53 \brief Notifies when series has been clicked on legend \a series \a button
53 \brief Notifies when series has been clicked on legend \a series \a button
54 */
54 */
55
55
56 /*!
56 /*!
57 \fn void QLegend::clicked(QBarSet* barset, Qt::MouseButton button)
57 \fn void QLegend::clicked(QBarSet* barset, Qt::MouseButton button)
58 \brief Notifies when barset has been clicked on legend \a barset \a button
58 \brief Notifies when barset has been clicked on legend \a barset \a button
59 */
59 */
60
60
61 /*!
61 /*!
62 \fn void QLegend::clicked(QPieSlice* slice, Qt::MouseButton button)
62 \fn void QLegend::clicked(QPieSlice* slice, Qt::MouseButton button)
63 \brief Notifies when pie slice has been clicked on legend \a slice \a button
63 \brief Notifies when pie slice has been clicked on legend \a slice \a button
64 */
64 */
65
65
66 /*!
66 /*!
67 Constructs the legend object and sets the parent to \a parent
67 Constructs the legend object and sets the parent to \a parent
68 */
68 */
69 QLegend::QLegend(QGraphicsItem *parent)
69 QLegend::QLegend(QGraphicsItem *parent)
70 : QGraphicsObject(parent)
70 : QGraphicsObject(parent)
71 ,mPos(0,0)
71 ,mPos(0,0)
72 ,mSize(0,0)
72 ,mSize(0,0)
73 ,mMinimumSize(50,20) // TODO: magic numbers
73 ,mMinimumSize(50,20) // TODO: magic numbers
74 ,mMaximumSize(150,100)
74 ,mMaximumSize(150,100)
75 ,m_brush(Qt::darkGray) // TODO: from theme?
75 ,m_brush(Qt::darkGray) // TODO: from theme?
76 ,mPreferredLayout(QLegend::PreferredLayoutTop)
76 ,mPreferredLayout(QLegend::PreferredLayoutTop)
77 ,mFirstMarker(0)
77 ,mFirstMarker(0)
78 ,mMargin(5)
78 ,mMargin(5)
79 {
79 {
80 // setVisible(false);
80 // setVisible(false);
81
81
82 mScrollButtonLeft = new LegendScrollButton(LegendScrollButton::ScrollButtonIdLeft, this);
82 mScrollButtonLeft = new LegendScrollButton(LegendScrollButton::ScrollButtonIdLeft, this);
83 mScrollButtonRight = new LegendScrollButton(LegendScrollButton::ScrollButtonIdRight, this);
83 mScrollButtonRight = new LegendScrollButton(LegendScrollButton::ScrollButtonIdRight, this);
84 mScrollButtonUp = new LegendScrollButton(LegendScrollButton::ScrollButtonIdUp, this);
84 mScrollButtonUp = new LegendScrollButton(LegendScrollButton::ScrollButtonIdUp, this);
85 mScrollButtonDown = new LegendScrollButton(LegendScrollButton::ScrollButtonIdDown, this);
85 mScrollButtonDown = new LegendScrollButton(LegendScrollButton::ScrollButtonIdDown, this);
86
86
87 connect(mScrollButtonLeft,SIGNAL(clicked(QGraphicsSceneMouseEvent*)),this,SLOT(handleScrollButtonClicked(QGraphicsSceneMouseEvent*)));
87 connect(mScrollButtonLeft, SIGNAL(clicked(QGraphicsSceneMouseEvent*)),
88 connect(mScrollButtonRight,SIGNAL(clicked(QGraphicsSceneMouseEvent*)),this,SLOT(handleScrollButtonClicked(QGraphicsSceneMouseEvent*)));
88 this, SLOT(handleScrollButtonClicked(QGraphicsSceneMouseEvent*)));
89 connect(mScrollButtonUp,SIGNAL(clicked(QGraphicsSceneMouseEvent*)),this,SLOT(handleScrollButtonClicked(QGraphicsSceneMouseEvent*)));
89 connect(mScrollButtonRight, SIGNAL(clicked(QGraphicsSceneMouseEvent*)),
90 connect(mScrollButtonDown,SIGNAL(clicked(QGraphicsSceneMouseEvent*)),this,SLOT(handleScrollButtonClicked(QGraphicsSceneMouseEvent*)));
90 this, SLOT(handleScrollButtonClicked(QGraphicsSceneMouseEvent*)));
91 connect(mScrollButtonUp, SIGNAL(clicked(QGraphicsSceneMouseEvent*)),
92 this, SLOT(handleScrollButtonClicked(QGraphicsSceneMouseEvent*)));
93 connect(mScrollButtonDown, SIGNAL(clicked(QGraphicsSceneMouseEvent*)),
94 this, SLOT(handleScrollButtonClicked(QGraphicsSceneMouseEvent*)));
91
95
92 setZValue(ChartPresenter::LegendZValue);
96 setZValue(ChartPresenter::LegendZValue);
93 }
97 }
94
98
95 /*!
99 /*!
96 Paints the legend to given \a painter. Paremeters \a option and \a widget arent used.
100 Paints the legend to given \a painter. Paremeters \a option and \a widget arent used.
97 */
101 */
98 void QLegend::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
102 void QLegend::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
99 {
103 {
100 Q_UNUSED(option)
104 Q_UNUSED(option)
101 Q_UNUSED(widget)
105 Q_UNUSED(widget)
102
106
103 painter->setOpacity(opacity());
107 painter->setOpacity(opacity());
104 painter->setPen(m_pen);
108 painter->setPen(m_pen);
105 painter->setBrush(m_brush);
109 painter->setBrush(m_brush);
106 painter->drawRect(boundingRect());
110 painter->drawRect(boundingRect());
107 }
111 }
108
112
109 /*!
113 /*!
110 Bounding rect of legend.
114 Bounding rect of legend.
111 */
115 */
112 QRectF QLegend::boundingRect() const
116 QRectF QLegend::boundingRect() const
113 {
117 {
114 return QRectF(mPos,mSize);
118 return QRectF(mPos,mSize);
115 }
119 }
116
120
117 /*!
121 /*!
118 Sets the \a brush of legend. Brush affects the background of legend.
122 Sets the \a brush of legend. Brush affects the background of legend.
119 */
123 */
120 void QLegend::setBrush(const QBrush& brush)
124 void QLegend::setBrush(const QBrush &brush)
121 {
125 {
122 if(m_brush!=brush){
126 if (m_brush != brush) {
123 m_brush = brush;
127 m_brush = brush;
124 update();
128 update();
125 }
129 }
126 }
130 }
127
131
128 /*!
132 /*!
129 Returns the brush used by legend.
133 Returns the brush used by legend.
130 */
134 */
131 QBrush QLegend::brush() const
135 QBrush QLegend::brush() const
132 {
136 {
133 return m_brush;
137 return m_brush;
134 }
138 }
135
139
136 /*!
140 /*!
137 Sets the \a pen of legend. Pen affects the legend borders.
141 Sets the \a pen of legend. Pen affects the legend borders.
138 */
142 */
139 void QLegend::setPen(const QPen& pen)
143 void QLegend::setPen(const QPen &pen)
140 {
144 {
141 if(m_pen!=pen){
145 if (m_pen != pen) {
142 m_pen = pen;
146 m_pen = pen;
143 update();
147 update();
144 }
148 }
145 }
149 }
146
150
147 /*!
151 /*!
148 Returns the pen used by legend
152 Returns the pen used by legend
149 */
153 */
150
154
151 QPen QLegend::pen() const
155 QPen QLegend::pen() const
152 {
156 {
153 return m_pen;
157 return m_pen;
154 }
158 }
155
159
156 /*!
160 /*!
157 Sets the \a preferred layout for legend. Legend tries to paint itself on the defined position in chart.
161 Sets the \a preferred layout for legend. Legend tries to paint itself on the defined position in chart.
158 \sa QLegend::PreferredLayout
162 \sa QLegend::PreferredLayout
159 */
163 */
160 void QLegend::setPreferredLayout(QLegend::PreferredLayout preferred)
164 void QLegend::setPreferredLayout(QLegend::PreferredLayout preferred)
161 {
165 {
162 mPreferredLayout = preferred;
166 mPreferredLayout = preferred;
163 updateLayout();
167 updateLayout();
164 }
168 }
165
169
166 /*!
170 /*!
167 Returns the preferred layout for legend
171 Returns the preferred layout for legend
168 */
172 */
169 QLegend::PreferredLayout QLegend::preferredLayout() const
173 QLegend::PreferredLayout QLegend::preferredLayout() const
170 {
174 {
171 return mPreferredLayout;
175 return mPreferredLayout;
172 }
176 }
173
177
174 /*!
178 /*!
175 Returns the maximum size of legend.
179 Returns the maximum size of legend.
176 */
180 */
177 QSizeF QLegend::maximumSize() const
181 QSizeF QLegend::maximumSize() const
178 {
182 {
179 return mMaximumSize;
183 return mMaximumSize;
180 }
184 }
181
185
182 /*!
186 /*!
183 Sets the maximum \a size for legend. The legend can't grow bigger than this size. If there are
187 Sets the maximum \a size for legend. The legend can't grow bigger than this size. If there are
184 more series than legend can fit to this size, scroll buttons are displayed.
188 more series than legend can fit to this size, scroll buttons are displayed.
185 */
189 */
186 void QLegend::setMaximumSize(const QSizeF size)
190 void QLegend::setMaximumSize(const QSizeF size)
187 {
191 {
188 mMaximumSize = size;
192 mMaximumSize = size;
189 updateLayout();
193 updateLayout();
190 }
194 }
191
195
192 /*!
196 /*!
193 Returns the current size of legend.
197 Returns the current size of legend.
194 */
198 */
195 QSizeF QLegend::size() const
199 QSizeF QLegend::size() const
196 {
200 {
197 return mSize;
201 return mSize;
198 }
202 }
199
203
200 /*!
204 /*!
201 Sets the \a size of legend. If size is bigger than maximum size of legend, the legend is resized to the maximum size.
205 Sets the \a size of legend. If size is bigger than maximum size of legend, the legend is resized to the maximum size.
202 \sa setMmaximumSize()
206 \sa setMmaximumSize()
203 */
207 */
204 void QLegend::setSize(const QSizeF size)
208 void QLegend::setSize(const QSizeF size)
205 {
209 {
206 mSize = size;
210 mSize = size;
207 if (mSize.width() > mMaximumSize.width()) {
211 if (mSize.width() > mMaximumSize.width()) {
208 mSize.setWidth(mMaximumSize.width());
212 mSize.setWidth(mMaximumSize.width());
209 }
213 }
210 if (mSize.height() > mMaximumSize.height()) {
214 if (mSize.height() > mMaximumSize.height()) {
211 mSize.setHeight(mMaximumSize.height());
215 mSize.setHeight(mMaximumSize.height());
212 }
216 }
213 }
217 }
214
218
215 /*!
219 /*!
216 Sets position of legend to \a pos
220 Sets position of legend to \a pos
217 */
221 */
218 void QLegend::setPos(const QPointF &pos)
222 void QLegend::setPos(const QPointF &pos)
219 {
223 {
220 mPos = pos;
224 mPos = pos;
221 updateLayout();
225 updateLayout();
222 }
226 }
223
227
224 /*!
228 /*!
225 \internal \a series \a domain Should be called when series is added to chart.
229 \internal \a series \a domain Should be called when series is added to chart.
226 */
230 */
227 void QLegend::handleSeriesAdded(QSeries* series, Domain* domain)
231 void QLegend::handleSeriesAdded(QSeries *series, Domain *domain)
228 {
232 {
229 Q_UNUSED(domain)
233 Q_UNUSED(domain)
230
234
231 createMarkers(series);
235 createMarkers(series);
232 connectSeries(series);
236 connectSeries(series);
233 updateLayout();
237 updateLayout();
234 }
238 }
235
239
236 /*!
240 /*!
237 \internal \a series Should be called when series is removed from chart.
241 \internal \a series Should be called when series is removed from chart.
238 */
242 */
239 void QLegend::handleSeriesRemoved(QSeries* series)
243 void QLegend::handleSeriesRemoved(QSeries *series)
240 {
244 {
241 disconnectSeries(series);
245 disconnectSeries(series);
242
246
243 if (series->type() == QSeries::SeriesTypeArea)
247 if (series->type() == QSeries::SeriesTypeArea)
244 {
248 {
245 // This is special case. Area series has upper and lower series, which each have markers
249 // This is special case. Area series has upper and lower series, which each have markers
246 QAreaSeries* s = static_cast<QAreaSeries*> (series);
250 QAreaSeries* s = static_cast<QAreaSeries *> (series);
247 deleteMarkers(s->upperSeries());
251 deleteMarkers(s->upperSeries());
248 deleteMarkers(s->lowerSeries());
252 deleteMarkers(s->lowerSeries());
249 } else {
253 } else {
250 deleteMarkers(series);
254 deleteMarkers(series);
251 }
255 }
252
256
253 updateLayout();
257 updateLayout();
254 }
258 }
255
259
256 /*!
260 /*!
257 \internal \a slices Should be called when slices are added to pie chart.
261 \internal \a slices Should be called when slices are added to pie chart.
258 */
262 */
259 void QLegend::handleAdded(QList<QPieSlice*> slices)
263 void QLegend::handleAdded(QList<QPieSlice *> slices)
260 {
264 {
261 QPieSeries* series = static_cast<QPieSeries*> (sender());
265 QPieSeries* series = static_cast<QPieSeries *> (sender());
262 foreach(QPieSlice* s, slices) {
266 foreach(QPieSlice* s, slices) {
263 LegendMarker* marker = new LegendMarker(series,s,this);
267 LegendMarker* marker = new LegendMarker(series, s, this);
264 marker->setName(s->label());
268 marker->setName(s->label());
265 marker->setBrush(s->sliceBrush());
269 marker->setBrush(s->sliceBrush());
266 connect(marker,SIGNAL(clicked(QPieSlice*,Qt::MouseButton)),this,SIGNAL(clicked(QPieSlice*,Qt::MouseButton)));
270 connect(marker, SIGNAL(clicked(QPieSlice*,Qt::MouseButton)),
267 connect(s,SIGNAL(changed()),marker,SLOT(changed()));
271 this, SIGNAL(clicked(QPieSlice*,Qt::MouseButton)));
268 connect(s,SIGNAL(destroyed()),marker,SLOT(deleteLater()));
272 connect(s, SIGNAL(changed()), marker, SLOT(changed()));
269 connect(marker,SIGNAL(destroyed()),this,SLOT(handleMarkerDestroyed()));
273 connect(s, SIGNAL(destroyed()), marker, SLOT(deleteLater()));
274 connect(marker, SIGNAL(destroyed()), this, SLOT(handleMarkerDestroyed()));
270 mMarkers.append(marker);
275 mMarkers.append(marker);
271 childItems().append(marker);
276 childItems().append(marker);
272 }
277 }
273 updateLayout();
278 updateLayout();
274 }
279 }
275
280
276 /*!
281 /*!
277 \internal \a slices Should be called when slices are removed from pie chart. Currently unused,
282 \internal \a slices Should be called when slices are removed from pie chart. Currently unused,
278 because removed slices are also deleted and we listen destroyed signal
283 because removed slices are also deleted and we listen destroyed signal
279 */
284 */
280 void QLegend::handleRemoved(QList<QPieSlice *> slices)
285 void QLegend::handleRemoved(QList<QPieSlice *> slices)
281 {
286 {
282 Q_UNUSED(slices)
287 Q_UNUSED(slices)
283 // Propably no need to listen for this, since removed slices are deleted and we listen destroyed signal
288 // Propably no need to listen for this, since removed slices are deleted and we listen destroyed signal
284 // qDebug() << "QLegend::handleRemoved(QList<QPieSlice*> slices) count:" << slices.count();
289 // qDebug() << "QLegend::handleRemoved(QList<QPieSlice*> slices) count:" << slices.count();
285 }
290 }
286
291
287
292
288 /*!
293 /*!
289 \internal Notifies legend that some marker has been removed. Sent by legend markers when destroyed
294 \internal Notifies legend that some marker has been removed. Sent by legend markers when destroyed
290 */
295 */
291 void QLegend::handleMarkerDestroyed()
296 void QLegend::handleMarkerDestroyed()
292 {
297 {
293 // TODO: what if more than one markers are destroyed and we update layout after first one?
298 // TODO: what if more than one markers are destroyed and we update layout after first one?
294 LegendMarker* m = static_cast<LegendMarker*> (sender());
299 LegendMarker* m = static_cast<LegendMarker *> (sender());
295 mMarkers.removeOne(m);
300 mMarkers.removeOne(m);
296 updateLayout();
301 updateLayout();
297 }
302 }
298
303
299 /*!
304 /*!
300 \internal \a event Handles clicked signals from scroll buttons
305 \internal \a event Handles clicked signals from scroll buttons
301 */
306 */
302 void QLegend::handleScrollButtonClicked(QGraphicsSceneMouseEvent *event)
307 void QLegend::handleScrollButtonClicked(QGraphicsSceneMouseEvent *event)
303 {
308 {
304 Q_UNUSED(event); // Maybe later something happens with right click...
309 Q_UNUSED(event); // Maybe later something happens with right click...
305
310
306 LegendScrollButton* scrollButton = static_cast<LegendScrollButton*> (sender());
311 LegendScrollButton* scrollButton = static_cast<LegendScrollButton *> (sender());
307 Q_ASSERT(scrollButton);
312 Q_ASSERT(scrollButton);
308
313
309 switch (scrollButton->id()) {
314 switch (scrollButton->id()) {
310 case LegendScrollButton::ScrollButtonIdLeft:
315 case LegendScrollButton::ScrollButtonIdLeft:
311 case LegendScrollButton::ScrollButtonIdUp: {
316 case LegendScrollButton::ScrollButtonIdUp: {
312 // Lower limit is same in these cases
317 // Lower limit is same in these cases
313 mFirstMarker--;
318 mFirstMarker--;
314 checkFirstMarkerBounds();
319 checkFirstMarkerBounds();
315 break;
320 break;
316 }
321 }
317 case LegendScrollButton::ScrollButtonIdRight:
322 case LegendScrollButton::ScrollButtonIdRight:
318 case LegendScrollButton::ScrollButtonIdDown: {
323 case LegendScrollButton::ScrollButtonIdDown: {
319 mFirstMarker++;
324 mFirstMarker++;
320 checkFirstMarkerBounds();
325 checkFirstMarkerBounds();
321 break;
326 break;
322 }
327 }
323 default: {
328 default: {
324 break;
329 break;
325 }
330 }
326 }
331 }
327 updateLayout();
332 updateLayout();
328 }
333 }
329
334
330 /*!
335 /*!
331 \internal Connects the \a series to legend. Legend listens changes in series, for example pie slices added / removed.
336 \internal Connects the \a series to legend. Legend listens changes in series, for example pie slices added / removed.
332 Not all series notify about events
337 Not all series notify about events
333 */
338 */
334 void QLegend::connectSeries(QSeries *series)
339 void QLegend::connectSeries(QSeries *series)
335 {
340 {
336 // Connect relevant signals from series
341 // Connect relevant signals from series
337 switch (series->type())
342 switch (series->type())
338 {
343 {
339 case QSeries::SeriesTypeLine: {
344 case QSeries::SeriesTypeLine: {
340 // QLineSeries* lineSeries = static_cast<QLineSeries*>(series);
345 // QLineSeries* lineSeries = static_cast<QLineSeries*>(series);
341 break;
346 break;
342 }
347 }
343 case QSeries::SeriesTypeArea: {
348 case QSeries::SeriesTypeArea: {
344 // QAreaSeries* areaSeries = static_cast<QAreaSeries*>(series);
349 // QAreaSeries* areaSeries = static_cast<QAreaSeries*>(series);
345 break;
350 break;
346 }
351 }
347 case QSeries::SeriesTypeBar: {
352 case QSeries::SeriesTypeBar: {
348 // QBarSeries* barSeries = static_cast<QBarSeries*>(series);
353 // QBarSeries* barSeries = static_cast<QBarSeries*>(series);
349 break;
354 break;
350 }
355 }
351 case QSeries::SeriesTypeStackedBar: {
356 case QSeries::SeriesTypeStackedBar: {
352 // QStackedBarSeries* stackedBarSeries = static_cast<QStackedBarSeries*>(series);
357 // QStackedBarSeries* stackedBarSeries = static_cast<QStackedBarSeries*>(series);
353 break;
358 break;
354 }
359 }
355 case QSeries::SeriesTypePercentBar: {
360 case QSeries::SeriesTypePercentBar: {
356 // QPercentBarSeries* percentBarSeries = static_cast<QPercentBarSeries*>(series);
361 // QPercentBarSeries* percentBarSeries = static_cast<QPercentBarSeries*>(series);
357 break;
362 break;
358 }
363 }
359 case QSeries::SeriesTypeScatter: {
364 case QSeries::SeriesTypeScatter: {
360 // QScatterSeries *scatterSeries = static_cast<QScatterSeries *>(series);
365 // QScatterSeries *scatterSeries = static_cast<QScatterSeries *>(series);
361 break;
366 break;
362 }
367 }
363 case QSeries::SeriesTypePie: {
368 case QSeries::SeriesTypePie: {
364 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
369 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
365 connect(pieSeries,SIGNAL(added(QList<QPieSlice*>)),this,SLOT(handleAdded(QList<QPieSlice*>)));
370 connect(pieSeries,SIGNAL(added(QList<QPieSlice*>)),this,SLOT(handleAdded(QList<QPieSlice*>)));
366 // connect(pieSeries,SIGNAL(removed(QList<QPieSlice*>)),this,SLOT(handleRemoved(QList<QPieSlice*>)));
371 // connect(pieSeries,SIGNAL(removed(QList<QPieSlice*>)),this,SLOT(handleRemoved(QList<QPieSlice*>)));
367 break;
372 break;
368 }
373 }
369 case QSeries::SeriesTypeSpline: {
374 case QSeries::SeriesTypeSpline: {
370 // QSplineSeries* splineSeries = static_cast<QSplineSeries*>(series);
375 // QSplineSeries* splineSeries = static_cast<QSplineSeries*>(series);
371 break;
376 break;
372 }
377 }
373 default: {
378 default: {
374 qDebug()<< "QLegend::connectSeries" << series->type() << "not implemented.";
379 qDebug()<< "QLegend::connectSeries" << series->type() << "not implemented.";
375 break;
380 break;
376 }
381 }
377 }
382 }
378 }
383 }
379
384
380 /*!
385 /*!
381 \internal Disconnects \a series from legend. No more status updates from series to legend.
386 \internal Disconnects \a series from legend. No more status updates from series to legend.
382 */
387 */
383 void QLegend::disconnectSeries(QSeries *series)
388 void QLegend::disconnectSeries(QSeries *series)
384 {
389 {
385 // Connect relevant signals from series
390 // Connect relevant signals from series
386 switch (series->type())
391 switch (series->type())
387 {
392 {
388 case QSeries::SeriesTypeLine: {
393 case QSeries::SeriesTypeLine: {
389 // QLineSeries* lineSeries = static_cast<QLineSeries*>(series);
394 // QLineSeries* lineSeries = static_cast<QLineSeries*>(series);
390 break;
395 break;
391 }
396 }
392 case QSeries::SeriesTypeArea: {
397 case QSeries::SeriesTypeArea: {
393 // QAreaSeries* areaSeries = static_cast<QAreaSeries*>(series);
398 // QAreaSeries* areaSeries = static_cast<QAreaSeries*>(series);
394 break;
399 break;
395 }
400 }
396 case QSeries::SeriesTypeBar: {
401 case QSeries::SeriesTypeBar: {
397 // QBarSeries* barSeries = static_cast<QBarSeries*>(series);
402 // QBarSeries* barSeries = static_cast<QBarSeries*>(series);
398 break;
403 break;
399 }
404 }
400 case QSeries::SeriesTypeStackedBar: {
405 case QSeries::SeriesTypeStackedBar: {
401 // QStackedBarSeries* stackedBarSeries = static_cast<QStackedBarSeries*>(series);
406 // QStackedBarSeries* stackedBarSeries = static_cast<QStackedBarSeries*>(series);
402 break;
407 break;
403 }
408 }
404 case QSeries::SeriesTypePercentBar: {
409 case QSeries::SeriesTypePercentBar: {
405 // QPercentBarSeries* percentBarSeries = static_cast<QPercentBarSeries*>(series);
410 // QPercentBarSeries* percentBarSeries = static_cast<QPercentBarSeries*>(series);
406 break;
411 break;
407 }
412 }
408 case QSeries::SeriesTypeScatter: {
413 case QSeries::SeriesTypeScatter: {
409 // QScatterSeries *scatterSeries = static_cast<QScatterSeries *>(series);
414 // QScatterSeries *scatterSeries = static_cast<QScatterSeries *>(series);
410 break;
415 break;
411 }
416 }
412 case QSeries::SeriesTypePie: {
417 case QSeries::SeriesTypePie: {
413 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
418 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
414 disconnect(pieSeries,SIGNAL(added(QList<QPieSlice*>)),this,SLOT(handleAdded(QList<QPieSlice*>)));
419 disconnect(pieSeries, SIGNAL(added(QList<QPieSlice *>)), this, SLOT(handleAdded(QList<QPieSlice *>)));
415 // disconnect(pieSeries,SIGNAL(removed(QList<QPieSlice*>)),this,SLOT(handleRemoved(QList<QPieSlice*>)));
420 // disconnect(pieSeries,SIGNAL(removed(QList<QPieSlice*>)),this,SLOT(handleRemoved(QList<QPieSlice*>)));
416 break;
421 break;
417 }
422 }
418 case QSeries::SeriesTypeSpline: {
423 case QSeries::SeriesTypeSpline: {
419 // QSplineSeries* splineSeries = static_cast<QSplineSeries*>(series);
424 // QSplineSeries* splineSeries = static_cast<QSplineSeries*>(series);
420 break;
425 break;
421 }
426 }
422 default: {
427 default: {
423 qDebug()<< "QLegend::disconnectSeries" << series->type() << "not implemented.";
428 qDebug()<< "QLegend::disconnectSeries" << series->type() << "not implemented.";
424 break;
429 break;
425 }
430 }
426 }
431 }
427 }
432 }
428
433
429 /*!
434 /*!
430 \internal Creates new markers for \a series. Marker contains the colored rectangle and series name.
435 \internal Creates new markers for \a series. Marker contains the colored rectangle and series name.
431 With pie chart, created markers depend on pie slices.
436 With pie chart, created markers depend on pie slices.
432 With bar chart, created markers depend on bar sets.
437 With bar chart, created markers depend on bar sets.
433 */
438 */
434 void QLegend::createMarkers(QSeries *series)
439 void QLegend::createMarkers(QSeries *series)
435 {
440 {
436 switch (series->type())
441 switch (series->type())
437 {
442 {
438 case QSeries::SeriesTypeLine: {
443 case QSeries::SeriesTypeLine: {
439 QLineSeries* lineSeries = static_cast<QLineSeries*>(series);
444 QLineSeries *lineSeries = static_cast<QLineSeries *>(series);
440 appendMarkers(lineSeries);
445 appendMarkers(lineSeries);
441 break;
446 break;
442 }
447 }
443 case QSeries::SeriesTypeArea: {
448 case QSeries::SeriesTypeArea: {
444 QAreaSeries* areaSeries = static_cast<QAreaSeries*>(series);
449 QAreaSeries *areaSeries = static_cast<QAreaSeries *>(series);
445 appendMarkers(areaSeries->upperSeries());
450 appendMarkers(areaSeries->upperSeries());
446 if(areaSeries->lowerSeries())
451 if(areaSeries->lowerSeries())
447 appendMarkers(areaSeries->lowerSeries());
452 appendMarkers(areaSeries->lowerSeries());
448 break;
453 break;
449 }
454 }
450
455
451 case QSeries::SeriesTypeBar: {
456 case QSeries::SeriesTypeBar: {
452 QBarSeries* barSeries = static_cast<QBarSeries*>(series);
457 QBarSeries *barSeries = static_cast<QBarSeries *>(series);
453 appendMarkers(barSeries);
458 appendMarkers(barSeries);
454 break;
459 break;
455 }
460 }
456
461
457 case QSeries::SeriesTypeStackedBar: {
462 case QSeries::SeriesTypeStackedBar: {
458 QStackedBarSeries* stackedBarSeries = static_cast<QStackedBarSeries*>(series);
463 QStackedBarSeries *stackedBarSeries = static_cast<QStackedBarSeries *>(series);
459 appendMarkers(stackedBarSeries);
464 appendMarkers(stackedBarSeries);
460 break;
465 break;
461 }
466 }
462
467
463 case QSeries::SeriesTypePercentBar: {
468 case QSeries::SeriesTypePercentBar: {
464 QPercentBarSeries* percentBarSeries = static_cast<QPercentBarSeries*>(series);
469 QPercentBarSeries *percentBarSeries = static_cast<QPercentBarSeries *>(series);
465 appendMarkers(percentBarSeries);
470 appendMarkers(percentBarSeries);
466 break;
471 break;
467 }
472 }
468
473
469 case QSeries::SeriesTypeScatter: {
474 case QSeries::SeriesTypeScatter: {
470 QScatterSeries *scatterSeries = static_cast<QScatterSeries *>(series);
475 QScatterSeries *scatterSeries = static_cast<QScatterSeries *>(series);
471 appendMarkers(scatterSeries);
476 appendMarkers(scatterSeries);
472 break;
477 break;
473 }
478 }
474
479
475 case QSeries::SeriesTypePie: {
480 case QSeries::SeriesTypePie: {
476 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
481 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
477 appendMarkers(pieSeries);
482 appendMarkers(pieSeries);
478 break;
483 break;
479 }
484 }
480
485
481 case QSeries::SeriesTypeSpline: {
486 case QSeries::SeriesTypeSpline: {
482 QSplineSeries* splineSeries = static_cast<QSplineSeries*>(series);
487 QSplineSeries *splineSeries = static_cast<QSplineSeries *>(series);
483 appendMarkers(splineSeries);
488 appendMarkers(splineSeries);
484 break;
489 break;
485 }
490 }
486 default: {
491 default: {
487 qDebug()<< "QLegend::createMarkers" << series->type() << "not implemented.";
492 qDebug()<< "QLegend::createMarkers" << series->type() << "not implemented.";
488 break;
493 break;
489 }
494 }
490 }
495 }
491 }
496 }
492
497
493 /*!
498 /*!
494 \internal Helper function. Appends markers from \a series to legend.
499 \internal Helper function. Appends markers from \a series to legend.
495 */
500 */
496 void QLegend::appendMarkers(QXYSeries* series)
501 void QLegend::appendMarkers(QXYSeries* series)
497 {
502 {
498 LegendMarker* marker = new LegendMarker(series,this);
503 LegendMarker* marker = new LegendMarker(series,this);
499 marker->setName(series->name());
504 marker->setName(series->name());
500 marker->setPen(series->pen());
505 marker->setPen(series->pen());
501 marker->setBrush(series->brush());
506 marker->setBrush(series->brush());
502 connect(marker,SIGNAL(clicked(QSeries*,Qt::MouseButton)),this,SIGNAL(clicked(QSeries*,Qt::MouseButton)));
507 connect(marker, SIGNAL(clicked(QSeries *, Qt::MouseButton)), this, SIGNAL(clicked(QSeries *, Qt::MouseButton)));
503 connect(marker,SIGNAL(destroyed()),this,SLOT(handleMarkerDestroyed()));
508 connect(marker, SIGNAL(destroyed()), this, SLOT(handleMarkerDestroyed()));
504 mMarkers.append(marker);
509 mMarkers.append(marker);
505 childItems().append(marker);
510 childItems().append(marker);
506 }
511 }
507
512
508 /*!
513 /*!
509 \internal Helper function. Appends markers from \a series to legend.
514 \internal Helper function. Appends markers from \a series to legend.
510 */
515 */
511 void QLegend::appendMarkers(QBarSeries *series)
516 void QLegend::appendMarkers(QBarSeries *series)
512 {
517 {
513 foreach(QBarSet* s, series->barSets()) {
518 foreach(QBarSet* s, series->barSets()) {
514 LegendMarker* marker = new LegendMarker(series,s,this);
519 LegendMarker* marker = new LegendMarker(series, s, this);
515 marker->setName(s->name());
520 marker->setName(s->name());
516 marker->setPen(s->pen());
521 marker->setPen(s->pen());
517 marker->setBrush(s->brush());
522 marker->setBrush(s->brush());
518 connect(marker,SIGNAL(clicked(QBarSet*,Qt::MouseButton)),this,SIGNAL(clicked(QBarSet*,Qt::MouseButton)));
523 connect(marker, SIGNAL(clicked(QBarSet *, Qt::MouseButton)),
519 connect(s,SIGNAL(valueChanged()),marker,SLOT(changed()));
524 this, SIGNAL(clicked(QBarSet *, Qt::MouseButton)));
520 connect(marker,SIGNAL(destroyed()),this,SLOT(handleMarkerDestroyed()));
525 connect(s, SIGNAL(valueChanged()), marker, SLOT(changed()));
526 connect(marker, SIGNAL(destroyed()), this, SLOT(handleMarkerDestroyed()));
521 mMarkers.append(marker);
527 mMarkers.append(marker);
522 childItems().append(marker);
528 childItems().append(marker);
523 }
529 }
524 }
530 }
525
531
526 /*!
532 /*!
527 \internal Helper function. Appends markers from \a series to legend.
533 \internal Helper function. Appends markers from \a series to legend.
528 */
534 */
529 void QLegend::appendMarkers(QPieSeries *series)
535 void QLegend::appendMarkers(QPieSeries *series)
530 {
536 {
531 foreach(QPieSlice* s, series->slices()) {
537 foreach(QPieSlice* s, series->slices()) {
532 LegendMarker* marker = new LegendMarker(series,s,this);
538 LegendMarker* marker = new LegendMarker(series, s, this);
533 marker->setName(s->label());
539 marker->setName(s->label());
534 marker->setPen(s->slicePen());
540 marker->setPen(s->slicePen());
535 marker->setBrush(s->sliceBrush());
541 marker->setBrush(s->sliceBrush());
536 connect(marker,SIGNAL(clicked(QPieSlice*,Qt::MouseButton)),this,SIGNAL(clicked(QPieSlice*,Qt::MouseButton)));
542 connect(marker, SIGNAL(clicked(QPieSlice *, Qt::MouseButton)),
537 connect(s,SIGNAL(changed()),marker,SLOT(changed()));
543 this, SIGNAL(clicked(QPieSlice *, Qt::MouseButton)));
538 connect(s,SIGNAL(destroyed()),marker,SLOT(deleteLater()));
544 connect(s, SIGNAL(changed()), marker, SLOT(changed()));
539 connect(marker,SIGNAL(destroyed()),this,SLOT(handleMarkerDestroyed()));
545 connect(s, SIGNAL(destroyed()), marker, SLOT(deleteLater()));
546 connect(marker, SIGNAL(destroyed()), this, SLOT(handleMarkerDestroyed()));
540 mMarkers.append(marker);
547 mMarkers.append(marker);
541 childItems().append(marker);
548 childItems().append(marker);
542 }
549 }
543 }
550 }
544
551
545 /*!
552 /*!
546 \internal Deletes all markers that are created from \a series
553 \internal Deletes all markers that are created from \a series
547 */
554 */
548 void QLegend::deleteMarkers(QSeries *series)
555 void QLegend::deleteMarkers(QSeries *series)
549 {
556 {
550 // Search all markers that belong to given series and delete them.
557 // Search all markers that belong to given series and delete them.
551 foreach (LegendMarker *m, mMarkers) {
558 foreach (LegendMarker *m, mMarkers) {
552 if (m->series() == series) {
559 if (m->series() == series) {
553 mMarkers.removeOne(m);
560 mMarkers.removeOne(m);
554 delete m;
561 delete m;
555 }
562 }
556 }
563 }
557 }
564 }
558
565
559 /*!
566 /*!
560 \internal Updates layout of legend. Tries to fit as many markers as possible up to the maximum size of legend.
567 \internal Updates layout of legend. Tries to fit as many markers as possible up to the maximum size of legend.
561 If items don't fit, sets the visibility of scroll buttons accordingly.
568 If items don't fit, sets the visibility of scroll buttons accordingly.
562 Causes legend to be resized.
569 Causes legend to be resized.
563 */
570 */
564 void QLegend::updateLayout()
571 void QLegend::updateLayout()
565 {
572 {
566 // Calculate layout for markers and text
573 // Calculate layout for markers and text
567 if (mMarkers.count() <= 0) {
574 if (mMarkers.count() <= 0) {
568 // Nothing to do
575 // Nothing to do
569 return;
576 return;
570 }
577 }
571
578
572 // Find out widest item.
579 // Find out widest item.
573 QSizeF markerMaxSize = maximumMarkerSize();
580 QSizeF markerMaxSize = maximumMarkerSize();
574 checkFirstMarkerBounds();
581 checkFirstMarkerBounds();
575
582
576 // Use max height as scroll button size
583 // Use max height as scroll button size
577 rescaleScrollButtons(QSize(markerMaxSize.height() ,markerMaxSize.height()));
584 rescaleScrollButtons(QSize(markerMaxSize.height() ,markerMaxSize.height()));
578
585
579
580 qreal totalWidth = 0;
586 qreal totalWidth = 0;
581 qreal totalHeight = 0;
587 qreal totalHeight = 0;
582 switch (mPreferredLayout)
588 switch (mPreferredLayout)
583 {
589 {
584 // Both cases organise items horizontally
590 // Both cases organise items horizontally
585 case QLegend::PreferredLayoutBottom:
591 case QLegend::PreferredLayoutBottom:
586 case QLegend::PreferredLayoutTop: {
592 case QLegend::PreferredLayoutTop: {
587
593
588 qreal xStep = markerMaxSize.width();
594 qreal xStep = markerMaxSize.width();
589 qreal x = mPos.x() + mMargin;
595 qreal x = mPos.x() + mMargin;
590 qreal y = mPos.y() + mMargin;
596 qreal y = mPos.y() + mMargin;
591 int column = 0;
597 int column = 0;
592 int maxColumns = 1;
598 int maxColumns = 1;
593 qreal scrollButtonWidth = 0;
599 qreal scrollButtonWidth = 0;
594
600
595 // Set correct visibility for scroll scrollbuttons
601 // Set correct visibility for scroll scrollbuttons
596 if (scrollButtonsVisible()) {
602 if (scrollButtonsVisible()) {
597 mScrollButtonLeft->setVisible(true);
603 mScrollButtonLeft->setVisible(true);
598 mScrollButtonRight->setVisible(true);
604 mScrollButtonRight->setVisible(true);
599 totalWidth += (mScrollButtonLeft->boundingRect().width() + mMargin) * 2; // scrollbuttons visible, so add their width to total width
605 // scrollbuttons visible, so add their width to total width
606 totalWidth += (mScrollButtonLeft->boundingRect().width() + mMargin) * 2;
600 scrollButtonWidth = mScrollButtonLeft->boundingRect().width() + mMargin;
607 scrollButtonWidth = mScrollButtonLeft->boundingRect().width() + mMargin;
601 x += scrollButtonWidth; // start position changes by scrollbutton width
608 // start position changes by scrollbutton width
609 x += scrollButtonWidth;
602 } else {
610 } else {
603 mScrollButtonLeft->setVisible(false);
611 mScrollButtonLeft->setVisible(false);
604 mScrollButtonRight->setVisible(false);
612 mScrollButtonRight->setVisible(false);
605 }
613 }
606 mScrollButtonUp->setVisible(false);
614 mScrollButtonUp->setVisible(false);
607 mScrollButtonDown->setVisible(false);
615 mScrollButtonDown->setVisible(false);
608
616
609 for (int i=0; i<mMarkers.count(); i++) {
617 for (int i=0; i < mMarkers.count(); i++) {
610 LegendMarker* m = mMarkers.at(i);
618 LegendMarker *m = mMarkers.at(i);
611 if (i<mFirstMarker) {
619 if (i < mFirstMarker) {
612 // Markers before first are not visible.
620 // Markers before first are not visible.
613 m->setVisible(false);
621 m->setVisible(false);
614 } else {
622 } else {
615 if ((x + xStep + scrollButtonWidth + mMargin) > (mPos.x() + mMaximumSize.width())) {
623 if ((x + xStep + scrollButtonWidth + mMargin) > (mPos.x() + mMaximumSize.width())) {
616 // This marker would go outside legend rect.
624 // This marker would go outside legend rect.
617 m->setVisible(false);
625 m->setVisible(false);
618 } else {
626 } else {
619 // This marker is ok
627 // This marker is ok
620 m->setVisible(true);
628 m->setVisible(true);
621 m->setPos(x,y);
629 m->setPos(x, y);
622 x += xStep;
630 x += xStep;
623 column++;
631 column++;
624 }
632 }
625 }
633 }
626 maxColumns = column;
634 maxColumns = column;
627 }
635 }
628
636
629 mScrollButtonLeft->setPos(mPos.x() + mMargin, y);
637 mScrollButtonLeft->setPos(mPos.x() + mMargin, y);
630 mScrollButtonRight->setPos(x+mMargin,y);
638 mScrollButtonRight->setPos(x + mMargin, y);
631
639
632 totalWidth += maxColumns * markerMaxSize.width() + mMargin * 2;
640 totalWidth += maxColumns * markerMaxSize.width() + mMargin * 2;
633 totalHeight = markerMaxSize.height() + mMargin * 2;
641 totalHeight = markerMaxSize.height() + mMargin * 2;
634
642
635 break;
643 break;
636 }
644 }
637 // Both cases organize items vertically
645 // Both cases organize items vertically
638 case QLegend::PreferredLayoutLeft:
646 case QLegend::PreferredLayoutLeft:
639 case QLegend::PreferredLayoutRight: {
647 case QLegend::PreferredLayoutRight: {
640 qreal yStep = markerMaxSize.height();
648 qreal yStep = markerMaxSize.height();
641 qreal x = mPos.x() + mMargin;
649 qreal x = mPos.x() + mMargin;
642 qreal y = mPos.y() + mMargin;
650 qreal y = mPos.y() + mMargin;
643 int row = 1;
651 int row = 1;
644 int maxRows = 1;
652 int maxRows = 1;
645 qreal scrollButtonHeight = 0;
653 qreal scrollButtonHeight = 0;
646
654
647 // Set correct visibility for scroll scrollbuttons
655 // Set correct visibility for scroll scrollbuttons
648 if (scrollButtonsVisible()) {
656 if (scrollButtonsVisible()) {
649 mScrollButtonUp->setVisible(true);
657 mScrollButtonUp->setVisible(true);
650 mScrollButtonDown->setVisible(true);
658 mScrollButtonDown->setVisible(true);
651 totalHeight += (mScrollButtonUp->boundingRect().height() + mMargin) * 2; // scrollbuttons visible, so add their height to total height
659 totalHeight += (mScrollButtonUp->boundingRect().height() + mMargin) * 2; // scrollbuttons visible, so add their height to total height
652 scrollButtonHeight = mScrollButtonUp->boundingRect().height();
660 scrollButtonHeight = mScrollButtonUp->boundingRect().height();
653 y += scrollButtonHeight + mMargin; // start position changes by scrollbutton height
661 y += scrollButtonHeight + mMargin; // start position changes by scrollbutton height
654 } else {
662 } else {
655 mScrollButtonUp->setVisible(false);
663 mScrollButtonUp->setVisible(false);
656 mScrollButtonDown->setVisible(false);
664 mScrollButtonDown->setVisible(false);
657 }
665 }
658 mScrollButtonLeft->setVisible(false);
666 mScrollButtonLeft->setVisible(false);
659 mScrollButtonRight->setVisible(false);
667 mScrollButtonRight->setVisible(false);
660
668
661 for (int i=0; i<mMarkers.count(); i++) {
669 for (int i=0; i < mMarkers.count(); i++) {
662 LegendMarker* m = mMarkers.at(i);
670 LegendMarker* m = mMarkers.at(i);
663 if (i<mFirstMarker) {
671 if (i < mFirstMarker) {
664 // Markers before first are not visible.
672 // Markers before first are not visible.
665 m->setVisible(false);
673 m->setVisible(false);
666 } else {
674 } else {
667 if ((y + yStep + scrollButtonHeight) > (mPos.y() + mMaximumSize.height())) {
675 if ((y + yStep + scrollButtonHeight) > (mPos.y() + mMaximumSize.height())) {
668 // This marker would go outside legend rect.
676 // This marker would go outside legend rect.
669 m->setVisible(false);
677 m->setVisible(false);
670 } else {
678 } else {
671 // This marker is ok
679 // This marker is ok
672 m->setVisible(true);
680 m->setVisible(true);
673 m->setPos(x,y);
681 m->setPos(x, y);
674 y += yStep;
682 y += yStep;
675 row++;
683 row++;
676 }
684 }
677 }
685 }
678 maxRows = row;
686 maxRows = row;
679 }
687 }
680
688
681 mScrollButtonUp->setPos(mPos.x() + mMargin, mPos.y() + mMargin);
689 mScrollButtonUp->setPos(mPos.x() + mMargin, mPos.y() + mMargin);
682 mScrollButtonDown->setPos(mPos.x() + mMargin, y + mMargin);
690 mScrollButtonDown->setPos(mPos.x() + mMargin, y + mMargin);
683
691
684 totalWidth += markerMaxSize.width() + mMargin * 2;
692 totalWidth += markerMaxSize.width() + mMargin * 2;
685 totalHeight = maxRows * markerMaxSize.height() + mMargin * 4 + scrollButtonHeight; // TODO: check this
693 totalHeight = maxRows * markerMaxSize.height() + mMargin * 4 + scrollButtonHeight; // TODO: check this
686 break;
694 break;
687 }
695 }
688 default: {
696 default: {
689 break;
697 break;
690 }
698 }
691 }
699 }
692
700
693 mSize.setWidth(totalWidth);
701 mSize.setWidth(totalWidth);
694 mSize.setHeight(totalHeight);
702 mSize.setHeight(totalHeight);
695
703
696 update();
704 update();
697 }
705 }
698
706
699 /*!
707 /*!
700 \internal Sets the size of scroll buttons to \a size
708 \internal Sets the size of scroll buttons to \a size
701 */
709 */
702 void QLegend::rescaleScrollButtons(const QSize &size)
710 void QLegend::rescaleScrollButtons(const QSize &size)
703 {
711 {
704 QPolygonF left;
712 QPolygonF left;
705 left << QPointF(size.width(),0) << QPointF(0,size.height()/2) << QPointF(size.width(),size.height());
713 left << QPointF(size.width(), 0) << QPointF(0, size.height() / 2) << QPointF(size.width(), size.height());
706 QPolygonF right;
714 QPolygonF right;
707 right << QPointF(0,0) << QPointF(size.width(),size.height()/2) << QPointF(0,size.height());
715 right << QPointF(0, 0) << QPointF(size.width(), size.height() / 2) << QPointF(0, size.height());
708 QPolygonF up;
716 QPolygonF up;
709 up << QPointF(0,size.height()) << QPointF(size.width()/2,0) << QPointF(size.width(),size.height());
717 up << QPointF(0, size.height()) << QPointF(size.width() / 2,0) << QPointF(size.width(), size.height());
710 QPolygonF down;
718 QPolygonF down;
711 down << QPointF(0,0) << QPointF(size.width()/2,size.height()) << QPointF(size.width(),0);
719 down << QPointF(0, 0) << QPointF(size.width() / 2, size.height()) << QPointF(size.width(), 0);
712
720
713 mScrollButtonLeft->setPolygon(left);
721 mScrollButtonLeft->setPolygon(left);
714 mScrollButtonRight->setPolygon(right);
722 mScrollButtonRight->setPolygon(right);
715 mScrollButtonUp->setPolygon(up);
723 mScrollButtonUp->setPolygon(up);
716 mScrollButtonDown->setPolygon(down);
724 mScrollButtonDown->setPolygon(down);
717 }
725 }
718
726
719 /*!
727 /*!
720 \internal Finds out maximum size of single marker. Marker sizes depend on series names.
728 \internal Finds out maximum size of single marker. Marker sizes depend on series names.
721 */
729 */
722 QSizeF QLegend::maximumMarkerSize()
730 QSizeF QLegend::maximumMarkerSize()
723 {
731 {
724 QSizeF max(0,0);
732 QSizeF max(0,0);
725 foreach (LegendMarker* m, mMarkers) {
733 foreach (LegendMarker* m, mMarkers) {
726 if (m->boundingRect().width() > max.width()) {
734 if (m->boundingRect().width() > max.width())
727 max.setWidth(m->boundingRect().width());
735 max.setWidth(m->boundingRect().width());
728 }
736 if (m->boundingRect().height() > max.height())
729 if (m->boundingRect().height() > max.height()) {
730 max.setHeight(m->boundingRect().height());
737 max.setHeight(m->boundingRect().height());
731 }
732 }
738 }
733 return max;
739 return max;
734 }
740 }
735
741
736 /*!
742 /*!
737 \internal Checks that first marker is in acceptable bounds. Bounds range from 0 to (maximum number of markers - visible markers)
743 \internal Checks that first marker is in acceptable bounds. Bounds range from 0 to (maximum number of markers - visible markers)
738 If scrollbuttons are visible, they affect the number of visible markers.
744 If scrollbuttons are visible, they affect the number of visible markers.
739 */
745 */
740 void QLegend::checkFirstMarkerBounds()
746 void QLegend::checkFirstMarkerBounds()
741 {
747 {
742 if ((mPreferredLayout == QLegend::PreferredLayoutLeft) || (mPreferredLayout == QLegend::PreferredLayoutRight)) {
748 if ((mPreferredLayout == QLegend::PreferredLayoutLeft) || (mPreferredLayout == QLegend::PreferredLayoutRight)) {
743 // Bounds limited by height.
749 // Bounds limited by height.
744 int max;
750 int max;
745 if (scrollButtonsVisible()) {
751 if (scrollButtonsVisible()) {
746 max = (mMaximumSize.height() - mScrollButtonLeft->boundingRect().height() * 2 - mMargin*4) / maximumMarkerSize().height();
752 max = (mMaximumSize.height() - mScrollButtonLeft->boundingRect().height() * 2 - mMargin * 4) / maximumMarkerSize().height();
747 } else {
753 } else {
748 max = mMaximumSize.height() / maximumMarkerSize().height();
754 max = mMaximumSize.height() / maximumMarkerSize().height();
749 }
755 }
750
756
751 if (mFirstMarker > mMarkers.count() - max) {
757 if (mFirstMarker > mMarkers.count() - max)
752 mFirstMarker = mMarkers.count() - max;
758 mFirstMarker = mMarkers.count() - max;
753 }
754 } else {
759 } else {
755 // Bounds limited by width
760 // Bounds limited by width
756 int max;
761 int max;
757 if (scrollButtonsVisible()) {
762 if (scrollButtonsVisible()) {
758 max = (mMaximumSize.width() - mScrollButtonLeft->boundingRect().width() * 2 - mMargin*4) / maximumMarkerSize().width();
763 max = (mMaximumSize.width() - mScrollButtonLeft->boundingRect().width() * 2 - mMargin*4) / maximumMarkerSize().width();
759 } else {
764 } else {
760 max = mMaximumSize.width() / maximumMarkerSize().width();
765 max = mMaximumSize.width() / maximumMarkerSize().width();
761 }
766 }
762
767
763 if (mFirstMarker > mMarkers.count() - max) {
768 if (mFirstMarker > mMarkers.count() - max)
764 mFirstMarker = mMarkers.count() - max;
769 mFirstMarker = mMarkers.count() - max;
765 }
766 }
770 }
767
771
768 if (mFirstMarker < 0) {
772 if (mFirstMarker < 0)
769 mFirstMarker = 0;
773 mFirstMarker = 0;
770 }
771 }
774 }
772
775
773 /*!
776 /*!
774 \internal Helper function. Visibility of scroll buttons isn't quite obvious, so helper function clarifies the logic.
777 \internal Helper function. Visibility of scroll buttons isn't quite obvious, so helper function clarifies the logic.
775 */
778 */
776 bool QLegend::scrollButtonsVisible()
779 bool QLegend::scrollButtonsVisible()
777 {
780 {
778 // Just a helper to clarify, what the magic below means :)
781 // Just a helper to clarify, what the magic below means :)
779 if ((mPreferredLayout == QLegend::PreferredLayoutTop) || (mPreferredLayout == QLegend::PreferredLayoutBottom)) {
782 if ((mPreferredLayout == QLegend::PreferredLayoutTop) || (mPreferredLayout == QLegend::PreferredLayoutBottom)) {
780 return (maximumMarkerSize().width() * mMarkers.count() + mMargin * 2 > mMaximumSize.width());
783 return (maximumMarkerSize().width() * mMarkers.count() + mMargin * 2 > mMaximumSize.width());
781 } else if ((mPreferredLayout == QLegend::PreferredLayoutLeft) || (mPreferredLayout == QLegend::PreferredLayoutRight)) {
784 } else if ((mPreferredLayout == QLegend::PreferredLayoutLeft) || (mPreferredLayout == QLegend::PreferredLayoutRight)) {
782 return (maximumMarkerSize().height() * mMarkers.count() + mMargin * 2 > mMaximumSize.height());
785 return (maximumMarkerSize().height() * mMarkers.count() + mMargin * 2 > mMaximumSize.height());
783 }
786 }
784
787
785 return (maximumMarkerSize().height() * mMarkers.count() + mMargin * 2 > mMaximumSize.height());
788 return (maximumMarkerSize().height() * mMarkers.count() + mMargin * 2 > mMaximumSize.height());
786 }
789 }
787
790
788 #include "moc_qlegend.cpp"
791 #include "moc_qlegend.cpp"
792
789 QTCOMMERCIALCHART_END_NAMESPACE
793 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,107 +1,107
1 #ifndef QLEGEND_H
1 #ifndef QLEGEND_H
2 #define QLEGEND_H
2 #define QLEGEND_H
3
3
4 #include <qchartglobal.h>
4 #include <qchartglobal.h>
5 #include <qseries.h>
5 #include <qseries.h>
6 #include <QGraphicsObject>
6 #include <QGraphicsObject>
7
7
8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9
9
10 class Domain;
10 class Domain;
11 class LegendMarker;
11 class LegendMarker;
12 class QPieSlice;
12 class QPieSlice;
13 class QXYSeries;
13 class QXYSeries;
14 class QBarSet;
14 class QBarSet;
15 class QBarSeries;
15 class QBarSeries;
16 class QPieSeries;
16 class QPieSeries;
17 class LegendScrollButton;
17 class LegendScrollButton;
18
18
19 class QTCOMMERCIALCHART_EXPORT QLegend : public QGraphicsObject
19 class QTCOMMERCIALCHART_EXPORT QLegend : public QGraphicsObject
20 {
20 {
21 Q_OBJECT
21 Q_OBJECT
22 public:
22 public:
23
23
24 enum PreferredLayout {
24 enum PreferredLayout {
25 PreferredLayoutTop,
25 PreferredLayoutTop,
26 PreferredLayoutBottom,
26 PreferredLayoutBottom,
27 PreferredLayoutLeft,
27 PreferredLayoutLeft,
28 PreferredLayoutRight,
28 PreferredLayoutRight
29 };
29 };
30
30
31 explicit QLegend(QGraphicsItem *parent = 0);
31 explicit QLegend(QGraphicsItem *parent = 0);
32
32
33 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
33 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
34 QRectF boundingRect() const;
34 QRectF boundingRect() const;
35
35
36 void setBrush(const QBrush& brush);
36 void setBrush(const QBrush &brush);
37 QBrush brush() const;
37 QBrush brush() const;
38
38
39 void setPen(const QPen& pen);
39 void setPen(const QPen &pen);
40 QPen pen() const;
40 QPen pen() const;
41
41
42 void setPreferredLayout(QLegend::PreferredLayout preferred);
42 void setPreferredLayout(QLegend::PreferredLayout preferred);
43 QLegend::PreferredLayout preferredLayout() const;
43 QLegend::PreferredLayout preferredLayout() const;
44
44
45 QSizeF maximumSize() const;
45 QSizeF maximumSize() const;
46 void setMaximumSize(const QSizeF size);
46 void setMaximumSize(const QSizeF size);
47
47
48 QSizeF size() const;
48 QSizeF size() const;
49 void setSize(const QSizeF size);
49 void setSize(const QSizeF size);
50 void setPos(const QPointF &pos);
50 void setPos(const QPointF &pos);
51
51
52 signals:
52 signals:
53 // for interactions.
53 // for interactions.
54 void clicked(QSeries* series, Qt::MouseButton button);
54 void clicked(QSeries *series, Qt::MouseButton button);
55 void clicked(QBarSet* barset, Qt::MouseButton button);
55 void clicked(QBarSet *barset, Qt::MouseButton button);
56 void clicked(QPieSlice* slice, Qt::MouseButton button);
56 void clicked(QPieSlice *slice, Qt::MouseButton button);
57
57
58 public slots:
58 public slots:
59 // PIMPL --->
59 // PIMPL --->
60 void handleSeriesAdded(QSeries* series,Domain* domain);
60 void handleSeriesAdded(QSeries *series, Domain *domain);
61 void handleSeriesRemoved(QSeries* series);
61 void handleSeriesRemoved(QSeries *series);
62 void handleAdded(QList<QPieSlice*> slices);
62 void handleAdded(QList<QPieSlice *> slices);
63 void handleRemoved(QList<QPieSlice*> slices);
63 void handleRemoved(QList<QPieSlice *> slices);
64 void handleMarkerDestroyed();
64 void handleMarkerDestroyed();
65 void handleScrollButtonClicked(QGraphicsSceneMouseEvent* event);
65 void handleScrollButtonClicked(QGraphicsSceneMouseEvent *event);
66 // PIMPL <---
66 // PIMPL <---
67
67
68 private:
68 private:
69 // PIMPL --->
69 // PIMPL --->
70 void connectSeries(QSeries* series);
70 void connectSeries(QSeries *series);
71 void disconnectSeries(QSeries* series);
71 void disconnectSeries(QSeries *series);
72 void createMarkers(QSeries* series);
72 void createMarkers(QSeries *series);
73 void appendMarkers(QXYSeries* series); // All line series are derived from QXYSeries, so this works for now
73 void appendMarkers(QXYSeries *series); // All line series are derived from QXYSeries, so this works for now
74 void appendMarkers(QBarSeries* series);
74 void appendMarkers(QBarSeries *series);
75 void appendMarkers(QPieSeries* series);
75 void appendMarkers(QPieSeries *series);
76 void deleteMarkers(QSeries* series);
76 void deleteMarkers(QSeries *series);
77 void updateLayout();
77 void updateLayout();
78 void rescaleScrollButtons(const QSize& size);
78 void rescaleScrollButtons(const QSize &size);
79 QSizeF maximumMarkerSize();
79 QSizeF maximumMarkerSize();
80 void checkFirstMarkerBounds();
80 void checkFirstMarkerBounds();
81 bool scrollButtonsVisible();
81 bool scrollButtonsVisible();
82
82
83 QPointF mPos;
83 QPointF mPos;
84 QSizeF mSize;
84 QSizeF mSize;
85 QSizeF mMinimumSize;
85 QSizeF mMinimumSize;
86 QSizeF mMaximumSize;
86 QSizeF mMaximumSize;
87
87
88 QList<LegendMarker*> mMarkers;
88 QList<LegendMarker *> mMarkers;
89
89
90 QBrush m_brush;
90 QBrush m_brush;
91 QPen m_pen;
91 QPen m_pen;
92 QLegend::PreferredLayout mPreferredLayout;
92 QLegend::PreferredLayout mPreferredLayout;
93
93
94 int mFirstMarker;
94 int mFirstMarker;
95
95
96 LegendScrollButton* mScrollButtonLeft;
96 LegendScrollButton *mScrollButtonLeft;
97 LegendScrollButton* mScrollButtonRight;
97 LegendScrollButton *mScrollButtonRight;
98 LegendScrollButton* mScrollButtonUp;
98 LegendScrollButton *mScrollButtonUp;
99 LegendScrollButton* mScrollButtonDown;
99 LegendScrollButton *mScrollButtonDown;
100
100
101 qreal mMargin;
101 qreal mMargin;
102 // <--- PIMPL
102 // <--- PIMPL
103 };
103 };
104
104
105 QTCOMMERCIALCHART_END_NAMESPACE
105 QTCOMMERCIALCHART_END_NAMESPACE
106
106
107 #endif // QLEGEND_H
107 #endif // QLEGEND_H
General Comments 0
You need to be logged in to leave comments. Login now