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