##// END OF EJS Templates
fixed clipping in barcharts
sauimone -
r839:27902acc0ab1
parent child
Show More
@@ -1,222 +1,234
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "barchartitem_p.h"
22 22 #include "bar_p.h"
23 23 #include "barlabel_p.h"
24 24 #include "qbarset.h"
25 25 #include "qbarseries.h"
26 26 #include "qchart.h"
27 27 #include "qchartaxis.h"
28 28 #include "qchartaxiscategories.h"
29 29 #include "chartpresenter_p.h"
30 30 #include "chartanimator_p.h"
31 31 #include "chartdataset_p.h"
32 #include <QDebug>
33 32 #include <QToolTip>
33 #include <QPainter>
34 34
35 35 QTCOMMERCIALCHART_BEGIN_NAMESPACE
36 36
37 37 BarChartItem::BarChartItem(QBarSeries *series, ChartPresenter *presenter) :
38 38 ChartItem(presenter),
39 39 m_layoutSet(false),
40 40 m_series(series)
41 41 {
42 42 connect(series, SIGNAL(showToolTip(QPoint,QString)), this, SLOT(showToolTip(QPoint,QString)));
43 43 connect(series, SIGNAL(updatedBars()), this, SLOT(handleLayoutChanged()));
44 44 connect(series, SIGNAL(restructuredBar(int)), this, SLOT(handleModelChanged(int)));
45 45 setZValue(ChartPresenter::BarSeriesZValue);
46 46 dataChanged();
47 47 }
48 48
49 49 BarChartItem::~BarChartItem()
50 50 {
51 51 disconnect(this,SLOT(showToolTip(QPoint,QString)));
52 deleteItems();
52 53 }
53 54
54 55 void BarChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
55 56 {
56 57 if (!m_layoutSet) {
57 58 qWarning() << "BarChartItem::paint called without layout set. Aborting.";
58 59 return;
59 60 }
60 61
61 foreach(QGraphicsItem* i, childItems())
62 i->paint(painter,option,widget);
62 painter->save();
63 painter->setClipRect(m_clipRect);
64 foreach (Bar *bar, m_bars)
65 bar->paint(painter,option,widget);
66 foreach (BarLabel* label, m_labels)
67 label->paint(painter,option,widget);
68 painter->restore();
63 69 }
64 70
65 71 QRectF BarChartItem::boundingRect() const
66 72 {
67 return m_rect;
73 return m_rect.translated(-m_rect.topLeft());
74 // return m_rect;
68 75 }
69 76
70 77 void BarChartItem::dataChanged()
71 78 {
72 79 // TODO: performance optimizations. Do we really need to delete and create items every time data is changed or can we reuse them?
73 // Delete old bars
74 foreach (QGraphicsItem *item, childItems())
75 delete item;
80 deleteItems();
76 81
77 82 m_bars.clear();
78 83 m_labels.clear();
79 84 m_layout.clear();
80 85
81 86 // Create new graphic items for bars
82 87 for (int c = 0; c < m_series->categoryCount(); c++) {
83 88 QString category = m_series->categoryName(c);
84 89 for (int s = 0; s < m_series->barsetCount(); s++) {
85 90 QBarSet *set = m_series->barsetAt(s);
86 Bar *bar = new Bar(category,this);
87 childItems().append(bar);
91 Bar *bar = new Bar(category,0); // Null parent is best :)
88 92 m_bars.append(bar);
89 93 connect(bar, SIGNAL(clicked(QString,Qt::MouseButtons)), set, SIGNAL(clicked(QString,Qt::MouseButtons)));
90 94 connect(bar, SIGNAL(hoverEntered(QPoint)), set, SLOT(barHoverEnterEvent(QPoint)));
91 95 connect(bar, SIGNAL(hoverLeaved()), set, SLOT(barHoverLeaveEvent()));
92 96 m_layout.append(QRectF(0, 0, 0, 0));
93 97 }
94 98 }
95 99
96 100 // Create labels
97 101 for (int category = 0; category < m_series->categoryCount(); category++) {
98 102 for (int s = 0; s < m_series->barsetCount(); s++) {
99 103 QBarSet *set = m_series->barsetAt(s);
100 BarLabel *value = new BarLabel(*set, this);
101 childItems().append(value);
104 BarLabel *value = new BarLabel(*set, 0);
102 105 m_labels.append(value);
103 106 connect(set,SIGNAL(labelsVisibleChanged(bool)),value,SLOT(labelsVisibleChanged(bool)));
104 107 }
105 108 }
106 109 }
107 110
108 111 QVector<QRectF> BarChartItem::calculateLayout()
109 112 {
110 113 QVector<QRectF> layout;
111 114
112 115 // Use temporary qreals for accurancy (we might get some compiler warnings... :)
113 116 qreal categoryCount = m_series->categoryCount();
114 117 qreal setCount = m_series->barsetCount();
115 118
116 119 qreal width = geometry().width();
117 120 qreal height = geometry().height();
118 121
119 122 qreal max = m_series->max();
120 123
121 124 // Domain:
122 125 if (m_domainMaxY > max) {
123 126 max = m_domainMaxY;
124 127 }
125 128
126 129 qreal scale = (height / max);
127 130 qreal categoryWidth = width / categoryCount;
128 131 qreal barWidth = categoryWidth / (setCount+1);
129 132
130 133 int itemIndex(0);
131 134 for (int category = 0; category < categoryCount; category++) {
132 135 qreal xPos = categoryWidth * category + barWidth / 2;
133 136 qreal yPos = height;
134 137 for (int set = 0; set < setCount; set++) {
135 138 QBarSet* barSet = m_series->barsetAt(set);
136 139
137 140 qreal barHeight = barSet->valueAt(category) * scale;
138 141 Bar* bar = m_bars.at(itemIndex);
139 142
140 143 QRectF rect(xPos, yPos - barHeight, barWidth, barHeight);
141 144 layout.append(rect);
142 145 bar->setPen(barSet->pen());
143 146 bar->setBrush(barSet->brush());
144 147
145 148 BarLabel* label = m_labels.at(itemIndex);
146 149
147 150 if (!qFuzzyIsNull(barSet->valueAt(category))) {
148 151 label->setText(QString::number(barSet->valueAt(category)));
149 152 } else {
150 153 label->setText(QString(""));
151 154 }
152 155
153 156 label->setPos(xPos + (rect.width()/2 - label->boundingRect().width()/2)
154 157 ,yPos - barHeight/2 - label->boundingRect().height()/2);
155 // value->setFont(barSet->valueFont());
158 label->setFont(barSet->labelFont());
156 159
157 160 itemIndex++;
158 161 xPos += barWidth;
159 162 }
160 163 }
161 164 return layout;
162 165 }
163 166
164 167 void BarChartItem::applyLayout(const QVector<QRectF> &layout)
165 168 {
166 169 if (animator())
167 170 animator()->updateLayout(this, m_layout, layout);
168 171 else
169 172 setLayout(layout);
170 173 }
171 174
172 175 void BarChartItem::setLayout(const QVector<QRectF> &layout)
173 176 {
174 177 m_layout = layout;
175 178
176 179 for (int i=0; i < m_bars.count(); i++)
177 180 m_bars.at(i)->setRect(layout.at(i));
178 181
179 182 update();
180 183 }
181 184
185 void BarChartItem::deleteItems()
186 {
187 foreach (Bar *bar, m_bars)
188 delete bar;
189 foreach (BarLabel* label, m_labels)
190 delete label;
191 }
192
182 193 //handlers
183 194
184 195 void BarChartItem::handleModelChanged(int index)
185 196 {
186 197 Q_UNUSED(index)
187 198 dataChanged();
188 199 }
189 200
190 201 void BarChartItem::handleDomainChanged(qreal minX, qreal maxX, qreal minY, qreal maxY)
191 202 {
192 203 m_domainMinX = minX;
193 204 m_domainMaxX = maxX;
194 205 m_domainMinY = minY;
195 206 m_domainMaxY = maxY;
196 207 handleLayoutChanged();
197 208 }
198 209
199 210 void BarChartItem::handleGeometryChanged(const QRectF &rect)
200 211 {
212 m_clipRect = rect.translated(-rect.topLeft());
201 213 m_rect = rect;
202 214 handleLayoutChanged();
203 215 m_layoutSet = true;
204 216 setPos(rect.topLeft());
205 217 }
206 218
207 219 void BarChartItem::handleLayoutChanged()
208 220 {
209 221 QVector<QRectF> layout = calculateLayout();
210 222 applyLayout(layout);
211 223 update();
212 224 }
213 225
214 226 void BarChartItem::showToolTip(QPoint pos, QString tip)
215 227 {
216 228 // TODO: cool tooltip instead of default
217 229 QToolTip::showText(pos, tip);
218 230 }
219 231
220 232 #include "moc_barchartitem_p.cpp"
221 233
222 234 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,89 +1,93
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #ifndef BARCHARTITEM_H
22 22 #define BARCHARTITEM_H
23 23
24 24 #include "chartitem_p.h"
25 25 #include "qbarseries.h"
26 26 #include <QPen>
27 27 #include <QBrush>
28 28
29 29 QTCOMMERCIALCHART_BEGIN_NAMESPACE
30 30
31 31 class Bar;
32 32 class BarLabel;
33 33 class QChartAxisCategories;
34 34 class QChart;
35 35
36 36 //typedef QVector<QRectF> BarLayout;
37 37
38 38 class BarChartItem : public ChartItem
39 39 {
40 40 Q_OBJECT
41 41 public:
42 42 BarChartItem(QBarSeries *series, ChartPresenter *presenter);
43 43 virtual ~BarChartItem();
44 44
45 45 public:
46 46 // From QGraphicsItem
47 47 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
48 48 QRectF boundingRect() const;
49 49
50 50 // TODO: Consider the domain for layoutChanged. May be use case, may not be. If it is, then the derived classes need to implement it
51 51 virtual void dataChanged(); // data of series has changed -> need to recalculate bar sizes
52 52
53 53 virtual QVector<QRectF> calculateLayout();
54 54 void applyLayout(const QVector<QRectF> &layout);
55 55 void setLayout(const QVector<QRectF> &layout);
56 56 void updateLayout(const QVector<QRectF> &layout);
57 57
58 58 QRectF geometry() const { return m_rect;}
59 59
60 private:
61 void deleteItems();
62
60 63 public Q_SLOTS:
61 64 void handleModelChanged(int index);
62 65 void handleDomainChanged(qreal minX, qreal maxX, qreal minY, qreal maxY);
63 66 void handleGeometryChanged(const QRectF &size);
64 67 void handleLayoutChanged();
65 68
66 69 // Internal slots
67 70 void showToolTip(QPoint pos, QString tip); // shows tooltip (if enabled)
68 71
69 72 protected:
70 73
71 74 // TODO: consider these.
72 75 qreal m_domainMinX;
73 76 qreal m_domainMaxX;
74 77 qreal m_domainMinY;
75 78 qreal m_domainMaxY;
76 79
77 80 QRectF m_rect;
81 QRectF m_clipRect;
78 82 bool m_layoutSet; // True, if component has been laid out.
79 83 QVector<QRectF> m_layout;
80 84
81 85 // Not owned.
82 86 QBarSeries *m_series;
83 87 QList<Bar *> m_bars;
84 88 QList<BarLabel *> m_labels;
85 89 };
86 90
87 91 QTCOMMERCIALCHART_END_NAMESPACE
88 92
89 93 #endif // BARCHARTITEM_H
@@ -1,86 +1,85
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "percentbarchartitem_p.h"
22 22 #include "bar_p.h"
23 23 #include "barlabel_p.h"
24 24 #include "qbarset.h"
25 #include <QDebug>
26 25
27 26 QTCOMMERCIALCHART_BEGIN_NAMESPACE
28 27
29 28 PercentBarChartItem::PercentBarChartItem(QBarSeries *series, ChartPresenter *presenter) :
30 29 BarChartItem(series, presenter)
31 30 {
32 31 }
33 32
34 33 QVector<QRectF> PercentBarChartItem::calculateLayout()
35 34 {
36 35 QVector<QRectF> layout;
37 36
38 // Use temporary qreals for accurancy (we might get some compiler warnings... :)
37 // Use temporary qreals for accurancy
39 38 qreal width = geometry().width();
40 39 qreal height = geometry().height();
41 40
42 41 qreal categoryCount = m_series->categoryCount();
43 42 qreal barWidth = width / (m_series->categoryCount() * 2);
44 43 qreal xStep = width / categoryCount;
45 44 qreal xPos = xStep / 2 - barWidth / 2;
46 45
47 46 int itemIndex(0);
48 47 for (int category = 0; category < categoryCount; category++) {
49 48 qreal colSum = m_series->categorySum(category);
50 49 qreal scale = (height / colSum);
51 50 qreal yPos = height;
52 51 for (int set=0; set < m_series->barsetCount(); set++) {
53 52 QBarSet* barSet = m_series->barsetAt(set);
54 53 qreal barHeight = barSet->valueAt(category) * scale;
55 54 Bar* bar = m_bars.at(itemIndex);
56 55 bar->setPen(barSet->pen());
57 56 bar->setBrush(barSet->brush());
58 57 QRectF rect(xPos, yPos-barHeight, barWidth, barHeight);
59 58 layout.append(rect);
60 59
61 60 BarLabel* label = m_labels.at(itemIndex);
62 61
63 62 if (!qFuzzyIsNull(m_series->valueAt(set,category))) {
64 63 int p = m_series->percentageAt(set,category) * 100;
65 64 QString vString(QString::number(p));
66 65 vString.truncate(3);
67 66 vString.append("%");
68 67 label->setText(vString);
69 68 } else {
70 69 label->setText(QString(""));
71 70 }
72 71
73 72 label->setPos(xPos + (rect.width()/2 - label->boundingRect().width()/2)
74 73 ,yPos - barHeight/2 - label->boundingRect().height()/2);
75 // value->setFont(barSet->valueFont());
74 label->setFont(barSet->labelFont());
76 75 itemIndex++;
77 76 yPos -= barHeight;
78 77 }
79 78 xPos += xStep;
80 79 }
81 80 return layout;
82 81 }
83 82
84 83 #include "moc_percentbarchartitem_p.cpp"
85 84
86 85 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,404 +1,407
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include <QDebug>
22 22 #include "qbarseries.h"
23 23 #include "qbarset.h"
24 24 #include "barchartmodel_p.h"
25 25
26 26 QTCOMMERCIALCHART_BEGIN_NAMESPACE
27 27
28 28 /*!
29 29 \class QBarSeries
30 30 \brief part of QtCommercial chart API.
31 31
32 32 QBarSeries represents a series of data shown as bars. One QBarSeries can contain multible
33 33 QBarSet data sets. QBarSeries groups the data from sets to categories, which are defined
34 34 by QStringList.
35 35
36 36 \mainclass
37 37
38 38 \sa QBarSet, QStackedBarSeries, QPercentBarSeries
39 39 */
40 40
41 41 /*!
42 42 \fn virtual QSeriesType QBarSeries::type() const
43 43 \brief Returns type of series.
44 44 \sa QSeries, QSeriesType
45 45 */
46 46
47 47 /*!
48 48 \fn void QBarSeries::showToolTip(QPoint pos, QString tip)
49 49 \brief \internal \a pos \a tip
50 50 */
51 51
52 52 /*!
53 53 Constructs empty QBarSeries. Parameter \a categories defines the categories for chart.
54 54 QBarSeries is QObject which is a child of a \a parent.
55 55 */
56 56 QBarSeries::QBarSeries(QBarCategories categories, QObject *parent) : QSeries(parent),
57 57 m_internalModel(new BarChartModel(categories, this))
58 58 {
59 59 m_model = 0;
60 60 m_mapCategories = -1;
61 61 m_mapBarBottom = -1;
62 62 m_mapBarTop = -1;
63 63 m_mapFirst = 0;
64 64 m_mapCount = 0;
65 65 m_mapOrientation = Qt::Vertical;
66 66 }
67 67
68 68 /*!
69 69 Adds a set of bars to series. Takes ownership of \a set.
70 70 Connects the clicked(QString, Qt::MouseButtons) signal
71 71 of \a set to this series
72 72 */
73 73 void QBarSeries::appendBarSet(QBarSet *set)
74 74 {
75 75 m_internalModel->appendBarSet(set);
76 76 connect(set, SIGNAL(clicked(QString,Qt::MouseButtons)), this, SLOT(barsetClicked(QString,Qt::MouseButtons)));
77 77 connect(set, SIGNAL(valueChanged()), this, SLOT(barsetChanged()));
78 78 emit updatedBars();
79 79 }
80 80
81 81 /*!
82 82 Removes a set of bars from series. Releases ownership of \a set. Doesnt delete \a set.
83 83 Disconnects the clicked(QString, Qt::MouseButtons) signal
84 84 of \a set from this series
85 85 */
86 86 void QBarSeries::removeBarSet(QBarSet *set)
87 87 {
88 88 disconnect(set, SIGNAL(clicked(QString,Qt::MouseButtons)), this, SLOT(barsetClicked(QString,Qt::MouseButtons)));
89 89 m_internalModel->removeBarSet(set);
90 90 emit updatedBars();
91 91 }
92 92
93 93 void QBarSeries::insertBarSet(int i, QBarSet *set)
94 94 {
95 95 m_internalModel->insertBarSet(i, set);
96 96 // emit barsetChanged();
97 97 }
98 98
99 99 void QBarSeries::insertCategory(int i, QString category)
100 100 {
101 101 m_internalModel->insertCategory(i, category);
102 102 }
103 103
104 104 void QBarSeries::removeCategory(int i)
105 105 {
106 106 m_internalModel->removeCategory(i);
107 107 }
108 108
109 109 /*!
110 110 Returns number of sets in series.
111 111 */
112 112 int QBarSeries::barsetCount() const
113 113 {
114 114 // if(m_model)
115 115 // return m_mapBarTop - m_mapBarBottom;
116 116 // else
117 117 return m_internalModel->barsetCount();
118 118 }
119 119
120 120 /*!
121 121 Returns number of categories in series
122 122 */
123 123 int QBarSeries::categoryCount() const
124 124 {
125 125 return m_internalModel->categoryCount();
126 126 }
127 127
128 128 /*!
129 129 Returns a list of sets in series. Keeps ownership of sets.
130 130 */
131 131 QList<QBarSet*> QBarSeries::barSets() const
132 132 {
133 133 return m_internalModel->barSets();
134 134 }
135 135
136 136 /*!
137 137 \internal \a index
138 138 */
139 139 QBarSet* QBarSeries::barsetAt(int index)
140 140 {
141 141 return m_internalModel->barsetAt(index);
142 142 }
143 143
144 144 /*!
145 145 \internal \a category
146 146 */
147 147 QString QBarSeries::categoryName(int category)
148 148 {
149 149 return m_internalModel->categoryName(category);
150 150 }
151 151
152 152 /*!
153 153 Enables or disables tooltip depending on parameter \a enabled.
154 154 Tooltip shows the name of set, when mouse is hovering on top of bar.
155 155 Calling without parameter \a enabled, enables the tooltip
156 156 */
157 157 void QBarSeries::setToolTipEnabled(bool enabled)
158 158 {
159 159 // TODO: what if we add sets after call to this function? Those sets won't have tooltip enabled.
160 160 if (enabled) {
161 161 for (int i=0; i<m_internalModel->barsetCount(); i++) {
162 162 QBarSet *set = m_internalModel->barsetAt(i);
163 163 connect(set, SIGNAL(showToolTip(QPoint,QString)), this, SIGNAL(showToolTip(QPoint,QString)));
164 164 }
165 165 } else {
166 166 for (int i=0; i<m_internalModel->barsetCount(); i++) {
167 167 QBarSet *set = m_internalModel->barsetAt(i);
168 168 disconnect(set, SIGNAL(showToolTip(QPoint,QString)), this, SIGNAL(showToolTip(QPoint,QString)));
169 169 }
170 170 }
171 171 }
172 172
173 173
174 174 /*!
175 175 \internal \a category
176 176 */
177 177 void QBarSeries::barsetClicked(QString category, Qt::MouseButtons button)
178 178 {
179 179 emit clicked(qobject_cast<QBarSet*>(sender()), category, button);
180 180 }
181 181
182 182 /*!
183 183 \internal
184 184 */
185 185 qreal QBarSeries::min()
186 186 {
187 187 return m_internalModel->min();
188 188 }
189 189
190 190 /*!
191 191 \internal
192 192 */
193 193 qreal QBarSeries::max()
194 194 {
195 195 return m_internalModel->max();
196 196 }
197 197
198 198 /*!
199 199 \internal \a set \a category
200 200 */
201 201 qreal QBarSeries::valueAt(int set, int category)
202 202 {
203 203 return m_internalModel->valueAt(set, category);
204 204 }
205 205
206 206 /*!
207 207 \internal \a set \a category
208 208 */
209 209 qreal QBarSeries::percentageAt(int set, int category)
210 210 {
211 211 return m_internalModel->percentageAt(set, category);
212 212 }
213 213
214 214 /*!
215 215 \internal \a category
216 216 */
217 217 qreal QBarSeries::categorySum(int category)
218 218 {
219 219 return m_internalModel->categorySum(category);
220 220 }
221 221
222 222 /*!
223 223 \internal
224 224 */
225 225 qreal QBarSeries::maxCategorySum()
226 226 {
227 227 return m_internalModel->maxCategorySum();
228 228 }
229 229
230 230 /*!
231 231 \internal
232 232 */
233 233 BarChartModel& QBarSeries::model()
234 234 {
235 235 return *m_internalModel;
236 236 }
237 237
238 238 bool QBarSeries::setModel(QAbstractItemModel *model)
239 239 {
240 240 // disconnect signals from old model
241 241 if(m_model)
242 242 {
243 243 disconnect(m_model, 0, this, 0);
244 244 m_mapCategories = -1;
245 245 m_mapBarBottom = -1;
246 246 m_mapBarTop = -1;
247 247 m_mapFirst = 0;
248 248 m_mapCount = 0;
249 249 m_mapOrientation = Qt::Vertical;
250 250 }
251 251
252 252 // set new model
253 253 if(model)
254 254 {
255 255 m_model = model;
256 256 return true;
257 257 }
258 258 else
259 259 {
260 260 m_model = 0;
261 261 return false;
262 262 }
263 263 }
264 264
265 265 // TODO
266 266 void QBarSeries::setModelMapping(int categories, int bottomBoundry, int topBoundry, Qt::Orientation orientation)
267 267 {
268 268 if (!m_model)
269 269 return;
270 270
271 271 m_mapCategories = categories;
272 272 m_mapBarBottom = bottomBoundry;
273 273 m_mapBarTop = topBoundry;
274 274 // m_mapFirst = 1;
275 275 m_mapOrientation = orientation;
276 276
277 277 // connect the signals
278 278 if (m_mapOrientation == Qt::Vertical) {
279 279 m_mapCount = m_model->rowCount() - m_mapFirst;
280 280 connect(m_model,SIGNAL(dataChanged(QModelIndex,QModelIndex)),
281 281 this, SLOT(modelUpdated(QModelIndex, QModelIndex)));
282 282 connect(m_model,SIGNAL(rowsInserted(QModelIndex, int, int)),
283 283 this, SLOT(modelDataAdded(QModelIndex,int,int)));
284 284 connect(m_model, SIGNAL(rowsRemoved(QModelIndex, int, int)),
285 285 this, SLOT(modelDataRemoved(QModelIndex,int,int)));
286 286 } else {
287 287 m_mapCount = m_model->columnCount() - m_mapFirst;
288 288 connect(m_model,SIGNAL(dataChanged(QModelIndex,QModelIndex)),
289 289 this, SLOT(modelUpdated(QModelIndex, QModelIndex)));
290 290 connect(m_model,SIGNAL(columnsInserted(QModelIndex, int, int)),
291 291 this, SLOT(modelDataAdded(QModelIndex,int,int)));
292 292 connect(m_model, SIGNAL(columnsRemoved(QModelIndex, int, int)),
293 293 this, SLOT(modelDataRemoved(QModelIndex,int,int)));
294 294 }
295 295
296 296
297 297 // create the initial bars
298 298 delete m_internalModel;
299 299 if (m_mapOrientation == Qt::Vertical) {
300 300 QStringList categories;
301 301 for (int k = m_mapFirst; k < m_mapFirst + m_mapCount; k++)
302 302 categories << m_model->data(m_model->index(k, m_mapCategories), Qt::DisplayRole).toString();
303 303 m_internalModel = new BarChartModel(categories, this);
304 304
305 305 for (int i = m_mapBarBottom; i <= m_mapBarTop; i++) {
306 306 QBarSet* barSet = new QBarSet(QString("Column: %1").arg(i + 1));
307 307 for(int m = m_mapFirst; m < m_mapFirst + m_mapCount; m++)
308 308 *barSet << m_model->data(m_model->index(m, i), Qt::DisplayRole).toDouble();
309 309 appendBarSet(barSet);
310 310 }
311 311 } else {
312 312 QStringList categories;
313 313 for (int k = m_mapFirst; k < m_mapFirst + m_mapCount; k++)
314 314 categories << m_model->data(m_model->index(m_mapCategories, k), Qt::DisplayRole).toString();
315 315 m_internalModel = new BarChartModel(categories, this);
316 316
317 317 for (int i = m_mapBarBottom; i <= m_mapBarTop; i++) {
318 318 QBarSet* barSet = new QBarSet(QString("Row: %1").arg(i + 1));
319 319 for(int m = m_mapFirst; m < m_mapFirst + m_mapCount; m++)
320 320 *barSet << m_model->data(m_model->index(i, m), Qt::DisplayRole).toDouble();
321 321 appendBarSet(barSet);
322 322 }
323 323 }
324 324 }
325 325
326 326 void QBarSeries::setModelMappingShift(int first, int count)
327 327 {
328 328 m_mapFirst = first;
329 329 m_mapCount = count;
330 330 }
331 331
332 332 void QBarSeries::modelUpdated(QModelIndex topLeft, QModelIndex bottomRight)
333 333 {
334 334 Q_UNUSED(bottomRight)
335 335
336 336 if (m_mapOrientation == Qt::Vertical)
337 337 {
338 338 // model update is relevant to BarSeries if the change was made to the part of the model that was mapped to BarSeries
339 339 if (topLeft.column() >= m_mapBarBottom && topLeft.column() <= m_mapBarTop && topLeft.row() >= m_mapFirst && topLeft.row() < m_mapFirst + m_mapCount)
340 340 barsetAt(topLeft.column() - m_mapBarBottom)->setValue(topLeft.row() - m_mapFirst, m_model->data(topLeft, Qt::DisplayRole).toDouble());
341 341 }
342 342 else
343 343 {
344 344 // model update is relevant to BarSeries if the change was made to the part of the model that was mapped to BarSeries
345 345 if (topLeft.row() >= m_mapBarBottom && topLeft.row() <= m_mapBarTop && topLeft.column() >= m_mapFirst && topLeft.column() < m_mapFirst + m_mapCount)
346 346 barsetAt(topLeft.row() - m_mapBarBottom)->setValue(topLeft.column() - m_mapFirst, m_model->data(topLeft, Qt::DisplayRole).toDouble());
347 347 }
348 348 }
349 349
350 350 void QBarSeries::modelDataAdded(QModelIndex /*parent*/, int start, int /*end*/)
351 351 {
352 352 if (m_mapOrientation == Qt::Vertical) {
353 353 insertCategory(start - m_mapFirst, QString("Row: %1").arg(start + 1));
354 354 for (int i = 0; i <= m_mapBarTop - m_mapBarBottom; i++) {
355 355 barsetAt(i)->insertValue(start - m_mapFirst, m_model->data(m_model->index(start, i), Qt::DisplayRole).toDouble());
356 356 }
357 357 } else {
358 358 insertCategory(start - m_mapFirst, QString("Column: %1").arg(start + 1));
359 359 for (int i = 0; i <= m_mapBarTop - m_mapBarBottom; i++) {
360 360 barsetAt(i)->insertValue(start - m_mapFirst, m_model->data(m_model->index(i, start), Qt::DisplayRole).toDouble());
361 361 }
362 362 }
363 363 emit restructuredBar(1);
364 364 }
365 365
366 366 void QBarSeries::modelDataRemoved(QModelIndex parent, int start, int end)
367 367 {
368 368 Q_UNUSED(parent)
369 369 Q_UNUSED(end)
370 370
371 371 removeCategory(start - m_mapFirst);
372 372 for (int i = 0; i <= m_mapBarTop - m_mapBarBottom; i++)
373 373 {
374 374 barsetAt(i)->removeValue(start - m_mapFirst);
375 375 }
376 376 emit restructuredBar(1);
377 377 }
378 378
379 379 void QBarSeries::barsetChanged()
380 380 {
381 381 emit updatedBars();
382 382 }
383 383
384 384 QBarCategories QBarSeries::categories() const
385 385 {
386 386 QBarCategories categories;
387 387 int count = m_internalModel->categoryCount();
388 388 for (int i=1; i <= count; i++) {
389 389 categories.insert(i, m_internalModel->categoryName(i - 1));
390 390 }
391 391 return categories;
392 392 }
393 393
394 /*!
395 Sets the visibility of labels in series to \a visible
396 */
394 397 void QBarSeries::setLabelsVisible(bool visible)
395 398 {
396 399 foreach (QBarSet* s, barSets()) {
397 400 s->setLabelsVisible(visible);
398 401 }
399 402 }
400 403
401 404
402 405 #include "moc_qbarseries.cpp"
403 406
404 407 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,274 +1,274
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "qbarset.h"
22 22 #include <QDebug>
23 23 #include <QToolTip>
24 24
25 25 QTCOMMERCIALCHART_BEGIN_NAMESPACE
26 26
27 27 /*!
28 28 \class QBarSet
29 29 \brief part of QtCommercial chart API.
30 30
31 31 QBarSet represents one set of bars. Set of bars contains one data value for each category.
32 32 First value of set is assumed to belong to first category, second to second category and so on.
33 33 If set has fewer values than there are categories, then the missing values are assumed to be
34 34 at the end of set. For missing values in middle of a set, numerical value of zero is used.
35 35
36 36 \mainclass
37 37
38 38 \sa QBarSeries, QStackedBarSeries, QPercentBarSeries
39 39 */
40 40
41 41 /*!
42 42 \fn void QBarSet::clicked(QString category, Qt::MouseButtons button)
43 43 \brief signals that set has been clicked
44 44 Parameter \a category describes on which category was clicked
45 45 Parameter \a button mouse button
46 46 */
47 47
48 48 /*!
49 49 \fn void QBarSet::hoverEnter(QPoint pos)
50 50 \brief signals that mouse has entered over the set at position \a pos.
51 51 */
52 52
53 53 /*!
54 54 \fn void QBarSet::hoverLeave()
55 55 \brief signals that mouse has left from the set.
56 56 */
57 57
58 58 /*!
59 59 \fn void QBarSet::setLabelssVisible(bool visible = true)
60 60 \brief Sets visibility of bar labels. If \a visible is true, labels are drawn on top of barsets.
61 61 */
62 62
63 63 /*!
64 64 \fn void QBarSet::showToolTip(QPoint pos, QString tip)
65 65 \brief \internal \a pos \a tip
66 66 */
67 67
68 68
69 69 /*!
70 70 Constructs QBarSet with a name of \a name and with parent of \a parent
71 71 */
72 72 QBarSet::QBarSet(QString name, QObject *parent)
73 73 : QObject(parent)
74 74 ,m_name(name)
75 75 ,m_labelsVisible(false)
76 76 {
77 77 }
78 78
79 79 /*!
80 80 Sets new \a name for set.
81 81 */
82 82 void QBarSet::setName(QString name)
83 83 {
84 84 m_name = name;
85 85 }
86 86
87 87 /*!
88 88 Returns name of the set.
89 89 */
90 90 QString QBarSet::name() const
91 91 {
92 92 return m_name;
93 93 }
94 94
95 95 /*!
96 96 Appends new value \a value to the end of set.
97 97 */
98 98 QBarSet& QBarSet::operator << (const qreal &value)
99 99 {
100 100 m_values.append(value);
101 101 emit structureChanged();
102 102 return *this;
103 103 }
104 104
105 105 void QBarSet::insertValue(int i, qreal value)
106 106 {
107 107 m_values.insert(i, value);
108 108 }
109 109
110 110 void QBarSet::removeValue(int i)
111 111 {
112 112 m_values.removeAt(i);
113 113 }
114 114
115 115 /*!
116 116 Returns count of values in set.
117 117 */
118 118 int QBarSet::count() const
119 119 {
120 120 return m_values.count();
121 121 }
122 122
123 123 /*!
124 124 Returns value of set indexed by \a index
125 125 */
126 126 qreal QBarSet::valueAt(int index) const
127 127 {
128 128 return m_values.at(index);
129 129 }
130 130
131 131 /*!
132 132 Sets a new value \a value to set, indexed by \a index
133 133 */
134 134 void QBarSet::setValue(int index, qreal value)
135 135 {
136 136 m_values.replace(index,value);
137 137 emit valueChanged();
138 138 }
139 139
140 140 /*!
141 141 Returns total sum of all values in barset.
142 142 */
143 143 qreal QBarSet::total() const
144 144 {
145 145 qreal total(0);
146 146 for (int i=0; i < m_values.count(); i++) {
147 147 total += m_values.at(i);
148 148 }
149 149 return total;
150 150 }
151 151
152 152 /*!
153 153 Sets pen for set. Bars of this set are drawn using \a pen
154 154 */
155 155 void QBarSet::setPen(const QPen &pen)
156 156 {
157 157 m_pen = pen;
158 158 emit valueChanged();
159 159 }
160 160
161 161 /*!
162 162 Returns pen of the set.
163 163 */
164 164 QPen QBarSet::pen() const
165 165 {
166 166 return m_pen;
167 167 }
168 168
169 169 /*!
170 170 Sets brush for the set. Bars of this set are drawn using \a brush
171 171 */
172 172 void QBarSet::setBrush(const QBrush &brush)
173 173 {
174 174 m_brush = brush;
175 175 emit valueChanged();
176 176 }
177 177
178 178 /*!
179 179 Returns brush of the set.
180 180 */
181 181 QBrush QBarSet::brush() const
182 182 {
183 183 return m_brush;
184 184 }
185 185
186 186 /*!
187 Sets pen of the values that are drawn on top of this barset
187 Sets \a pen of the values that are drawn on top of this barset
188 188 */
189 189 void QBarSet::setLabelPen(const QPen &pen)
190 190 {
191 191 m_labelPen = pen;
192 192 emit valueChanged();
193 193 }
194 194
195 195 /*!
196 196 Returns pen of the values that are drawn on top of this barset
197 197 */
198 198 QPen QBarSet::labelPen() const
199 199 {
200 200 return m_labelPen;
201 201 }
202 202
203 203 /*!
204 Sets brush of the values that are drawn on top of this barset
204 Sets \a brush of the values that are drawn on top of this barset
205 205 */
206 206 void QBarSet::setLabelBrush(const QBrush &brush)
207 207 {
208 208 m_labelBrush = brush;
209 209 emit valueChanged();
210 210 }
211 211
212 212 /*!
213 213 Returns brush of the values that are drawn on top of this barset
214 214 */
215 215 QBrush QBarSet::labelBrush() const
216 216 {
217 217 return m_labelBrush;
218 218 }
219 219
220 220 /*!
221 Sets the pen for values that are drawn on top of this barset
221 Sets the \a font for values that are drawn on top of this barset
222 222 */
223 223 void QBarSet::setLabelFont(const QFont &font)
224 224 {
225 225 m_labelFont = font;
226 226 emit valueChanged();
227 227 }
228 228
229 229 /*!
230 230 Returns the pen for values that are drawn on top of this set
231 231 */
232 232 QFont QBarSet::labelFont() const
233 233 {
234 234 return m_labelFont;
235 235 }
236 236
237 237 /*!
238 238 Sets the visibility of barset values to \a visible
239 239 */
240 240 void QBarSet::setLabelsVisible(bool visible)
241 241 {
242 242 m_labelsVisible = visible;
243 243 emit labelsVisibleChanged(visible);
244 244 }
245 245
246 246 /*!
247 247 Returns the visibility of values
248 248 */
249 249 bool QBarSet::labelsVisible() const
250 250 {
251 251 return m_labelsVisible;
252 252 }
253 253
254 254 /*!
255 255 \internal \a pos
256 256 */
257 257 void QBarSet::barHoverEnterEvent(QPoint pos)
258 258 {
259 259 emit showToolTip(pos, m_name);
260 260 emit hoverEnter(pos);
261 261 }
262 262
263 263 /*!
264 264 \internal
265 265 */
266 266 void QBarSet::barHoverLeaveEvent()
267 267 {
268 268 // Emit signal to user of charts
269 269 emit hoverLeave();
270 270 }
271 271
272 272 #include "moc_qbarset.cpp"
273 273
274 274 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,92 +1,83
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "stackedbarchartitem_p.h"
22 22 #include "bar_p.h"
23 23 #include "barlabel_p.h"
24 24 #include "qbarset.h"
25 #include <QDebug>
26 25
27 26 QTCOMMERCIALCHART_BEGIN_NAMESPACE
28 27
29 28 StackedBarChartItem::StackedBarChartItem(QBarSeries *series, ChartPresenter *presenter) :
30 29 BarChartItem(series, presenter)
31 30 {
32 31 }
33 32
34 StackedBarChartItem::~StackedBarChartItem()
35 {
36 }
37
38 33 QVector<QRectF> StackedBarChartItem::calculateLayout()
39 34 {
40 35 QVector<QRectF> layout;
41 // Use temporary qreals for accurancy (we might get some compiler warnings... :)
36 // Use temporary qreals for accurancy
42 37
43 qreal maxSum = m_series->maxCategorySum();
44 38 // Domain:
45 if (m_domainMaxY > maxSum) {
46 maxSum = m_domainMaxY;
47 }
48
39 qreal range = m_domainMaxY - m_domainMinY;
49 40 qreal height = geometry().height();
50 41 qreal width = geometry().width();
51 qreal scale = (height / m_series->maxCategorySum());
42 qreal scale = (height / range);
52 43 qreal categotyCount = m_series->categoryCount();
53 44 qreal barWidth = width / (categotyCount * 2);
54 45 qreal xStep = width / categotyCount;
55 46 qreal xPos = xStep / 2 - barWidth / 2;
56 47
57 48 int itemIndex(0);
58 49 for (int category = 0; category < categotyCount; category++) {
59 qreal yPos = height;
50 qreal yPos = height + scale * m_domainMinY;
60 51 for (int set=0; set < m_series->barsetCount(); set++) {
61 52 QBarSet* barSet = m_series->barsetAt(set);
62 53
63 54 qreal barHeight = barSet->valueAt(category) * scale;
64 55 Bar* bar = m_bars.at(itemIndex);
65 56 bar->setPen(barSet->pen());
66 57 bar->setBrush(barSet->brush());
67 58 QRectF rect(xPos, yPos-barHeight, barWidth, barHeight);
68 59 layout.append(rect);
69 60
70 61 BarLabel* label = m_labels.at(itemIndex);
71 62
72 63 if (!qFuzzyIsNull(barSet->valueAt(category))) {
73 64 label->setText(QString::number(barSet->valueAt(category)));
74 65 } else {
75 66 label->setText(QString(""));
76 67 }
77 68
78 69 label->setPos(xPos + (rect.width()/2 - label->boundingRect().width()/2)
79 70 ,yPos - barHeight/2 - label->boundingRect().height()/2);
80 // value->setFont(barSet->valueFont());
71 label->setFont(barSet->labelFont());
81 72 itemIndex++;
82 73 yPos -= barHeight;
83 74 }
84 75 xPos += xStep;
85 76 }
86 77
87 78 return layout;
88 79 }
89 80
90 81 #include "moc_stackedbarchartitem_p.cpp"
91 82
92 83 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,48 +1,47
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #ifndef STACKEDBARCHARTITEM_H
22 22 #define STACKEDBARCHARTITEM_H
23 23
24 24 #include "barchartitem_p.h"
25 25 #include "qstackedbarseries.h"
26 26 #include <QGraphicsItem>
27 27
28 28 QTCOMMERCIALCHART_BEGIN_NAMESPACE
29 29
30 30 class StackedBarChartItem : public BarChartItem
31 31 {
32 32 Q_OBJECT
33 33 public:
34 34 StackedBarChartItem(QBarSeries *series, ChartPresenter *presenter);
35 ~StackedBarChartItem();
36 35
37 36 private:
38 37 // From BarChartItem
39 38 virtual QVector<QRectF> calculateLayout();
40 39
41 40 private:
42 41
43 42 // Data
44 43 };
45 44
46 45 QTCOMMERCIALCHART_END_NAMESPACE
47 46
48 47 #endif // STACKEDBARCHARTITEM_H
General Comments 0
You need to be logged in to leave comments. Login now