##// END OF EJS Templates
Better way to enable features to user. Do less, but expose signals to user and allow user to descide what to do.
sauimone -
r425:85842e6c8dba
parent child
Show More
@@ -0,0 +1,6
1 #include "chartwidget.h"
2
3 ChartWidget::ChartWidget(QWidget *parent) :
4 QChartView(parent)
5 {
6 }
@@ -0,0 +1,21
1 #ifndef CHARTWIDGET_H
2 #define CHARTWIDGET_H
3
4 #include <qchartview.h>
5
6 QTCOMMERCIALCHART_USE_NAMESPACE
7
8
9 class ChartWidget : public QChartView
10 {
11 Q_OBJECT
12 public:
13 explicit ChartWidget(QWidget *parent = 0);
14
15 signals:
16
17 public slots:
18
19 };
20
21 #endif // CHARTWIDGET_H
@@ -0,0 +1,83
1 #include <QApplication>
2 #include <QMainWindow>
3 #include <qchartview.h>
4 #include <qstackedbarseries.h>
5 #include <qbarset.h>
6 #include <qchartaxis.h>
7 #include <QStringList>
8
9 QTCOMMERCIALCHART_USE_NAMESPACE
10
11 int main(int argc, char *argv[])
12 {
13 QApplication a(argc, argv);
14 QMainWindow window;
15
16 // TODO:
17 /*
18 //! [1]
19 // Define categories
20 QStringList categories;
21 categories << "Jan" << "Feb" << "Mar" << "Apr" << "May" << "Jun";
22 //! [1]
23
24 //! [2]
25 // Create some test sets for chat
26 QBarSet *set0 = new QBarSet("Bub");
27 QBarSet *set1 = new QBarSet("Bob");
28 QBarSet *set2 = new QBarSet("Guybrush");
29 QBarSet *set3 = new QBarSet("Larry");
30 QBarSet *set4 = new QBarSet("Zak");
31
32 *set0 << 1 << 2 << 3 << 4 << 5 << 6;
33 *set1 << 5 << 0 << 0 << 4 << 0 << 7;
34 *set2 << 3 << 5 << 8 << 13 << 8 << 5;
35 *set3 << 5 << 6 << 7 << 3 << 4 << 5;
36 *set4 << 9 << 7 << 5 << 3 << 1 << 2;
37 //! [2]
38
39 //! [3]
40 // Create series and add sets to it
41 QStackedBarSeries* series = new QStackedBarSeries(categories);
42
43 series->addBarSet(set0);
44 series->addBarSet(set1);
45 series->addBarSet(set2);
46 series->addBarSet(set3);
47 series->addBarSet(set4);
48 //! [3]
49
50 //! [4]
51 // Enable tooltip
52 series->setToolTipEnabled();
53
54 // Connect clicked signal of set to toggle floating values of set.
55 // Note that we leave QBarset "Zak" unconnected here, so clicking on it doesn't toggle values.
56 QObject::connect(set0,SIGNAL(clicked(QBarSet*,QString)),set0,SIGNAL(toggleFloatingValues()));
57 QObject::connect(set1,SIGNAL(clicked(QBarSet*,QString)),set1,SIGNAL(toggleFloatingValues()));
58 QObject::connect(set2,SIGNAL(clicked(QBarSet*,QString)),set2,SIGNAL(toggleFloatingValues()));
59 QObject::connect(set3,SIGNAL(clicked(QBarSet*,QString)),set3,SIGNAL(toggleFloatingValues()));
60 //! [4]
61
62 //! [5]
63 // Create view for chart and add series to it. Apply theme.
64
65 QChartView* chartView = new QChartView(&window);
66 chartView->addSeries(series);
67 chartView->setChartTitle("simple stacked barchart");
68 chartView->setChartTheme(QChart::ChartThemeIcy);
69 //! [5]
70
71 //! [6]
72 chartView->axisX()->setAxisVisible(false);
73 chartView->axisX()->setGridVisible(false);
74 chartView->axisX()->setLabelsVisible(false);
75 //! [6]
76
77 window.setCentralWidget(chartView);
78 window.resize(400, 300);
79 window.show();
80 */
81 return a.exec();
82 }
83
@@ -0,0 +1,9
1 !include( ../example.pri ) {
2 error( "Couldn't find the example.pri file!" )
3 }
4 TARGET = stackedbarchartdrilldown
5 SOURCES += main.cpp \
6 chartwidget.cpp
7 HEADERS += \
8 chartwidget.h
9
@@ -1,76 +1,82
1 1 #include <QApplication>
2 2 #include <QMainWindow>
3 3 #include <qchartview.h>
4 4 #include <qbarseries.h>
5 5 #include <qbarset.h>
6 6 #include <qchartaxis.h>
7 7 #include <QStringList>
8 8
9 9 QTCOMMERCIALCHART_USE_NAMESPACE
10 10
11 11 int main(int argc, char *argv[])
12 12 {
13 13 QApplication a(argc, argv);
14 14 QMainWindow window;
15 15
16 16 //! [1]
17 17 // Define categories
18 18 QStringList categories;
19 19 categories << "Jan" << "Feb" << "Mar" << "Apr" << "May" << "Jun";
20 20 //! [1]
21 21
22 22 //! [2]
23 23 // Create some test sets for chat
24 24
25 25 QBarSet *set0 = new QBarSet("Bub");
26 26 QBarSet *set1 = new QBarSet("Bob");
27 27 QBarSet *set2 = new QBarSet("Guybrush");
28 28 QBarSet *set3 = new QBarSet("Larry");
29 29 QBarSet *set4 = new QBarSet("Zak");
30 30
31 31 *set0 << 1 << 2 << 3 << 4 << 5 << 6;
32 32 *set1 << 5 << 0 << 0 << 4 << 0 << 7;
33 33 *set2 << 3 << 5 << 8 << 13 << 8 << 5;
34 34 *set3 << 5 << 6 << 7 << 3 << 4 << 5;
35 35 *set4 << 9 << 7 << 5 << 3 << 1 << 2;
36 36 //! [2]
37 37
38 38 //! [3]
39 39 // Create series and add sets to it
40 40 QBarSeries* series= new QBarSeries(categories);
41 41
42 42 series->addBarSet(set0);
43 43 series->addBarSet(set1);
44 44 series->addBarSet(set2);
45 45 series->addBarSet(set3);
46 46 series->addBarSet(set4);
47 47 //! [3]
48 48
49 49 //! [4]
50 // Enable some features
50 // Enable tooltip
51 51 series->setToolTipEnabled();
52 series->setFloatingValuesEnabled();
52
53 // Connect clicked signal of set to toggle floating values of set.
54 // Note that we leave QBarset "Zak" unconnected here, so clicking on it doesn't toggle values.
55 QObject::connect(set0,SIGNAL(clicked(QString)),set0,SIGNAL(toggleFloatingValues()));
56 QObject::connect(set1,SIGNAL(clicked(QString)),set1,SIGNAL(toggleFloatingValues()));
57 QObject::connect(set2,SIGNAL(clicked(QString)),set2,SIGNAL(toggleFloatingValues()));
58 QObject::connect(set3,SIGNAL(clicked(QString)),set3,SIGNAL(toggleFloatingValues()));
53 59 //! [4]
54 60
55 61 //! [5]
56 62 // Create view for chart and add series to it. Apply theme.
57 63
58 64 QChartView* chartView = new QChartView(&window);
59 65 chartView->addSeries(series);
60 66 chartView->setChartTitle("simple barchart");
61 67 chartView->setChartTheme(QChart::ChartThemeIcy);
62 68 //! [5]
63 69
64 70 //! [6]
65 71 chartView->axisX()->setAxisVisible(false);
66 72 chartView->axisX()->setGridVisible(false);
67 73 chartView->axisX()->setLabelsVisible(false);
68 74 //! [6]
69 75
70 76 window.setCentralWidget(chartView);
71 77 window.resize(400, 300);
72 78 window.show();
73 79
74 80 return a.exec();
75 81 }
76 82
@@ -1,18 +1,19
1 1 TEMPLATE = subdirs
2 2 SUBDIRS += linechart \
3 3 zoomlinechart \
4 4 colorlinechart \
5 5 barchart \
6 6 stackedbarchart \
7 7 percentbarchart \
8 8 scatter \
9 9 piechart \
10 10 piechartdrilldown \
11 11 dynamiclinechart \
12 12 axischart \
13 13 multichart \
14 14 gdpbarchart \
15 15 presenterchart \
16 16 chartview \
17 17 scatterinteractions \
18 areachart
18 areachart \
19 stackedbarchartdrilldown
@@ -1,76 +1,82
1 1 #include <QApplication>
2 2 #include <QMainWindow>
3 3 #include <QStandardItemModel>
4 4 #include <qpercentbarseries.h>
5 5 #include <qchartview.h>
6 6 #include <qbarset.h>
7 7 #include <qchartaxis.h>
8 8 #include <QStringList>
9 9
10 10 QTCOMMERCIALCHART_USE_NAMESPACE
11 11
12 12 int main(int argc, char *argv[])
13 13 {
14 14 QApplication a(argc, argv);
15 15 QMainWindow window;
16 16
17 17 //! [1]
18 18 // Define categories
19 19 QStringList categories;
20 20 categories << "Jan" << "Feb" << "Mar" << "Apr" << "May" << "Jun";
21 21 //! [1]
22 22
23 23 //! [2]
24 24 // Create some test sets for chat
25 25 QBarSet *set0 = new QBarSet("Bub");
26 26 QBarSet *set1 = new QBarSet("Bob");
27 27 QBarSet *set2 = new QBarSet("Guybrush");
28 28 QBarSet *set3 = new QBarSet("Larry");
29 29 QBarSet *set4 = new QBarSet("Zak");
30 30
31 31 *set0 << 1 << 2 << 3 << 4 << 5 << 6;
32 32 *set1 << 5 << 0 << 0 << 4 << 0 << 7;
33 33 *set2 << 3 << 5 << 8 << 13 << 8 << 5;
34 34 *set3 << 5 << 6 << 7 << 3 << 4 << 5;
35 35 *set4 << 9 << 7 << 5 << 3 << 1 << 2;
36 36 //! [2]
37 37
38 38 //! [3]
39 39 // Create series and add sets to it
40 40 QPercentBarSeries* series = new QPercentBarSeries(categories);
41 41
42 42 series->addBarSet(set0);
43 43 series->addBarSet(set1);
44 44 series->addBarSet(set2);
45 45 series->addBarSet(set3);
46 46 series->addBarSet(set4);
47 47 //! [3]
48 48
49 49 //! [4]
50 // Enable features
50 // Enable tooltip
51 51 series->setToolTipEnabled();
52 series->setFloatingValuesEnabled();
52
53 // Connect clicked signal of set to toggle floating values of set.
54 // Note that we leave QBarset "Zak" unconnected here, so clicking on it doesn't toggle values.
55 QObject::connect(set0,SIGNAL(clicked(QString)),set0,SIGNAL(toggleFloatingValues()));
56 QObject::connect(set1,SIGNAL(clicked(QString)),set1,SIGNAL(toggleFloatingValues()));
57 QObject::connect(set2,SIGNAL(clicked(QString)),set2,SIGNAL(toggleFloatingValues()));
58 QObject::connect(set3,SIGNAL(clicked(QString)),set3,SIGNAL(toggleFloatingValues()));
53 59 //! [4]
54 60
55 61 //! [5]
56 62 // Create view for chart and add series to it. Apply theme.
57 63
58 64 QChartView* chartView = new QChartView(&window);
59 65 chartView->addSeries(series);
60 66 chartView->setChartTitle("simple percent barchart");
61 67 chartView->setChartTheme(QChart::ChartThemeIcy);
62 68 //! [5]
63 69
64 70 //! [6]
65 71 chartView->axisX()->setAxisVisible(false);
66 72 chartView->axisX()->setGridVisible(false);
67 73 chartView->axisX()->setLabelsVisible(false);
68 74 //! [6]
69 75
70 76 window.setCentralWidget(chartView);
71 77 window.resize(400, 300);
72 78 window.show();
73 79
74 80 return a.exec();
75 81 }
76 82
@@ -1,75 +1,81
1 1 #include <QApplication>
2 2 #include <QMainWindow>
3 3 #include <qchartview.h>
4 4 #include <qstackedbarseries.h>
5 5 #include <qbarset.h>
6 6 #include <qchartaxis.h>
7 7 #include <QStringList>
8 8
9 9 QTCOMMERCIALCHART_USE_NAMESPACE
10 10
11 11 int main(int argc, char *argv[])
12 12 {
13 13 QApplication a(argc, argv);
14 14 QMainWindow window;
15 15
16 16 //! [1]
17 17 // Define categories
18 18 QStringList categories;
19 19 categories << "Jan" << "Feb" << "Mar" << "Apr" << "May" << "Jun";
20 20 //! [1]
21 21
22 22 //! [2]
23 23 // Create some test sets for chat
24 24 QBarSet *set0 = new QBarSet("Bub");
25 25 QBarSet *set1 = new QBarSet("Bob");
26 26 QBarSet *set2 = new QBarSet("Guybrush");
27 27 QBarSet *set3 = new QBarSet("Larry");
28 28 QBarSet *set4 = new QBarSet("Zak");
29 29
30 30 *set0 << 1 << 2 << 3 << 4 << 5 << 6;
31 31 *set1 << 5 << 0 << 0 << 4 << 0 << 7;
32 32 *set2 << 3 << 5 << 8 << 13 << 8 << 5;
33 33 *set3 << 5 << 6 << 7 << 3 << 4 << 5;
34 34 *set4 << 9 << 7 << 5 << 3 << 1 << 2;
35 35 //! [2]
36 36
37 37 //! [3]
38 38 // Create series and add sets to it
39 39 QStackedBarSeries* series = new QStackedBarSeries(categories);
40 40
41 41 series->addBarSet(set0);
42 42 series->addBarSet(set1);
43 43 series->addBarSet(set2);
44 44 series->addBarSet(set3);
45 45 series->addBarSet(set4);
46 46 //! [3]
47 47
48 48 //! [4]
49 // Enable features
49 // Enable tooltip
50 50 series->setToolTipEnabled();
51 series->setFloatingValuesEnabled();
51
52 // Connect clicked signal of set to toggle floating values of set.
53 // Note that we leave QBarset "Zak" unconnected here, so clicking on it doesn't toggle values.
54 QObject::connect(set0,SIGNAL(clicked(QString)),set0,SIGNAL(toggleFloatingValues()));
55 QObject::connect(set1,SIGNAL(clicked(QString)),set1,SIGNAL(toggleFloatingValues()));
56 QObject::connect(set2,SIGNAL(clicked(QString)),set2,SIGNAL(toggleFloatingValues()));
57 QObject::connect(set3,SIGNAL(clicked(QString)),set3,SIGNAL(toggleFloatingValues()));
52 58 //! [4]
53 59
54 60 //! [5]
55 61 // Create view for chart and add series to it. Apply theme.
56 62
57 63 QChartView* chartView = new QChartView(&window);
58 64 chartView->addSeries(series);
59 65 chartView->setChartTitle("simple stacked barchart");
60 66 chartView->setChartTheme(QChart::ChartThemeIcy);
61 67 //! [5]
62 68
63 69 //! [6]
64 70 chartView->axisX()->setAxisVisible(false);
65 71 chartView->axisX()->setGridVisible(false);
66 72 chartView->axisX()->setLabelsVisible(false);
67 73 //! [6]
68 74
69 75 window.setCentralWidget(chartView);
70 76 window.resize(400, 300);
71 77 window.show();
72 78
73 79 return a.exec();
74 80 }
75 81
@@ -1,88 +1,89
1 1 #include "bar_p.h"
2 2 #include <QDebug>
3 3 #include <QPainter>
4 4 #include <QGraphicsSceneEvent>
5 5
6 6 QTCOMMERCIALCHART_BEGIN_NAMESPACE
7 7
8 Bar::Bar(QGraphicsItem *parent)
8 Bar::Bar(QString category, QGraphicsItem *parent)
9 9 : QGraphicsObject(parent)
10 ,mCategory(category)
10 11 {
11 12 setAcceptedMouseButtons(Qt::LeftButton|Qt::RightButton);
12 13 setAcceptHoverEvents(true);
13 14 }
14 15
15 16 void Bar::setSize(const QSizeF& size)
16 17 {
17 18 mWidth = size.width();
18 19 mHeight = size.height();
19 20 }
20 21
21 22
22 23 void Bar::resize( qreal w, qreal h )
23 24 {
24 25 mWidth = w;
25 26 mHeight = h;
26 27 }
27 28
28 29 void Bar::setPos(qreal x, qreal y)
29 30 {
30 31 mXpos = x;
31 32 mYpos = y;
32 33 }
33 34
34 35 void Bar::setPen(QPen pen)
35 36 {
36 37 mPen = pen;
37 38 }
38 39
39 40 void Bar::setBrush(QBrush brush)
40 41 {
41 42 mBrush = brush;
42 43 }
43 44
44 45 void Bar::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
45 46 {
46 47 if (0 == mHeight) {
47 48 return;
48 49 }
49 50 painter->setBrush(mBrush);
50 51
51 52 // This compensates for rounding errors. drawRect takes ints and cumulative error of pos + size may be over 1.
52 53 int x0 = mXpos;
53 54 int x1 = (mXpos + mWidth);
54 55 int w = x1-x0;
55 56 int y0 = mYpos;
56 57 int y1 = (mYpos + mHeight);
57 58 int h = y1-y0;
58 59 painter->drawRect(x0, y0 ,w ,h);
59 60 }
60 61
61 62 QRectF Bar::boundingRect() const
62 63 {
63 64 QRectF r(mXpos, mYpos, mWidth, mHeight);
64 65 return r;
65 66 }
66 67
67 68 void Bar::mousePressEvent(QGraphicsSceneMouseEvent* event)
68 69 {
69 70 if (event->button() == Qt::LeftButton) {
70 emit clicked();
71 emit clicked(mCategory);
71 72 } else if (event->button() == Qt::RightButton) {
72 emit rightClicked();
73 emit rightClicked(mCategory);
73 74 }
74 75 }
75 76
76 77 void Bar::hoverEnterEvent(QGraphicsSceneHoverEvent* event)
77 78 {
78 79 emit hoverEntered(event->lastScreenPos());
79 80 }
80 81
81 82 void Bar::hoverLeaveEvent(QGraphicsSceneHoverEvent* /*event*/)
82 83 {
83 84 emit hoverLeaved();
84 85 }
85 86
86 87 #include "moc_bar_p.cpp"
87 88
88 89 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,55 +1,56
1 1 #ifndef BAR_H
2 2 #define BAR_H
3 3
4 4 #include "qchartglobal.h"
5 5 #include <QGraphicsObject>
6 6 #include <QPen>
7 7 #include <QBrush>
8 8
9 9 QTCOMMERCIALCHART_BEGIN_NAMESPACE
10 10
11 11 // Single visual bar item of chart
12 12 class Bar : public QGraphicsObject
13 13 {
14 14 Q_OBJECT
15 15 public:
16 Bar(QGraphicsItem *parent=0);
16 Bar(QString category, QGraphicsItem *parent=0);
17 17
18 18 public: // from ChartItem
19 19 void setSize(const QSizeF &size);
20 20
21 21 // Layout Stuff
22 22 void resize(qreal w, qreal h);
23 23 void setPos(qreal x, qreal y);
24 24 void setPen(QPen pen);
25 25 void setBrush(QBrush brush);
26 26
27 27 public:
28 28 // From QGraphicsItem
29 29 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
30 30 QRectF boundingRect() const;
31 31 void mousePressEvent(QGraphicsSceneMouseEvent *event);
32 32 void hoverEnterEvent(QGraphicsSceneHoverEvent *event);
33 33 void hoverLeaveEvent(QGraphicsSceneHoverEvent *event);
34 34
35 35 Q_SIGNALS:
36 void clicked();
37 void rightClicked();
36 void clicked(QString category);
37 void rightClicked(QString category);
38 38 void hoverEntered(QPoint pos);
39 39 void hoverLeaved();
40 40
41 41 private:
42 42
43 43 qreal mHeight;
44 44 qreal mWidth;
45 45 qreal mXpos;
46 46 qreal mYpos;
47 47
48 48 QBrush mBrush;
49 49 QPen mPen;
50 50
51 QString mCategory;
51 52 };
52 53
53 54 QTCOMMERCIALCHART_END_NAMESPACE
54 55
55 56 #endif // BAR_H
@@ -1,37 +1,35
1 1 INCLUDEPATH += $$PWD
2 2 DEPENDPATH += $$PWD
3 3
4 4 SOURCES += \
5 5 $$PWD/bar.cpp \
6 6 $$PWD/barchartmodel.cpp \
7 7 $$PWD/barlabel.cpp \
8 8 $$PWD/barpresenter.cpp \
9 9 $$PWD/barpresenterbase.cpp \
10 10 $$PWD/percentbarpresenter.cpp \
11 11 $$PWD/qbarseries.cpp \
12 12 $$PWD/qbarset.cpp \
13 13 $$PWD/qpercentbarseries.cpp \
14 14 $$PWD/qstackedbarseries.cpp \
15 15 $$PWD/separator.cpp \
16 16 $$PWD/stackedbarpresenter.cpp \
17 $$PWD/barvalue.cpp \
18 $$PWD/barcategory.cpp
17 $$PWD/barvalue.cpp
19 18
20 19 PRIVATE_HEADERS += \
21 20 $$PWD/bar_p.h \
22 21 $$PWD/barchartmodel_p.h \
23 22 $$PWD/barlabel_p.h \
24 23 $$PWD/barpresenter_p.h \
25 24 $$PWD/barpresenterbase_p.h \
26 25 $$PWD/percentbarpresenter_p.h \
27 26 $$PWD/separator_p.h \
28 27 $$PWD/stackedbarpresenter_p.h \
29 $$PWD/barvalue_p.h \
30 $$PWD/barcategory_p.h
28 $$PWD/barvalue_p.h
31 29
32 30 PUBLIC_HEADERS += \
33 31 $$PWD/qbarseries.h \
34 32 $$PWD/qbarset.h \
35 33 $$PWD/qpercentbarseries.h \
36 34 $$PWD/qstackedbarseries.h
37 35
@@ -1,182 +1,172
1 1 #include <limits.h>
2 2 #include <QVector>
3 3 #include <QDebug>
4 4 #include "barchartmodel_p.h"
5 #include "barcategory_p.h"
6 5 #include "qbarset.h"
7 6
8 7 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9 8
10 9 BarChartModel::BarChartModel(QStringList categories, QObject *parent) :
11 10 QObject(parent)
12 11 ,mCategory(categories)
13 12 {
14 for (int i=0; i<mCategory.count(); i++) {
15 BarCategory* cat = new BarCategory(mCategory.at(i), this);
16 mCategoryObjects.append(cat);
17 }
18 13 }
19 14
20 15 QStringList BarChartModel::category()
21 16 {
22 17 return mCategory;
23 18 }
24 19
25 20 void BarChartModel::addBarSet(QBarSet *set)
26 21 {
27 22 mDataModel.append(set);
28 23 }
29 24
30 25 void BarChartModel::removeBarSet(QBarSet *set)
31 26 {
32 27 if (mDataModel.contains(set)) {
33 28 mDataModel.removeOne(set);
34 29 }
35 30 }
36 31
37 32 QBarSet* BarChartModel::setAt(int index)
38 33 {
39 34 return mDataModel.at(index);
40 35 }
41 36
42 37 QList<QBarSet*> BarChartModel::barSets()
43 38 {
44 39 return mDataModel;
45 40 }
46 41
47 42 QList<QSeries::Legend> BarChartModel::legend()
48 43 {
49 44 QList<QSeries::Legend> legend;
50 45
51 46 for (int i=0; i<mDataModel.count(); i++) {
52 47 QSeries::Legend l;
53 48 l.mName = mDataModel.at(i)->name();
54 49 l.mPen = mDataModel.at(i)->pen();
55 50 legend.append(l);
56 51 }
57 52 return legend;
58 53 }
59 54
60 55 int BarChartModel::barsetCount()
61 56 {
62 57 return mDataModel.count();
63 58 }
64 59
65 60 int BarChartModel::categoryCount()
66 61 {
67 62 return mCategory.count();
68 63 }
69 64
70 65 qreal BarChartModel::min()
71 66 {
72 67 Q_ASSERT(mDataModel.count() > 0);
73 68 // TODO: make min and max members and update them when data changes.
74 69 // This is slower since they are checked every time, even if data is same since previous call.
75 70 qreal min = INT_MAX;
76 71
77 72 for (int i=0; i <mDataModel.count(); i++) {
78 73 int itemCount = mDataModel.at(i)->count();
79 74 for (int j=0; j<itemCount; j++) {
80 75 qreal temp = mDataModel.at(i)->valueAt(j);
81 76 if (temp < min) {
82 77 min = temp;
83 78 }
84 79 }
85 80 }
86 81 return min;
87 82 }
88 83
89 84 qreal BarChartModel::max()
90 85 {
91 86 Q_ASSERT(mDataModel.count() > 0);
92 87
93 88 // TODO: make min and max members and update them when data changes.
94 89 // This is slower since they are checked every time, even if data is same since previous call.
95 90 qreal max = INT_MIN;
96 91
97 92 for (int i=0; i <mDataModel.count(); i++) {
98 93 int itemCount = mDataModel.at(i)->count();
99 94 for (int j=0; j<itemCount; j++) {
100 95 qreal temp = mDataModel.at(i)->valueAt(j);
101 96 if (temp > max) {
102 97 max = temp;
103 98 }
104 99 }
105 100 }
106 101
107 102 return max;
108 103 }
109 104
110 105 qreal BarChartModel::valueAt(int set, int category)
111 106 {
112 107 if ((set < 0) || (set >= mDataModel.count())) {
113 108 // No set, no value.
114 109 return 0;
115 110 } else if ((category < 0) || (category >= mDataModel.at(set)->count())) {
116 111 // No category, no value.
117 112 return 0;
118 113 }
119 114
120 115 return mDataModel.at(set)->valueAt(category);
121 116 }
122 117
123 118 qreal BarChartModel::percentageAt(int set, int category)
124 119 {
125 120 if ((set < 0) || (set >= mDataModel.count())) {
126 121 // No set, no value.
127 122 return 0;
128 123 } else if ((category < 0) || (category >= mDataModel.at(set)->count())) {
129 124 // No category, no value.
130 125 return 0;
131 126 }
132 127
133 128 qreal value = mDataModel.at(set)->valueAt(category);
134 129 qreal total = categorySum(category);
135 130 if (0 == total) {
136 131 return 100.0;
137 132 }
138 133
139 134 return value / total;
140 135 }
141 136
142 137
143 138 qreal BarChartModel::categorySum(int category)
144 139 {
145 140 qreal sum(0);
146 141 int count = mDataModel.count(); // Count sets
147 142
148 143 for (int set = 0; set < count; set++) {
149 144 if (category < mDataModel.at(set)->count()) {
150 145 sum += mDataModel.at(set)->valueAt(category);
151 146 }
152 147 }
153 148 return sum;
154 149 }
155 150
156 151 qreal BarChartModel::maxCategorySum()
157 152 {
158 153 qreal max = INT_MIN;
159 154 int count = categoryCount();
160 155
161 156 for (int col=0; col<count; col++) {
162 157 qreal sum = categorySum(col);
163 158 if (sum > max) {
164 159 max = sum;
165 160 }
166 161 }
167 162 return max;
168 163 }
169 164
170 165 QString BarChartModel::categoryName(int category)
171 166 {
172 167 return mCategory.at(category);
173 168 }
174 169
175 BarCategory* BarChartModel::categoryObject(int category)
176 {
177 return mCategoryObjects.at(category);
178 }
179
180 170 #include "moc_barchartmodel_p.cpp"
181 171
182 172 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,62 +1,59
1 1 #ifndef BARCHARTMODEL_H
2 2 #define BARCHARTMODEL_H
3 3
4 4 #include <QObject>
5 5 #include <QStringList>
6 6 #include "qchartglobal.h"
7 7 #include <qseries.h>
8 8
9 9 QTCOMMERCIALCHART_BEGIN_NAMESPACE
10 10
11 11 // Model for bar chart. Internal class.
12 12 // TODO: Implement as QAbstractItemModel?
13 13
14 14 class QBarSet;
15 class BarCategory;
16 15
17 16 class BarChartModel : public QObject //, public QAbstractItemModel
18 17 {
19 18 Q_OBJECT
20 19 public:
21 20 explicit BarChartModel(QStringList categories, QObject *parent = 0);
22 21
23 22 QStringList category();
24 23 void addBarSet(QBarSet *set);
25 24 void removeBarSet(QBarSet *set);
26 25 QBarSet *setAt(int index);
27 26 QList<QBarSet*> barSets();
28 27
29 28 QList<QSeries::Legend> legend();
30 29
31 30 int barsetCount(); // Number of sets in model
32 31 int categoryCount(); // Number of categories
33 32
34 33 qreal max(); // Maximum value of all sets
35 34 qreal min(); // Minimum value of all sets
36 35 qreal valueAt(int set, int category);
37 36 qreal percentageAt(int set, int category);
38 37
39 38 qreal categorySum(int category);
40 39 qreal maxCategorySum(); // returns maximum sum of sets in all categories.
41 40
42 41 QString categoryName(int category);
43 BarCategory* categoryObject(int category);
44 42
45 43 signals:
46 44 void modelUpdated();
47 45
48 46 public slots:
49 47
50 48 private:
51 49
52 50 QList<QBarSet*> mDataModel;
53 51 QStringList mCategory;
54 QList<BarCategory*> mCategoryObjects;
55 52
56 53 int mCurrentSet;
57 54
58 55 };
59 56
60 57 QTCOMMERCIALCHART_END_NAMESPACE
61 58
62 59 #endif // BARCHARTMODEL_H
@@ -1,161 +1,160
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 #include "barcategory_p.h"
7 6 #include "qbarset.h"
8 7 #include "qbarseries.h"
9 8 #include <QDebug>
10 9 #include <QToolTip>
11 10
12 11 QTCOMMERCIALCHART_BEGIN_NAMESPACE
13 12
14 13 BarPresenterBase::BarPresenterBase(QBarSeries *series, QGraphicsItem *parent)
15 14 : ChartItem(parent)
16 15 ,mBarDefaultWidth(20) // TODO: remove hard coding, when we have layout code ready
17 16 ,mLayoutSet(false)
18 17 ,mLayoutDirty(true)
19 18 ,mSeparatorsEnabled(false)
20 19 ,mSeries(series)
21 20 {
22 21 connect(series,SIGNAL(showToolTip(QPoint,QString)),this,SLOT(showToolTip(QPoint,QString)));
23 connect(series,SIGNAL(separatorsEnabled(bool)),this,SLOT(enableSeparators(bool)));
22 // connect(series,SIGNAL(separatorsEnabled(bool)),this,SLOT(enableSeparators(bool)));
24 23 dataChanged();
25 24 }
26 25
27 26 BarPresenterBase::~BarPresenterBase()
28 27 {
29 28 disconnect(this,SLOT(showToolTip(QPoint,QString)));
30 29 delete mSeries;
31 30 }
32 31
33 32 void BarPresenterBase::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
34 33 {
35 34 if (!mLayoutSet) {
36 35 qDebug() << "BarPresenterBase::paint called without layout set. Aborting.";
37 36 return;
38 37 }
39 38 // if (mLayoutDirty) {
40 39 // Layout or data has changed. Need to redraw.
41 40 foreach(QGraphicsItem* i, childItems()) {
42 41 i->paint(painter,option,widget);
43 42 }
44 43 // }
45 44 }
46 45
47 46 QRectF BarPresenterBase::boundingRect() const
48 47 {
49 48 return QRectF(0,0,mWidth,mHeight);
50 49 }
51 50
52 51 void BarPresenterBase::setBarWidth( int w )
53 52 {
54 53 mBarDefaultWidth = w;
55 54 }
56 55
57 56 void BarPresenterBase::dataChanged()
58 57 {
59 58 // TODO: performance optimizations. Do we really need to delete and create items every time data is changed or can we reuse them?
60 59 // qDebug() << "datachanged";
61 60 // Delete old bars
62 61 foreach (QGraphicsItem* item, childItems()) {
63 62 delete item;
64 63 }
65 64
66 65 mBars.clear();
67 66 mLabels.clear();
68 67 mSeparators.clear();
69 68 mFloatingValues.clear();
70 69
71 70 // Create new graphic items for bars
72 71 for (int c=0; c<mSeries->categoryCount(); c++) {
73 BarCategory *category = mSeries->categoryObject(c);
72 QString category = mSeries->categoryName(c);
74 73 for (int s=0; s<mSeries->barsetCount(); s++) {
75 74 QBarSet *set = mSeries->barsetAt(s);
76 Bar *bar = new Bar(this);
75 Bar *bar = new Bar(category,this);
77 76 childItems().append(bar);
78 77 mBars.append(bar);
79 connect(bar,SIGNAL(clicked()),set,SLOT(barClickedEvent()));
80 connect(bar,SIGNAL(rightClicked()),category,SLOT(barRightClickEvent()));
78 connect(bar,SIGNAL(clicked(QString)),set,SIGNAL(clicked(QString)));
79 connect(bar,SIGNAL(rightClicked(QString)),set,SIGNAL(rightClicked(QString)));
81 80 connect(bar,SIGNAL(hoverEntered(QPoint)),set,SLOT(barHoverEnterEvent(QPoint)));
82 81 connect(bar,SIGNAL(hoverLeaved()),set,SLOT(barHoverLeaveEvent()));
83 82 }
84 83 }
85 84
86 85 // Create labels
87 86 int count = mSeries->categoryCount();
88 87 for (int i=0; i<count; i++) {
89 88 BarLabel* label = new BarLabel(this);
90 89 label->set(mSeries->categoryName(i));
91 90 childItems().append(label);
92 91 mLabels.append(label);
93 92 }
94 93
95 94 // Create separators
96 95 count = mSeries->categoryCount() - 1; // There is one less separator than columns
97 96 for (int i=0; i<count; i++) {
98 97 Separator* sep = new Separator(this);
99 98 sep->setColor(QColor(255,0,0,255)); // TODO: color for separations from theme
100 99 sep->setVisible(mSeparatorsEnabled);
101 100 childItems().append(sep);
102 101 mSeparators.append(sep);
103 102 }
104 103
105 104 // Create floating values
106 105 for (int category=0; category<mSeries->categoryCount(); category++) {
107 106 for (int s=0; s<mSeries->barsetCount(); s++) {
108 107 QBarSet *set = mSeries->barsetAt(s);
109 108 BarValue *value = new BarValue(*set, this);
110 109 childItems().append(value);
111 110 mFloatingValues.append(value);
112 111 connect(set,SIGNAL(toggleFloatingValues()),value,SLOT(toggleVisible()));
113 112 }
114 113 }
115 114
116 115 // TODO: if (autolayout) { layoutChanged() } or something
117 116 mLayoutDirty = true;
118 117 }
119 118
120 119 //handlers
121 120
122 121 void BarPresenterBase::handleModelChanged(int index)
123 122 {
124 123 // qDebug() << "BarPresenterBase::handleModelChanged" << index;
125 124 dataChanged();
126 125 }
127 126
128 127 void BarPresenterBase::handleDomainChanged(const Domain& domain)
129 128 {
130 129 // qDebug() << "BarPresenterBase::handleDomainChanged";
131 130 // TODO: Figure out the use case for this.
132 131 // Affects the size of visible item, so layout is changed.
133 132 // layoutChanged();
134 133 }
135 134
136 135 void BarPresenterBase::handleGeometryChanged(const QRectF& rect)
137 136 {
138 137 mWidth = rect.width();
139 138 mHeight = rect.height();
140 139 layoutChanged();
141 140 mLayoutSet = true;
142 141 setPos(rect.topLeft());
143 142 }
144 143
145 144 void BarPresenterBase::showToolTip(QPoint pos, QString tip)
146 145 {
147 146 // TODO: cool tooltip instead of default
148 147 QToolTip::showText(pos,tip);
149 148 }
150 149
151 150 void BarPresenterBase::enableSeparators(bool enabled)
152 151 {
153 152 for (int i=0; i<mSeparators.count(); i++) {
154 153 mSeparators.at(i)->setVisible(enabled);
155 154 }
156 155 mSeparatorsEnabled = enabled;
157 156 }
158 157
159 158 #include "moc_barpresenterbase_p.cpp"
160 159
161 160 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,73 +1,66
1 1 #include "barvalue_p.h"
2 2 #include <QPainter>
3 3 #include <QPen>
4 4
5 5 QTCOMMERCIALCHART_BEGIN_NAMESPACE
6 6
7 7 BarValue::BarValue(QBarSet &set, QGraphicsItem *parent)
8 8 : QGraphicsObject(parent)
9 9 ,mBarSet(set)
10 10 {
11 11 setVisible(false);
12 12 }
13 13
14 14 void BarValue::setValueString(QString str)
15 15 {
16 16 mValueString = str;
17 17 }
18 18
19 19 QString BarValue::valueString()
20 20 {
21 21 return mValueString;
22 22 }
23 23
24 24 void BarValue::setPen(const QPen& pen)
25 25 {
26 26 mPen = pen;
27 27 }
28 28
29 29 const QPen& BarValue::pen()
30 30 {
31 31 return mPen;
32 32 }
33 33
34 34 void BarValue::resize(qreal w, qreal h)
35 35 {
36 36 mWidth = w;
37 37 mHeight = h;
38 38 }
39 39
40 40 void BarValue::setPos(qreal x, qreal y)
41 41 {
42 42 mXpos = x;
43 43 mYpos = y;
44 44 }
45 45
46 /*
47 bool BarValue::belongsToSet(QBarSet *set)
48 {
49 return (&mBarSet == set);
50 }
51 */
52
53 46 void BarValue::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
54 47 {
55 48 if (isVisible()) {
56 49 painter->setPen(mPen);
57 50 painter->drawText(boundingRect(),mValueString);
58 51 }
59 52 }
60 53
61 54 QRectF BarValue::boundingRect() const
62 55 {
63 56 QRectF r(mXpos, mYpos, mWidth, mHeight);
64 57 return r;
65 58 }
66 59
67 60 void BarValue::toggleVisible()
68 61 {
69 62 setVisible(!isVisible());
70 63 }
71 64
72 65 #include "moc_barvalue_p.cpp"
73 66 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,54 +1,50
1 1 #ifndef BARVALUE_P_H
2 2 #define BARVALUE_P_H
3 3
4 4 #include "qchartglobal.h"
5 5 #include <QGraphicsObject>
6 6 #include <QPen>
7 7
8 8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9 9
10 10 class QBarSet;
11 11
12 12 // Visual class for floating bar values
13 // TODO: fonts, colors etc.
14 13 // By default these are not visible.
15 14 class BarValue : public QGraphicsObject
16 15 {
17 16 Q_OBJECT
18 17 public:
19 18 BarValue(QBarSet &set, QGraphicsItem *parent = 0);
20 19
21 20 void setValueString(QString str);
22 21 QString valueString();
23 22
24 23 void setPen(const QPen& pen);
25 24 const QPen& pen();
26 25
27 26 void resize(qreal w, qreal h);
28 27 void setPos(qreal x, qreal y);
29 28
30 // Propably not needed.
31 // bool belongsToSet(QBarSet *set);
32
33 29 // From QGraphicsItem
34 30 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
35 31 QRectF boundingRect() const;
36 32
37 33 public Q_SLOTS:
38 34 void toggleVisible();
39 35
40 36 private:
41 37
42 38 QBarSet& mBarSet;
43 39 QPen mPen;
44 40 QString mValueString;
45 41
46 42 qreal mXpos;
47 43 qreal mYpos;
48 44 qreal mWidth;
49 45 qreal mHeight;
50 46 };
51 47
52 48 QTCOMMERCIALCHART_END_NAMESPACE
53 49
54 50 #endif // BARVALUE_P_H
@@ -1,240 +1,221
1 1 #include <QDebug>
2 2 #include "qbarseries.h"
3 3 #include "qbarset.h"
4 4 #include "barchartmodel_p.h"
5 #include "barcategory_p.h"
6 5
7 6 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8 7
9 8 /*!
10 9 \class QBarSeries
11 10 \brief part of QtCommercial chart API.
12 11
13 12 QBarSeries represents a series of data shown as bars. One QBarSeries can contain multible
14 13 QBarSet data sets. QBarSeries groups the data from sets to categories, which are defined
15 14 by QStringList.
16 15
17 16 \mainclass
18 17
19 18 \sa QBarSet, QStackedBarSeries, QPercentBarSeries
20 19 */
21 20
22 21 /*!
23 22 \fn virtual QSeriesType QBarSeries::type() const
24 23 \brief Returns type of series.
25 24 \sa QSeries, QSeriesType
26 25 */
27 /*!
28 \fn void QBarSeries::changed(int index)
29 \brief \internal \a index
30 */
31 /*!
32 \fn void QBarSeries::floatingValuesEnabled(bool enabled)
33 \brief \internal \a enabled
34 */
35 /*!
36 \fn void QBarSeries::toolTipEnabled(bool enabled)
37 \brief \internal \a enabled
38 */
39 /*!
40 \fn void QBarSeries::separatorsEnabled(bool enabled)
41 \brief \internal \a enabled
42 */
26
43 27 /*!
44 28 \fn void QBarSeries::showToolTip(QPoint pos, QString tip)
45 29 \brief \internal \a pos \a tip
46 30 */
47 31
48 32 /*!
49 33 Constructs empty QBarSeries. Parameter \a categories defines the categories for chart.
50 34 QBarSeries is QObject which is a child of a \a parent.
51 35 */
52 36 QBarSeries::QBarSeries(QStringList categories, QObject *parent)
53 37 : QSeries(parent)
54 38 ,mModel(new BarChartModel(categories, this))
55 39 {
56 for (int i=0; i<mModel->categoryCount(); i++) {
57 BarCategory *categoryObject = mModel->categoryObject(i);
58 connect(categoryObject, SIGNAL(rightClicked(QString)), this, SIGNAL(categoryRightClicked(QString)));
59 }
60 40 }
61 41
62 42 /*!
63 Adds a set of bars to series. Takes ownership of \a set
43 Adds a set of bars to series. Takes ownership of \a set.
44 Connects the clicked(QString) and rightClicked(QString) signals
45 of \a set to this series
64 46 */
65 47 void QBarSeries::addBarSet(QBarSet *set)
66 48 {
67 49 mModel->addBarSet(set);
50 connect(set,SIGNAL(clicked(QString)),this,SLOT(barsetClicked(QString)));
51 connect(set,SIGNAL(rightClicked(QString)),this,SLOT(barsetRightClicked(QString)));
68 52 }
69 53
70 54 /*!
71 55 Removes a set of bars from series. Releases ownership of \a set. Doesnt delete \a set.
56 Disconnects the clicked(QString) and rightClicked(QString) signals
57 of \a set from this series
72 58 */
73 59 void QBarSeries::removeBarSet(QBarSet *set)
74 60 {
61 disconnect(set,SIGNAL(clicked(QString)),this,SLOT(barsetClicked(QString)));
62 disconnect(set,SIGNAL(rightClicked(QString)),this,SLOT(barsetRightClicked(QString)));
75 63 mModel->removeBarSet(set);
76 64 }
77 65
78 66 /*!
79 67 Returns number of sets in series.
80 68 */
81 69 int QBarSeries::barsetCount()
82 70 {
83 71 return mModel->barsetCount();
84 72 }
85 73
86 74 /*!
87 75 Returns number of categories in series
88 76 */
89 77 int QBarSeries::categoryCount()
90 78 {
91 79 return mModel->categoryCount();
92 80 }
93 81
94 82 /*!
95 83 Returns a list of sets in series. Keeps ownership of sets.
96 84 */
97 85 QList<QBarSet*> QBarSeries::barSets()
98 86 {
99 87 return mModel->barSets();
100 88 }
101 89
102 90 /*!
103 91 \internal \a index
104 92 */
105 93 QBarSet* QBarSeries::barsetAt(int index)
106 94 {
107 95 return mModel->setAt(index);
108 96 }
109 97
110 98 /*!
111 99 Returns legend of series.
112 100 */
113 101 QList<QSeries::Legend> QBarSeries::legend()
114 102 {
115 103 return mModel->legend();
116 104 }
117 105
118 106 /*!
119 107 \internal \a category
120 108 */
121 109 QString QBarSeries::categoryName(int category)
122 110 {
123 111 return mModel->categoryName(category);
124 112 }
125 113
126 114 /*!
127 Enables or disables floating values depending on parameter \a enabled.
128 Floating values are bar values, that are displayed on top of each bar.
129 Calling without parameter \a enabled, enables the floating values
130 */
131 void QBarSeries::setFloatingValuesEnabled(bool enabled)
132 {
133 if (enabled) {
134 for (int i=0; i<mModel->barsetCount(); i++) {
135 QBarSet *set = mModel->setAt(i);
136 connect(set,SIGNAL(clicked()),set,SIGNAL(toggleFloatingValues()));
137 }
138 } else {
139 for (int i=0; i<mModel->barsetCount(); i++) {
140 QBarSet *set = mModel->setAt(i);
141 disconnect(set,SIGNAL(clicked()),set,SIGNAL(toggleFloatingValues()));
142 }
143 }
144 }
145
146 /*!
147 115 Enables or disables tooltip depending on parameter \a enabled.
148 116 Tooltip shows the name of set, when mouse is hovering on top of bar.
149 117 Calling without parameter \a enabled, enables the tooltip
150 118 */
151 119 void QBarSeries::setToolTipEnabled(bool enabled)
152 120 {
153 121 if (enabled) {
154 122 for (int i=0; i<mModel->barsetCount(); i++) {
155 123 QBarSet *set = mModel->setAt(i);
156 124 connect(set,SIGNAL(showToolTip(QPoint,QString)),this,SIGNAL(showToolTip(QPoint,QString)));
157 125 }
158 126 } else {
159 127 for (int i=0; i<mModel->barsetCount(); i++) {
160 128 QBarSet *set = mModel->setAt(i);
161 129 disconnect(set,SIGNAL(showToolTip(QPoint,QString)),this,SIGNAL(showToolTip(QPoint,QString)));
162 130 }
163 131 }
164 132 }
165 133
166 134 /*!
167 135 Enables or disables separators depending on parameter \a enabled.
168 136 Separators are visual elements that are drawn between categories.
169 137 Calling without parameter \a enabled, enables the separators
170 138 */
171 139 void QBarSeries::setSeparatorsEnabled(bool enabled)
172 140 {
173 emit separatorsEnabled(enabled);
141 // TODO: toggle
142 // emit separatorsEnabled(enabled);
174 143 }
175 144
145
146 /*!
147 \internal \a category
148 */
149 void QBarSeries::barsetClicked(QString category)
150 {
151 emit clicked(qobject_cast<QBarSet*>(sender()), category);
152 }
153
154 /*!
155 \internal \a category
156 */
157 void QBarSeries::barsetRightClicked(QString category)
158 {
159 emit rightClicked(qobject_cast<QBarSet*>(sender()), category);
160 }
161
162
176 163 /*!
177 164 \internal
178 165 */
179 166 qreal QBarSeries::min()
180 167 {
181 168 return mModel->min();
182 169 }
183 170
184 171 /*!
185 172 \internal
186 173 */
187 174 qreal QBarSeries::max()
188 175 {
189 176 return mModel->max();
190 177 }
191 178
192 179 /*!
193 180 \internal \a set \a category
194 181 */
195 182 qreal QBarSeries::valueAt(int set, int category)
196 183 {
197 184 return mModel->valueAt(set,category);
198 185 }
199 186
200 187 /*!
201 188 \internal \a set \a category
202 189 */
203 190 qreal QBarSeries::percentageAt(int set, int category)
204 191 {
205 192 return mModel->percentageAt(set,category);
206 193 }
207 194
208 195 /*!
209 196 \internal \a category
210 197 */
211 198 qreal QBarSeries::categorySum(int category)
212 199 {
213 200 return mModel->categorySum(category);
214 201 }
215 202
216 203 /*!
217 204 \internal
218 205 */
219 206 qreal QBarSeries::maxCategorySum()
220 207 {
221 208 return mModel->maxCategorySum();
222 209 }
223 210
224 211 /*!
225 212 \internal
226 213 */
227 214 BarChartModel& QBarSeries::model()
228 215 {
229 216 return *mModel;
230 217 }
231 218
232 BarCategory* QBarSeries::categoryObject(int category)
233 {
234 return mModel->categoryObject(category);
235 }
236
237
238 219 #include "moc_qbarseries.cpp"
239 220
240 221 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,68 +1,69
1 1 #ifndef BARSERIES_H
2 2 #define BARSERIES_H
3 3
4 4 #include "qseries.h"
5 5 #include <QStringList>
6 6
7 7 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8 8
9 9 class QBarSet;
10 10 class BarChartModel;
11 11 class BarCategory;
12 12
13 13 // Container for series
14 14 class QTCOMMERCIALCHART_EXPORT QBarSeries : public QSeries
15 15 {
16 16 Q_OBJECT
17 17 public:
18 18 QBarSeries(QStringList categories, QObject* parent=0);
19 19
20 20 virtual QSeriesType type() const { return QSeries::SeriesTypeBar; }
21 21
22 22 void addBarSet(QBarSet *set); // Takes ownership of set
23 23 void removeBarSet(QBarSet *set); // Releases ownership, doesn't delete set
24 24 int barsetCount();
25 25 int categoryCount();
26 26 QList<QBarSet*> barSets();
27 27 QList<QSeries::Legend> legend();
28 28
29 29 public:
30 30 // TODO: Functions below this are not part of api and will be moved
31 31 // to private implementation, when we start using it
32 32 // TODO: TO PIMPL --->
33 33 QBarSet* barsetAt(int index);
34 34 QString categoryName(int category);
35 35 qreal min();
36 36 qreal max();
37 37 qreal valueAt(int set, int category);
38 38 qreal percentageAt(int set, int category);
39 39 qreal categorySum(int category);
40 40 qreal maxCategorySum();
41 41 BarChartModel& model();
42 BarCategory* categoryObject(int category);
43 42 // <--- TO PIMPL
44 43
45 44 signals:
46 void changed(int index);
47 void categoryRightClicked(QString category);
45 //void changed(int index);
46 void clicked(QBarSet* barset, QString category); // Up to user of api, what to do with these signals
47 void rightClicked(QBarSet* barset, QString category);
48 48
49 49 // TODO: internal signals, these to private implementation.
50 50 // TODO: TO PIMPL --->
51 void floatingValuesEnabled(bool enabled);
52 void toolTipEnabled(bool enabled);
53 void separatorsEnabled(bool enabled);
54 51 void showToolTip(QPoint pos, QString tip);
55 52 // <--- TO PIMPL
56 53
57 54 public Q_SLOTS:
58 void setFloatingValuesEnabled(bool enabled=true); // enables floating values on top of bars
59 55 void setToolTipEnabled(bool enabled=true); // enables tooltips
60 56 void setSeparatorsEnabled(bool enabled=true); // enables separators between categories
61 57
58 // TODO: TO PIMPL --->
59 void barsetClicked(QString category);
60 void barsetRightClicked(QString category);
61 // <--- TO PIMPL
62
62 63 protected:
63 64 BarChartModel* mModel;
64 65 };
65 66
66 67 QTCOMMERCIALCHART_END_NAMESPACE
67 68
68 69 #endif // BARSERIES_H
@@ -1,162 +1,177
1 1 #include "qbarset.h"
2 2 #include <QDebug>
3 3 #include <QToolTip>
4 4
5 5 QTCOMMERCIALCHART_BEGIN_NAMESPACE
6 6
7 7 /*!
8 8 \class QBarSet
9 9 \brief part of QtCommercial chart API.
10 10
11 11 QBarSet represents one set of bars. Set of bars contains one data value for each category.
12 12 First value of set is assumed to belong to first category, second to second category and so on.
13 13 If set has fewer values than there are categories, then the missing values are assumed to be
14 14 at the end of set. For missing values in middle of a set, numerical value of zero is used.
15 15
16 16 \mainclass
17 17
18 18 \sa QBarSeries, QStackedBarSeries, QPercentBarSeries
19 19 */
20 20
21 21 /*!
22 \fn void QBarSet::clicked()
22 \fn void QBarSet::clicked(QString category)
23 23 \brief signals that set has been clicked
24 Parameter \a category describes on which category was clicked
24 25 */
26
27 /*!
28 \fn void QBarSet::rightClicked(QString category)
29 \brief signals that set has been clicked with right mouse button
30 Parameter \a category describes on which category was clicked
31 */
32
25 33 /*!
26 34 \fn void QBarSet::hoverEnter(QPoint pos)
27 35 \brief signals that mouse has entered over the set at position \a pos.
28 36 */
37
29 38 /*!
30 39 \fn void QBarSet::hoverLeave()
31 40 \brief signals that mouse has left from the set.
32 41 */
42
33 43 /*!
34 44 \fn void QBarSet::toggleFloatingValues()
35 45 \brief \internal
36 46 */
47
37 48 /*!
38 49 \fn void QBarSet::showToolTip(QPoint pos, QString tip)
39 50 \brief \internal \a pos \a tip
40 51 */
41 52
42 53
43 54 /*!
44 55 Constructs QBarSet with a name of \a name and with parent of \a parent
45 56 */
46 57 QBarSet::QBarSet(QString name, QObject *parent)
47 58 : QObject(parent)
48 59 ,mName(name)
49 60 {
50 61 }
51 62
52 63 /*!
53 64 Sets new \a name for set.
54 65 */
55 66 void QBarSet::setName(QString name)
56 67 {
57 68 mName = name;
58 69 }
59 70
60 71 /*!
61 72 Returns name of the set.
62 73 */
63 74 QString QBarSet::name()
64 75 {
65 76 return mName;
66 77 }
67 78
68 79 /*!
69 80 Appends new value \a value to the end of set.
70 81 */
71 82 QBarSet& QBarSet::operator << (const qreal &value)
72 83 {
73 84 mValues.append(value);
74 85 return *this;
75 86 }
76 87
77 88 /*!
78 89 Returns count of values in set.
79 90 */
80 91 int QBarSet::count()
81 92 {
82 93 return mValues.count();
83 94 }
84 95
85 96 /*!
86 97 Returns value of set indexed by \a index
87 98 */
88 99 qreal QBarSet::valueAt(int index)
89 100 {
90 101 return mValues.at(index);
91 102 }
92 103
93 104 /*!
94 105 Sets a new value \a value to set, indexed by \a index
95 106 */
96 107 void QBarSet::setValue(int index, qreal value)
97 108 {
98 109 mValues.replace(index,value);
99 110 }
100 111
101 112 /*!
102 113 Sets pen for set. Bars of this set are drawn using \a pen
103 114 */
104 115 void QBarSet::setPen(QPen pen)
105 116 {
106 117 mPen = pen;
107 118 }
108 119
109 120 /*!
110 121 Returns pen of the set.
111 122 */
112 123 QPen QBarSet::pen()
113 124 {
114 125 return mPen;
115 126 }
116 127
117 128 /*!
118 129 Sets brush for the set. Bars of this set are drawn using \a brush
119 130 */
120 131 void QBarSet::setBrush(QBrush brush)
121 132 {
122 133 mBrush = brush;
123 134 }
124 135
125 136 /*!
126 137 Returns brush of the set.
127 138 */
128 139 QBrush QBarSet::brush()
129 140 {
130 141 return mBrush;
131 142 }
132 143
133 /*!
134 \internal
135 */
136 void QBarSet::barClickedEvent()
144 /*
145 void QBarSet::barClickedEvent(QString category)
137 146 {
138 147 // Some bar of this set has been clicked
139 148 // TODO: What happens then?
140 emit clicked(); // Notify that set has been clicked
149 emit clicked(category); // Notify that set has been clicked
141 150 }
142 151
152 void QBarSet::barRightClickedEvent(QString category)
153 {
154 emit rightClicked(category);
155 }
156 */
157
143 158 /*!
144 159 \internal \a pos
145 160 */
146 161 void QBarSet::barHoverEnterEvent(QPoint pos)
147 162 {
148 163 emit showToolTip(pos, mName);
149 164 emit hoverEnter(pos);
150 165 }
151 166
152 167 /*!
153 168 \internal
154 169 */
155 170 void QBarSet::barHoverLeaveEvent()
156 171 {
157 172 // Emit signal to user of charts
158 173 emit hoverLeave();
159 174 }
160 175
161 176 #include "moc_qbarset.cpp"
162 177 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,60 +1,62
1 1 #ifndef QBARSET_H
2 2 #define QBARSET_H
3 3
4 4 #include <qchartglobal.h>
5 5 #include <QPen>
6 6 #include <QBrush>
7 7
8 8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9 9
10 10 class QTCOMMERCIALCHART_EXPORT QBarSet : public QObject
11 11 {
12 12 Q_OBJECT
13 13 public:
14 14 QBarSet(QString name, QObject *parent = 0);
15 15
16 16 void setName(QString name);
17 17 QString name();
18 18 QBarSet& operator << (const qreal &value); // appends new value to set
19 19
20 20 int count(); // count of values in set
21 21 qreal valueAt(int index); // for modifying individual values
22 22 void setValue(int index, qreal value); // setter for individual value
23 23
24 24 void setPen(QPen pen);
25 25 QPen pen();
26 26
27 27 void setBrush(QBrush brush);
28 28 QBrush brush();
29 29
30 30 Q_SIGNALS:
31 void clicked(); // Clicked and hover signals exposed to user
32 void hoverEnter(QPoint pos);
33 void hoverLeave();
31 void clicked(QString category); // Clicked and hover signals exposed to user
32 void rightClicked(QString category);
33 void toggleFloatingValues();
34 34
35 35 // TODO: Expose this to user or not?
36 36 // TODO: TO PIMPL --->
37 void toggleFloatingValues();
37 void hoverEnter(QPoint pos);
38 void hoverLeave();
38 39 void showToolTip(QPoint pos, QString tip); // Private signal
39 40 // <--- TO PIMPL
40 41
41 42 public Q_SLOTS:
42 43 // These are for internal communication
43 44 // TODO: TO PIMPL --->
44 void barClickedEvent();
45 // void barClickedEvent(QString category);
46 // void barRightClickedEvent(QString category);
45 47 void barHoverEnterEvent(QPoint pos);
46 48 void barHoverLeaveEvent();
47 49 // <--- TO PIMPL
48 50
49 51 private:
50 52
51 53 QString mName;
52 54 QList<qreal> mValues;
53 55 QPen mPen;
54 56 QBrush mBrush;
55 57
56 58 };
57 59
58 60 QTCOMMERCIALCHART_END_NAMESPACE
59 61
60 62 #endif // QBARSET_H
@@ -1,300 +1,300
1 1 #include "qchart.h"
2 2 #include "qchartaxis.h"
3 3 #include "chartpresenter_p.h"
4 4 #include "chartdataset_p.h"
5 5 #include "charttheme_p.h"
6 6 //series
7 7 #include "qbarseries.h"
8 8 #include "qstackedbarseries.h"
9 9 #include "qpercentbarseries.h"
10 10 #include "qlineseries.h"
11 11 #include "qareaseries.h"
12 12 #include "qpieseries.h"
13 13 #include "qscatterseries.h"
14 14 //items
15 15 #include "axisitem_p.h"
16 16 #include "axisanimationitem_p.h"
17 17 #include "areachartitem_p.h"
18 18 #include "barpresenter_p.h"
19 19 #include "stackedbarpresenter_p.h"
20 20 #include "percentbarpresenter_p.h"
21 21 #include "linechartitem_p.h"
22 22 #include "linechartanimationitem_p.h"
23 23 #include "piepresenter_p.h"
24 24 #include "scatterpresenter_p.h"
25 25
26 26 QTCOMMERCIALCHART_BEGIN_NAMESPACE
27 27
28 28 ChartPresenter::ChartPresenter(QChart* chart,ChartDataSet* dataset):QObject(chart),
29 29 m_chart(chart),
30 30 m_dataset(dataset),
31 31 m_chartTheme(0),
32 32 m_marginSize(0),
33 33 m_rect(QRectF(QPoint(0,0),m_chart->size())),
34 34 m_options(0)
35 35 {
36 36 createConnections();
37 37 setChartTheme(QChart::ChartThemeDefault);
38 38
39 39 }
40 40
41 41 ChartPresenter::~ChartPresenter()
42 42 {
43 43 }
44 44
45 45 void ChartPresenter::createConnections()
46 46 {
47 47 QObject::connect(m_chart,SIGNAL(geometryChanged()),this,SLOT(handleGeometryChanged()));
48 48 QObject::connect(m_dataset,SIGNAL(seriesAdded(QSeries*)),this,SLOT(handleSeriesAdded(QSeries*)));
49 49 QObject::connect(m_dataset,SIGNAL(seriesRemoved(QSeries*)),this,SLOT(handleSeriesRemoved(QSeries*)));
50 50 QObject::connect(m_dataset,SIGNAL(axisAdded(QChartAxis*)),this,SLOT(handleAxisAdded(QChartAxis*)));
51 51 QObject::connect(m_dataset,SIGNAL(axisRemoved(QChartAxis*)),this,SLOT(handleAxisRemoved(QChartAxis*)));
52 52 QObject::connect(m_dataset,SIGNAL(seriesDomainChanged(QSeries*,const Domain&)),this,SLOT(handleSeriesDomainChanged(QSeries*,const Domain&)));
53 53 QObject::connect(m_dataset,SIGNAL(axisRangeChanged(QChartAxis*,const QStringList&)),this,SLOT(handleAxisRangeChanged(QChartAxis*,const QStringList&)));
54 54 }
55 55
56 56
57 57 QRectF ChartPresenter::geometry() const
58 58 {
59 59 return m_rect;
60 60 }
61 61
62 62 void ChartPresenter::handleGeometryChanged()
63 63 {
64 64 m_rect = QRectF(QPoint(0,0),m_chart->size());
65 65 m_rect.adjust(m_marginSize,m_marginSize, -m_marginSize, -m_marginSize);
66 66 Q_ASSERT(m_rect.isValid());
67 67 emit geometryChanged(m_rect);
68 68 }
69 69
70 70 int ChartPresenter::margin() const
71 71 {
72 72 return m_marginSize;
73 73 }
74 74
75 75 void ChartPresenter::setMargin(int margin)
76 76 {
77 77 m_marginSize = margin;
78 78 }
79 79
80 80 void ChartPresenter::handleAxisAdded(QChartAxis* axis)
81 81 {
82 82
83 83 AxisItem* item ;
84 84
85 85 if(!m_options.testFlag(QChart::GridAxisAnimations))
86 86 {
87 87 item = new AxisItem(axis==m_dataset->axisX()?AxisItem::X_AXIS : AxisItem::Y_AXIS,m_chart);
88 88 }else{
89 89 item = new AxisAnimationItem(axis==m_dataset->axisX()?AxisItem::X_AXIS : AxisItem::Y_AXIS,m_chart);
90 90 }
91 91
92 92 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
93 93 QObject::connect(axis,SIGNAL(update(QChartAxis*)),item,SLOT(handleAxisUpdate(QChartAxis*)));
94 94
95 95 item->handleAxisUpdate(axis);
96 96 item->handleGeometryChanged(m_rect);
97 97 m_chartTheme->decorate(axis,item);
98 98 m_axisItems.insert(axis,item);
99 99 }
100 100
101 101 void ChartPresenter::handleAxisRemoved(QChartAxis* axis)
102 102 {
103 103 AxisItem* item = m_axisItems.take(axis);
104 104 Q_ASSERT(item);
105 105 delete item;
106 106 }
107 107
108 108
109 109 void ChartPresenter::handleSeriesAdded(QSeries* series)
110 110 {
111 111 switch(series->type())
112 112 {
113 113 case QSeries::SeriesTypeLine: {
114 114
115 115 QLineSeries* lineSeries = static_cast<QLineSeries*>(series);
116 116 LineChartItem* item;
117 117 if(m_options.testFlag(QChart::SeriesAnimations)){
118 118 item = new LineChartAnimationItem(this,lineSeries,m_chart);
119 119 }else{
120 120 item = new LineChartItem(this,lineSeries,m_chart);
121 121 }
122 122 m_chartTheme->decorate(item,lineSeries,m_chartItems.count());
123 123 m_chartItems.insert(series,item);
124 124 if(m_rect.isValid()) item->handleGeometryChanged(m_rect);
125 125 break;
126 126 }
127 127
128 128 case QSeries::SeriesTypeArea: {
129 129
130 130 QAreaSeries* areaSeries = static_cast<QAreaSeries*>(series);
131 131 AreaChartItem* item;
132 132 if(m_options.testFlag(QChart::SeriesAnimations)) {
133 133 item = new AreaChartItem(this,areaSeries,m_chart);
134 134 }
135 135 else {
136 136 item = new AreaChartItem(this,areaSeries,m_chart);
137 137 }
138 138 m_chartTheme->decorate(item,areaSeries,m_chartItems.count());
139 139 m_chartItems.insert(series,item);
140 140 if(m_rect.isValid()) item->handleGeometryChanged(m_rect);
141 141 break;
142 142 }
143 143
144 144 case QSeries::SeriesTypeBar: {
145 145 QBarSeries* barSeries = static_cast<QBarSeries*>(series);
146 146 BarPresenter* item = new BarPresenter(barSeries,m_chart);
147 147 m_chartTheme->decorate(item,barSeries,m_chartItems.count());
148 148 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
149 QObject::connect(barSeries,SIGNAL(changed(int)),item,SLOT(handleModelChanged(int)));
149 // QObject::connect(barSeries,SIGNAL(changed(int)),item,SLOT(handleModelChanged(int)));
150 150 m_chartItems.insert(series,item);
151 151 // m_axisXItem->setVisible(false);
152 152 if(m_rect.isValid()) item->handleGeometryChanged(m_rect);
153 153 break;
154 154 }
155 155
156 156 case QSeries::SeriesTypeStackedBar: {
157 157
158 158 QStackedBarSeries* stackedBarSeries = static_cast<QStackedBarSeries*>(series);
159 159 StackedBarPresenter* item = new StackedBarPresenter(stackedBarSeries,m_chart);
160 160 m_chartTheme->decorate(item,stackedBarSeries,m_chartItems.count());
161 161 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
162 QObject::connect(stackedBarSeries,SIGNAL(changed(int)),item,SLOT(handleModelChanged(int)));
162 // QObject::connect(stackedBarSeries,SIGNAL(changed(int)),item,SLOT(handleModelChanged(int)));
163 163 m_chartItems.insert(series,item);
164 164 if(m_rect.isValid()) item->handleGeometryChanged(m_rect);
165 165 break;
166 166 }
167 167
168 168 case QSeries::SeriesTypePercentBar: {
169 169
170 170 QPercentBarSeries* percentBarSeries = static_cast<QPercentBarSeries*>(series);
171 171 PercentBarPresenter* item = new PercentBarPresenter(percentBarSeries,m_chart);
172 172 m_chartTheme->decorate(item,percentBarSeries ,m_chartItems.count());
173 173 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
174 QObject::connect(percentBarSeries,SIGNAL(changed(int)),item,SLOT(handleModelChanged(int)));
174 // QObject::connect(percentBarSeries,SIGNAL(changed(int)),item,SLOT(handleModelChanged(int)));
175 175 m_chartItems.insert(series,item);
176 176 if(m_rect.isValid()) item->handleGeometryChanged(m_rect);
177 177 break;
178 178 }
179 179 case QSeries::SeriesTypeScatter: {
180 180 QScatterSeries *scatterSeries = qobject_cast<QScatterSeries *>(series);
181 181 ScatterPresenter *scatterPresenter = new ScatterPresenter(scatterSeries, m_chart);
182 182 QObject::connect(scatterPresenter, SIGNAL(clicked(QPointF)),
183 183 scatterSeries, SIGNAL(clicked(QPointF)));
184 184 QObject::connect(this, SIGNAL(geometryChanged(const QRectF&)),
185 185 scatterPresenter, SLOT(handleGeometryChanged(const QRectF&)));
186 186 m_chartTheme->decorate(scatterPresenter, scatterSeries, m_chartItems.count());
187 187 m_chartItems.insert(scatterSeries, scatterPresenter);
188 188 if(m_rect.isValid()) scatterPresenter->handleGeometryChanged(m_rect);
189 189 break;
190 190 }
191 191 case QSeries::SeriesTypePie: {
192 192 QPieSeries *s = qobject_cast<QPieSeries *>(series);
193 193 PiePresenter* pie = new PiePresenter(m_chart, s);
194 194 m_chartTheme->decorate(pie, s, m_chartItems.count());
195 195 QObject::connect(this, SIGNAL(geometryChanged(const QRectF&)), pie, SLOT(handleGeometryChanged(const QRectF&)));
196 196
197 197 // Hide all from background when there is only piechart
198 198 // TODO: refactor this ugly code... should be one setting for this
199 199 if (m_chartItems.count() == 0) {
200 200 m_chart->axisX()->setAxisVisible(false);
201 201 m_chart->axisY()->setAxisVisible(false);
202 202 m_chart->axisX()->setGridVisible(false);
203 203 m_chart->axisY()->setGridVisible(false);
204 204 m_chart->axisX()->setLabelsVisible(false);
205 205 m_chart->axisY()->setLabelsVisible(false);
206 206 m_chart->axisX()->setShadesVisible(false);
207 207 m_chart->axisY()->setShadesVisible(false);
208 208 m_chart->setChartBackgroundBrush(Qt::transparent);
209 209 }
210 210
211 211 m_chartItems.insert(series, pie);
212 212 pie->handleGeometryChanged(m_rect);
213 213 break;
214 214 }
215 215 default: {
216 216 qDebug()<< "Series type" << series->type() << "not implemented.";
217 217 break;
218 218 }
219 219 }
220 220 }
221 221
222 222 void ChartPresenter::handleSeriesRemoved(QSeries* series)
223 223 {
224 224 ChartItem* item = m_chartItems.take(series);
225 225 delete item;
226 226 }
227 227
228 228 void ChartPresenter::handleSeriesDomainChanged(QSeries* series, const Domain& domain)
229 229 {
230 230 m_chartItems.value(series)->handleDomainChanged(domain);
231 231 }
232 232
233 233 void ChartPresenter::handleAxisRangeChanged(QChartAxis* axis,const QStringList& labels)
234 234 {
235 235 m_axisItems.value(axis)->handleRangeChanged(axis,labels);
236 236 }
237 237
238 238 void ChartPresenter::setChartTheme(QChart::ChartTheme theme)
239 239 {
240 240 delete m_chartTheme;
241 241
242 242 m_chartTheme = ChartTheme::createTheme(theme);
243 243
244 244 m_chartTheme->decorate(m_chart);
245 245 QMapIterator<QSeries*,ChartItem*> i(m_chartItems);
246 246
247 247 int index=0;
248 248 while (i.hasNext()) {
249 249 i.next();
250 250 m_chartTheme->decorate(i.value(),i.key(),index);
251 251 index++;
252 252 }
253 253
254 254 QMapIterator<QChartAxis*,AxisItem*> j(m_axisItems);
255 255 while (j.hasNext()) {
256 256 j.next();
257 257 m_chartTheme->decorate(j.key(),j.value());
258 258 }
259 259 }
260 260
261 261 QChart::ChartTheme ChartPresenter::chartTheme()
262 262 {
263 263 return m_chartTheme->id();
264 264 }
265 265
266 266 void ChartPresenter::setAnimationOptions(QChart::AnimationOptions options)
267 267 {
268 268 if(m_options!=options) {
269 269
270 270 m_options=options;
271 271
272 272 //recreate elements
273 273
274 274 QList<QChartAxis*> axisList = m_axisItems.uniqueKeys();
275 275 QList<QSeries*> seriesList = m_chartItems.uniqueKeys();
276 276
277 277 foreach(QChartAxis* axis, axisList) {
278 278 handleAxisRemoved(axis);
279 279 handleAxisAdded(axis);
280 280 }
281 281 foreach(QSeries* series, seriesList) {
282 282 handleSeriesRemoved(series);
283 283 handleSeriesAdded(series);
284 284 }
285 285
286 286 //now reintialize view data
287 287 //TODO: make it more nice
288 288 m_dataset->setDomain(m_dataset->domainIndex());
289 289 }
290 290 }
291 291
292 292 QChart::AnimationOptions ChartPresenter::animationOptions() const
293 293 {
294 294 return m_options;
295 295 }
296 296
297 297
298 298 #include "moc_chartpresenter_p.cpp"
299 299
300 300 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,391 +1,392
1 1 #include "mainwidget.h"
2 2 #include "dataseriedialog.h"
3 3 #include "qpieseries.h"
4 4 #include "qscatterseries.h"
5 5 #include <qlineseries.h>
6 6 #include <qbarset.h>
7 7 #include <qbarseries.h>
8 8 #include <qstackedbarseries.h>
9 9 #include <qpercentbarseries.h>
10 10 #include <QPushButton>
11 11 #include <QComboBox>
12 12 #include <QSpinBox>
13 13 #include <QCheckBox>
14 14 #include <QGridLayout>
15 15 #include <QHBoxLayout>
16 16 #include <QLabel>
17 17 #include <QSpacerItem>
18 18 #include <QMessageBox>
19 19 #include <cmath>
20 20 #include <QDebug>
21 21 #include <QStandardItemModel>
22 22
23 23
24 24 QTCOMMERCIALCHART_USE_NAMESPACE
25 25
26 26 MainWidget::MainWidget(QWidget *parent) :
27 27 QWidget(parent),
28 28 m_addSerieDialog(0),
29 29 m_chartView(0)
30 30 {
31 31 m_chartView = new QChartView(this);
32 32 m_chartView->setRubberBandPolicy(QChartView::HorizonalRubberBand);
33 33
34 34 // Grid layout for the controls for configuring the chart widget
35 35 QGridLayout *grid = new QGridLayout();
36 36 QPushButton *addSeriesButton = new QPushButton("Add series");
37 37 connect(addSeriesButton, SIGNAL(clicked()), this, SLOT(addSeries()));
38 38 grid->addWidget(addSeriesButton, 0, 1);
39 39 initBackroundCombo(grid);
40 40 initScaleControls(grid);
41 41 initThemeCombo(grid);
42 42 initCheckboxes(grid);
43 43
44 44 // add row with empty label to make all the other rows static
45 45 grid->addWidget(new QLabel(""), grid->rowCount(), 0);
46 46 grid->setRowStretch(grid->rowCount() - 1, 1);
47 47
48 48 // Another grid layout as a main layout
49 49 QGridLayout *mainLayout = new QGridLayout();
50 50 mainLayout->addLayout(grid, 0, 0);
51 51
52 52 // Init series type specific controls
53 53 initPieControls();
54 54 mainLayout->addLayout(m_pieLayout, 2, 0);
55 55 // Scatter series specific settings
56 56 // m_scatterLayout = new QGridLayout();
57 57 // m_scatterLayout->addWidget(new QLabel("scatter"), 0, 0);
58 58 // m_scatterLayout->setEnabled(false);
59 59 // mainLayout->addLayout(m_scatterLayout, 1, 0);
60 60
61 61 // Add layouts and the chart widget to the main layout
62 62 mainLayout->addWidget(m_chartView, 0, 1, 3, 1);
63 63 setLayout(mainLayout);
64 64 }
65 65
66 66 // Combo box for selecting the chart's background
67 67 void MainWidget::initBackroundCombo(QGridLayout *grid)
68 68 {
69 69 QComboBox *backgroundCombo = new QComboBox(this);
70 70 backgroundCombo->addItem("Color");
71 71 backgroundCombo->addItem("Gradient");
72 72 backgroundCombo->addItem("Image");
73 73 connect(backgroundCombo, SIGNAL(currentIndexChanged(int)),
74 74 this, SLOT(backgroundChanged(int)));
75 75
76 76 grid->addWidget(new QLabel("Background:"), grid->rowCount(), 0);
77 77 grid->addWidget(backgroundCombo, grid->rowCount() - 1, 1);
78 78 }
79 79
80 80 // Scale related controls (auto-scale vs. manual min-max values)
81 81 void MainWidget::initScaleControls(QGridLayout *grid)
82 82 {
83 83 m_autoScaleCheck = new QCheckBox("Automatic scaling");
84 84 connect(m_autoScaleCheck, SIGNAL(stateChanged(int)), this, SLOT(autoScaleChanged(int)));
85 85 // Allow setting also non-sense values (like -2147483648 and 2147483647)
86 86 m_xMinSpin = new QSpinBox();
87 87 m_xMinSpin->setMinimum(INT_MIN);
88 88 m_xMinSpin->setMaximum(INT_MAX);
89 89 m_xMinSpin->setValue(0);
90 90 connect(m_xMinSpin, SIGNAL(valueChanged(int)), this, SLOT(xMinChanged(int)));
91 91 m_xMaxSpin = new QSpinBox();
92 92 m_xMaxSpin->setMinimum(INT_MIN);
93 93 m_xMaxSpin->setMaximum(INT_MAX);
94 94 m_xMaxSpin->setValue(10);
95 95 connect(m_xMaxSpin, SIGNAL(valueChanged(int)), this, SLOT(xMaxChanged(int)));
96 96 m_yMinSpin = new QSpinBox();
97 97 m_yMinSpin->setMinimum(INT_MIN);
98 98 m_yMinSpin->setMaximum(INT_MAX);
99 99 m_yMinSpin->setValue(0);
100 100 connect(m_yMinSpin, SIGNAL(valueChanged(int)), this, SLOT(yMinChanged(int)));
101 101 m_yMaxSpin = new QSpinBox();
102 102 m_yMaxSpin->setMinimum(INT_MIN);
103 103 m_yMaxSpin->setMaximum(INT_MAX);
104 104 m_yMaxSpin->setValue(10);
105 105 connect(m_yMaxSpin, SIGNAL(valueChanged(int)), this, SLOT(yMaxChanged(int)));
106 106
107 107 grid->addWidget(m_autoScaleCheck, grid->rowCount(), 0);
108 108 grid->addWidget(new QLabel("x min:"), grid->rowCount(), 0);
109 109 grid->addWidget(m_xMinSpin, grid->rowCount() - 1, 1);
110 110 grid->addWidget(new QLabel("x max:"), grid->rowCount(), 0);
111 111 grid->addWidget(m_xMaxSpin, grid->rowCount() - 1, 1);
112 112 grid->addWidget(new QLabel("y min:"), grid->rowCount(), 0);
113 113 grid->addWidget(m_yMinSpin, grid->rowCount() - 1, 1);
114 114 grid->addWidget(new QLabel("y max:"), grid->rowCount(), 0);
115 115 grid->addWidget(m_yMaxSpin, grid->rowCount() - 1, 1);
116 116
117 117 m_autoScaleCheck->setChecked(true);
118 118 }
119 119
120 120 // Combo box for selecting theme
121 121 void MainWidget::initThemeCombo(QGridLayout *grid)
122 122 {
123 123 QComboBox *chartTheme = new QComboBox();
124 124 chartTheme->addItem("Default");
125 125 chartTheme->addItem("Vanilla");
126 126 chartTheme->addItem("Icy");
127 127 chartTheme->addItem("Grayscale");
128 128 chartTheme->addItem("Scientific");
129 129 chartTheme->addItem("Unnamed1");
130 130 connect(chartTheme, SIGNAL(currentIndexChanged(int)),
131 131 this, SLOT(changeChartTheme(int)));
132 132 grid->addWidget(new QLabel("Chart theme:"), 8, 0);
133 133 grid->addWidget(chartTheme, 8, 1);
134 134 }
135 135
136 136 // Different check boxes for customizing chart
137 137 void MainWidget::initCheckboxes(QGridLayout *grid)
138 138 {
139 139 // TODO: setZoomEnabled slot has been removed from QChartView -> Re-implement zoom on/off
140 140 QCheckBox *zoomCheckBox = new QCheckBox("Drag'n drop Zoom");
141 141 connect(zoomCheckBox, SIGNAL(toggled(bool)), m_chartView, SLOT(setZoomEnabled(bool)));
142 142 zoomCheckBox->setChecked(true);
143 143 grid->addWidget(zoomCheckBox, grid->rowCount(), 0);
144 144
145 145 QCheckBox *aliasCheckBox = new QCheckBox("Anti-alias");
146 146 connect(aliasCheckBox, SIGNAL(toggled(bool)), this, SLOT(antiAliasToggled(bool)));
147 147 aliasCheckBox->setChecked(false);
148 148 grid->addWidget(aliasCheckBox, grid->rowCount(), 0);
149 149 }
150 150
151 151 void MainWidget::antiAliasToggled(bool enabled)
152 152 {
153 153 m_chartView->setRenderHint(QPainter::Antialiasing, enabled);
154 154 }
155 155
156 156 void MainWidget::initPieControls()
157 157 {
158 158 // Pie series specific settings
159 159 // Pie size factory
160 160 QDoubleSpinBox *pieSizeSpin = new QDoubleSpinBox();
161 161 pieSizeSpin->setMinimum(LONG_MIN);
162 162 pieSizeSpin->setMaximum(LONG_MAX);
163 163 pieSizeSpin->setValue(1.0);
164 164 pieSizeSpin->setSingleStep(0.1);
165 165 connect(pieSizeSpin, SIGNAL(valueChanged(double)), this, SLOT(setPieSizeFactor(double)));
166 166 // Pie position
167 167 QComboBox *piePosCombo = new QComboBox(this);
168 168 piePosCombo->addItem("Maximized");
169 169 piePosCombo->addItem("Top left");
170 170 piePosCombo->addItem("Top right");
171 171 piePosCombo->addItem("Bottom left");
172 172 piePosCombo->addItem("Bottom right");
173 173 connect(piePosCombo, SIGNAL(currentIndexChanged(int)),
174 174 this, SLOT(setPiePosition(int)));
175 175 m_pieLayout = new QGridLayout();
176 176 m_pieLayout->setEnabled(false);
177 177 m_pieLayout->addWidget(new QLabel("Pie size factor"), 0, 0);
178 178 m_pieLayout->addWidget(pieSizeSpin, 0, 1);
179 179 m_pieLayout->addWidget(new QLabel("Pie position"), 1, 0);
180 180 m_pieLayout->addWidget(piePosCombo, 1, 1);
181 181 }
182 182
183 183 void MainWidget::addSeries()
184 184 {
185 185 if (!m_addSerieDialog) {
186 186 m_addSerieDialog = new DataSerieDialog(this);
187 187 connect(m_addSerieDialog, SIGNAL(accepted(QString, int, int, QString, bool)),
188 188 this, SLOT(addSeries(QString, int, int, QString, bool)));
189 189 }
190 190 m_addSerieDialog->exec();
191 191 }
192 192
193 193 QList<RealList> MainWidget::generateTestData(int columnCount, int rowCount, QString dataCharacteristics)
194 194 {
195 195 // TODO: dataCharacteristics
196 196 QList<RealList> testData;
197 197 for (int j(0); j < columnCount; j++) {
198 198 QList <qreal> newColumn;
199 199 for (int i(0); i < rowCount; i++) {
200 200 if (dataCharacteristics == "Sin") {
201 201 newColumn.append(abs(sin(3.14159265358979 / 50 * i) * 100));
202 202 } else if (dataCharacteristics == "Sin + random") {
203 203 newColumn.append(abs(sin(3.14159265358979 / 50 * i) * 100) + (rand() % 5));
204 204 } else if (dataCharacteristics == "Random") {
205 205 newColumn.append(rand() % 5);
206 206 } else if (dataCharacteristics == "Linear") {
207 207 //newColumn.append(i * (j + 1.0));
208 208 // TODO: temporary hack to make pie work; prevent zero values:
209 209 newColumn.append(i * (j + 1.0) + 0.1);
210 210 } else { // "constant"
211 211 newColumn.append((j + 1.0));
212 212 }
213 213 }
214 214 testData.append(newColumn);
215 215 }
216 216 return testData;
217 217 }
218 218
219 219 QStringList MainWidget::generateLabels(int count)
220 220 {
221 221 QStringList result;
222 222 for (int i(0); i < count; i++)
223 223 result.append("label" + QString::number(i));
224 224 return result;
225 225 }
226 226
227 227 void MainWidget::addSeries(QString seriesName, int columnCount, int rowCount, QString dataCharacteristics, bool labelsEnabled)
228 228 {
229 229 qDebug() << "addSeries: " << seriesName
230 230 << " columnCount: " << columnCount
231 231 << " rowCount: " << rowCount
232 232 << " dataCharacteristics: " << dataCharacteristics
233 233 << " labels enabled: " << labelsEnabled;
234 234 m_defaultSeriesName = seriesName;
235 235
236 236 QList<RealList> data = generateTestData(columnCount, rowCount, dataCharacteristics);
237 237
238 238 // Line series and scatter series use similar data
239 239 if (seriesName.contains("line", Qt::CaseInsensitive)) {
240 240 for (int j(0); j < data.count(); j ++) {
241 241 QList<qreal> column = data.at(j);
242 242 QLineSeries *series = new QLineSeries();
243 243 for (int i(0); i < column.count(); i++) {
244 244 series->add(i, column.at(i));
245 245 }
246 246 m_chartView->addSeries(series);
247 247 setCurrentSeries(series);
248 248 }
249 249 } else if (seriesName.contains("scatter", Qt::CaseInsensitive)) {
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 for (int i(0); i < column.count(); i++) {
254 254 (*series) << QPointF(i, column.at(i));
255 255 }
256 256 m_chartView->addSeries(series);
257 257 setCurrentSeries(series);
258 258 }
259 259 } else if (seriesName.contains("pie", Qt::CaseInsensitive)) {
260 260 QStringList labels = generateLabels(rowCount);
261 261 for (int j(0); j < data.count(); j++) {
262 262 QPieSeries *series = new QPieSeries();
263 263 QList<qreal> column = data.at(j);
264 264 for (int i(0); i < column.count(); i++) {
265 265 series->add(column.at(i), labels.at(i));
266 266 }
267 267 m_chartView->addSeries(series);
268 268 setCurrentSeries(series);
269 269 }
270 270 } else if (seriesName == "Bar"
271 271 || seriesName == "Stacked bar"
272 272 || seriesName == "Percent bar") {
273 273 QStringList category;
274 274 QStringList labels = generateLabels(rowCount);
275 275 foreach(QString label, labels)
276 276 category << label;
277 277 QBarSeries* series = 0;
278 278 if (seriesName == "Bar")
279 279 series = new QBarSeries(category, this);
280 280 else if (seriesName == "Stacked bar")
281 281 series = new QStackedBarSeries(category, this);
282 282 else
283 283 series = new QPercentBarSeries(category, this);
284 284
285 285 for (int j(0); j < data.count(); j++) {
286 286 QList<qreal> column = data.at(j);
287 287 QBarSet *set = new QBarSet("set" + QString::number(j));
288 288 for (int i(0); i < column.count(); i++) {
289 289 *set << column.at(i);
290 290 }
291 291 series->addBarSet(set);
292 292 }
293 series->setFloatingValuesEnabled(true);
293 // TODO: new implementation of setFloatingValuesEnabled with signals
294 //series->setFloatingValuesEnabled(true);
294 295 series->setToolTipEnabled(true);
295 296 series->setSeparatorsEnabled(false);
296 297 m_chartView->addSeries(series);
297 298 setCurrentSeries(series);
298 299 }
299 300
300 301 // TODO: spline and area
301 302 }
302 303
303 304 void MainWidget::setCurrentSeries(QSeries *series)
304 305 {
305 306 if (series) {
306 307 m_currentSeries = series;
307 308 switch (m_currentSeries->type()) {
308 309 case QSeries::SeriesTypeLine:
309 310 break;
310 311 case QSeries::SeriesTypeScatter:
311 312 break;
312 313 case QSeries::SeriesTypePie:
313 314 break;
314 315 case QSeries::SeriesTypeBar:
315 316 qDebug() << "setCurrentSeries (bar)";
316 317 break;
317 318 case QSeries::SeriesTypeStackedBar:
318 319 qDebug() << "setCurrentSeries (Stackedbar)";
319 320 break;
320 321 case QSeries::SeriesTypePercentBar:
321 322 qDebug() << "setCurrentSeries (Percentbar)";
322 323 break;
323 324 default:
324 325 Q_ASSERT(false);
325 326 break;
326 327 }
327 328 }
328 329 }
329 330
330 331 void MainWidget::backgroundChanged(int itemIndex)
331 332 {
332 333 qDebug() << "backgroundChanged: " << itemIndex;
333 334 }
334 335
335 336 void MainWidget::autoScaleChanged(int value)
336 337 {
337 338 if (value) {
338 339 // TODO: enable auto scaling
339 340 } else {
340 341 // TODO: set scaling manually (and disable auto scaling)
341 342 }
342 343
343 344 m_xMinSpin->setEnabled(!value);
344 345 m_xMaxSpin->setEnabled(!value);
345 346 m_yMinSpin->setEnabled(!value);
346 347 m_yMaxSpin->setEnabled(!value);
347 348 }
348 349
349 350 void MainWidget::xMinChanged(int value)
350 351 {
351 352 qDebug() << "xMinChanged: " << value;
352 353 }
353 354
354 355 void MainWidget::xMaxChanged(int value)
355 356 {
356 357 qDebug() << "xMaxChanged: " << value;
357 358 }
358 359
359 360 void MainWidget::yMinChanged(int value)
360 361 {
361 362 qDebug() << "yMinChanged: " << value;
362 363 }
363 364
364 365 void MainWidget::yMaxChanged(int value)
365 366 {
366 367 qDebug() << "yMaxChanged: " << value;
367 368 }
368 369
369 370 void MainWidget::changeChartTheme(int themeIndex)
370 371 {
371 372 qDebug() << "changeChartTheme: " << themeIndex;
372 373 m_chartView->setChartTheme((QChart::ChartTheme) themeIndex);
373 374 //TODO: remove this hack. This is just to make it so that theme change is seen immediately.
374 375 QSize s = size();
375 376 s.setWidth(s.width()+1);
376 377 resize(s);
377 378 }
378 379
379 380 void MainWidget::setPieSizeFactor(double size)
380 381 {
381 382 QPieSeries *pie = qobject_cast<QPieSeries *>(m_currentSeries);
382 383 if (pie)
383 384 pie->setSizeFactor(qreal(size));
384 385 }
385 386
386 387 void MainWidget::setPiePosition(int position)
387 388 {
388 389 QPieSeries *pie = qobject_cast<QPieSeries *>(m_currentSeries);
389 390 if (pie)
390 391 pie->setPosition((QPieSeries::PiePosition) position);
391 392 }
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
General Comments 0
You need to be logged in to leave comments. Login now