##// END OF EJS Templates
Labels for barchart to axis
sauimone -
r487:03622a1338c4
parent child
Show More
@@ -1,152 +1,152
1 1 #include <QtGui/QApplication>
2 2 #include <QMainWindow>
3 3 #include <qchartglobal.h>
4 4 #include <qchartview.h>
5 5 #include <qstackedbarseries.h>
6 6 #include <qbarset.h>
7 7 #include <qchartaxis.h>
8 8 #include <QStringList>
9 9 #include <QDebug>
10 10
11 11 QTCOMMERCIALCHART_USE_NAMESPACE
12 12
13 13 //! [1]
14 14 class DrilldownBarSeries : public QStackedBarSeries
15 15 {
16 16 Q_OBJECT
17 17 public:
18 18 DrilldownBarSeries(QStringList categories, QObject *parent = 0) : QStackedBarSeries(categories,parent) {}
19 19
20 20 void mapDrilldownSeries(QString category, DrilldownBarSeries* drilldownSeries)
21 21 {
22 22 mDrilldownSeries[category] = drilldownSeries;
23 23 }
24 24
25 25 DrilldownBarSeries* drilldownSeries(QString category)
26 26 {
27 27 return mDrilldownSeries[category];
28 28 }
29 29
30 30 public Q_SLOTS:
31 31
32 32 private:
33 33
34 34 QMap<QString, DrilldownBarSeries*> mDrilldownSeries;
35 35 };
36 36 //! [1]
37 37
38 38 //! [2]
39 39 class DrilldownChart : public QChartView
40 40 {
41 41 Q_OBJECT
42 42 public:
43 43 explicit DrilldownChart(QWidget *parent = 0) : QChartView(parent), m_currentSeries(0) {}
44 44
45 45 void changeSeries(QSeries* series)
46 46 {
47 47 if (m_currentSeries)
48 48 removeSeries(m_currentSeries);
49 49 m_currentSeries = series;
50 50 addSeries(series);
51 51 setChartTitle(series->title());
52 52 }
53 53
54 54 public Q_SLOTS:
55 55 void handleRightClick(QBarSet *barset, QString category)
56 56 {
57 57 // qDebug() << "DrilldownChart::handleRightClick" << barset->name() << category;
58 58 DrilldownBarSeries* series = static_cast<DrilldownBarSeries*> (sender());
59 59 changeSeries(series->drilldownSeries(category));
60 60 }
61 61
62 62 private:
63 63 QSeries* m_currentSeries;
64 64 };
65 65 //! [2]
66 66
67 67 int main(int argc, char *argv[])
68 68 {
69 69 QApplication a(argc, argv);
70 70 QMainWindow window;
71 71
72 72 DrilldownChart* drilldownChart = new DrilldownChart(&window);
73 73 drilldownChart->setChartTheme(QChart::ChartThemeIcy);
74 74
75 75 //! [3]
76 76 // Define categories
77 77 QStringList months;
78 78 months << "May" << "Jun" << "Jul" << "Aug" << "Sep";
79 79 QStringList weeks;
80 80 weeks << "week 1" << "week 2" << "week 3" << "week 4";
81 81 QStringList plants;
82 82 plants << "Habanero" << "Lemon Drop" << "Starfish" << "Aji Amarillo";
83 83 //! [3]
84 84
85 85 //! [4]
86 86 // Create drilldown structure
87 87 DrilldownBarSeries* seasonSeries = new DrilldownBarSeries(months, drilldownChart);
88 88 seasonSeries->setTitle("Crop by month - Season");
89 89
90 90 // Each month in season series has drilldown series for weekly data
91 91 foreach (QString month, months) {
92 92
93 93 // Create drilldown series for every week
94 94 DrilldownBarSeries* weeklySeries = new DrilldownBarSeries(weeks, drilldownChart);
95 95 seasonSeries->mapDrilldownSeries(month, weeklySeries);
96 96
97 97 // Drilling down from weekly data brings us back to season data.
98 98 foreach (QString week, weeks) {
99 99 weeklySeries->mapDrilldownSeries(week, seasonSeries);
100 100 weeklySeries->setTitle(QString("Crop by week - " + month));
101 101 }
102 102
103 103 // Use right click signal to implement drilldown
104 104 QObject::connect(weeklySeries,SIGNAL(rightClicked(QBarSet*,QString)),drilldownChart,SLOT(handleRightClick(QBarSet*,QString)));
105 105 }
106 106
107 107 // Enable drilldown from season series using right click.
108 108 QObject::connect(seasonSeries,SIGNAL(rightClicked(QBarSet*,QString)),drilldownChart,SLOT(handleRightClick(QBarSet*,QString)));
109 109 //! [4]
110 110
111 111 //! [5]
112 112 // Fill monthly and weekly series with data
113 113 foreach (QString plant, plants) {
114 114 QBarSet* monthlyCrop = new QBarSet(plant);
115 115 foreach (QString month, months) {
116 116 QBarSet* weeklyCrop = new QBarSet(plant);
117 117 foreach (QString week, weeks ) {
118 118 *weeklyCrop << (qrand() % 20);
119 119 }
120 120 // Get the drilldown series from season series and add crop to it.
121 121 seasonSeries->drilldownSeries(month)->addBarSet(weeklyCrop);
122 122 seasonSeries->drilldownSeries(month)->setToolTipEnabled(true);
123 123 *monthlyCrop << weeklyCrop->total();
124 124
125 125 QObject::connect(weeklyCrop,SIGNAL(clicked(QString)),weeklyCrop,SIGNAL(toggleFloatingValues()));
126 126 }
127 127 seasonSeries->addBarSet(monthlyCrop);
128 128 QObject::connect(monthlyCrop,SIGNAL(clicked(QString)),monthlyCrop,SIGNAL(toggleFloatingValues()));
129 129 }
130 130 //! [5]
131 131
132 132 seasonSeries->setToolTipEnabled(true);
133 133
134 134 //! [6]
135 135 // Show season series in initial view
136 136 drilldownChart->changeSeries(seasonSeries);
137 137 drilldownChart->setChartTitle(seasonSeries->title());
138 138 //! [6]
139 139
140 140 // Disable axis, since they don't really apply to bar chart
141 drilldownChart->axisX()->setAxisVisible(false);
141 // drilldownChart->axisX()->setAxisVisible(false);
142 142 drilldownChart->axisX()->setGridVisible(false);
143 drilldownChart->axisX()->setLabelsVisible(false);
143 // drilldownChart->axisX()->setLabelsVisible(false);
144 144
145 145 window.setCentralWidget(drilldownChart);
146 146 window.resize(400, 300);
147 147 window.show();
148 148
149 149 return a.exec();
150 150 }
151 151
152 152 #include "main.moc"
@@ -1,95 +1,94
1 1 #include "barpresenter_p.h"
2 2 #include "bar_p.h"
3 3 #include "barlabel_p.h"
4 4 #include "barvalue_p.h"
5 5 #include "qbarset.h"
6 6 #include <QDebug>
7 7
8 8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9 9
10 BarPresenter::BarPresenter(QBarSeries *series, QGraphicsItem *parent) :
10 BarPresenter::BarPresenter(QBarSeries *series, QChart *parent) :
11 11 BarPresenterBase(series, parent)
12 12 {
13 mBarWidth = 5;
14 13 }
15 14
16 15 void BarPresenter::layoutChanged()
17 16 {
18 17 // Scale bars to new layout
19 18 // Layout for bars:
20 19 if (mSeries->barsetCount() <= 0) {
21 20 qDebug() << "No sets in model!";
22 21 return;
23 22 }
24 23
25 24 if (childItems().count() == 0) {
26 25 qDebug() << "WARNING: BarPresenter::layoutChanged called before graphics items are created!";
27 26 return;
28 27 }
29 28
30 29 // Use temporary qreals for accurancy (we might get some compiler warnings... :)
31 30 int categoryCount = mSeries->categoryCount();
32 31 int setCount = mSeries->barsetCount();
33 32
34 33 qreal tW = mWidth;
35 34 qreal tH = mHeight;
36 35 qreal tM = mSeries->max();
37 36 qreal scale = (tH/tM);
38 37 qreal tC = categoryCount + 1;
39 38 mBarWidth = tW / ((categoryCount * setCount) + tC);
40 39 qreal xStepPerCategory = (tW/tC) + mBarWidth;
41 40
42 41 int itemIndex(0);
43 42 int labelIndex(0);
44 43
45 44 for (int category=0; category < categoryCount; category++) {
46 45 qreal xPos = xStepPerCategory * category;
47 46 qreal yPos = mHeight;
48 47 for (int set = 0; set < setCount; set++) {
49 48 qreal barHeight = mSeries->valueAt(set,category) * scale;
50 49 Bar* bar = mBars.at(itemIndex);
51 50
52 51 // TODO: width settable per bar?
53 52 bar->resize(mBarWidth, barHeight);
54 53 bar->setBrush(mSeries->barsetAt(set)->brush());
55 54 bar->setPos(xPos, yPos-barHeight);
56 55 itemIndex++;
57 56 xPos += mBarWidth;
58 57 }
59 58
60 59 // TODO: Layout for labels, remove magic number
61 60 xPos = xStepPerCategory * category + mBarWidth/2;
62 61 BarLabel* label = mLabels.at(labelIndex);
63 62 label->setPos(xPos, mHeight - 20);
64 63 labelIndex++;
65 64 }
66 65
67 66 // Position floating values
68 67 itemIndex = 0;
69 68 for (int category=0; category < mSeries->categoryCount(); category++) {
70 69 qreal xPos = xStepPerCategory * category + mBarWidth/2;
71 70 qreal yPos = mHeight;
72 71 for (int set=0; set < mSeries->barsetCount(); set++) {
73 72 qreal barHeight = mSeries->valueAt(set,category) * scale;
74 73 BarValue* value = mFloatingValues.at(itemIndex);
75 74
76 75 // TODO: remove hard coding, apply layout
77 76 value->resize(100,50);
78 77 value->setPos(xPos, yPos-barHeight/2);
79 78 value->setPen(QPen(QColor(255,255,255,255)));
80 79
81 80 if (mSeries->valueAt(set,category) != 0) {
82 81 value->setValueString(QString::number(mSeries->valueAt(set,category)));
83 82 } else {
84 83 value->setValueString(QString(""));
85 84 }
86 85
87 86 itemIndex++;
88 87 xPos += mBarWidth;
89 88 }
90 89 }
91 90 }
92 91
93 92 #include "moc_barpresenter_p.cpp"
94 93
95 94 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,30 +1,30
1 1 #ifndef BARPRESENTER_H
2 2 #define BARPRESENTER_H
3 3
4 4 #include "qchartglobal.h"
5 5 #include "barpresenterbase_p.h"
6 6 #include <QGraphicsItem>
7 7
8 8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9 9
10 10 class QBarSeries;
11 11
12 12 // Presenter for parallel bars. Grouping of bars is done on category basis.
13 13 class BarPresenter : public BarPresenterBase
14 14 {
15 15 Q_OBJECT
16 16 public:
17 explicit BarPresenter(QBarSeries *series, QGraphicsItem *parent = 0);
17 explicit BarPresenter(QBarSeries *series, QChart *parent = 0);
18 18
19 19 private:
20 20
21 21 // From BarPresenterBase
22 22 void layoutChanged(); // layout has changed -> need to recalculate bar sizes
23 23
24 24 private:
25 25 // Data
26 26 };
27 27
28 28 QTCOMMERCIALCHART_END_NAMESPACE
29 29
30 30 #endif // BARPRESENTER_H
@@ -1,150 +1,190
1 1 #include "barpresenterbase_p.h"
2 2 #include "bar_p.h"
3 3 #include "barvalue_p.h"
4 4 #include "barlabel_p.h"
5 5 #include "separator_p.h"
6 6 #include "qbarset.h"
7 7 #include "qbarseries.h"
8 #include "qchart.h"
9 #include "qchartaxis.h"
10 #include "qchartaxiscategories.h"
8 11 #include <QDebug>
9 12 #include <QToolTip>
10 13
11 14 QTCOMMERCIALCHART_BEGIN_NAMESPACE
12 15
13 BarPresenterBase::BarPresenterBase(QBarSeries *series, QGraphicsItem *parent)
16 BarPresenterBase::BarPresenterBase(QBarSeries *series, QChart *parent)
14 17 : ChartItem(parent)
15 ,mBarWidth(20) // TODO: remove hard coding, when we have layout code ready
16 18 ,mLayoutSet(false)
17 19 ,mSeparatorsEnabled(false)
18 20 ,mSeries(series)
21 ,mChart(parent)
19 22 {
20 23 connect(series,SIGNAL(showToolTip(QPoint,QString)),this,SLOT(showToolTip(QPoint,QString)));
24 initAxisLabels();
21 25 dataChanged();
22 26 }
23 27
24 28 BarPresenterBase::~BarPresenterBase()
25 29 {
26 30 disconnect(this,SLOT(showToolTip(QPoint,QString)));
27 31 }
28 32
29 33 void BarPresenterBase::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
30 34 {
31 35 if (!mLayoutSet) {
32 36 qDebug() << "BarPresenterBase::paint called without layout set. Aborting.";
33 37 return;
34 38 }
35 39 foreach(QGraphicsItem* i, childItems()) {
36 40 i->paint(painter,option,widget);
37 41 }
38 42 }
39 43
40 44 QRectF BarPresenterBase::boundingRect() const
41 45 {
42 46 return QRectF(0,0,mWidth,mHeight);
43 47 }
44 48
45 void BarPresenterBase::setBarWidth( int w )
46 {
47 mBarWidth = w;
48 }
49
50 49 void BarPresenterBase::dataChanged()
51 50 {
52 51 // TODO: performance optimizations. Do we really need to delete and create items every time data is changed or can we reuse them?
53 52 // Delete old bars
54 53 foreach (QGraphicsItem* item, childItems()) {
55 54 delete item;
56 55 }
57 56
58 57 mBars.clear();
59 58 mLabels.clear();
60 59 mSeparators.clear();
61 60 mFloatingValues.clear();
62 61
63 62 // Create new graphic items for bars
64 63 for (int c=0; c<mSeries->categoryCount(); c++) {
65 64 QString category = mSeries->categoryName(c);
66 65 for (int s=0; s<mSeries->barsetCount(); s++) {
67 66 QBarSet *set = mSeries->barsetAt(s);
68 67 Bar *bar = new Bar(category,this);
69 68 childItems().append(bar);
70 69 mBars.append(bar);
71 70 connect(bar,SIGNAL(clicked(QString)),set,SIGNAL(clicked(QString)));
72 71 connect(bar,SIGNAL(rightClicked(QString)),set,SIGNAL(rightClicked(QString)));
73 72 connect(bar,SIGNAL(hoverEntered(QPoint)),set,SLOT(barHoverEnterEvent(QPoint)));
74 73 connect(bar,SIGNAL(hoverLeaved()),set,SLOT(barHoverLeaveEvent()));
75 74 }
76 75 }
77 76
78 77 // Create labels
78 /*
79 79 int count = mSeries->categoryCount();
80 80 for (int i=0; i<count; i++) {
81 81 BarLabel* label = new BarLabel(this);
82 82 label->set(mSeries->categoryName(i));
83 83 childItems().append(label);
84 84 mLabels.append(label);
85 85 }
86 */
86 87
87 88 // Create separators
88 count = mSeries->categoryCount() - 1; // There is one less separator than columns
89 int count = mSeries->categoryCount() - 1; // There is one less separator than columns
89 90 for (int i=0; i<count; i++) {
90 91 Separator* sep = new Separator(this);
91 92 sep->setColor(QColor(255,0,0,255)); // TODO: color for separations from theme
92 93 sep->setVisible(mSeparatorsEnabled);
93 94 childItems().append(sep);
94 95 mSeparators.append(sep);
95 96 }
96 97
97 98 // Create floating values
98 99 for (int category=0; category<mSeries->categoryCount(); category++) {
99 100 for (int s=0; s<mSeries->barsetCount(); s++) {
100 101 QBarSet *set = mSeries->barsetAt(s);
101 102 BarValue *value = new BarValue(*set, this);
102 103 childItems().append(value);
103 104 mFloatingValues.append(value);
104 105 connect(set,SIGNAL(toggleFloatingValues()),value,SLOT(toggleVisible()));
105 106 }
106 107 }
107 108 }
108 109
110 void BarPresenterBase::initAxisLabels()
111 {
112 int count = mSeries->categoryCount();
113 if (0 == count) {
114 return;
115 }
116
117 mChart->axisX()->setTicksCount(count);
118
119 qreal min = 0;
120 qreal max = mSeries->categoryCount();
121
122 mChart->axisX()->setMin(min);
123 mChart->axisX()->setMax(max);
124 qreal step = (max-min)/count;
125 QChartAxisCategories& categories = mChart->axisX()->categories();
126 categories.clear();
127 for (int i=0; i<count; i++) {
128 qDebug() << "initAxisLabels" << min << mSeries->categoryName(i);
129 categories.insert(min,mSeries->categoryName(i));
130 min += step;
131 }
132 mChart->axisX()->setLabelsVisible(true);
133 }
134
109 135 //handlers
110 136
111 137 void BarPresenterBase::handleModelChanged(int index)
112 138 {
113 139 // qDebug() << "BarPresenterBase::handleModelChanged" << index;
114 140 dataChanged();
115 141 }
116 142
117 143 void BarPresenterBase::handleDomainChanged(const Domain& domain)
118 144 {
119 // qDebug() << "BarPresenterBase::handleDomainChanged";
120 // TODO: Figure out the use case for this.
121 // Affects the size of visible item, so layout is changed.
122 // layoutChanged();
145 qDebug() << "BarPresenterBase::handleDomainChanged";
146 /*
147 int count = mSeries->categoryCount();
148 if (0 == count) {
149 return;
150 }
151
152 // Position labels to domain
153 qreal min = domain.minX();
154 qreal max = domain.maxX();
155 qreal step = (max-min)/count;
156 QChartAxisCategories& categories = mChart->axisX()->categories();
157 categories.clear();
158 for (int i=0; i<count; i++) {
159 categories.insert(min,mSeries->categoryName(i));
160 min += step;
161 }
162 */
123 163 }
124 164
125 165 void BarPresenterBase::handleGeometryChanged(const QRectF& rect)
126 166 {
127 167 mWidth = rect.width();
128 168 mHeight = rect.height();
129 169 layoutChanged();
130 170 mLayoutSet = true;
131 171 setPos(rect.topLeft());
132 172 }
133 173
134 174 void BarPresenterBase::showToolTip(QPoint pos, QString tip)
135 175 {
136 176 // TODO: cool tooltip instead of default
137 177 QToolTip::showText(pos,tip);
138 178 }
139 179
140 180 void BarPresenterBase::enableSeparators(bool enabled)
141 181 {
142 182 for (int i=0; i<mSeparators.count(); i++) {
143 183 mSeparators.at(i)->setVisible(enabled);
144 184 }
145 185 mSeparatorsEnabled = enabled;
146 186 }
147 187
148 188 #include "moc_barpresenterbase_p.cpp"
149 189
150 190 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,68 +1,70
1 1 #ifndef BARPRESENTERBASE_H
2 2 #define BARPRESENTERBASE_H
3 3
4 4 #include "chartitem_p.h"
5 5 #include "qbarseries.h"
6 6 #include <QPen>
7 7 #include <QBrush>
8 8 #include <QGraphicsItem>
9 9
10 10 QTCOMMERCIALCHART_BEGIN_NAMESPACE
11 11
12 12 class Bar;
13 13 class BarLabel;
14 14 class Separator;
15 15 class BarValue;
16 class QChartAxisCategories;
17 class QChart;
16 18
17 19 // Common implemantation of different presenters. Not to be instantiated.
18 20 // TODO: combine this with BarPresenter and derive other presenters from it?
19 21 class BarPresenterBase : public QObject, public ChartItem
20 22 {
21 23 Q_OBJECT
22 24 public:
23 BarPresenterBase(QBarSeries *series, QGraphicsItem *parent = 0);
25 BarPresenterBase(QBarSeries *series, QChart *parent = 0);
24 26 virtual ~BarPresenterBase();
25 27
26 28 public:
27 29 // From QGraphicsItem
28 30 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
29 31 QRectF boundingRect() const;
30 32
31 // TODO: these may change with layout awarness.
32 void setBarWidth( int w );
33
34 33 // TODO: Consider the domain for layoutChanged. May be use case, may not be. If it is, then the derived classes need to implement it
35 34 virtual void dataChanged(); // data of series has changed -> need to recalculate bar sizes
36 35 virtual void layoutChanged() = 0; // layout has changed -> need to recalculate bar sizes
37 36
37 protected:
38 void initAxisLabels();
39
38 40 public slots:
39 41 void handleModelChanged(int index);
40 42 void handleDomainChanged(const Domain& domain);
41 43 void handleGeometryChanged(const QRectF& size);
42 44
43 45 // Internal slots
44 46 void showToolTip(QPoint pos, QString tip); // shows tooltip (if enabled)
45 47 void enableSeparators(bool enabled);
46 48
47 49 protected:
48 50
49 51 // TODO: consider these.
50 52 int mHeight; // Layout spesific
51 53 int mWidth;
52 54 qreal mBarWidth;
53 55
54 56 bool mLayoutSet; // True, if component has been laid out.
55 57 bool mSeparatorsEnabled;
56 58
57 59 // Not owned.
58 60 QBarSeries* mSeries;
59 61 QList<Bar*> mBars;
60 62 QList<BarLabel*> mLabels;
61 63 QList<Separator*> mSeparators;
62 64 QList<BarValue*> mFloatingValues;
63
65 QChart* mChart;
64 66 };
65 67
66 68 QTCOMMERCIALCHART_END_NAMESPACE
67 69
68 70 #endif // BARPRESENTERBASE_H
@@ -1,110 +1,110
1 1 #include "percentbarpresenter_p.h"
2 2 #include "bar_p.h"
3 3 #include "barlabel_p.h"
4 4 #include "barvalue_p.h"
5 5 #include "separator_p.h"
6 6 #include "qbarset.h"
7 7 #include <QDebug>
8 8
9 9 QTCOMMERCIALCHART_BEGIN_NAMESPACE
10 10
11 11
12 PercentBarPresenter::PercentBarPresenter(QBarSeries *series, QGraphicsItem *parent) :
12 PercentBarPresenter::PercentBarPresenter(QBarSeries *series, QChart *parent) :
13 13 BarPresenterBase(series, parent)
14 14 {
15 15 }
16 16
17 17 void PercentBarPresenter::layoutChanged()
18 18 {
19 19 // Scale bars to new layout
20 20 // Layout for bars:
21 21 if (mSeries->barsetCount() <= 0) {
22 22 qDebug() << "No sets in model!";
23 23 // Nothing to do.
24 24 return;
25 25 }
26 26
27 27 if (childItems().count() == 0) {
28 28 qDebug() << "WARNING: PercentBarPresenter::layoutChanged called before graphics items are created!";
29 29 return;
30 30 }
31 31
32 32 // Use temporary qreals for accurancy (we might get some compiler warnings... :)
33 33 qreal tW = mWidth;
34 34 qreal tC = mSeries->categoryCount() + 1;
35 35 qreal cC = mSeries->categoryCount() * 2 + 1;
36 36 mBarWidth = tW / cC;
37 37 qreal xStep = (tW/tC);
38 38 qreal xPos = ((tW/tC) - mBarWidth / 2);
39 39 qreal h = mHeight;
40 40
41 41 int itemIndex(0);
42 42 int labelIndex(0);
43 43 for (int category = 0; category < mSeries->categoryCount(); category++) {
44 44 qreal colSum = mSeries->categorySum(category);
45 45 qreal scale = (h / colSum);
46 46 qreal yPos = h;
47 47 for (int set=0; set < mSeries->barsetCount(); set++) {
48 48 qreal barHeight = mSeries->valueAt(set, category) * scale;
49 49 Bar* bar = mBars.at(itemIndex);
50 50
51 51 // TODO: width settable per bar?
52 52 bar->resize(mBarWidth, barHeight);
53 53 bar->setBrush(mSeries->barsetAt(set)->brush());
54 54 bar->setPos(xPos, yPos-barHeight);
55 55 itemIndex++;
56 56 yPos -= barHeight;
57 57 }
58 58
59 59 // TODO: Layout for labels, remove magic number
60 60 BarLabel* label = mLabels.at(labelIndex);
61 61 label->setPos(xPos, mHeight + 20);
62 62 labelIndex++;
63 63 xPos += xStep;
64 64 }
65 65
66 66 // Position separators
67 67 xPos = xStep + xStep/2;
68 68 for (int s=0; s < mSeries->categoryCount() - 1; s++) {
69 69 Separator* sep = mSeparators.at(s);
70 70 sep->setPos(xPos,0);
71 71 sep->setSize(QSizeF(1,mHeight));
72 72 xPos += xStep;
73 73 }
74 74
75 75 // Position floating values
76 76 itemIndex = 0;
77 77 xPos = (tW/tC);
78 78 for (int category=0; category < mSeries->categoryCount(); category++) {
79 79 qreal yPos = h;
80 80 qreal colSum = mSeries->categorySum(category);
81 81 qreal scale = (h / colSum);
82 82 for (int set=0; set < mSeries->barsetCount(); set++) {
83 83 qreal barHeight = mSeries->valueAt(set,category) * scale;
84 84 BarValue* value = mFloatingValues.at(itemIndex);
85 85
86 86 // TODO: remove hard coding, apply layout
87 87 value->resize(100,50);
88 88 value->setPos(xPos, yPos-barHeight/2);
89 89 value->setPen(QPen(QColor(255,255,255,255)));
90 90
91 91 if (mSeries->valueAt(set,category) != 0) {
92 92 int p = mSeries->percentageAt(set,category) * 100;
93 93 QString vString(QString::number(p));
94 94 vString.truncate(3);
95 95 vString.append("%");
96 96 value->setValueString(vString);
97 97 } else {
98 98 value->setValueString(QString(""));
99 99 }
100 100
101 101 itemIndex++;
102 102 yPos -= barHeight;
103 103 }
104 104 xPos += xStep;
105 105 }
106 106 }
107 107
108 108 #include "moc_percentbarpresenter_p.cpp"
109 109
110 110 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,29 +1,29
1 1 #ifndef PERCENTBARPRESENTER_H
2 2 #define PERCENTBARPRESENTER_H
3 3
4 4 #include "chartitem_p.h"
5 5 #include "bar_p.h"
6 6 #include "qpercentbarseries.h"
7 7 #include "barpresenterbase_p.h"
8 8 #include <QGraphicsItem>
9 9
10 10 QTCOMMERCIALCHART_BEGIN_NAMESPACE
11 11
12 12 class PercentBarPresenter : public BarPresenterBase
13 13 {
14 14 Q_OBJECT
15 15 public:
16 PercentBarPresenter(QBarSeries *series, QGraphicsItem *parent = 0);
16 PercentBarPresenter(QBarSeries *series, QChart *parent = 0);
17 17
18 18 private:
19 19
20 20 void layoutChanged(); // layout has changed -> need to recalculate bar sizes
21 21
22 22 private:
23 23
24 24 // Data
25 25 };
26 26
27 27 QTCOMMERCIALCHART_END_NAMESPACE
28 28
29 29 #endif // PERCENTBARPRESENTER_H
@@ -1,221 +1,222
1 1 #include <QDebug>
2 2 #include "qbarseries.h"
3 3 #include "qbarset.h"
4 4 #include "barchartmodel_p.h"
5 5
6 6 QTCOMMERCIALCHART_BEGIN_NAMESPACE
7 7
8 8 /*!
9 9 \class QBarSeries
10 10 \brief part of QtCommercial chart API.
11 11
12 12 QBarSeries represents a series of data shown as bars. One QBarSeries can contain multible
13 13 QBarSet data sets. QBarSeries groups the data from sets to categories, which are defined
14 14 by QStringList.
15 15
16 16 \mainclass
17 17
18 18 \sa QBarSet, QStackedBarSeries, QPercentBarSeries
19 19 */
20 20
21 21 /*!
22 22 \fn virtual QSeriesType QBarSeries::type() const
23 23 \brief Returns type of series.
24 24 \sa QSeries, QSeriesType
25 25 */
26 26
27 27 /*!
28 28 \fn void QBarSeries::showToolTip(QPoint pos, QString tip)
29 29 \brief \internal \a pos \a tip
30 30 */
31 31
32 32 /*!
33 33 Constructs empty QBarSeries. Parameter \a categories defines the categories for chart.
34 34 QBarSeries is QObject which is a child of a \a parent.
35 35 */
36 36 QBarSeries::QBarSeries(QStringList categories, QObject *parent)
37 37 : QSeries(parent)
38 38 ,mModel(new BarChartModel(categories, this))
39 39 {
40 40 }
41 41
42 42 /*!
43 43 Adds a set of bars to series. Takes ownership of \a set.
44 44 Connects the clicked(QString) and rightClicked(QString) signals
45 45 of \a set to this series
46 46 */
47 47 void QBarSeries::addBarSet(QBarSet *set)
48 48 {
49 49 mModel->addBarSet(set);
50 50 connect(set,SIGNAL(clicked(QString)),this,SLOT(barsetClicked(QString)));
51 51 connect(set,SIGNAL(rightClicked(QString)),this,SLOT(barsetRightClicked(QString)));
52 52 }
53 53
54 54 /*!
55 55 Removes a set of bars from series. Releases ownership of \a set. Doesnt delete \a set.
56 56 Disconnects the clicked(QString) and rightClicked(QString) signals
57 57 of \a set from this series
58 58 */
59 59 void QBarSeries::removeBarSet(QBarSet *set)
60 60 {
61 61 disconnect(set,SIGNAL(clicked(QString)),this,SLOT(barsetClicked(QString)));
62 62 disconnect(set,SIGNAL(rightClicked(QString)),this,SLOT(barsetRightClicked(QString)));
63 63 mModel->removeBarSet(set);
64 64 }
65 65
66 66 /*!
67 67 Returns number of sets in series.
68 68 */
69 69 int QBarSeries::barsetCount()
70 70 {
71 71 return mModel->barsetCount();
72 72 }
73 73
74 74 /*!
75 75 Returns number of categories in series
76 76 */
77 77 int QBarSeries::categoryCount()
78 78 {
79 79 return mModel->categoryCount();
80 80 }
81 81
82 82 /*!
83 83 Returns a list of sets in series. Keeps ownership of sets.
84 84 */
85 85 QList<QBarSet*> QBarSeries::barSets()
86 86 {
87 87 return mModel->barSets();
88 88 }
89 89
90 90 /*!
91 91 \internal \a index
92 92 */
93 93 QBarSet* QBarSeries::barsetAt(int index)
94 94 {
95 95 return mModel->setAt(index);
96 96 }
97 97
98 98 /*!
99 99 Returns legend of series.
100 100 */
101 101 QList<QSeries::Legend> QBarSeries::legend()
102 102 {
103 103 return mModel->legend();
104 104 }
105 105
106 106 /*!
107 107 \internal \a category
108 108 */
109 109 QString QBarSeries::categoryName(int category)
110 110 {
111 111 return mModel->categoryName(category);
112 112 }
113 113
114 114 /*!
115 115 Enables or disables tooltip depending on parameter \a enabled.
116 116 Tooltip shows the name of set, when mouse is hovering on top of bar.
117 117 Calling without parameter \a enabled, enables the tooltip
118 118 */
119 119 void QBarSeries::setToolTipEnabled(bool enabled)
120 120 {
121 // TODO: what if we add sets after call to this function? Those sets won't have tooltip enabled.
121 122 if (enabled) {
122 123 for (int i=0; i<mModel->barsetCount(); i++) {
123 124 QBarSet *set = mModel->setAt(i);
124 125 connect(set,SIGNAL(showToolTip(QPoint,QString)),this,SIGNAL(showToolTip(QPoint,QString)));
125 126 }
126 127 } else {
127 128 for (int i=0; i<mModel->barsetCount(); i++) {
128 129 QBarSet *set = mModel->setAt(i);
129 130 disconnect(set,SIGNAL(showToolTip(QPoint,QString)),this,SIGNAL(showToolTip(QPoint,QString)));
130 131 }
131 132 }
132 133 }
133 134
134 135 /*!
135 136 Enables or disables separators depending on parameter \a enabled.
136 137 Separators are visual elements that are drawn between categories.
137 138 Calling without parameter \a enabled, enables the separators
138 139 */
139 140 void QBarSeries::setSeparatorsEnabled(bool enabled)
140 141 {
141 142 // TODO: toggle
142 143 // emit separatorsEnabled(enabled);
143 144 }
144 145
145 146
146 147 /*!
147 148 \internal \a category
148 149 */
149 150 void QBarSeries::barsetClicked(QString category)
150 151 {
151 152 emit clicked(qobject_cast<QBarSet*>(sender()), category);
152 153 }
153 154
154 155 /*!
155 156 \internal \a category
156 157 */
157 158 void QBarSeries::barsetRightClicked(QString category)
158 159 {
159 160 emit rightClicked(qobject_cast<QBarSet*>(sender()), category);
160 161 }
161 162
162 163
163 164 /*!
164 165 \internal
165 166 */
166 167 qreal QBarSeries::min()
167 168 {
168 169 return mModel->min();
169 170 }
170 171
171 172 /*!
172 173 \internal
173 174 */
174 175 qreal QBarSeries::max()
175 176 {
176 177 return mModel->max();
177 178 }
178 179
179 180 /*!
180 181 \internal \a set \a category
181 182 */
182 183 qreal QBarSeries::valueAt(int set, int category)
183 184 {
184 185 return mModel->valueAt(set,category);
185 186 }
186 187
187 188 /*!
188 189 \internal \a set \a category
189 190 */
190 191 qreal QBarSeries::percentageAt(int set, int category)
191 192 {
192 193 return mModel->percentageAt(set,category);
193 194 }
194 195
195 196 /*!
196 197 \internal \a category
197 198 */
198 199 qreal QBarSeries::categorySum(int category)
199 200 {
200 201 return mModel->categorySum(category);
201 202 }
202 203
203 204 /*!
204 205 \internal
205 206 */
206 207 qreal QBarSeries::maxCategorySum()
207 208 {
208 209 return mModel->maxCategorySum();
209 210 }
210 211
211 212 /*!
212 213 \internal
213 214 */
214 215 BarChartModel& QBarSeries::model()
215 216 {
216 217 return *mModel;
217 218 }
218 219
219 220 #include "moc_qbarseries.cpp"
220 221
221 222 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,113 +1,113
1 1 #include "stackedbarpresenter_p.h"
2 2 #include "bar_p.h"
3 3 #include "barlabel_p.h"
4 4 #include "barvalue_p.h"
5 5 #include "separator_p.h"
6 6 #include "qbarset.h"
7 7 #include <QDebug>
8 8
9 9 QTCOMMERCIALCHART_BEGIN_NAMESPACE
10 10
11 StackedBarPresenter::StackedBarPresenter(QBarSeries *series, QGraphicsItem *parent) :
11 StackedBarPresenter::StackedBarPresenter(QBarSeries *series, QChart *parent) :
12 12 BarPresenterBase(series,parent)
13 13 {
14 14 }
15 15
16 16 StackedBarPresenter::~StackedBarPresenter()
17 17 {
18 18 }
19 19
20 20
21 21 void StackedBarPresenter::layoutChanged()
22 22 {
23 23 // Scale bars to new layout
24 24 // Layout for bars:
25 25 if (mSeries->barsetCount() <= 0) {
26 26 qDebug() << "No sets in model!";
27 27 // Nothing to do.
28 28 return;
29 29 }
30 30
31 31 if (mSeries->categoryCount() == 0) {
32 32 qDebug() << "No categories in model!";
33 33 // Nothing to do
34 34 return;
35 35 }
36 36
37 37 if (childItems().count() == 0) {
38 38 qDebug() << "WARNING: StackedBarPresenter::layoutChanged called before graphics items are created!";
39 39 return;
40 40 }
41 41
42 42 // Use temporary qreals for accurancy (we might get some compiler warnings... :)
43 43 qreal maxSum = mSeries->maxCategorySum();
44 44 qreal h = mHeight;
45 45 qreal scale = (h / maxSum);
46 46 qreal tW = mWidth;
47 47 qreal tC = mSeries->categoryCount() + 1;
48 48 qreal cC = mSeries->categoryCount() * 2 + 1;
49 49 mBarWidth = tW / cC;
50 50 qreal xStep = (tW/tC);
51 51 qreal xPos = ((tW/tC) - mBarWidth / 2);
52 52
53 53 int itemIndex(0);
54 54 int labelIndex(0);
55 55 for (int category = 0; category < mSeries->categoryCount(); category++) {
56 56 qreal yPos = h;
57 57 for (int set=0; set < mSeries->barsetCount(); set++) {
58 58 qreal barHeight = mSeries->valueAt(set, category) * scale;
59 59 Bar* bar = mBars.at(itemIndex);
60 60
61 61 bar->resize(mBarWidth, barHeight);
62 62 bar->setBrush(mSeries->barsetAt(set)->brush());
63 63 bar->setPos(xPos, yPos-barHeight);
64 64 itemIndex++;
65 65 yPos -= barHeight;
66 66 }
67 67
68 68 // TODO: Layout for labels, remove magic number
69 BarLabel* label = mLabels.at(labelIndex);
70 label->setPos(xPos, mHeight + 20);
69 // BarLabel* label = mLabels.at(labelIndex);
70 // label->setPos(xPos, mHeight + 20);
71 71 labelIndex++;
72 72 xPos += xStep;
73 73 }
74 74
75 75 // Position separators
76 76 xPos = xStep + xStep/2;
77 77 for (int s=0; s < mSeries->categoryCount() - 1; s++) {
78 78 Separator* sep = mSeparators.at(s);
79 79 sep->setPos(xPos,0);
80 80 sep->setSize(QSizeF(1,mHeight));
81 81 xPos += xStep;
82 82 }
83 83
84 84 // Position floating values
85 85 itemIndex = 0;
86 86 xPos = (tW/tC);
87 87 for (int category=0; category < mSeries->categoryCount(); category++) {
88 88 qreal yPos = h;
89 89 for (int set=0; set < mSeries->barsetCount(); set++) {
90 90 qreal barHeight = mSeries->valueAt(set,category) * scale;
91 91 BarValue* value = mFloatingValues.at(itemIndex);
92 92
93 93 // TODO: remove hard coding, apply layout
94 94 value->resize(100,50);
95 95 value->setPos(xPos, yPos-barHeight/2);
96 96 value->setPen(QPen(QColor(255,255,255,255)));
97 97
98 98 if (mSeries->valueAt(set,category) != 0) {
99 99 value->setValueString(QString::number(mSeries->valueAt(set,category)));
100 100 } else {
101 101 value->setValueString(QString(""));
102 102 }
103 103
104 104 itemIndex++;
105 105 yPos -= barHeight;
106 106 }
107 107 xPos += xStep;
108 108 }
109 109 }
110 110
111 111 #include "moc_stackedbarpresenter_p.cpp"
112 112
113 113 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,28 +1,28
1 1 #ifndef STACKEDBARPRESENTER_H
2 2 #define STACKEDBARPRESENTER_H
3 3
4 4 #include "barpresenterbase_p.h"
5 5 #include "qstackedbarseries.h"
6 6 #include <QGraphicsItem>
7 7
8 8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9 9
10 10 class StackedBarPresenter : public BarPresenterBase
11 11 {
12 12 Q_OBJECT
13 13 public:
14 StackedBarPresenter(QBarSeries *series, QGraphicsItem *parent = 0);
14 StackedBarPresenter(QBarSeries *series, QChart *parent = 0);
15 15 ~StackedBarPresenter();
16 16
17 17 private:
18 18 // From BarPresenterBase
19 19 void layoutChanged(); // layout has changed -> need to recalculate bar sizes
20 20
21 21 private:
22 22
23 23 // Data
24 24 };
25 25
26 26 QTCOMMERCIALCHART_END_NAMESPACE
27 27
28 28 #endif // STACKEDBARPRESENTER_H
General Comments 0
You need to be logged in to leave comments. Login now