##// END OF EJS Templates
Drilldown example using stacked barchart.
sauimone -
r449:2d02ec95e04f
parent child
Show More
@@ -1,160 +1,152
1 #include <QtGui/QApplication>
1 #include <QtGui/QApplication>
2 #include <QMainWindow>
2 #include <QMainWindow>
3 #include <qchartglobal.h>
3 #include <qchartglobal.h>
4 #include <qchartview.h>
4 #include <qchartview.h>
5 #include <qstackedbarseries.h>
5 #include <qstackedbarseries.h>
6 #include <qbarset.h>
6 #include <qbarset.h>
7 #include <qchartaxis.h>
7 #include <qchartaxis.h>
8 #include <QStringList>
8 #include <QStringList>
9 #include <QDebug>
9 #include <QDebug>
10
10
11 QTCOMMERCIALCHART_USE_NAMESPACE
11 QTCOMMERCIALCHART_USE_NAMESPACE
12
12
13 //! [1]
13 //! [1]
14 class DrilldownBarSeries : public QStackedBarSeries
14 class DrilldownBarSeries : public QStackedBarSeries
15 {
15 {
16 Q_OBJECT
16 Q_OBJECT
17 public:
17 public:
18 DrilldownBarSeries(QStringList categories, QObject* parent = 0) : QStackedBarSeries(categories,parent) {}
18 DrilldownBarSeries(QStringList categories, QObject *parent = 0) : QStackedBarSeries(categories,parent) {}
19
19
20
20 void addDrilldownSeries(QString category, DrilldownBarSeries* drilldownSeries)
21 public Q_SLOTS:
22 void handleRightClick(QBarSet *barset, QString category)
23 {
21 {
24 qDebug() << "DrilldownBarSeries::handleRightClick" << barset->name() << category;
22 mDrilldownSeries[category] = drilldownSeries;
25 // mChart->changeSeries(this);
26 }
23 }
27
24
28 };
29 //! [1]
30
31 //! [2]
32 class DrilldownBarSet : public QBarSet
33 {
34 Q_OBJECT
35 public:
36 DrilldownBarSet(QString name, DrilldownBarSeries* drilldownSeries) : QBarSet(name) , mSeries(drilldownSeries) {}
37
38 DrilldownBarSeries* drilldownSeries(QString category)
25 DrilldownBarSeries* drilldownSeries(QString category)
39 {
26 {
40 return mSeries;
27 // qDebug() << "DrilldownBarSeries::drilldownSeries" << category << mDrilldownSeries[category];
41 }
28 return mDrilldownSeries[category];
29 }
30
31 public Q_SLOTS:
42
32
43 private:
33 private:
44 DrilldownBarSeries* mSeries;
34
35 QMap<QString, DrilldownBarSeries*> mDrilldownSeries;
45 };
36 };
46 //! [2]
37 //! [1]
47
38
48 //! [3]
39 //! [2]
49 class DrilldownChart : public QChartView
40 class DrilldownChart : public QChartView
50 {
41 {
51 Q_OBJECT
42 Q_OBJECT
52 public:
43 public:
53 explicit DrilldownChart(QWidget *parent = 0) : QChartView(parent), m_currentSeries(0) {}
44 explicit DrilldownChart(QWidget *parent = 0) : QChartView(parent), m_currentSeries(0) {}
54
45
55 void changeSeries(QSeries* series)
46 void changeSeries(QSeries* series)
56 {
47 {
57 if (m_currentSeries)
48 if (m_currentSeries)
58 removeSeries(m_currentSeries);
49 removeSeries(m_currentSeries);
59 m_currentSeries = series;
50 m_currentSeries = series;
60 addSeries(series);
51 addSeries(series);
61 setChartTitle(series->title());
52 setChartTitle(series->title());
62 }
53 }
63
54
64 public Q_SLOTS:
55 public Q_SLOTS:
65 void handleRightClick(QBarSet *barset, QString category)
56 void handleRightClick(QBarSet *barset, QString category)
66 {
57 {
67 qDebug() << "DrilldownChart::handleRightClick" << barset->name() << category;
58 qDebug() << "DrilldownChart::handleRightClick" << barset->name() << category;
68 // TODO: continue from here
59 // TODO: continue from here
69 DrilldownBarSet* drilldownBarSet = static_cast<DrilldownBarSet*>(barset);
60 DrilldownBarSeries* series = static_cast<DrilldownBarSeries*> (sender());
70 changeSeries(drilldownBarSet->drilldownSeries(category));
61 changeSeries(series->drilldownSeries(category));
71 }
62 }
72
63
73 private:
64 private:
74 QSeries* m_currentSeries;
65 QSeries* m_currentSeries;
75 };
66 };
76 //! [3]
67 //! [2]
77
68
78 int main(int argc, char *argv[])
69 int main(int argc, char *argv[])
79 {
70 {
80 QApplication a(argc, argv);
71 QApplication a(argc, argv);
81 QMainWindow window;
72 QMainWindow window;
82
73
83 DrilldownChart* drilldownChart = new DrilldownChart(&window);
74 DrilldownChart* drilldownChart = new DrilldownChart(&window);
84 drilldownChart->setChartTheme(QChart::ChartThemeIcy);
75 drilldownChart->setChartTheme(QChart::ChartThemeIcy);
85
76
86 //! [4]
77 //! [3]
87 // Define categories
78 // Define categories
88 QStringList months;
79 QStringList months;
89 months << "Jun" << "Jul" << "Aug" << "Sep";
80 months << "Jun" << "Jul" << "Aug" << "Sep";
90 QStringList weeks;
81 QStringList weeks;
91 weeks << "week 1" << "week 2" << "week 3" << "week 4";
82 weeks << "week 1" << "week 2" << "week 3" << "week 4";
92 QStringList plants;
83 QStringList plants;
93 plants << "Habanero" << "Lemon Drop" << "Starfish" << "Aji Amarillo";
84 plants << "Habanero" << "Lemon Drop" << "Starfish" << "Aji Amarillo";
85 //! [3]
86
94 //! [4]
87 //! [4]
88 // Create drilldown structure
89 DrilldownBarSeries* seasonSeries = new DrilldownBarSeries(months, drilldownChart);
90 seasonSeries->setTitle("Crop by month - Season");
95
91
96 DrilldownBarSeries* monthlySeries = new DrilldownBarSeries(months, drilldownChart);
92 // Each month in season series has drilldown series for weekly data
97 monthlySeries->setTitle("Crop by month - Season");
93 foreach (QString month, months) {
98
94
99 foreach (QString plant, plants) {
95 // Create drilldown series for every week
100 DrilldownBarSeries* weeklySeries = new DrilldownBarSeries(weeks, drilldownChart);
96 DrilldownBarSeries* weeklySeries = new DrilldownBarSeries(weeks, drilldownChart);
101 DrilldownBarSet* monthlyCrop = new DrilldownBarSet(plant,weeklySeries);
97 seasonSeries->addDrilldownSeries(month, weeklySeries);
102 weeklySeries->setTitle("Crop by week - Month");
103
104 foreach(QString month, months) {
105 DrilldownBarSet* weeklyCrop = new DrilldownBarSet(plant,monthlySeries);
106
107 foreach (QString week, weeks ) {
108 *weeklyCrop << (qrand() % 20);
109 }
110
98
111 weeklySeries->addBarSet(weeklyCrop);
99 // Drilling down from weekly data brings us back to season data.
112 weeklySeries->setToolTipEnabled(true);
100 foreach (QString week, weeks) {
113 *monthlyCrop << weeklyCrop->total();
101 weeklySeries->addDrilldownSeries(week, seasonSeries);
114
102 weeklySeries->setTitle(QString("Crop by week - " + month));
115 QObject::connect(weeklyCrop,SIGNAL(clicked(QString)),weeklyCrop,SIGNAL(toggleFloatingValues()));
116 QObject::connect(weeklySeries,SIGNAL(rightClicked(QBarSet*,QString)),drilldownChart,SLOT(handleRightClick(QBarSet*,QString)));
117 }
103 }
118
104
119 QObject::connect(monthlyCrop,SIGNAL(clicked(QString)),monthlyCrop,SIGNAL(toggleFloatingValues()));
105 // Use right click signal to implement drilldown
120 monthlySeries->addBarSet(monthlyCrop);
106 QObject::connect(weeklySeries,SIGNAL(rightClicked(QBarSet*,QString)),drilldownChart,SLOT(handleRightClick(QBarSet*,QString)));
121 }
107 }
108 //! [4]
122
109
123 /*
110 //! [5]
111 // Fill monthly and weekly series with data
124 foreach (QString plant, plants) {
112 foreach (QString plant, plants) {
125 DrilldownBarSeries* weeklySeries = new DrilldownBarSeries(weeks, drilldownChart);
113 QBarSet* monthlyCrop = new QBarSet(plant);
126 DrilldownBarSet* monthlyCrop = new DrilldownBarSet(plant,weeklySeries);
114 foreach (QString month, months) {
127 weeklySeries->setTitle("Crop by week - Month");
115 QBarSet* weeklyCrop = new QBarSet(plant);
128 foreach(QString month, months) {
129 DrilldownBarSet* weeklyCrop = new DrilldownBarSet(plant,monthlySeries);
130 foreach (QString week, weeks ) {
116 foreach (QString week, weeks ) {
131 *weeklyCrop << (qrand() % 20);
117 *weeklyCrop << (qrand() % 20);
132 }
118 }
133 weeklySeries->addBarSet(weeklyCrop);
119 // Get the drilldown series from upper level series and add crop to it.
134 weeklySeries->setToolTipEnabled(true);
120 seasonSeries->drilldownSeries(month)->addBarSet(weeklyCrop);
121 seasonSeries->drilldownSeries(month)->setToolTipEnabled(true);
135 *monthlyCrop << weeklyCrop->total();
122 *monthlyCrop << weeklyCrop->total();
123
136 QObject::connect(weeklyCrop,SIGNAL(clicked(QString)),weeklyCrop,SIGNAL(toggleFloatingValues()));
124 QObject::connect(weeklyCrop,SIGNAL(clicked(QString)),weeklyCrop,SIGNAL(toggleFloatingValues()));
137 QObject::connect(weeklySeries,SIGNAL(rightClicked(QBarSet*,QString)),drilldownChart,SLOT(handleRightClick(QBarSet*,QString)));
138 }
125 }
126 seasonSeries->addBarSet(monthlyCrop);
139 QObject::connect(monthlyCrop,SIGNAL(clicked(QString)),monthlyCrop,SIGNAL(toggleFloatingValues()));
127 QObject::connect(monthlyCrop,SIGNAL(clicked(QString)),monthlyCrop,SIGNAL(toggleFloatingValues()));
140 monthlySeries->addBarSet(monthlyCrop);
141 }
128 }
142 */
129 //! [5]
143 QObject::connect(monthlySeries,SIGNAL(rightClicked(QBarSet*,QString)),drilldownChart,SLOT(handleRightClick(QBarSet*,QString)));
130
131 seasonSeries->setToolTipEnabled(true);
132
133 // Enable drilldown from season series using right click.
134 QObject::connect(seasonSeries,SIGNAL(rightClicked(QBarSet*,QString)),drilldownChart,SLOT(handleRightClick(QBarSet*,QString)));
144
135
145 monthlySeries->setToolTipEnabled(true);
136 // Show season series in initial view
146 drilldownChart->changeSeries(monthlySeries);
137 drilldownChart->changeSeries(seasonSeries);
147 drilldownChart->setChartTitle(monthlySeries->title());
138 drilldownChart->setChartTitle(seasonSeries->title());
148
139
140 // Disable axis, since they don't really apply to bar chart
149 drilldownChart->axisX()->setAxisVisible(false);
141 drilldownChart->axisX()->setAxisVisible(false);
150 drilldownChart->axisX()->setGridVisible(false);
142 drilldownChart->axisX()->setGridVisible(false);
151 drilldownChart->axisX()->setLabelsVisible(false);
143 drilldownChart->axisX()->setLabelsVisible(false);
152
144
153 window.setCentralWidget(drilldownChart);
145 window.setCentralWidget(drilldownChart);
154 window.resize(400, 300);
146 window.resize(400, 300);
155 window.show();
147 window.show();
156
148
157 return a.exec();
149 return a.exec();
158 }
150 }
159
151
160 #include "main.moc"
152 #include "main.moc"
@@ -1,117 +1,116
1 #include "stackedbarpresenter_p.h"
1 #include "stackedbarpresenter_p.h"
2 #include "bar_p.h"
2 #include "bar_p.h"
3 #include "barlabel_p.h"
3 #include "barlabel_p.h"
4 #include "barvalue_p.h"
4 #include "barvalue_p.h"
5 #include "separator_p.h"
5 #include "separator_p.h"
6 #include "qbarset.h"
6 #include "qbarset.h"
7 #include <QDebug>
7 #include <QDebug>
8
8
9 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9 QTCOMMERCIALCHART_BEGIN_NAMESPACE
10
10
11 StackedBarPresenter::StackedBarPresenter(QBarSeries *series, QGraphicsItem *parent) :
11 StackedBarPresenter::StackedBarPresenter(QBarSeries *series, QGraphicsItem *parent) :
12 BarPresenterBase(series,parent)
12 BarPresenterBase(series,parent)
13 {
13 {
14 }
14 }
15
15
16 StackedBarPresenter::~StackedBarPresenter()
16 StackedBarPresenter::~StackedBarPresenter()
17 {
17 {
18 qDebug() << "StackedBarPresenter deleted";
19 }
18 }
20
19
21
20
22 void StackedBarPresenter::layoutChanged()
21 void StackedBarPresenter::layoutChanged()
23 {
22 {
24 // Scale bars to new layout
23 // Scale bars to new layout
25 // Layout for bars:
24 // Layout for bars:
26 if (mSeries->barsetCount() <= 0) {
25 if (mSeries->barsetCount() <= 0) {
27 qDebug() << "No sets in model!";
26 qDebug() << "No sets in model!";
28 // Nothing to do.
27 // Nothing to do.
29 return;
28 return;
30 }
29 }
31
30
32 if (mSeries->categoryCount() == 0) {
31 if (mSeries->categoryCount() == 0) {
33 qDebug() << "No categories in model!";
32 qDebug() << "No categories in model!";
34 // Nothing to do
33 // Nothing to do
35 return;
34 return;
36 }
35 }
37
36
38 if (childItems().count() == 0) {
37 if (childItems().count() == 0) {
39 qDebug() << "WARNING: StackedBarPresenter::layoutChanged called before graphics items are created!";
38 qDebug() << "WARNING: StackedBarPresenter::layoutChanged called before graphics items are created!";
40 return;
39 return;
41 }
40 }
42
41
43 // TODO: better way to auto-layout
42 // TODO: better way to auto-layout
44 // Use reals for accurancy (we might get some compiler warnings... :)
43 // Use reals for accurancy (we might get some compiler warnings... :)
45 // TODO: use temp variable for category count...
44 // TODO: use temp variable for category count...
46 qreal maxSum = mSeries->maxCategorySum();
45 qreal maxSum = mSeries->maxCategorySum();
47 qreal h = mHeight;
46 qreal h = mHeight;
48 qreal scale = (h / maxSum);
47 qreal scale = (h / maxSum);
49
48
50 int itemIndex(0);
49 int itemIndex(0);
51 int labelIndex(0);
50 int labelIndex(0);
52 qreal tW = mWidth;
51 qreal tW = mWidth;
53 qreal tC = mSeries->categoryCount() + 1;
52 qreal tC = mSeries->categoryCount() + 1;
54 qreal xStep = (tW/tC);
53 qreal xStep = (tW/tC);
55 qreal xPos = ((tW/tC) - mBarDefaultWidth / 2);
54 qreal xPos = ((tW/tC) - mBarDefaultWidth / 2);
56
55
57 for (int category = 0; category < mSeries->categoryCount(); category++) {
56 for (int category = 0; category < mSeries->categoryCount(); category++) {
58 qreal yPos = h;
57 qreal yPos = h;
59 for (int set=0; set < mSeries->barsetCount(); set++) {
58 for (int set=0; set < mSeries->barsetCount(); set++) {
60 qreal barHeight = mSeries->valueAt(set, category) * scale;
59 qreal barHeight = mSeries->valueAt(set, category) * scale;
61 Bar* bar = mBars.at(itemIndex);
60 Bar* bar = mBars.at(itemIndex);
62
61
63 bar->resize(mBarDefaultWidth, barHeight);
62 bar->resize(mBarDefaultWidth, barHeight);
64 bar->setBrush(mSeries->barsetAt(set)->brush());
63 bar->setBrush(mSeries->barsetAt(set)->brush());
65 bar->setPos(xPos, yPos-barHeight);
64 bar->setPos(xPos, yPos-barHeight);
66 itemIndex++;
65 itemIndex++;
67 yPos -= barHeight;
66 yPos -= barHeight;
68 }
67 }
69
68
70 // TODO: Layout for labels, remove magic number
69 // TODO: Layout for labels, remove magic number
71 BarLabel* label = mLabels.at(labelIndex);
70 BarLabel* label = mLabels.at(labelIndex);
72 label->setPos(xPos, mHeight + 20);
71 label->setPos(xPos, mHeight + 20);
73 labelIndex++;
72 labelIndex++;
74 xPos += xStep;
73 xPos += xStep;
75 }
74 }
76
75
77 // Position separators
76 // Position separators
78 xPos = xStep + xStep/2;
77 xPos = xStep + xStep/2;
79 for (int s=0; s < mSeries->categoryCount() - 1; s++) {
78 for (int s=0; s < mSeries->categoryCount() - 1; s++) {
80 Separator* sep = mSeparators.at(s);
79 Separator* sep = mSeparators.at(s);
81 sep->setPos(xPos,0);
80 sep->setPos(xPos,0);
82 sep->setSize(QSizeF(1,mHeight));
81 sep->setSize(QSizeF(1,mHeight));
83 xPos += xStep;
82 xPos += xStep;
84 }
83 }
85
84
86 // Position floating values
85 // Position floating values
87 itemIndex = 0;
86 itemIndex = 0;
88 xPos = ((tW/tC) - mBarDefaultWidth / 2);
87 xPos = ((tW/tC) - mBarDefaultWidth / 2);
89 for (int category=0; category < mSeries->categoryCount(); category++) {
88 for (int category=0; category < mSeries->categoryCount(); category++) {
90 qreal yPos = h;
89 qreal yPos = h;
91 for (int set=0; set < mSeries->barsetCount(); set++) {
90 for (int set=0; set < mSeries->barsetCount(); set++) {
92 qreal barHeight = mSeries->valueAt(set,category) * scale;
91 qreal barHeight = mSeries->valueAt(set,category) * scale;
93 BarValue* value = mFloatingValues.at(itemIndex);
92 BarValue* value = mFloatingValues.at(itemIndex);
94
93
95 // TODO: remove hard coding, apply layout
94 // TODO: remove hard coding, apply layout
96 value->resize(100,50);
95 value->resize(100,50);
97 value->setPos(xPos, yPos-barHeight/2);
96 value->setPos(xPos, yPos-barHeight/2);
98 value->setPen(QPen(QColor(255,255,255,255)));
97 value->setPen(QPen(QColor(255,255,255,255)));
99
98
100 if (mSeries->valueAt(set,category) != 0) {
99 if (mSeries->valueAt(set,category) != 0) {
101 value->setValueString(QString::number(mSeries->valueAt(set,category)));
100 value->setValueString(QString::number(mSeries->valueAt(set,category)));
102 } else {
101 } else {
103 value->setValueString(QString(""));
102 value->setValueString(QString(""));
104 }
103 }
105
104
106 itemIndex++;
105 itemIndex++;
107 yPos -= barHeight;
106 yPos -= barHeight;
108 }
107 }
109 xPos += xStep;
108 xPos += xStep;
110 }
109 }
111
110
112 mLayoutDirty = true;
111 mLayoutDirty = true;
113 }
112 }
114
113
115 #include "moc_stackedbarpresenter_p.cpp"
114 #include "moc_stackedbarpresenter_p.cpp"
116
115
117 QTCOMMERCIALCHART_END_NAMESPACE
116 QTCOMMERCIALCHART_END_NAMESPACE
General Comments 0
You need to be logged in to leave comments. Login now