##// END OF EJS Templates
barchart: removed tooltip. hoverEntered and hoverLeaved signals combined to hovered(bool) signal
sauimone -
r975:b81e04837829
parent child
Show More
@@ -1,117 +1,116
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 <QtGui/QApplication>
22 22 #include <QMainWindow>
23 23 #include <QChartView>
24 24 #include <QBarSet>
25 25 #include <QLegend>
26 26 #include "drilldownseries.h"
27 27 #include "drilldownchart.h"
28 28
29 29 QTCOMMERCIALCHART_USE_NAMESPACE
30 30
31 31 int main(int argc, char *argv[])
32 32 {
33 33 //! [1]
34 34 QApplication a(argc, argv);
35 35 QMainWindow window;
36 36 //! [1]
37 37
38 38 //! [2]
39 39 DrilldownChart* drilldownChart = new DrilldownChart();
40 40 drilldownChart->setTheme(QChart::ChartThemeBlueIcy);
41 41 drilldownChart->setAnimationOptions(QChart::SeriesAnimations);
42 42 //! [2]
43 43
44 44 //! [3]
45 45 // Define categories
46 46 QStringList months;
47 47 months << "May" << "Jun" << "Jul" << "Aug" << "Sep";
48 48 QStringList weeks;
49 49 weeks << "week 1" << "week 2" << "week 3" << "week 4";
50 50 QStringList plants;
51 51 plants << "Habanero" << "Lemon Drop" << "Starfish" << "Aji Amarillo";
52 52 //! [3]
53 53
54 54 //! [4]
55 55 // Create drilldown structure
56 56 DrilldownBarSeries* seasonSeries = new DrilldownBarSeries(months, drilldownChart);
57 57 seasonSeries->setName("Crop by month - Season");
58 58
59 59 // Each month in season series has drilldown series for weekly data
60 60 foreach (QString month, months) {
61 61
62 62 // Create drilldown series for every week
63 63 DrilldownBarSeries* weeklySeries = new DrilldownBarSeries(weeks, drilldownChart);
64 64 seasonSeries->mapDrilldownSeries(month, weeklySeries);
65 65
66 66 // Drilling down from weekly data brings us back to season data.
67 67 foreach (QString week, weeks) {
68 68 weeklySeries->mapDrilldownSeries(week, seasonSeries);
69 69 weeklySeries->setName(QString("Crop by week - " + month));
70 70 }
71 71
72 72 // Use right click signal to implement drilldown
73 73 QObject::connect(weeklySeries, SIGNAL(clicked(QBarSet*,QString,Qt::MouseButtons)), drilldownChart, SLOT(handleClicked(QBarSet*,QString,Qt::MouseButtons)));
74 74 }
75 75
76 76 // Enable drilldown from season series using right click.
77 77 QObject::connect(seasonSeries, SIGNAL(clicked(QBarSet*,QString,Qt::MouseButtons)), drilldownChart, SLOT(handleClicked(QBarSet*,QString,Qt::MouseButtons)));
78 78 //! [4]
79 79
80 80 //! [5]
81 81 // Fill monthly and weekly series with data
82 82 foreach (QString plant, plants) {
83 83 QBarSet* monthlyCrop = new QBarSet(plant);
84 84 foreach (QString month, months) {
85 85 QBarSet* weeklyCrop = new QBarSet(plant);
86 86 foreach (QString week, weeks )
87 87 *weeklyCrop << (qrand() % 20);
88 88 // Get the drilldown series from season series and add crop to it.
89 89 seasonSeries->drilldownSeries(month)->appendBarSet(weeklyCrop);
90 seasonSeries->drilldownSeries(month)->setToolTipEnabled(true);
91 90 *monthlyCrop << weeklyCrop->sum();
92 91 }
93 92 seasonSeries->appendBarSet(monthlyCrop);
94 93 }
95 94 //! [5]
96 95
97 96 //! [6]
98 97 // Show season series in initial view
99 98 drilldownChart->changeSeries(seasonSeries);
100 99 drilldownChart->setTitle(seasonSeries->name());
101 100 //! [6]
102 101
103 102 //! [7]
104 103 drilldownChart->axisX()->setGridLineVisible(false);
105 104 drilldownChart->axisY()->setNiceNumbers(true);
106 105 drilldownChart->legend()->setVisible(true);
107 106 drilldownChart->legend()->setAlignment(QLegend::AlignmentBottom);
108 107 //! [7]
109 108
110 109 QChartView *chartView = new QChartView(drilldownChart);
111 110 window.setCentralWidget(chartView);
112 111 window.resize(400, 300);
113 112 window.show();
114 113
115 114 return a.exec();
116 115 }
117 116
@@ -1,55 +1,57
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 "bar_p.h"
22 22 #include <QDebug>
23 23 #include <QPainter>
24 24 #include <QGraphicsSceneEvent>
25 25
26 26 QTCOMMERCIALCHART_BEGIN_NAMESPACE
27 27
28 28 Bar::Bar(QBarSet *barset, QString category, QGraphicsItem *parent) : QGraphicsRectItem(parent),
29 29 m_category(category),
30 30 m_barset(barset)
31 31 {
32 32 setAcceptedMouseButtons(Qt::LeftButton | Qt::RightButton);
33 33 setAcceptHoverEvents(true);
34 34 }
35 35
36 36 void Bar::mousePressEvent(QGraphicsSceneMouseEvent *event)
37 37 {
38 38 emit clicked(m_category, event->button());
39 39 emit clicked(m_barset, m_category, event->button());
40 40 }
41 41
42 42 void Bar::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
43 43 {
44 emit hoverEntered(event->lastScreenPos());
44 emit hovered(true);
45 emit hovered(m_barset, true);
45 46 }
46 47
47 48 void Bar::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
48 49 {
49 50 Q_UNUSED(event)
50 emit hoverLeaved();
51 emit hovered(false);
52 emit hovered(m_barset, false);
51 53 }
52 54
53 55 #include "moc_bar_p.cpp"
54 56
55 57 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,56 +1,56
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 BAR_H
22 22 #define BAR_H
23 23
24 24 #include "qchartglobal.h"
25 25 #include <QGraphicsRectItem>
26 26
27 27 QTCOMMERCIALCHART_BEGIN_NAMESPACE
28 28
29 29 class QBarSet;
30 30
31 31 // Single visual bar item of chart
32 32 class Bar : public QObject, public QGraphicsRectItem
33 33 {
34 34 Q_OBJECT
35 35 public:
36 36 Bar(QBarSet *barset, QString category, QGraphicsItem *parent = 0);
37 37
38 38 public:
39 39 void mousePressEvent(QGraphicsSceneMouseEvent *event);
40 40 void hoverEnterEvent(QGraphicsSceneHoverEvent *event);
41 41 void hoverLeaveEvent(QGraphicsSceneHoverEvent *event);
42 42
43 43 Q_SIGNALS:
44 44 void clicked(QString category, Qt::MouseButtons button);
45 45 void clicked(QBarSet *barset, QString category, Qt::MouseButtons button);
46 void hoverEntered(QPoint pos);
47 void hoverLeaved();
46 void hovered(bool status);
47 void hovered(QBarSet *barset, bool status);
48 48
49 49 private:
50 50 QString m_category;
51 51 QBarSet *m_barset;
52 52 };
53 53
54 54 QTCOMMERCIALCHART_END_NAMESPACE
55 55
56 56 #endif // BAR_H
@@ -1,218 +1,208
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 "qbarset_p.h"
26 26 #include "qbarseries.h"
27 27 #include "qbarseries_p.h"
28 28 #include "qchart.h"
29 29 #include "qchartaxis.h"
30 30 #include "qchartaxiscategories.h"
31 31 #include "chartpresenter_p.h"
32 32 #include "chartanimator_p.h"
33 33 #include "chartdataset_p.h"
34 #include <QToolTip>
35 34 #include <QPainter>
36 35
37 36 QTCOMMERCIALCHART_BEGIN_NAMESPACE
38 37
39 38 BarChartItem::BarChartItem(QBarSeries *series, ChartPresenter *presenter) :
40 39 ChartItem(presenter),
41 40 m_layoutSet(false),
42 41 m_series(series)
43 42 {
44 43 setFlag(ItemClipsChildrenToShape);
45 connect(series->d_func(), SIGNAL(showToolTip(QPoint,QString)), this, SLOT(showToolTip(QPoint,QString)));
46 44 connect(series->d_func(), SIGNAL(updatedBars()), this, SLOT(handleLayoutChanged()));
47 45 connect(series->d_func(), SIGNAL(restructuredBars()), this, SLOT(handleModelChanged()));
48 46 setZValue(ChartPresenter::BarSeriesZValue);
49 47 dataChanged();
50 48 }
51 49
52 50 BarChartItem::~BarChartItem()
53 51 {
54 disconnect(this,SLOT(showToolTip(QPoint,QString)));
55 52 }
56 53
57 54 void BarChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
58 55 {
59 56 Q_UNUSED(painter);
60 57 Q_UNUSED(option);
61 58 Q_UNUSED(widget);
62 59 }
63 60
64 61 QRectF BarChartItem::boundingRect() const
65 62 {
66 63 return m_rect.translated(-m_rect.topLeft());
67 64 }
68 65
69 66 void BarChartItem::dataChanged()
70 67 {
71 // TODO: performance optimizations. Do we really need to delete and create items every time data is changed or can we reuse them?
72 68 foreach(QGraphicsItem *item, childItems()) {
73 69 delete item;
74 70 }
75 71
76 72 m_bars.clear();
77 73 m_labels.clear();
78 74 m_layout.clear();
79 75
80 76 // Create new graphic items for bars
81 77 for (int c = 0; c < m_series->categoryCount(); c++) {
82 78 QString category = m_series->d_func()->categoryName(c);
83 79 for (int s = 0; s < m_series->barsetCount(); s++) {
84 80 QBarSet *set = m_series->d_func()->barsetAt(s);
85 81 Bar *bar = new Bar(set,category,this);
86 82 m_bars.append(bar);
87 83 connect(bar, SIGNAL(clicked(QString,Qt::MouseButtons)), set, SIGNAL(clicked(QString,Qt::MouseButtons)));
88 84 connect(bar, SIGNAL(clicked(QBarSet*,QString,Qt::MouseButtons)), m_series, SIGNAL(clicked(QBarSet*,QString,Qt::MouseButtons)));
89 connect(bar, SIGNAL(hoverEntered(QPoint)), set->d_ptr.data(), SLOT(barHoverEnterEvent(QPoint)));
90 connect(bar, SIGNAL(hoverLeaved()), set->d_ptr.data(), SLOT(barHoverLeaveEvent()));
85 connect(bar, SIGNAL(hovered(bool)), set, SIGNAL(hovered(bool)));
86 connect(bar, SIGNAL(hovered(QBarSet*,bool)), m_series, SIGNAL(hovered(QBarSet*,bool)));
91 87 m_layout.append(QRectF(0, 0, 0, 0));
92 88 }
93 89 }
94 90
95 91 // Create labels
96 92 for (int category = 0; category < m_series->categoryCount(); category++) {
97 93 for (int s = 0; s < m_series->barsetCount(); s++) {
98 94 QBarSet *set = m_series->d_func()->barsetAt(s);
99 95 BarLabel *value = new BarLabel(*set, this);
100 96 m_labels.append(value);
101 97 connect(set->d_ptr.data(),SIGNAL(labelsVisibleChanged(bool)),value,SLOT(labelsVisibleChanged(bool)));
102 98 }
103 99 }
104 100 }
105 101
106 102 QVector<QRectF> BarChartItem::calculateLayout()
107 103 {
108 104 QVector<QRectF> layout;
109 105
110 106 // Use temporary qreals for accurancy
111 107 qreal categoryCount = m_series->categoryCount();
112 108 qreal setCount = m_series->barsetCount();
113 109
114 110 // Domain:
115 111 qreal width = geometry().width();
116 112 qreal height = geometry().height();
117 113 qreal range = m_domainMaxY - m_domainMinY;
118 114 qreal scale = (height / range);
119 115 qreal categoryWidth = width / categoryCount;
120 116 qreal barWidth = categoryWidth / (setCount+1);
121 117
122 118 int itemIndex(0);
123 119 for (int category = 0; category < categoryCount; category++) {
124 120 qreal xPos = categoryWidth * category + barWidth / 2;
125 121 qreal yPos = height + scale * m_domainMinY;
126 122 for (int set = 0; set < setCount; set++) {
127 123 QBarSet* barSet = m_series->d_func()->barsetAt(set);
128 124
129 125 qreal barHeight = barSet->valueAt(category) * scale;
130 126 Bar* bar = m_bars.at(itemIndex);
131 127
132 128 QRectF rect(xPos, yPos - barHeight, barWidth, barHeight);
133 129 layout.append(rect);
134 130 bar->setPen(barSet->pen());
135 131 bar->setBrush(barSet->brush());
136 132
137 133 BarLabel* label = m_labels.at(itemIndex);
138 134
139 135 if (!qFuzzyIsNull(barSet->valueAt(category))) {
140 136 label->setText(QString::number(barSet->valueAt(category)));
141 137 } else {
142 138 label->setText(QString(""));
143 139 }
144 140
145 141 label->setPos(xPos + (rect.width()/2 - label->boundingRect().width()/2)
146 142 ,yPos - barHeight/2 - label->boundingRect().height()/2);
147 143 label->setFont(barSet->labelFont());
148 144
149 145 itemIndex++;
150 146 xPos += barWidth;
151 147 }
152 148 }
153 149 return layout;
154 150 }
155 151
156 152 void BarChartItem::applyLayout(const QVector<QRectF> &layout)
157 153 {
158 154 if (animator())
159 155 animator()->updateLayout(this, m_layout, layout);
160 156 else
161 157 setLayout(layout);
162 158 }
163 159
164 160 void BarChartItem::setLayout(const QVector<QRectF> &layout)
165 161 {
166 162 m_layout = layout;
167 163
168 164 for (int i=0; i < m_bars.count(); i++)
169 165 m_bars.at(i)->setRect(layout.at(i));
170 166
171 167 update();
172 168 }
173 169 //handlers
174 170
175 171 void BarChartItem::handleModelChanged()
176 172 {
177 173 dataChanged();
178 174 }
179 175
180 176 void BarChartItem::handleDomainChanged(qreal minX, qreal maxX, qreal minY, qreal maxY)
181 177 {
182 178 m_domainMinX = minX;
183 179 m_domainMaxX = maxX;
184 180 m_domainMinY = minY;
185 181 m_domainMaxY = maxY;
186 182 handleLayoutChanged();
187 183 }
188 184
189 185 void BarChartItem::handleGeometryChanged(const QRectF &rect)
190 186 {
191 187 prepareGeometryChange();
192 188 m_clipRect = rect.translated(-rect.topLeft());
193 189 m_rect = rect;
194 190 handleLayoutChanged();
195 191 m_layoutSet = true;
196 192 setPos(rect.topLeft());
197 193 }
198 194
199 195 void BarChartItem::handleLayoutChanged()
200 196 {
201 197 if ((m_rect.width() <= 0) || (m_rect.height() <= 0)) {
202 198 // rect size zero.
203 199 return;
204 200 }
205 201 QVector<QRectF> layout = calculateLayout();
206 202 applyLayout(layout);
207 203 update();
208 204 }
209 205
210 void BarChartItem::showToolTip(QPoint pos, QString tip)
211 {
212 // TODO: cool tooltip instead of default
213 QToolTip::showText(pos, tip);
214 }
215
216 206 #include "moc_barchartitem_p.cpp"
217 207
218 208 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,90 +1,87
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 60 public Q_SLOTS:
61 61 void handleModelChanged();
62 62 void handleDomainChanged(qreal minX, qreal maxX, qreal minY, qreal maxY);
63 63 void handleGeometryChanged(const QRectF &size);
64 64 void handleLayoutChanged();
65 65
66 // Internal slots
67 void showToolTip(QPoint pos, QString tip); // shows tooltip (if enabled)
68
69 66 protected:
70 67
71 68 // TODO: consider these.
72 69 qreal m_domainMinX;
73 70 qreal m_domainMaxX;
74 71 qreal m_domainMinY;
75 72 qreal m_domainMaxY;
76 73
77 74 QRectF m_rect;
78 75 QRectF m_clipRect;
79 76 bool m_layoutSet; // True, if component has been laid out.
80 77 QVector<QRectF> m_layout;
81 78
82 79 // Not owned.
83 80 QBarSeries *m_series;
84 81 QList<Bar *> m_bars;
85 82 QList<BarLabel *> m_labels;
86 83 };
87 84
88 85 QTCOMMERCIALCHART_END_NAMESPACE
89 86
90 87 #endif // BARCHARTITEM_H
@@ -1,540 +1,513
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 "qbarseries.h"
22 22 #include "qbarseries_p.h"
23 23 #include "qbarset.h"
24 24 #include "qbarset_p.h"
25 25 #include "barchartmodel_p.h"
26 26 #include "domain_p.h"
27 27 #include "legendmarker_p.h"
28 28 #include "chartdataset_p.h"
29 29 #include "charttheme_p.h"
30 30 #include "chartanimator_p.h"
31 31
32 32 #include <QAbstractItemModel>
33 33 #include <QModelIndex>
34 34
35 35 QTCOMMERCIALCHART_BEGIN_NAMESPACE
36 36
37 37 /*!
38 38 \class QBarSeries
39 39 \brief part of QtCommercial chart API.
40 40
41 41 QBarSeries represents a series of data shown as bars. One QBarSeries can contain multiple
42 42 QBarSet data sets. QBarSeries groups the data from sets to categories, which are defined
43 43 by QStringList.
44 44
45 45 \mainclass
46 46
47 47 \sa QBarSet, QStackedBarSeries, QPercentBarSeries
48 48 */
49 49
50 50 /*!
51 51 \fn virtual QSeriesType QBarSeries::type() const
52 52 \brief Returns type of series.
53 53 \sa QSeries, QSeriesType
54 54 */
55 55
56 56 /*!
57 57 \fn void QBarSeries::clicked(QBarSet *barset, QString category, Qt::MouseButtons button)
58 58
59 59 The signal is emitted if the user clicks with a mouse \a button on top of QBarSet \a barset of category \a category
60 60 contained by the series.
61 61 */
62 62
63 63 /*!
64 64 \fn void QBarSeries::selected()
65 65
66 66 The signal is emitted if the user selects/deselects the series. The logic for storing selections should be
67 67 implemented by the user of QBarSeries API.
68 68 */
69 69
70 70 /*!
71 71 Constructs empty QBarSeries. Parameter \a categories defines the categories for chart.
72 72 QBarSeries is QObject which is a child of a \a parent.
73 73 */
74 74 QBarSeries::QBarSeries(QBarCategories categories, QObject *parent) :
75 75 QSeries(*new QBarSeriesPrivate(categories, this),parent)
76 76 {
77 77 }
78 78
79 79 /*!
80 80 \internal
81 81 */
82 82 QBarSeries::QBarSeries(QBarSeriesPrivate &d, QObject *parent) :
83 83 QSeries(d,parent)
84 84 {
85 85 }
86 86
87 87 QSeries::QSeriesType QBarSeries::type() const
88 88 {
89 89 return QSeries::SeriesTypeBar;
90 90 }
91 91
92 92 /*!
93 93 Adds a set of bars to series. Takes ownership of \a set.
94 94 Connects the clicked(QString, Qt::MouseButtons) signal
95 95 of \a set to this series
96 96 */
97 97 void QBarSeries::appendBarSet(QBarSet *set)
98 98 {
99 99 Q_D(QBarSeries);
100 100 d->m_internalModel->appendBarSet(set);
101 101 QObject::connect(set->d_ptr.data(), SIGNAL(valueChanged()), d, SLOT(barsetChanged()));
102 102 emit d->restructuredBars();
103 103 }
104 104
105 105 /*!
106 106 Removes a set of bars from series. Releases ownership of \a set. Doesn't delete \a set.
107 107 Disconnects the clicked(QString, Qt::MouseButtons) signal
108 108 of \a set from this series
109 109 */
110 110 void QBarSeries::removeBarSet(QBarSet *set)
111 111 {
112 112 Q_D(QBarSeries);
113 113 d->m_internalModel->removeBarSet(set);
114 114 emit d->restructuredBars();
115 115 }
116 116
117 117 /*!
118 118 Adds a list of barsets to series. Takes ownership of \a sets.
119 119 Connects the clicked(QString, Qt::MouseButtons) signals
120 120 of \a sets to this series
121 121 */
122 122 void QBarSeries::appendBarSets(QList<QBarSet* > sets)
123 123 {
124 124 Q_D(QBarSeries);
125 125 foreach (QBarSet* barset, sets) {
126 126 d->m_internalModel->appendBarSet(barset);
127 127 QObject::connect(barset, SIGNAL(valueChanged()), this, SLOT(barsetChanged()));
128 128 }
129 129 emit d->restructuredBars();
130 130
131 131 }
132 132
133 133 /*!
134 134 Removes a list of barsets from series. Releases ownership of \a sets. Doesn't delete \a sets.
135 135 Disconnects the clicked(QString, Qt::MouseButtons) signal
136 136 of \a sets from this series
137 137 */
138 138 void QBarSeries::removeBarSets(QList<QBarSet* > sets)
139 139 {
140 140 Q_D(QBarSeries);
141 141
142 142 foreach (QBarSet* barset, sets) {
143 143 d->m_internalModel->removeBarSet(barset);
144 144 }
145 145 emit d->restructuredBars();
146 146 }
147 147
148 148 /*!
149 149 Inserts new \a set on the \a i position.
150 150 The barset that is currently at this postion is moved to postion i + 1
151 151 */
152 152 void QBarSeries::insertBarSet(int i, QBarSet *set)
153 153 {
154 154 Q_D(QBarSeries);
155 155 d->m_internalModel->insertBarSet(i, set);
156 156 emit d->barsetChanged();
157 157 }
158 158
159 159 /*!
160 160 Inserts new \a category on the \a i position.
161 161 The category that is currently at this postion is moved to postion i + 1
162 162 \sa removeCategory()
163 163 */
164 164 void QBarSeries::insertCategory(int i, QString category)
165 165 {
166 166 Q_D(QBarSeries);
167 167 d->m_internalModel->insertCategory(i, category);
168 168 }
169 169
170 170 /*!
171 171 Removes the category specified by \a i
172 172 \sa insertCategory()
173 173 */
174 174 void QBarSeries::removeCategory(int i)
175 175 {
176 176 Q_D(QBarSeries);
177 177 d->m_internalModel->removeCategory(i);
178 178 }
179 179
180 180 /*!
181 181 Returns number of sets in series.
182 182 */
183 183 int QBarSeries::barsetCount() const
184 184 {
185 185 Q_D(const QBarSeries);
186 186 return d->m_internalModel->barsetCount();
187 187 }
188 188
189 189 /*!
190 190 Returns number of categories in series
191 191 */
192 192 int QBarSeries::categoryCount() const
193 193 {
194 194 Q_D(const QBarSeries);
195 195 return d->m_internalModel->categoryCount();
196 196 }
197 197
198 198 /*!
199 199 Returns a list of sets in series. Keeps ownership of sets.
200 200 */
201 201 QList<QBarSet*> QBarSeries::barSets() const
202 202 {
203 203 Q_D(const QBarSeries);
204 204 return d->m_internalModel->barSets();
205 205 }
206 206
207 207 /*!
208 Enables or disables tooltip depending on parameter \a enabled.
209 Tooltip shows the name of set, when mouse is hovering on top of bar.
210 Calling without parameter \a enabled, enables the tooltip
211 */
212 void QBarSeries::setToolTipEnabled(bool enabled)
213 {
214 Q_D(QBarSeries);
215 d->setToolTipEnabled(enabled);
216 }
217
218 /*!
219 208 \fn bool QBarSeries::setModel(QAbstractItemModel *model)
220 209 Sets the \a model to be used as a data source
221 210 */
222 211 bool QBarSeries::setModel(QAbstractItemModel *model)
223 212 {
224 213 Q_D(QBarSeries);
225 214 return d->setModel(model);
226 215 }
227 216
228 217 /*!
229 218 \fn bool QBarSeries::setModelMapping(int categories, int bottomBoundry, int topBoundry, Qt::Orientation orientation)
230 219 Sets column/row specified by \a categories to be used as a list of bar series categories.
231 220 Parameter \a bottomBoundry indicates the column/row where the first bar set is located in the model.
232 221 Parameter \a topBoundry indicates the column/row where the last bar set is located in the model.
233 222 All the columns/rows inbetween those two values are also used as data for bar sets.
234 223 The \a orientation parameter specifies whether the data is in columns or in rows.
235 224 */
236 225 void QBarSeries::setModelMapping(int categories, int bottomBoundary, int topBoundary, Qt::Orientation orientation)
237 226 {
238 227 Q_D(QBarSeries);
239 228 d->setModelMapping(categories,bottomBoundary,topBoundary,orientation);
240 229 }
241 230
242 231 /*!
243 232 Returns the bar categories of the series.
244 233 */
245 234 QBarCategories QBarSeries::categories() const
246 235 {
247 236 Q_D(const QBarSeries);
248 237
249 238 QBarCategories categories;
250 239 int count = d->m_internalModel->categoryCount();
251 240 for (int i=1; i <= count; i++) {
252 241 categories.insert(i, d->m_internalModel->categoryName(i - 1));
253 242 }
254 243 return categories;
255 244
256 245 }
257 246
258 247 /*!
259 248 Sets the visibility of labels in series to \a visible
260 249 */
261 250 void QBarSeries::setLabelsVisible(bool visible)
262 251 {
263 252 foreach (QBarSet* s, barSets()) {
264 253 s->setLabelsVisible(visible);
265 254 }
266 255 }
267 256
268 257 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
269 258
270 259 QBarSeriesPrivate::QBarSeriesPrivate(QBarCategories categories, QBarSeries *q) : QSeriesPrivate(q),
271 260 m_internalModel(new BarChartModel(categories,this)),
272 261 m_model(0),
273 262 m_mapCategories(-1),
274 263 m_mapBarBottom(-1),
275 264 m_mapBarTop(-1),
276 265 m_mapFirst(0),
277 266 m_mapCount(0),
278 267 m_mapOrientation(Qt::Vertical)
279 268 {
280 269 }
281 270
282 271 QBarSet* QBarSeriesPrivate::barsetAt(int index)
283 272 {
284 273 return m_internalModel->barsetAt(index);
285 274 }
286 275
287 276 QString QBarSeriesPrivate::categoryName(int category)
288 277 {
289 278 return m_internalModel->categoryName(category);
290 279 }
291 280
292 void QBarSeriesPrivate::setToolTipEnabled(bool enabled)
293 {
294 // TODO: what if we add sets after call to this function? Those sets won't have tooltip enabled.
295 if (enabled) {
296 for (int i=0; i<m_internalModel->barsetCount(); i++) {
297 QBarSet *set = m_internalModel->barsetAt(i);
298 connect(set->d_ptr.data(), SIGNAL(showToolTip(QPoint,QString)), this, SIGNAL(showToolTip(QPoint,QString)));
299 }
300 } else {
301 for (int i=0; i<m_internalModel->barsetCount(); i++) {
302 QBarSet *set = m_internalModel->barsetAt(i);
303 disconnect(set->d_ptr.data(), SIGNAL(showToolTip(QPoint,QString)), this, SIGNAL(showToolTip(QPoint,QString)));
304 }
305 }
306 }
307
308 281 qreal QBarSeriesPrivate::min()
309 282 {
310 283 return m_internalModel->min();
311 284 }
312 285
313 286 qreal QBarSeriesPrivate::max()
314 287 {
315 288 return m_internalModel->max();
316 289 }
317 290
318 291 qreal QBarSeriesPrivate::valueAt(int set, int category)
319 292 {
320 293 return m_internalModel->valueAt(set, category);
321 294 }
322 295
323 296 qreal QBarSeriesPrivate::percentageAt(int set, int category)
324 297 {
325 298 return m_internalModel->percentageAt(set, category);
326 299 }
327 300
328 301 qreal QBarSeriesPrivate::categorySum(int category)
329 302 {
330 303 return m_internalModel->categorySum(category);
331 304 }
332 305
333 306 qreal QBarSeriesPrivate::absoluteCategorySum(int category)
334 307 {
335 308 return m_internalModel->absoluteCategorySum(category);
336 309 }
337 310
338 311 qreal QBarSeriesPrivate::maxCategorySum()
339 312 {
340 313 return m_internalModel->maxCategorySum();
341 314 }
342 315
343 316 BarChartModel& QBarSeriesPrivate::modelInternal()
344 317 {
345 318 return *m_internalModel;
346 319 }
347 320
348 321 bool QBarSeriesPrivate::setModel(QAbstractItemModel *model)
349 322 {
350 323 // disconnect signals from old model
351 324 if(m_model)
352 325 {
353 326 disconnect(m_model, 0, this, 0);
354 327 m_mapCategories = -1;
355 328 m_mapBarBottom = -1;
356 329 m_mapBarTop = -1;
357 330 m_mapFirst = 0;
358 331 m_mapCount = 0;
359 332 m_mapOrientation = Qt::Vertical;
360 333 }
361 334
362 335 // set new model
363 336 if(model)
364 337 {
365 338 m_model = model;
366 339 return true;
367 340 }
368 341 else
369 342 {
370 343 m_model = 0;
371 344 return false;
372 345 }
373 346 }
374 347
375 348 void QBarSeriesPrivate::setModelMapping(int categories, int bottomBoundry, int topBoundry, Qt::Orientation orientation)
376 349 {
377 350 Q_Q(QBarSeries);
378 351
379 352 if (m_model == 0)
380 353 return;
381 354
382 355 m_mapCategories = categories;
383 356 m_mapBarBottom = bottomBoundry;
384 357 m_mapBarTop = topBoundry;
385 358 // m_mapFirst = 1;
386 359 m_mapOrientation = orientation;
387 360
388 361 // connect the signals
389 362 if (m_mapOrientation == Qt::Vertical) {
390 363 m_mapCount = m_model->rowCount() - m_mapFirst;
391 364 connect(m_model,SIGNAL(dataChanged(QModelIndex,QModelIndex)),
392 365 this, SLOT(modelUpdated(QModelIndex,QModelIndex)));
393 366 connect(m_model,SIGNAL(rowsInserted(QModelIndex,int,int)),
394 367 this, SLOT(modelDataAdded(QModelIndex,int,int)));
395 368 connect(m_model, SIGNAL(rowsRemoved(QModelIndex,int,int)),
396 369 this, SLOT(modelDataRemoved(QModelIndex,int,int)));
397 370 } else {
398 371 m_mapCount = m_model->columnCount() - m_mapFirst;
399 372 connect(m_model,SIGNAL(dataChanged(QModelIndex,QModelIndex)),
400 373 this, SLOT(modelUpdated(QModelIndex,QModelIndex)));
401 374 connect(m_model,SIGNAL(columnsInserted(QModelIndex,int,int)),
402 375 this, SLOT(modelDataAdded(QModelIndex,int,int)));
403 376 connect(m_model, SIGNAL(columnsRemoved(QModelIndex,int,int)),
404 377 this, SLOT(modelDataRemoved(QModelIndex,int,int)));
405 378 }
406 379
407 380 // create the initial bars
408 381 delete m_internalModel;
409 382 if (m_mapOrientation == Qt::Vertical) {
410 383 QStringList categories;
411 384 for (int k = m_mapFirst; k < m_mapFirst + m_mapCount; k++)
412 385 categories << m_model->data(m_model->index(k, m_mapCategories), Qt::DisplayRole).toString();
413 386 m_internalModel = new BarChartModel(categories, this);
414 387
415 388 for (int i = m_mapBarBottom; i <= m_mapBarTop; i++) {
416 389 QBarSet* barSet = new QBarSet(QString("Column: %1").arg(i + 1));
417 390 for(int m = m_mapFirst; m < m_mapFirst + m_mapCount; m++)
418 391 *barSet << m_model->data(m_model->index(m, i), Qt::DisplayRole).toDouble();
419 392 q->appendBarSet(barSet);
420 393 }
421 394 } else {
422 395 QStringList categories;
423 396 for (int k = m_mapFirst; k < m_mapFirst + m_mapCount; k++)
424 397 categories << m_model->data(m_model->index(m_mapCategories, k), Qt::DisplayRole).toString();
425 398 m_internalModel = new BarChartModel(categories, this);
426 399
427 400 for (int i = m_mapBarBottom; i <= m_mapBarTop; i++) {
428 401 QBarSet* barSet = new QBarSet(QString("Row: %1").arg(i + 1));
429 402 for(int m = m_mapFirst; m < m_mapFirst + m_mapCount; m++)
430 403 *barSet << m_model->data(m_model->index(i, m), Qt::DisplayRole).toDouble();
431 404 q->appendBarSet(barSet);
432 405 }
433 406 }
434 407 }
435 408
436 409 void QBarSeriesPrivate::modelUpdated(QModelIndex topLeft, QModelIndex bottomRight)
437 410 {
438 411 Q_UNUSED(bottomRight)
439 412
440 413 if (m_mapOrientation == Qt::Vertical)
441 414 {
442 415 // model update is relevant to BarSeries if the change was made to the part of the model that was mapped to BarSeries
443 416 if (topLeft.column() >= m_mapBarBottom && topLeft.column() <= m_mapBarTop && topLeft.row() >= m_mapFirst && topLeft.row() < m_mapFirst + m_mapCount)
444 417 barsetAt(topLeft.column() - m_mapBarBottom)->setValue(topLeft.row() - m_mapFirst, m_model->data(topLeft, Qt::DisplayRole).toDouble());
445 418 }
446 419 else
447 420 {
448 421 // model update is relevant to BarSeries if the change was made to the part of the model that was mapped to BarSeries
449 422 if (topLeft.row() >= m_mapBarBottom && topLeft.row() <= m_mapBarTop && topLeft.column() >= m_mapFirst && topLeft.column() < m_mapFirst + m_mapCount)
450 423 barsetAt(topLeft.row() - m_mapBarBottom)->setValue(topLeft.column() - m_mapFirst, m_model->data(topLeft, Qt::DisplayRole).toDouble());
451 424 }
452 425 }
453 426
454 427 void QBarSeriesPrivate::modelDataAdded(QModelIndex /*parent*/, int start, int /*end*/)
455 428 {
456 429 Q_Q(QBarSeries);
457 430
458 431 if (m_mapOrientation == Qt::Vertical) {
459 432 q->insertCategory(start - m_mapFirst, QString("Row: %1").arg(start + 1));
460 433 for (int i = 0; i <= m_mapBarTop - m_mapBarBottom; i++) {
461 434 barsetAt(i)->insertValue(start - m_mapFirst, m_model->data(m_model->index(start, i), Qt::DisplayRole).toDouble());
462 435 }
463 436 } else {
464 437 q->insertCategory(start - m_mapFirst, QString("Column: %1").arg(start + 1));
465 438 for (int i = 0; i <= m_mapBarTop - m_mapBarBottom; i++) {
466 439 barsetAt(i)->insertValue(start - m_mapFirst, m_model->data(m_model->index(i, start), Qt::DisplayRole).toDouble());
467 440 }
468 441 }
469 442 emit restructuredBars();
470 443 }
471 444
472 445 void QBarSeriesPrivate::modelDataRemoved(QModelIndex parent, int start, int end)
473 446 {
474 447 Q_Q(QBarSeries);
475 448 Q_UNUSED(parent)
476 449 Q_UNUSED(end)
477 450
478 451 q->removeCategory(start - m_mapFirst);
479 452 for (int i = 0; i <= m_mapBarTop - m_mapBarBottom; i++)
480 453 {
481 454 barsetAt(i)->removeValue(start - m_mapFirst);
482 455 }
483 456 emit restructuredBars();
484 457 }
485 458
486 459 void QBarSeriesPrivate::barsetChanged()
487 460 {
488 461 emit updatedBars();
489 462 }
490 463
491 464 void QBarSeriesPrivate::scaleDomain(Domain& domain)
492 465 {
493 466 qreal minX(domain.minX());
494 467 qreal minY(domain.minY());
495 468 qreal maxX(domain.maxX());
496 469 qreal maxY(domain.maxY());
497 470 int tickXCount(domain.tickXCount());
498 471 int tickYCount(domain.tickYCount());
499 472
500 473 qreal x = m_internalModel->categoryCount();
501 474 qreal y = max();
502 475 minX = qMin(minX, x);
503 476 minY = qMin(minY, y);
504 477 maxX = qMax(maxX, x);
505 478 maxY = qMax(maxY, y);
506 479 tickXCount = x+1;
507 480
508 481 domain.setRangeX(minX,maxX,tickXCount);
509 482 domain.setRangeY(minY,maxY,tickYCount);
510 483 }
511 484
512 485 Chart* QBarSeriesPrivate::createGraphics(ChartPresenter* presenter)
513 486 {
514 487 Q_Q(QBarSeries);
515 488
516 489 BarChartItem* bar = new BarChartItem(q,presenter);
517 490 if(presenter->animationOptions().testFlag(QChart::SeriesAnimations)) {
518 491 presenter->animator()->addAnimation(bar);
519 492 }
520 493 presenter->chartTheme()->decorate(q, presenter->dataSet()->seriesIndex(q));
521 494 return bar;
522 495
523 496 }
524 497
525 498 QList<LegendMarker*> QBarSeriesPrivate::createLegendMarker(QLegend* legend)
526 499 {
527 500 Q_Q(QBarSeries);
528 501 QList<LegendMarker*> markers;
529 502 foreach(QBarSet* set, q->barSets()) {
530 503 BarLegendMarker* marker = new BarLegendMarker(q,set,legend);
531 504 markers << marker;
532 505 }
533 506
534 507 return markers;
535 508 }
536 509
537 510 #include "moc_qbarseries.cpp"
538 511 #include "moc_qbarseries_p.cpp"
539 512
540 513 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,83 +1,81
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 BARSERIES_H
22 22 #define BARSERIES_H
23 23
24 24 #include <qseries.h>
25 25 #include <QStringList>
26 26
27 27 class QModelIndex;
28 28
29 29 QTCOMMERCIALCHART_BEGIN_NAMESPACE
30 30
31 31 typedef QStringList QBarCategories;
32 32
33 33 class QBarSet;
34 34 class BarChartModel;
35 35 class BarCategory;
36 36 class QBarSeriesPrivate;
37 37
38 38 // Container for series
39 39 class QTCOMMERCIALCHART_EXPORT QBarSeries : public QSeries
40 40 {
41 41 Q_OBJECT
42 42 public:
43 43 explicit QBarSeries(QBarCategories categories, QObject *parent = 0);
44 44
45 45 QSeries::QSeriesType type() const;
46 46
47 47 void appendBarSet(QBarSet *set); // Takes ownership of set
48 48 void removeBarSet(QBarSet *set); // Releases ownership, doesn't delete set
49 49 void appendBarSets(QList<QBarSet* > sets);
50 50 void removeBarSets(QList<QBarSet* > sets);
51 51 void insertBarSet(int i, QBarSet *set);
52 52 void insertCategory(int i, QString category);
53 53 void removeCategory(int i);
54 54 int barsetCount() const;
55 55 int categoryCount() const;
56 56 QList<QBarSet*> barSets() const;
57 57 QBarCategories categories() const;
58 58
59 59 void setLabelsVisible(bool visible = true);
60 60
61 61 bool setModel(QAbstractItemModel *model);
62 62 void setModelMapping(int categories, int bottomBoundary, int topBoundary, Qt::Orientation orientation = Qt::Vertical);
63 63
64 64 protected:
65 65 explicit QBarSeries(QBarSeriesPrivate &d,QObject *parent = 0);
66 66
67 67 Q_SIGNALS:
68 68 void clicked(QBarSet *barset, QString category, Qt::MouseButtons button);
69 69 void selected();
70
71 public Q_SLOTS:
72 void setToolTipEnabled(bool enabled = true); // enables tooltips
70 void hovered(QBarSet* barset, bool status);
73 71
74 72 protected:
75 73 Q_DECLARE_PRIVATE(QBarSeries)
76 74 friend class BarChartItem;
77 75 friend class PercentBarChartItem;
78 76 friend class StackedBarChartItem;
79 77 };
80 78
81 79 QTCOMMERCIALCHART_END_NAMESPACE
82 80
83 81 #endif // BARSERIES_H
@@ -1,70 +1,66
1 1 #ifndef QBARSERIES_P_H
2 2 #define QBARSERIES_P_H
3 3
4 4 #include "qbarseries.h"
5 5 #include "qseries_p.h"
6 6 #include <QStringList>
7 7 #include <QSeries>
8 8
9 9 class QModelIndex;
10 10
11 11 QTCOMMERCIALCHART_BEGIN_NAMESPACE
12 12
13 13 // Container for series
14 14 class QBarSeriesPrivate : public QSeriesPrivate
15 15 {
16 16 Q_OBJECT
17 17 public:
18 18 QBarSeriesPrivate(QBarCategories categories, QBarSeries *parent);
19 19
20 20 void scaleDomain(Domain& domain);
21 21 Chart* createGraphics(ChartPresenter* presenter);
22 22 QList<LegendMarker*> createLegendMarker(QLegend* legend);
23 23
24 24 bool setModel(QAbstractItemModel *model);
25 25 void setModelMapping(int categories, int bottomBoundry, int topBoundry, Qt::Orientation orientation = Qt::Vertical);
26 26
27 27 QBarSet* barsetAt(int index);
28 28 QString categoryName(int category);
29 29 qreal min();
30 30 qreal max();
31 31 qreal valueAt(int set, int category);
32 32 qreal percentageAt(int set, int category);
33 33 qreal categorySum(int category);
34 34 qreal absoluteCategorySum(int category);
35 35 qreal maxCategorySum();
36 36 BarChartModel& modelInternal();
37 37
38 38 Q_SIGNALS:
39 39 void clicked(QBarSet *barset, QString category, Qt::MouseButtons button);
40 40 void selected();
41 41 void updatedBars();
42 42 void restructuredBars();
43 void showToolTip(QPoint pos, QString tip);
44
45 public Q_SLOTS:
46 void setToolTipEnabled(bool enabled = true); // enables tooltips
47 43
48 44 private Q_SLOTS:
49 45 // slots for updating bars when data in model changes
50 46 void modelUpdated(QModelIndex topLeft, QModelIndex bottomRight);
51 47 void modelDataAdded(QModelIndex parent, int start, int end);
52 48 void modelDataRemoved(QModelIndex parent, int start, int end);
53 49 void barsetChanged();
54 50
55 51 protected:
56 52 BarChartModel *m_internalModel; // TODO: this may change... current "2 models" situation doesn't look good.
57 53 QAbstractItemModel* m_model;
58 54 int m_mapCategories;
59 55 int m_mapBarBottom;
60 56 int m_mapBarTop;
61 57 int m_mapFirst;
62 58 int m_mapCount;
63 59 Qt::Orientation m_mapOrientation;
64 60 private:
65 61 Q_DECLARE_PUBLIC(QBarSeries)
66 62 };
67 63
68 64 QTCOMMERCIALCHART_END_NAMESPACE
69 65
70 66 #endif // QBARSERIESPRIVATE_P_H
@@ -1,308 +1,281
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 "qbarset_p.h"
23 #include <QToolTip>
24 23
25 24 QTCOMMERCIALCHART_BEGIN_NAMESPACE
26 25
27 26 /*!
28 27 \class QBarSet
29 28 \brief part of QtCommercial chart API.
30 29
31 30 QBarSet represents one set of bars. Set of bars contains one data value for each category.
32 31 First value of set is assumed to belong to first category, second to second category and so on.
33 32 If set has fewer values than there are categories, then the missing values are assumed to be
34 33 at the end of set. For missing values in middle of a set, numerical value of zero is used.
35 34
36 35 \mainclass
37 36
38 37 \sa QBarSeries, QStackedBarSeries, QPercentBarSeries
39 38 */
40 39
41 40 /*!
42 41 \fn void QBarSet::clicked(QString category, Qt::MouseButtons button)
43 42 \brief signals that set has been clicked
44 43 Parameter \a category describes on which category was clicked
45 44 Parameter \a button mouse button
46 45 */
47 46
48 47 /*!
48 \fn void QBarSet::hovered(bool status)
49 \brief signals that mouse has hovered over the set. If \a status is true, then mouse was entered. If \a status is false, then mouse was left.
50 */
51
52 /*!
49 53 Constructs QBarSet with a name of \a name and with parent of \a parent
50 54 */
51 55 QBarSet::QBarSet(QString name, QObject *parent)
52 56 : QObject(parent)
53 57 ,d_ptr(new QBarSetPrivate(name,this))
54 58 {
55 59 }
56 60
57 61 QBarSet::~QBarSet()
58 62 {
59 63
60 64 }
61 65
62 66 /*!
63 67 Sets new \a name for set.
64 68 */
65 69 void QBarSet::setName(QString name)
66 70 {
67 71 d_ptr->m_name = name;
68 72 }
69 73
70 74 /*!
71 75 Returns name of the set.
72 76 */
73 77 QString QBarSet::name() const
74 78 {
75 79 return d_ptr->m_name;
76 80 }
77 81
78 82 /*!
79 83 Appends new value \a value to the end of set.
80 84 */
81 85 QBarSet& QBarSet::operator << (const qreal &value)
82 86 {
83 87 d_ptr->m_values.append(value);
84 88 emit d_ptr->structureChanged();
85 89 return *this;
86 90 }
87 91
88 92 /*!
89 93 Inserts new \a value on the \a i position.
90 94 The value that is currently at this postion is moved to postion i + 1
91 95 \sa removeValue()
92 96 */
93 97 void QBarSet::insertValue(int i, qreal value)
94 98 {
95 99 d_ptr->m_values.insert(i, value);
96 100 }
97 101
98 102 /*!
99 103 Removes the value specified by \a i
100 104 \sa insertValue()
101 105 */
102 106 void QBarSet::removeValue(int i)
103 107 {
104 108 d_ptr->m_values.removeAt(i);
105 109 }
106 110
107 111 /*!
108 112 Returns count of values in set.
109 113 */
110 114 int QBarSet::count() const
111 115 {
112 116 return d_ptr->m_values.count();
113 117 }
114 118
115 119 /*!
116 120 Returns value of set indexed by \a index
117 121 */
118 122 qreal QBarSet::valueAt(int index) const
119 123 {
120 124 return d_ptr->m_values.at(index);
121 125 }
122 126
123 127 /*!
124 128 Sets a new value \a value to set, indexed by \a index
125 129 */
126 130 void QBarSet::setValue(int index, qreal value)
127 131 {
128 132 d_ptr->m_values.replace(index,value);
129 133 emit d_ptr->valueChanged();
130 134 }
131 135
132 136 /*!
133 137 Returns sum of all values in barset.
134 138 */
135 139 qreal QBarSet::sum() const
136 140 {
137 141 qreal total(0);
138 142 for (int i=0; i < d_ptr->m_values.count(); i++) {
139 143 total += d_ptr->m_values.at(i);
140 144 }
141 145 return total;
142 146 }
143 147
144 148 /*!
145 149 Sets pen for set. Bars of this set are drawn using \a pen
146 150 */
147 151 void QBarSet::setPen(const QPen &pen)
148 152 {
149 153 if(d_ptr->m_pen!=pen){
150 154 d_ptr->m_pen = pen;
151 155 emit d_ptr->valueChanged();
152 156 }
153 157 }
154 158
155 159 /*!
156 160 Returns pen of the set.
157 161 */
158 162 QPen QBarSet::pen() const
159 163 {
160 164 return d_ptr->m_pen;
161 165 }
162 166
163 167 /*!
164 168 Sets brush for the set. Bars of this set are drawn using \a brush
165 169 */
166 170 void QBarSet::setBrush(const QBrush &brush)
167 171 {
168 172 if(d_ptr->m_brush!=brush){
169 173 d_ptr->m_brush = brush;
170 174 emit d_ptr->valueChanged();
171 175 }
172 176 }
173 177
174 178 /*!
175 179 Returns brush of the set.
176 180 */
177 181 QBrush QBarSet::brush() const
178 182 {
179 183 return d_ptr->m_brush;
180 184 }
181 185
182 186 /*!
183 187 Sets \a pen of the values that are drawn on top of this barset
184 188 */
185 189 void QBarSet::setLabelPen(const QPen &pen)
186 190 {
187 191 if(d_ptr->m_labelPen!=pen){
188 192 d_ptr->m_labelPen = pen;
189 193 emit d_ptr->valueChanged();
190 194 }
191 195 }
192 196
193 197 /*!
194 198 Returns pen of the values that are drawn on top of this barset
195 199 */
196 200 QPen QBarSet::labelPen() const
197 201 {
198 202 return d_ptr->m_labelPen;
199 203 }
200 204
201 205 /*!
202 206 Sets \a brush of the values that are drawn on top of this barset
203 207 */
204 208 void QBarSet::setLabelBrush(const QBrush &brush)
205 209 {
206 210 if(d_ptr->m_labelBrush!=brush){
207 211 d_ptr->m_labelBrush = brush;
208 212 emit d_ptr->valueChanged();
209 213 }
210 214 }
211 215
212 216 /*!
213 217 Returns brush of the values that are drawn on top of this barset
214 218 */
215 219 QBrush QBarSet::labelBrush() const
216 220 {
217 221 return d_ptr->m_labelBrush;
218 222 }
219 223
220 224 /*!
221 225 Sets the \a font for values that are drawn on top of this barset
222 226 */
223 227 void QBarSet::setLabelFont(const QFont &font)
224 228 {
225 229 if(d_ptr->m_labelFont!=font) {
226 230 d_ptr->m_labelFont = font;
227 231 emit d_ptr->valueChanged();
228 232 }
229 233
230 234 }
231 235
232 236 /*!
233 237 Returns the pen for values that are drawn on top of this set
234 238 */
235 239 QFont QBarSet::labelFont() const
236 240 {
237 241 return d_ptr->m_labelFont;
238 242 }
239 243
240 244 /*!
241 245 Sets visibility of bar labels. If \a visible is true, labels are drawn on top of barsets.
242 246 */
243 247
244 248 void QBarSet::setLabelsVisible(bool visible)
245 249 {
246 250 if(d_ptr->m_labelsVisible!=visible) {
247 251 d_ptr->m_labelsVisible = visible;
248 252 emit d_ptr->labelsVisibleChanged(visible);
249 253 }
250 254 }
251 255
252 256 /*!
253 257 Returns the visibility of values
254 258 */
255 259 bool QBarSet::labelsVisible() const
256 260 {
257 261 return d_ptr->m_labelsVisible;
258 262 }
259 263
260 /*
261 void QBarSet::barHoverEnterEvent(QPoint pos)
262 {
263 emit showToolTip(pos, m_name);
264 emit hoverEnter(pos);
265 }
266 */
267 /*
268 void QBarSet::barHoverLeaveEvent()
269 {
270 // Emit signal to user of charts
271 emit hoverLeave();
272 }
273 */
274
275 264 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
276 265
277 266 QBarSetPrivate::QBarSetPrivate(QString name, QBarSet *parent) : QObject(parent),
278 267 q_ptr(parent),
279 268 m_name(name),
280 269 m_labelsVisible(false)
281 270 {
282 271
283 272 }
284 273
285 274 QBarSetPrivate::~QBarSetPrivate()
286 275 {
287 276
288 277 }
289
290
291 //TODO: fixme , refactor it and get rid of it
292 void QBarSetPrivate::barHoverEnterEvent(QPoint pos)
293 {
294 emit showToolTip(pos, m_name);
295 emit hoverEnter(pos);
296 }
297
298 //TODO: fixme , refactor it and get rid of it
299 void QBarSetPrivate::barHoverLeaveEvent()
300 {
301 // Emit signal to user of charts
302 emit hoverLeave();
303 }
304
305 278 #include "moc_qbarset.cpp"
306 279 #include "moc_qbarset_p.cpp"
307 280
308 281 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,82 +1,84
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 QBARSET_H
22 22 #define QBARSET_H
23 23
24 24 #include <qchartglobal.h>
25 25 #include <QPen>
26 26 #include <QBrush>
27 27 #include <QFont>
28 28
29 29 QTCOMMERCIALCHART_BEGIN_NAMESPACE
30 30 class QBarSetPrivate;
31 31
32 32 class QTCOMMERCIALCHART_EXPORT QBarSet : public QObject
33 33 {
34 34 Q_OBJECT
35 35
36 36 public:
37 37 explicit QBarSet(QString name, QObject *parent = 0);
38 38 ~QBarSet();
39 39
40 40 void setName(QString name);
41 41 QString name() const;
42 42 QBarSet& operator << (const qreal &value); // appends new value to set
43 43 void insertValue(int i, qreal value);
44 44 void removeValue(int i);
45 45 int count() const; // count of values in set
46 46 qreal valueAt(int index) const; // for modifying individual values
47 47 void setValue(int index, qreal value); // setter for individual value
48 48 qreal sum() const; // sum of all values in the set
49 49
50 50 void setPen(const QPen &pen);
51 51 QPen pen() const;
52 52
53 53 void setBrush(const QBrush &brush);
54 54 QBrush brush() const;
55 55
56 56 void setLabelPen(const QPen &pen);
57 57 QPen labelPen() const;
58 58
59 59 void setLabelBrush(const QBrush &brush);
60 60 QBrush labelBrush() const;
61 61
62 62 void setLabelFont(const QFont &font);
63 63 QFont labelFont() const;
64 64
65 65 void setLabelsVisible(bool visible = true);
66 66 bool labelsVisible() const;
67 67
68 68 Q_SIGNALS:
69 void clicked(QString category, Qt::MouseButtons button); // Clicked and hover signals exposed to user
69 void clicked(QString category, Qt::MouseButtons button);
70 void selected();
71 void hovered(bool status);
70 72
71 73 private:
72 74 QScopedPointer<QBarSetPrivate> d_ptr;
73 75 Q_DISABLE_COPY(QBarSet)
74 76 friend class QBarSeries;
75 77 friend class BarLegendMarker;
76 78 friend class BarChartItem;
77 79 friend class QBarSeriesPrivate;
78 80 };
79 81
80 82 QTCOMMERCIALCHART_END_NAMESPACE
81 83
82 84 #endif // QBARSET_H
@@ -1,46 +1,39
1 1 #ifndef QBARSET_P_H
2 2 #define QBARSET_P_H
3 3
4 4 #include "qbarset.h"
5 5
6 6 QTCOMMERCIALCHART_BEGIN_NAMESPACE
7 7
8 8 class QBarSetPrivate : public QObject
9 9 {
10 10 Q_OBJECT
11 11
12 12 public:
13 13 QBarSetPrivate(QString name, QBarSet *parent);
14 14 ~QBarSetPrivate();
15 15
16 16 Q_SIGNALS:
17 17 void clicked(QString category, Qt::MouseButtons button);
18 18 void structureChanged();
19 19 void valueChanged();
20 void hoverEnter(QPoint pos);
21 void hoverLeave();
22 void showToolTip(QPoint pos, QString tip);
23 20 void labelsVisibleChanged(bool visible);
24 21
25 public Q_SLOTS:
26 void barHoverEnterEvent(QPoint pos);
27 void barHoverLeaveEvent();
28
29 22 public:
30 23 QBarSet * const q_ptr;
31 24 QString m_name;
32 25 QList<qreal> m_values; // TODO: replace with map (category, value)
33 26 QMap<QString, qreal> m_mappedValues;
34 27 QPen m_pen;
35 28 QBrush m_brush;
36 29 QPen m_labelPen;
37 30 QBrush m_labelBrush;
38 31 QFont m_labelFont;
39 32 bool m_labelsVisible;
40 33
41 34 friend class QBarSet;
42 35 };
43 36
44 37 QTCOMMERCIALCHART_END_NAMESPACE
45 38
46 39 #endif // QBARSETPRIVATE_P_H
@@ -1,348 +1,345
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 "mainwidget.h"
22 22 #include "dataseriedialog.h"
23 23 #include "qchartview.h"
24 24 #include "qpieseries.h"
25 25 #include "qscatterseries.h"
26 26 #include "qlineseries.h"
27 27 #include <qareaseries.h>
28 28 #include <qsplineseries.h>
29 29 #include <qbarset.h>
30 30 #include <qbarseries.h>
31 31 #include <qstackedbarseries.h>
32 32 #include <qpercentbarseries.h>
33 33 #include <QPushButton>
34 34 #include <QComboBox>
35 35 #include <QSpinBox>
36 36 #include <QCheckBox>
37 37 #include <QGridLayout>
38 38 #include <QHBoxLayout>
39 39 #include <QLabel>
40 40 #include <QSpacerItem>
41 41 #include <QMessageBox>
42 42 #include <cmath>
43 43 #include <QDebug>
44 44 #include <QStandardItemModel>
45 45
46 46
47 47 QTCOMMERCIALCHART_USE_NAMESPACE
48 48
49 49 MainWidget::MainWidget(QWidget *parent) :
50 50 QWidget(parent),
51 51 m_addSerieDialog(0),
52 52 m_chart(0)
53 53 {
54 54 m_chart = new QChart();
55 55
56 56 // Grid layout for the controls for configuring the chart widget
57 57 QGridLayout *grid = new QGridLayout();
58 58 QPushButton *addSeriesButton = new QPushButton("Add series");
59 59 connect(addSeriesButton, SIGNAL(clicked()), this, SLOT(addSeries()));
60 60 grid->addWidget(addSeriesButton, 0, 1);
61 61 initBackroundCombo(grid);
62 62 initScaleControls(grid);
63 63 initThemeCombo(grid);
64 64 initCheckboxes(grid);
65 65
66 66 // add row with empty label to make all the other rows static
67 67 grid->addWidget(new QLabel(""), grid->rowCount(), 0);
68 68 grid->setRowStretch(grid->rowCount() - 1, 1);
69 69
70 70 // Create chart view with the chart
71 71 m_chartView = new QChartView(m_chart, this);
72 72 m_chartView->setRubberBand(QChartView::HorizonalRubberBand);
73 73
74 74 // Another grid layout as a main layout
75 75 QGridLayout *mainLayout = new QGridLayout();
76 76 mainLayout->addLayout(grid, 0, 0);
77 77 mainLayout->addWidget(m_chartView, 0, 1, 3, 1);
78 78 setLayout(mainLayout);
79 79 }
80 80
81 81 // Combo box for selecting the chart's background
82 82 void MainWidget::initBackroundCombo(QGridLayout *grid)
83 83 {
84 84 QComboBox *backgroundCombo = new QComboBox(this);
85 85 backgroundCombo->addItem("Color");
86 86 backgroundCombo->addItem("Gradient");
87 87 backgroundCombo->addItem("Image");
88 88 connect(backgroundCombo, SIGNAL(currentIndexChanged(int)),
89 89 this, SLOT(backgroundChanged(int)));
90 90
91 91 grid->addWidget(new QLabel("Background:"), grid->rowCount(), 0);
92 92 grid->addWidget(backgroundCombo, grid->rowCount() - 1, 1);
93 93 }
94 94
95 95 // Scale related controls (auto-scale vs. manual min-max values)
96 96 void MainWidget::initScaleControls(QGridLayout *grid)
97 97 {
98 98 m_autoScaleCheck = new QCheckBox("Automatic scaling");
99 99 connect(m_autoScaleCheck, SIGNAL(stateChanged(int)), this, SLOT(autoScaleChanged(int)));
100 100 // Allow setting also non-sense values (like -2147483648 and 2147483647)
101 101 m_xMinSpin = new QSpinBox();
102 102 m_xMinSpin->setMinimum(INT_MIN);
103 103 m_xMinSpin->setMaximum(INT_MAX);
104 104 m_xMinSpin->setValue(0);
105 105 connect(m_xMinSpin, SIGNAL(valueChanged(int)), this, SLOT(xMinChanged(int)));
106 106 m_xMaxSpin = new QSpinBox();
107 107 m_xMaxSpin->setMinimum(INT_MIN);
108 108 m_xMaxSpin->setMaximum(INT_MAX);
109 109 m_xMaxSpin->setValue(10);
110 110 connect(m_xMaxSpin, SIGNAL(valueChanged(int)), this, SLOT(xMaxChanged(int)));
111 111 m_yMinSpin = new QSpinBox();
112 112 m_yMinSpin->setMinimum(INT_MIN);
113 113 m_yMinSpin->setMaximum(INT_MAX);
114 114 m_yMinSpin->setValue(0);
115 115 connect(m_yMinSpin, SIGNAL(valueChanged(int)), this, SLOT(yMinChanged(int)));
116 116 m_yMaxSpin = new QSpinBox();
117 117 m_yMaxSpin->setMinimum(INT_MIN);
118 118 m_yMaxSpin->setMaximum(INT_MAX);
119 119 m_yMaxSpin->setValue(10);
120 120 connect(m_yMaxSpin, SIGNAL(valueChanged(int)), this, SLOT(yMaxChanged(int)));
121 121
122 122 grid->addWidget(m_autoScaleCheck, grid->rowCount(), 0);
123 123 grid->addWidget(new QLabel("x min:"), grid->rowCount(), 0);
124 124 grid->addWidget(m_xMinSpin, grid->rowCount() - 1, 1);
125 125 grid->addWidget(new QLabel("x max:"), grid->rowCount(), 0);
126 126 grid->addWidget(m_xMaxSpin, grid->rowCount() - 1, 1);
127 127 grid->addWidget(new QLabel("y min:"), grid->rowCount(), 0);
128 128 grid->addWidget(m_yMinSpin, grid->rowCount() - 1, 1);
129 129 grid->addWidget(new QLabel("y max:"), grid->rowCount(), 0);
130 130 grid->addWidget(m_yMaxSpin, grid->rowCount() - 1, 1);
131 131
132 132 m_autoScaleCheck->setChecked(true);
133 133 }
134 134
135 135 // Combo box for selecting theme
136 136 void MainWidget::initThemeCombo(QGridLayout *grid)
137 137 {
138 138 QComboBox *chartTheme = new QComboBox();
139 139 chartTheme->addItem("Default");
140 140 chartTheme->addItem("Light");
141 141 chartTheme->addItem("Blue Cerulean");
142 142 chartTheme->addItem("Dark");
143 143 chartTheme->addItem("Brown Sand");
144 144 chartTheme->addItem("Blue NCS");
145 145 chartTheme->addItem("High Contrast");
146 146 chartTheme->addItem("Blue Icy");
147 147 connect(chartTheme, SIGNAL(currentIndexChanged(int)),
148 148 this, SLOT(changeChartTheme(int)));
149 149 grid->addWidget(new QLabel("Chart theme:"), 8, 0);
150 150 grid->addWidget(chartTheme, 8, 1);
151 151 }
152 152
153 153 // Different check boxes for customizing chart
154 154 void MainWidget::initCheckboxes(QGridLayout *grid)
155 155 {
156 156 // TODO: setZoomEnabled slot has been removed from QChartView -> Re-implement zoom on/off
157 157 QCheckBox *zoomCheckBox = new QCheckBox("Drag'n drop Zoom");
158 158 // connect(zoomCheckBox, SIGNAL(toggled(bool)), m_chartView, SLOT(setZoomEnabled(bool)));
159 159 zoomCheckBox->setChecked(true);
160 160 grid->addWidget(zoomCheckBox, grid->rowCount(), 0);
161 161
162 162 QCheckBox *aliasCheckBox = new QCheckBox("Anti-alias");
163 163 connect(aliasCheckBox, SIGNAL(toggled(bool)), this, SLOT(antiAliasToggled(bool)));
164 164 aliasCheckBox->setChecked(false);
165 165 grid->addWidget(aliasCheckBox, grid->rowCount(), 0);
166 166 }
167 167
168 168 void MainWidget::antiAliasToggled(bool enabled)
169 169 {
170 170 m_chartView->setRenderHint(QPainter::Antialiasing, enabled);
171 171 }
172 172
173 173 void MainWidget::addSeries()
174 174 {
175 175 if (!m_addSerieDialog) {
176 176 m_addSerieDialog = new DataSerieDialog(this);
177 177 connect(m_addSerieDialog, SIGNAL(accepted(QString,int,int,QString,bool)),
178 178 this, SLOT(addSeries(QString,int,int,QString,bool)));
179 179 }
180 180 m_addSerieDialog->exec();
181 181 }
182 182
183 183 QList<RealList> MainWidget::generateTestData(int columnCount, int rowCount, QString dataCharacteristics)
184 184 {
185 185 // TODO: dataCharacteristics
186 186 QList<RealList> testData;
187 187 for (int j(0); j < columnCount; j++) {
188 188 QList <qreal> newColumn;
189 189 for (int i(0); i < rowCount; i++) {
190 190 if (dataCharacteristics == "Sin") {
191 191 newColumn.append(abs(sin(3.14159265358979 / 50 * i) * 100));
192 192 } else if (dataCharacteristics == "Sin + random") {
193 193 newColumn.append(abs(sin(3.14159265358979 / 50 * i) * 100) + (rand() % 5));
194 194 } else if (dataCharacteristics == "Random") {
195 195 newColumn.append(rand() % 10 + (qreal) rand() / (qreal) RAND_MAX);
196 196 } else if (dataCharacteristics == "Linear") {
197 197 //newColumn.append(i * (j + 1.0));
198 198 // TODO: temporary hack to make pie work; prevent zero values:
199 199 newColumn.append(i * (j + 1.0) + 0.1);
200 200 } else { // "constant"
201 201 newColumn.append((j + 1.0));
202 202 }
203 203 }
204 204 testData.append(newColumn);
205 205 }
206 206 return testData;
207 207 }
208 208
209 209 QStringList MainWidget::generateLabels(int count)
210 210 {
211 211 QStringList result;
212 212 for (int i(0); i < count; i++)
213 213 result.append("label" + QString::number(i));
214 214 return result;
215 215 }
216 216
217 217 void MainWidget::addSeries(QString seriesName, int columnCount, int rowCount, QString dataCharacteristics, bool labelsEnabled)
218 218 {
219 219 qDebug() << "addSeries: " << seriesName
220 220 << " columnCount: " << columnCount
221 221 << " rowCount: " << rowCount
222 222 << " dataCharacteristics: " << dataCharacteristics
223 223 << " labels enabled: " << labelsEnabled;
224 224 m_defaultSeriesName = seriesName;
225 225
226 226 QList<RealList> data = generateTestData(columnCount, rowCount, dataCharacteristics);
227 227
228 228 // Line series and scatter series use similar data
229 229 if (seriesName == "Line") {
230 230 for (int j(0); j < data.count(); j ++) {
231 231 QList<qreal> column = data.at(j);
232 232 QLineSeries *series = new QLineSeries();
233 233 series->setName("line" + QString::number(j));
234 234 for (int i(0); i < column.count(); i++)
235 235 series->append(i, column.at(i));
236 236 m_chart->addSeries(series);
237 237 }
238 238 } else if (seriesName == "Area") {
239 239 // TODO: lower series for the area?
240 240 for (int j(0); j < data.count(); j ++) {
241 241 QList<qreal> column = data.at(j);
242 242 QLineSeries *lineSeries = new QLineSeries();
243 243 for (int i(0); i < column.count(); i++)
244 244 lineSeries->append(i, column.at(i));
245 245 QAreaSeries *areaSeries = new QAreaSeries(lineSeries);
246 246 areaSeries->setName("area" + QString::number(j));
247 247 m_chart->addSeries(areaSeries);
248 248 }
249 249 } else if (seriesName == "Scatter") {
250 250 for (int j(0); j < data.count(); j++) {
251 251 QList<qreal> column = data.at(j);
252 252 QScatterSeries *series = new QScatterSeries();
253 253 series->setName("scatter" + QString::number(j));
254 254 for (int i(0); i < column.count(); i++)
255 255 series->append(i, column.at(i));
256 256 m_chart->addSeries(series);
257 257 }
258 258 } else if (seriesName == "Pie") {
259 259 QStringList labels = generateLabels(rowCount);
260 260 for (int j(0); j < data.count(); j++) {
261 261 QPieSeries *series = new QPieSeries();
262 262 QList<qreal> column = data.at(j);
263 263 for (int i(0); i < column.count(); i++)
264 264 series->append(column.at(i), labels.at(i));
265 265 m_chart->addSeries(series);
266 266 }
267 267 } else if (seriesName == "Bar"
268 268 || seriesName == "Stacked bar"
269 269 || seriesName == "Percent bar") {
270 270 QStringList category;
271 271 QStringList labels = generateLabels(rowCount);
272 272 foreach(QString label, labels)
273 273 category << label;
274 274 QBarSeries* series = 0;
275 275 if (seriesName == "Bar")
276 276 series = new QBarSeries(category, this);
277 277 else if (seriesName == "Stacked bar")
278 278 series = new QStackedBarSeries(category, this);
279 279 else
280 280 series = new QPercentBarSeries(category, this);
281 281
282 282 for (int j(0); j < data.count(); j++) {
283 283 QList<qreal> column = data.at(j);
284 284 QBarSet *set = new QBarSet("set" + QString::number(j));
285 285 for (int i(0); i < column.count(); i++)
286 286 *set << column.at(i);
287 287 series->appendBarSet(set);
288 288 }
289 289
290 // TODO: new implementation of setFloatingValuesEnabled with signals
291 //series->setFloatingValuesEnabled(true);
292 series->setToolTipEnabled(true);
293 290 m_chart->addSeries(series);
294 291 } else if (seriesName == "Spline") {
295 292 for (int j(0); j < data.count(); j ++) {
296 293 QList<qreal> column = data.at(j);
297 294 QSplineSeries *series = new QSplineSeries();
298 295 for (int i(0); i < column.count(); i++)
299 296 series->append(i, column.at(i));
300 297 m_chart->addSeries(series);
301 298 }
302 299 }
303 300 }
304 301
305 302 void MainWidget::backgroundChanged(int itemIndex)
306 303 {
307 304 qDebug() << "backgroundChanged: " << itemIndex;
308 305 }
309 306
310 307 void MainWidget::autoScaleChanged(int value)
311 308 {
312 309 if (value) {
313 310 // TODO: enable auto scaling
314 311 } else {
315 312 // TODO: set scaling manually (and disable auto scaling)
316 313 }
317 314
318 315 m_xMinSpin->setEnabled(!value);
319 316 m_xMaxSpin->setEnabled(!value);
320 317 m_yMinSpin->setEnabled(!value);
321 318 m_yMaxSpin->setEnabled(!value);
322 319 }
323 320
324 321 void MainWidget::xMinChanged(int value)
325 322 {
326 323 qDebug() << "xMinChanged: " << value;
327 324 }
328 325
329 326 void MainWidget::xMaxChanged(int value)
330 327 {
331 328 qDebug() << "xMaxChanged: " << value;
332 329 }
333 330
334 331 void MainWidget::yMinChanged(int value)
335 332 {
336 333 qDebug() << "yMinChanged: " << value;
337 334 }
338 335
339 336 void MainWidget::yMaxChanged(int value)
340 337 {
341 338 qDebug() << "yMaxChanged: " << value;
342 339 }
343 340
344 341 void MainWidget::changeChartTheme(int themeIndex)
345 342 {
346 343 qDebug() << "changeChartTheme: " << themeIndex;
347 344 m_chart->setTheme((QChart::ChartTheme) themeIndex);
348 345 }
@@ -1,337 +1,336
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 "tablewidget.h"
22 22 #include <QGridLayout>
23 23 #include <QTableView>
24 24 #include <QStyledItemDelegate>
25 25 #include <QLineSeries>
26 26 #include <QSplineSeries>
27 27 #include <QScatterSeries>
28 28 #include "customtablemodel.h"
29 29 #include <QPieSeries>
30 30 #include <QPieSlice>
31 31 #include <QAreaSeries>
32 32 #include <QBarSeries>
33 33 #include <QBarSet>
34 34 #include <QPushButton>
35 35 #include <QRadioButton>
36 36 #include <QLabel>
37 37 #include <QSpinBox>
38 38 #include <QTime>
39 39
40 40 TableWidget::TableWidget(QWidget *parent)
41 41 : QWidget(parent)
42 42 {
43 43 setGeometry(100, 100, 1000, 600);
44 44 qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
45 45 // create simple model for storing data
46 46 // user's table data model
47 47 m_model = new CustomTableModel;
48 48 m_tableView = new QTableView;
49 49 m_tableView->setModel(m_model);
50 50 m_tableView->setMinimumHeight(300);
51 51 // tableView->setMinimumSize(340, 480);
52 52 // tableView->setItemDelegate(new QStyledItemDelegate);
53 53 m_chart = new QChart;
54 54 m_chartView = new QChartView(m_chart);
55 55 m_chartView->setRenderHint(QPainter::Antialiasing);
56 56 m_chartView->setMinimumSize(640, 480);
57 57
58 58 // add, remove data buttons
59 59 QPushButton* addRowAboveButton = new QPushButton("Add row above");
60 60 connect(addRowAboveButton, SIGNAL(clicked()), this, SLOT(addRowAbove()));
61 61
62 62 QPushButton* addRowBelowButton = new QPushButton("Add row below");
63 63 connect(addRowBelowButton, SIGNAL(clicked()), this, SLOT(addRowBelow()));
64 64
65 65 QPushButton* removeRowButton = new QPushButton("Remove row");
66 66 connect(removeRowButton, SIGNAL(clicked()), this, SLOT(removeRow()));
67 67
68 68 QLabel *spinBoxLabel = new QLabel("Rows affected:");
69 69
70 70 // spin box for setting number of affected items (add, remove)
71 71 m_linesCountSpinBox = new QSpinBox;
72 72 m_linesCountSpinBox->setRange(1, 10);
73 73 m_linesCountSpinBox->setValue(1);
74 74
75 75 // buttons layout
76 76 QVBoxLayout* buttonsLayout = new QVBoxLayout;
77 77 buttonsLayout->addWidget(spinBoxLabel);
78 78 buttonsLayout->addWidget(m_linesCountSpinBox);
79 79 buttonsLayout->addWidget(addRowAboveButton);
80 80 buttonsLayout->addWidget(addRowBelowButton);
81 81 buttonsLayout->addWidget(removeRowButton);
82 82 buttonsLayout->addStretch();
83 83
84 84 // chart type radio buttons
85 85 m_lineRadioButton = new QRadioButton("Line");
86 86 m_splineRadioButton = new QRadioButton("Spline");
87 87 m_scatterRadioButton = new QRadioButton("Scatter");
88 88 m_pieRadioButton = new QRadioButton("Pie");
89 89 m_areaRadioButton = new QRadioButton("Area");
90 90 m_barRadioButton = new QRadioButton("Bar");
91 91
92 92 connect(m_lineRadioButton, SIGNAL(toggled(bool)), this, SLOT(updateChartType(bool)));
93 93 connect(m_splineRadioButton, SIGNAL(toggled(bool)), this, SLOT(updateChartType(bool)));
94 94 connect(m_scatterRadioButton, SIGNAL(toggled(bool)), this, SLOT(updateChartType(bool)));
95 95 connect(m_pieRadioButton, SIGNAL(toggled(bool)), this, SLOT(updateChartType(bool)));
96 96 connect(m_areaRadioButton, SIGNAL(toggled(bool)), this, SLOT(updateChartType(bool)));
97 97 connect(m_barRadioButton, SIGNAL(toggled(bool)), this, SLOT(updateChartType(bool)));
98 98 m_lineRadioButton->setChecked(true);
99 99
100 100 // radio buttons layout
101 101 QVBoxLayout* radioLayout = new QVBoxLayout;
102 102 radioLayout->addWidget(m_lineRadioButton);
103 103 radioLayout->addWidget(m_splineRadioButton);
104 104 radioLayout->addWidget(m_scatterRadioButton);
105 105 radioLayout->addWidget(m_pieRadioButton);
106 106 radioLayout->addWidget(m_areaRadioButton);
107 107 radioLayout->addWidget(m_barRadioButton);
108 108 radioLayout->addStretch();
109 109
110 110 // create main layout
111 111 QGridLayout* mainLayout = new QGridLayout;
112 112 mainLayout->addLayout(buttonsLayout, 1, 1);
113 113 mainLayout->addLayout(radioLayout, 2, 1);
114 114 mainLayout->addWidget(m_tableView, 1, 0);
115 115 mainLayout->addWidget(m_chartView, 2, 0);
116 116 setLayout(mainLayout);
117 117 m_lineRadioButton->setFocus();
118 118 }
119 119
120 120 void TableWidget::addRowAbove()
121 121 {
122 122 m_model->insertRows(m_tableView->currentIndex().row(), m_linesCountSpinBox->value());
123 123
124 124 }
125 125
126 126 void TableWidget::addRowBelow()
127 127 {
128 128 m_model->insertRows(m_tableView->currentIndex().row() + 1, m_linesCountSpinBox->value());
129 129
130 130 }
131 131
132 132 void TableWidget::removeRow()
133 133 {
134 134 m_model->removeRows(m_tableView->currentIndex().row(), qMin(m_model->rowCount() - m_tableView->currentIndex().row(), m_linesCountSpinBox->value()));
135 135 }
136 136
137 137 void TableWidget::updateChartType(bool toggle)
138 138 {
139 139 // this if is needed, so that the function is only called once.
140 140 // For the radioButton that was enabled.
141 141 if (toggle) {
142 142 m_chart->removeAllSeries();
143 143
144 144 // renable axes of the chart (pie hides them)
145 145 // x axis
146 146 QChartAxis *axis = m_chart->axisX();
147 147 axis->setAxisVisible(true);
148 148 axis->setGridLineVisible(true);
149 149 axis->setLabelsVisible(true);
150 150
151 151 // y axis
152 152 axis = m_chart->axisY();
153 153 axis->setAxisVisible(true);
154 154 axis->setGridLineVisible(true);
155 155 axis->setLabelsVisible(true);
156 156
157 157 m_model->clearMapping();
158 158
159 159 QString seriesColorHex = "#000000";
160 160 QPen pen;
161 161 pen.setWidth(2);
162 162
163 163 if (m_lineRadioButton->isChecked())
164 164 {
165 165 // series 1
166 166 m_series = new QLineSeries;
167 167 m_series->setModel(m_model);
168 168 m_series->setModelMapping(0,1, Qt::Vertical);
169 169 m_series->setModelMappingRange(1, 4);
170 170 m_chart->addSeries(m_series);
171 171 seriesColorHex = "#" + QString::number(m_series->pen().color().rgb(), 16).right(6).toUpper();
172 172 m_model->addMapping(seriesColorHex, QRect(0, 1, 2, 4));
173 173
174 174 // series 2
175 175 m_series = new QLineSeries;
176 176 m_series->setModel(m_model);
177 177 m_series->setModelMapping(2,3, Qt::Vertical);
178 178 m_chart->addSeries(m_series);
179 179 seriesColorHex = "#" + QString::number(m_series->pen().color().rgb(), 16).right(6).toUpper();
180 180 m_model->addMapping(seriesColorHex, QRect(2, 0, 2, 1000));
181 181
182 182 // series 3
183 183 m_series = new QLineSeries;
184 184 m_series->setModel(m_model);
185 185 m_series->setModelMapping(4,5, Qt::Vertical);
186 186 m_series->setModelMappingRange(2, 0);
187 187 m_chart->addSeries(m_series);
188 188 seriesColorHex = "#" + QString::number(m_series->pen().color().rgb(), 16).right(6).toUpper();
189 189 m_model->addMapping(seriesColorHex, QRect(4, 2, 2, 1000));
190 190 }
191 191 else if (m_splineRadioButton->isChecked())
192 192 {
193 193 // series 1
194 194 m_series = new QSplineSeries;
195 195 m_series->setModel(m_model);
196 196 m_series->setModelMapping(0,1, Qt::Vertical);
197 197 m_series->setModelMappingRange(1, 4);
198 198 // series->setModelMapping(0,1, Qt::Horizontal);
199 199 m_chart->addSeries(m_series);
200 200 seriesColorHex = "#" + QString::number(m_series->pen().color().rgb(), 16).right(6).toUpper();
201 201 m_model->addMapping(seriesColorHex, QRect(0, 1, 2, 4));
202 202
203 203 // series 2
204 204 m_series = new QSplineSeries;
205 205 m_series->setModel(m_model);
206 206 m_series->setModelMapping(2,3, Qt::Vertical);
207 207 m_series->setModelMappingRange(0, 0);
208 208 // series->setModelMapping(2,3, Qt::Horizontal);
209 209 m_chart->addSeries(m_series);
210 210 seriesColorHex = "#" + QString::number(m_series->pen().color().rgb(), 16).right(6).toUpper();
211 211 m_model->addMapping(seriesColorHex, QRect(2, 0, 2, 1000));
212 212
213 213 // series 3
214 214 m_series = new QSplineSeries;
215 215 m_series->setModel(m_model);
216 216 m_series->setModelMapping(4,5, Qt::Vertical);
217 217 m_series->setModelMappingRange(2, 0);
218 218 // series->setModelMapping(4,5, Qt::Horizontal);
219 219 m_chart->addSeries(m_series);
220 220 seriesColorHex = "#" + QString::number(m_series->pen().color().rgb(), 16).right(6).toUpper();
221 221 m_model->addMapping(seriesColorHex, QRect(4, 2, 2, 1000));
222 222 }
223 223 else if (m_scatterRadioButton->isChecked())
224 224 {
225 225 // series 1
226 226 m_series = new QScatterSeries;
227 227 m_series->setModel(m_model);
228 228 m_series->setModelMapping(0,1, Qt::Vertical);
229 229 m_series->setModelMappingRange(2, 0);
230 230 // series->setModelMapping(0,1, Qt::Horizontal);
231 231 m_chart->addSeries(m_series);
232 232
233 233 seriesColorHex = "#" + QString::number(m_series->brush().color().rgb(), 16).right(6).toUpper();
234 234 m_model->addMapping(seriesColorHex, QRect(0, 2, 2, 1000));
235 235
236 236 // series 2
237 237 m_series = new QScatterSeries;
238 238 m_series->setModel(m_model);
239 239 m_series->setModelMapping(2,3, Qt::Vertical);
240 240 m_series->setModelMappingRange(1, 6);
241 241 // series->setModelMapping(2,3, Qt::Horizontal);
242 242 m_chart->addSeries(m_series);
243 243
244 244 seriesColorHex = "#" + QString::number(m_series->brush().color().rgb(), 16).right(6).toUpper();
245 245 m_model->addMapping(seriesColorHex, QRect(2, 1, 2, 6));
246 246
247 247 // series 3
248 248 m_series = new QScatterSeries;
249 249 m_series->setModel(m_model);
250 250 m_series->setModelMapping(4,5, Qt::Vertical);
251 251 // series->setModelMapping(4,5, Qt::Horizontal);
252 252 m_chart->addSeries(m_series);
253 253 seriesColorHex = "#" + QString::number(m_series->brush().color().rgb(), 16).right(6).toUpper();
254 254 m_model->addMapping(seriesColorHex, QRect(4, 0, 2, 1000));
255 255 }
256 256 else if (m_pieRadioButton->isChecked())
257 257 {
258 258 // pie 1
259 259 QPieSeries* pieSeries = new QPieSeries;
260 260 pieSeries->setModel(m_model);
261 261 pieSeries->setModelMapping(0,0, Qt::Vertical);
262 262 pieSeries->setLabelsVisible(true);
263 263 pieSeries->setPieSize(0.4);
264 264 pieSeries->setHorizontalPosition(0.2);
265 265 pieSeries->setVerticalPosition(0.35);
266 266
267 267 m_chart->addSeries(pieSeries);
268 268 seriesColorHex = "#" + QString::number(pieSeries->slices().at(pieSeries->slices().count()/2)->brush().color().rgb(), 16).right(6).toUpper();
269 269 m_model->addMapping(seriesColorHex, QRect(0, 0, 1, 1000));
270 270
271 271 // pie 2
272 272 pieSeries = new QPieSeries;
273 273 pieSeries->setModel(m_model);
274 274 pieSeries->setModelMapping(1,1, Qt::Vertical);
275 275 pieSeries->setLabelsVisible(true);
276 276 pieSeries->setPieSize(0.4);
277 277 pieSeries->setHorizontalPosition(0.8);
278 278 pieSeries->setVerticalPosition(0.35);
279 279 m_chart->addSeries(pieSeries);
280 280 seriesColorHex = "#" + QString::number(pieSeries->slices().at(pieSeries->slices().count()/2)->brush().color().rgb(), 16).right(6).toUpper();
281 281 m_model->addMapping(seriesColorHex, QRect(1, 0, 1, 1000));
282 282
283 283 // pie 3
284 284 pieSeries = new QPieSeries;
285 285 pieSeries->setModel(m_model);
286 286 pieSeries->setModelMapping(2,2, Qt::Vertical);
287 287 pieSeries->setLabelsVisible(true);
288 288 pieSeries->setPieSize(0.4);
289 289 pieSeries->setHorizontalPosition(0.5);
290 290 pieSeries->setVerticalPosition(0.65);
291 291 m_chart->addSeries(pieSeries);
292 292 seriesColorHex = "#" + QString::number(pieSeries->slices().at(pieSeries->slices().count()/2)->brush().color().rgb(), 16).right(6).toUpper();
293 293 m_model->addMapping(seriesColorHex, QRect(2, 0, 1, 1000));
294 294 }
295 295 else if (m_areaRadioButton->isChecked())
296 296 {
297 297 QLineSeries* upperLineSeries = new QLineSeries;
298 298 upperLineSeries->setModel(m_model);
299 299 upperLineSeries->setModelMapping(0, 1, Qt::Vertical);
300 300 upperLineSeries->setModelMappingRange(1, 5);
301 301 QLineSeries* lowerLineSeries = new QLineSeries;
302 302 lowerLineSeries->setModel(m_model);
303 303 lowerLineSeries->setModelMapping(2, 3, Qt::Vertical);
304 304 QAreaSeries* areaSeries = new QAreaSeries(upperLineSeries, lowerLineSeries);
305 305 m_chart->addSeries(areaSeries);
306 306 seriesColorHex = "#" + QString::number(areaSeries->brush().color().rgb(), 16).right(6).toUpper();
307 307 m_model->addMapping(seriesColorHex, QRect(0, 1, 2, 5));
308 308 m_model->addMapping(seriesColorHex, QRect(2, 0, 2, 1000));
309 309 }
310 310 else if (m_barRadioButton->isChecked())
311 311 {
312 312 QBarSeries* barSeries = new QBarSeries(QStringList());
313 313 barSeries->setModel(m_model);
314 314 barSeries->setModelMapping(5, 2, 4, Qt::Vertical);
315 barSeries->setToolTipEnabled(true);
316 315 m_chart->addSeries(barSeries);
317 316 QList<QBarSet*> barsets = barSeries->barSets();
318 317 for (int i = 0; i < barsets.count(); i++) {
319 318 seriesColorHex = "#" + QString::number(barsets.at(i)->brush().color().rgb(), 16).right(6).toUpper();
320 319 m_model->addMapping(seriesColorHex, QRect(2 + i, 0, 1, 1000));
321 320 }
322 321 }
323 322
324 323
325 324 m_chart->axisX()->setRange(0, 500);
326 325 m_chart->axisY()->setRange(0, 120);
327 326
328 327 // repaint table view colors
329 328 m_tableView->repaint();
330 329 m_tableView->setFocus();
331 330 }
332 331 }
333 332
334 333 TableWidget::~TableWidget()
335 334 {
336 335
337 336 }
General Comments 0
You need to be logged in to leave comments. Login now