##// END OF EJS Templates
Marek Rosa -
r416:b3ab09e85735 merge
parent child
Show More
@@ -0,0 +1,113
1 #include <QtGui/QApplication>
2 #include <QMainWindow>
3 #include <qchartglobal.h>
4 #include <qchartview.h>
5 #include <qpieseries.h>
6 #include <qpieslice.h>
7 #include <QTime>
8
9 QTCOMMERCIALCHART_USE_NAMESPACE
10
11 class DrilldownSlice : public QPieSlice
12 {
13 Q_OBJECT
14
15 public:
16 DrilldownSlice(qreal value, QString prefix, QSeries* drilldownSeries)
17 :m_drilldownSeries(drilldownSeries),
18 m_prefix(prefix)
19 {
20 setValue(value);
21 setLabelVisible(true);
22 updateLabel();
23 connect(this, SIGNAL(changed()), this, SLOT(updateLabel()));
24 }
25
26 QSeries* drilldownSeries() const { return m_drilldownSeries; }
27
28 public Q_SLOTS:
29 void updateLabel()
30 {
31 QString label = m_prefix;
32 label += " " + QString::number(this->value())+ "e (";
33 label += QString::number(this->percentage()*100, 'f', 1) + "%)";
34 setLabel(label);
35 }
36
37 private:
38 QSeries* m_drilldownSeries;
39 QString m_prefix;
40 };
41
42 class DrilldownChart : public QChartView
43 {
44 Q_OBJECT
45 public:
46 explicit DrilldownChart(QWidget *parent = 0):QChartView(parent), m_currentSeries(0) {}
47
48 void changeSeries(QSeries* series)
49 {
50 if (m_currentSeries)
51 removeSeries(m_currentSeries);
52 m_currentSeries = series;
53 addSeries(series);
54 setChartTitle(series->title());
55 }
56
57 public Q_SLOTS:
58 void handleSliceClicked(QPieSlice* slice)
59 {
60 DrilldownSlice* drilldownSlice = static_cast<DrilldownSlice*>(slice);
61 changeSeries(drilldownSlice->drilldownSeries());
62 }
63
64 private:
65 QSeries* m_currentSeries;
66 };
67
68 int main(int argc, char *argv[])
69 {
70 QApplication a(argc, argv);
71
72 qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
73
74 QMainWindow window;
75
76 DrilldownChart* drilldownChart = new DrilldownChart(&window);
77 drilldownChart->setRenderHint(QPainter::Antialiasing);
78 drilldownChart->setChartTheme(QChart::ChartThemeVanilla);
79
80 QPieSeries* yearSeries = new QPieSeries(drilldownChart);
81 yearSeries->setTitle("Sales by year - All");
82 yearSeries->setHoverHighlighting();
83
84 QList<QString> months;
85 months << "Jan" << "Feb" << "Mar" << "Apr" << "May" << "Jun" << "Jul" << "Aug" << "Sep" << "Oct" << "Nov" << "Dec";
86 QList<QString> names;
87 names << "Jane" << "John" << "Axel" << "Mary" << "Samantha" << "Bob";
88
89 foreach (QString name, names) {
90 QPieSeries* series = new QPieSeries(drilldownChart);
91 series->setTitle("Sales by month - " + name);
92 series->setHoverHighlighting();
93
94 foreach (QString month, months)
95 *series << new DrilldownSlice(qrand() % 1000, month, yearSeries);
96
97 QObject::connect(series, SIGNAL(clicked(QPieSlice*)), drilldownChart, SLOT(handleSliceClicked(QPieSlice*)));
98
99 *yearSeries << new DrilldownSlice(series->total(), name, series);
100 }
101
102 QObject::connect(yearSeries, SIGNAL(clicked(QPieSlice*)), drilldownChart, SLOT(handleSliceClicked(QPieSlice*)));
103
104 drilldownChart->changeSeries(yearSeries);
105
106 window.setCentralWidget(drilldownChart);
107 window.resize(600, 600);
108 window.show();
109
110 return a.exec();
111 }
112
113 #include "main.moc"
@@ -0,0 +1,9
1 !include( ../example.pri ) {
2 error( "Couldn't find the example.pri file!" )
3 }
4 TARGET = piechartdrilldown
5 SOURCES += main.cpp
6 HEADERS +=
7
8
9 MOC_DIR = $$PWD/moc
@@ -0,0 +1,17
1 #include "barcategory_p.h"
2
3 QTCOMMERCIALCHART_BEGIN_NAMESPACE
4 BarCategory::BarCategory(QString name, QObject *parent) :
5 QObject(parent)
6 ,mName(name)
7 {
8 }
9
10 void BarCategory::barRightClickEvent()
11 {
12 // TODO:
13 emit rightClicked(mName);
14 }
15
16 #include "moc_barcategory_p.cpp"
17 QTCOMMERCIALCHART_END_NAMESPACE
@@ -0,0 +1,26
1 #ifndef BARCATEGORY_P_H
2 #define BARCATEGORY_P_H
3
4 #include <QObject>
5 #include <qchartglobal.h>
6
7 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8 // Event handler for bar category
9 class BarCategory : public QObject
10 {
11 Q_OBJECT
12 public:
13 explicit BarCategory(QString name, QObject *parent = 0);
14
15 signals:
16 void rightClicked(QString name); // "We want something to happen that involves this category"
17
18 public slots:
19 void barRightClickEvent();
20
21 private:
22 QString mName;
23 };
24
25 QTCOMMERCIALCHART_END_NAMESPACE
26 #endif // BARCATEGORY_P_H
@@ -1,16 +1,17
1 TEMPLATE = subdirs
1 TEMPLATE = subdirs
2 SUBDIRS += linechart \
2 SUBDIRS += linechart \
3 zoomlinechart \
3 zoomlinechart \
4 colorlinechart \
4 colorlinechart \
5 barchart \
5 barchart \
6 stackedbarchart \
6 stackedbarchart \
7 percentbarchart \
7 percentbarchart \
8 scatter \
8 scatter \
9 piechart \
9 piechart \
10 piechartdrilldown \
10 dynamiclinechart \
11 dynamiclinechart \
11 axischart \
12 axischart \
12 multichart \
13 multichart \
13 gdpbarchart \
14 gdpbarchart \
14 presenterchart \
15 presenterchart \
15 chartview \
16 chartview \
16 scatterinteractions
17 scatterinteractions
@@ -1,84 +1,88
1 #include "bar_p.h"
1 #include "bar_p.h"
2 #include <QDebug>
2 #include <QDebug>
3 #include <QPainter>
3 #include <QPainter>
4 #include <QGraphicsSceneEvent>
4 #include <QGraphicsSceneEvent>
5
5
6 QTCOMMERCIALCHART_BEGIN_NAMESPACE
6 QTCOMMERCIALCHART_BEGIN_NAMESPACE
7
7
8 Bar::Bar(QGraphicsItem *parent)
8 Bar::Bar(QGraphicsItem *parent)
9 : QGraphicsObject(parent)
9 : QGraphicsObject(parent)
10 {
10 {
11 setAcceptedMouseButtons(Qt::LeftButton);
11 setAcceptedMouseButtons(Qt::LeftButton|Qt::RightButton);
12 setAcceptHoverEvents(true);
12 setAcceptHoverEvents(true);
13 }
13 }
14
14
15 void Bar::setSize(const QSizeF& size)
15 void Bar::setSize(const QSizeF& size)
16 {
16 {
17 mWidth = size.width();
17 mWidth = size.width();
18 mHeight = size.height();
18 mHeight = size.height();
19 }
19 }
20
20
21
21
22 void Bar::resize( qreal w, qreal h )
22 void Bar::resize( qreal w, qreal h )
23 {
23 {
24 mWidth = w;
24 mWidth = w;
25 mHeight = h;
25 mHeight = h;
26 }
26 }
27
27
28 void Bar::setPos(qreal x, qreal y)
28 void Bar::setPos(qreal x, qreal y)
29 {
29 {
30 mXpos = x;
30 mXpos = x;
31 mYpos = y;
31 mYpos = y;
32 }
32 }
33
33
34 void Bar::setPen(QPen pen)
34 void Bar::setPen(QPen pen)
35 {
35 {
36 mPen = pen;
36 mPen = pen;
37 }
37 }
38
38
39 void Bar::setBrush(QBrush brush)
39 void Bar::setBrush(QBrush brush)
40 {
40 {
41 mBrush = brush;
41 mBrush = brush;
42 }
42 }
43
43
44 void Bar::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
44 void Bar::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
45 {
45 {
46 if (0 == mHeight) {
46 if (0 == mHeight) {
47 return;
47 return;
48 }
48 }
49 painter->setBrush(mBrush);
49 painter->setBrush(mBrush);
50
50
51 // This compensates for rounding errors. drawRect takes ints and cumulative error of pos + size may be over 1.
51 // This compensates for rounding errors. drawRect takes ints and cumulative error of pos + size may be over 1.
52 int x0 = mXpos;
52 int x0 = mXpos;
53 int x1 = (mXpos + mWidth);
53 int x1 = (mXpos + mWidth);
54 int w = x1-x0;
54 int w = x1-x0;
55 int y0 = mYpos;
55 int y0 = mYpos;
56 int y1 = (mYpos + mHeight);
56 int y1 = (mYpos + mHeight);
57 int h = y1-y0;
57 int h = y1-y0;
58 painter->drawRect(x0, y0 ,w ,h);
58 painter->drawRect(x0, y0 ,w ,h);
59 }
59 }
60
60
61 QRectF Bar::boundingRect() const
61 QRectF Bar::boundingRect() const
62 {
62 {
63 QRectF r(mXpos, mYpos, mWidth, mHeight);
63 QRectF r(mXpos, mYpos, mWidth, mHeight);
64 return r;
64 return r;
65 }
65 }
66
66
67 void Bar::mousePressEvent(QGraphicsSceneMouseEvent* /*event*/)
67 void Bar::mousePressEvent(QGraphicsSceneMouseEvent* event)
68 {
68 {
69 emit clicked();
69 if (event->button() == Qt::LeftButton) {
70 emit clicked();
71 } else if (event->button() == Qt::RightButton) {
72 emit rightClicked();
73 }
70 }
74 }
71
75
72 void Bar::hoverEnterEvent(QGraphicsSceneHoverEvent* event)
76 void Bar::hoverEnterEvent(QGraphicsSceneHoverEvent* event)
73 {
77 {
74 emit hoverEntered(event->lastScreenPos());
78 emit hoverEntered(event->lastScreenPos());
75 }
79 }
76
80
77 void Bar::hoverLeaveEvent(QGraphicsSceneHoverEvent* /*event*/)
81 void Bar::hoverLeaveEvent(QGraphicsSceneHoverEvent* /*event*/)
78 {
82 {
79 emit hoverLeaved();
83 emit hoverLeaved();
80 }
84 }
81
85
82 #include "moc_bar_p.cpp"
86 #include "moc_bar_p.cpp"
83
87
84 QTCOMMERCIALCHART_END_NAMESPACE
88 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,55 +1,55
1 #ifndef BAR_H
1 #ifndef BAR_H
2 #define BAR_H
2 #define BAR_H
3
3
4 #include "qchartglobal.h"
4 #include "qchartglobal.h"
5 #include <QGraphicsObject>
5 #include <QGraphicsObject>
6 #include <QPen>
6 #include <QPen>
7 #include <QBrush>
7 #include <QBrush>
8
8
9 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9 QTCOMMERCIALCHART_BEGIN_NAMESPACE
10
10
11 // Single visual bar item of chart
11 // Single visual bar item of chart
12 class Bar : public QGraphicsObject
12 class Bar : public QGraphicsObject
13 {
13 {
14 Q_OBJECT
14 Q_OBJECT
15 public:
15 public:
16 Bar(QGraphicsItem *parent=0);
16 Bar(QGraphicsItem *parent=0);
17
17
18 public: // from ChartItem
18 public: // from ChartItem
19 void setSize(const QSizeF &size);
19 void setSize(const QSizeF &size);
20
20
21 // Layout Stuff
21 // Layout Stuff
22 void resize(qreal w, qreal h);
22 void resize(qreal w, qreal h);
23 void setPos(qreal x, qreal y);
23 void setPos(qreal x, qreal y);
24 void setPen(QPen pen);
24 void setPen(QPen pen);
25 void setBrush(QBrush brush);
25 void setBrush(QBrush brush);
26
26
27 public:
27 public:
28 // From QGraphicsItem
28 // From QGraphicsItem
29 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
29 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
30 QRectF boundingRect() const;
30 QRectF boundingRect() const;
31 void mousePressEvent(QGraphicsSceneMouseEvent *event);
31 void mousePressEvent(QGraphicsSceneMouseEvent *event);
32 void hoverEnterEvent(QGraphicsSceneHoverEvent *event);
32 void hoverEnterEvent(QGraphicsSceneHoverEvent *event);
33 void hoverLeaveEvent(QGraphicsSceneHoverEvent *event);
33 void hoverLeaveEvent(QGraphicsSceneHoverEvent *event);
34
34
35 Q_SIGNALS:
35 Q_SIGNALS:
36 void clicked();
36 void clicked();
37 void rightClicked();
37 void hoverEntered(QPoint pos);
38 void hoverEntered(QPoint pos);
38 void hoverLeaved();
39 void hoverLeaved();
39
40
40 private:
41 private:
41
42
42 qreal mHeight;
43 qreal mHeight;
43 qreal mWidth;
44 qreal mWidth;
44 qreal mXpos;
45 qreal mXpos;
45 qreal mYpos;
46 qreal mYpos;
46 QColor mColor;
47
47
48 QBrush mBrush;
48 QBrush mBrush;
49 QPen mPen;
49 QPen mPen;
50
50
51 };
51 };
52
52
53 QTCOMMERCIALCHART_END_NAMESPACE
53 QTCOMMERCIALCHART_END_NAMESPACE
54
54
55 #endif // BAR_H
55 #endif // BAR_H
@@ -1,36 +1,37
1 INCLUDEPATH += $$PWD
1 INCLUDEPATH += $$PWD
2 DEPENDPATH += $$PWD
2 DEPENDPATH += $$PWD
3
3
4 SOURCES += \
4 SOURCES += \
5 $$PWD/bar.cpp \
5 $$PWD/bar.cpp \
6 $$PWD/barchartmodel.cpp \
6 $$PWD/barchartmodel.cpp \
7 $$PWD/barlabel.cpp \
7 $$PWD/barlabel.cpp \
8 $$PWD/barpresenter.cpp \
8 $$PWD/barpresenter.cpp \
9 $$PWD/barpresenterbase.cpp \
9 $$PWD/barpresenterbase.cpp \
10 $$PWD/percentbarpresenter.cpp \
10 $$PWD/percentbarpresenter.cpp \
11 $$PWD/qbarseries.cpp \
11 $$PWD/qbarseries.cpp \
12 $$PWD/qbarset.cpp \
12 $$PWD/qbarset.cpp \
13 $$PWD/qpercentbarseries.cpp \
13 $$PWD/qpercentbarseries.cpp \
14 $$PWD/qstackedbarseries.cpp \
14 $$PWD/qstackedbarseries.cpp \
15 $$PWD/separator.cpp \
15 $$PWD/separator.cpp \
16 $$PWD/stackedbarpresenter.cpp \
16 $$PWD/stackedbarpresenter.cpp \
17 $$PWD/barvalue.cpp
17 $$PWD/barvalue.cpp \
18 $$PWD/barcategory.cpp
18
19
19 PRIVATE_HEADERS += \
20 PRIVATE_HEADERS += \
20 $$PWD/bar_p.h \
21 $$PWD/bar_p.h \
21 $$PWD/barchartmodel_p.h \
22 $$PWD/barchartmodel_p.h \
22 $$PWD/barlabel_p.h \
23 $$PWD/barlabel_p.h \
23 $$PWD/barpresenter_p.h \
24 $$PWD/barpresenter_p.h \
24 $$PWD/barpresenterbase_p.h \
25 $$PWD/barpresenterbase_p.h \
25 $$PWD/percentbarpresenter_p.h \
26 $$PWD/percentbarpresenter_p.h \
26 $$PWD/separator_p.h \
27 $$PWD/separator_p.h \
27 $$PWD/stackedbarpresenter_p.h \
28 $$PWD/stackedbarpresenter_p.h \
28 $$PWD/barvalue_p.h
29 $$PWD/barvalue_p.h \
30 $$PWD/barcategory_p.h
29
31
30 PUBLIC_HEADERS += \
32 PUBLIC_HEADERS += \
31 $$PWD/qbarseries.h \
33 $$PWD/qbarseries.h \
32 $$PWD/qbarset.h \
34 $$PWD/qbarset.h \
33 $$PWD/qpercentbarseries.h \
35 $$PWD/qpercentbarseries.h \
34 $$PWD/qstackedbarseries.h
36 $$PWD/qstackedbarseries.h
35
36
37
@@ -1,172 +1,182
1 #include <limits.h>
1 #include <limits.h>
2 #include <QVector>
2 #include <QVector>
3 #include <QDebug>
3 #include <QDebug>
4 #include "barchartmodel_p.h"
4 #include "barchartmodel_p.h"
5 #include "barcategory_p.h"
5 #include "qbarset.h"
6 #include "qbarset.h"
6
7
7 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8
9
9 BarChartModel::BarChartModel(QStringList categories, QObject *parent) :
10 BarChartModel::BarChartModel(QStringList categories, QObject *parent) :
10 QObject(parent)
11 QObject(parent)
11 ,mCategory(categories)
12 ,mCategory(categories)
12 {
13 {
14 for (int i=0; i<mCategory.count(); i++) {
15 BarCategory* cat = new BarCategory(mCategory.at(i), this);
16 mCategoryObjects.append(cat);
17 }
13 }
18 }
14
19
15 QStringList BarChartModel::category()
20 QStringList BarChartModel::category()
16 {
21 {
17 return mCategory;
22 return mCategory;
18 }
23 }
19
24
20 void BarChartModel::addBarSet(QBarSet *set)
25 void BarChartModel::addBarSet(QBarSet *set)
21 {
26 {
22 mDataModel.append(set);
27 mDataModel.append(set);
23 }
28 }
24
29
25 void BarChartModel::removeBarSet(QBarSet *set)
30 void BarChartModel::removeBarSet(QBarSet *set)
26 {
31 {
27 if (mDataModel.contains(set)) {
32 if (mDataModel.contains(set)) {
28 mDataModel.removeOne(set);
33 mDataModel.removeOne(set);
29 }
34 }
30 }
35 }
31
36
32 QBarSet* BarChartModel::setAt(int index)
37 QBarSet* BarChartModel::setAt(int index)
33 {
38 {
34 return mDataModel.at(index);
39 return mDataModel.at(index);
35 }
40 }
36
41
37 QList<QBarSet*> BarChartModel::barSets()
42 QList<QBarSet*> BarChartModel::barSets()
38 {
43 {
39 return mDataModel;
44 return mDataModel;
40 }
45 }
41
46
42 QList<QSeries::Legend> BarChartModel::legend()
47 QList<QSeries::Legend> BarChartModel::legend()
43 {
48 {
44 QList<QSeries::Legend> legend;
49 QList<QSeries::Legend> legend;
45
50
46 for (int i=0; i<mDataModel.count(); i++) {
51 for (int i=0; i<mDataModel.count(); i++) {
47 QSeries::Legend l;
52 QSeries::Legend l;
48 l.mName = mDataModel.at(i)->name();
53 l.mName = mDataModel.at(i)->name();
49 l.mPen = mDataModel.at(i)->pen();
54 l.mPen = mDataModel.at(i)->pen();
50 legend.append(l);
55 legend.append(l);
51 }
56 }
52 return legend;
57 return legend;
53 }
58 }
54
59
55 int BarChartModel::barsetCount()
60 int BarChartModel::barsetCount()
56 {
61 {
57 return mDataModel.count();
62 return mDataModel.count();
58 }
63 }
59
64
60 int BarChartModel::categoryCount()
65 int BarChartModel::categoryCount()
61 {
66 {
62 return mCategory.count();
67 return mCategory.count();
63 }
68 }
64
69
65 qreal BarChartModel::min()
70 qreal BarChartModel::min()
66 {
71 {
67 Q_ASSERT(mDataModel.count() > 0);
72 Q_ASSERT(mDataModel.count() > 0);
68 // TODO: make min and max members and update them when data changes.
73 // TODO: make min and max members and update them when data changes.
69 // This is slower since they are checked every time, even if data is same since previous call.
74 // This is slower since they are checked every time, even if data is same since previous call.
70 qreal min = INT_MAX;
75 qreal min = INT_MAX;
71
76
72 for (int i=0; i <mDataModel.count(); i++) {
77 for (int i=0; i <mDataModel.count(); i++) {
73 int itemCount = mDataModel.at(i)->count();
78 int itemCount = mDataModel.at(i)->count();
74 for (int j=0; j<itemCount; j++) {
79 for (int j=0; j<itemCount; j++) {
75 qreal temp = mDataModel.at(i)->valueAt(j);
80 qreal temp = mDataModel.at(i)->valueAt(j);
76 if (temp < min) {
81 if (temp < min) {
77 min = temp;
82 min = temp;
78 }
83 }
79 }
84 }
80 }
85 }
81 return min;
86 return min;
82 }
87 }
83
88
84 qreal BarChartModel::max()
89 qreal BarChartModel::max()
85 {
90 {
86 Q_ASSERT(mDataModel.count() > 0);
91 Q_ASSERT(mDataModel.count() > 0);
87
92
88 // TODO: make min and max members and update them when data changes.
93 // TODO: make min and max members and update them when data changes.
89 // This is slower since they are checked every time, even if data is same since previous call.
94 // This is slower since they are checked every time, even if data is same since previous call.
90 qreal max = INT_MIN;
95 qreal max = INT_MIN;
91
96
92 for (int i=0; i <mDataModel.count(); i++) {
97 for (int i=0; i <mDataModel.count(); i++) {
93 int itemCount = mDataModel.at(i)->count();
98 int itemCount = mDataModel.at(i)->count();
94 for (int j=0; j<itemCount; j++) {
99 for (int j=0; j<itemCount; j++) {
95 qreal temp = mDataModel.at(i)->valueAt(j);
100 qreal temp = mDataModel.at(i)->valueAt(j);
96 if (temp > max) {
101 if (temp > max) {
97 max = temp;
102 max = temp;
98 }
103 }
99 }
104 }
100 }
105 }
101
106
102 return max;
107 return max;
103 }
108 }
104
109
105 qreal BarChartModel::valueAt(int set, int category)
110 qreal BarChartModel::valueAt(int set, int category)
106 {
111 {
107 if ((set < 0) || (set >= mDataModel.count())) {
112 if ((set < 0) || (set >= mDataModel.count())) {
108 // No set, no value.
113 // No set, no value.
109 return 0;
114 return 0;
110 } else if ((category < 0) || (category >= mDataModel.at(set)->count())) {
115 } else if ((category < 0) || (category >= mDataModel.at(set)->count())) {
111 // No category, no value.
116 // No category, no value.
112 return 0;
117 return 0;
113 }
118 }
114
119
115 return mDataModel.at(set)->valueAt(category);
120 return mDataModel.at(set)->valueAt(category);
116 }
121 }
117
122
118 qreal BarChartModel::percentageAt(int set, int category)
123 qreal BarChartModel::percentageAt(int set, int category)
119 {
124 {
120 if ((set < 0) || (set >= mDataModel.count())) {
125 if ((set < 0) || (set >= mDataModel.count())) {
121 // No set, no value.
126 // No set, no value.
122 return 0;
127 return 0;
123 } else if ((category < 0) || (category >= mDataModel.at(set)->count())) {
128 } else if ((category < 0) || (category >= mDataModel.at(set)->count())) {
124 // No category, no value.
129 // No category, no value.
125 return 0;
130 return 0;
126 }
131 }
127
132
128 qreal value = mDataModel.at(set)->valueAt(category);
133 qreal value = mDataModel.at(set)->valueAt(category);
129 qreal total = categorySum(category);
134 qreal total = categorySum(category);
130 if (0 == total) {
135 if (0 == total) {
131 return 100.0;
136 return 100.0;
132 }
137 }
133
138
134 return value / total;
139 return value / total;
135 }
140 }
136
141
137
142
138 qreal BarChartModel::categorySum(int category)
143 qreal BarChartModel::categorySum(int category)
139 {
144 {
140 qreal sum(0);
145 qreal sum(0);
141 int count = mDataModel.count(); // Count sets
146 int count = mDataModel.count(); // Count sets
142
147
143 for (int set = 0; set < count; set++) {
148 for (int set = 0; set < count; set++) {
144 if (category < mDataModel.at(set)->count()) {
149 if (category < mDataModel.at(set)->count()) {
145 sum += mDataModel.at(set)->valueAt(category);
150 sum += mDataModel.at(set)->valueAt(category);
146 }
151 }
147 }
152 }
148 return sum;
153 return sum;
149 }
154 }
150
155
151 qreal BarChartModel::maxCategorySum()
156 qreal BarChartModel::maxCategorySum()
152 {
157 {
153 qreal max = INT_MIN;
158 qreal max = INT_MIN;
154 int count = categoryCount();
159 int count = categoryCount();
155
160
156 for (int col=0; col<count; col++) {
161 for (int col=0; col<count; col++) {
157 qreal sum = categorySum(col);
162 qreal sum = categorySum(col);
158 if (sum > max) {
163 if (sum > max) {
159 max = sum;
164 max = sum;
160 }
165 }
161 }
166 }
162 return max;
167 return max;
163 }
168 }
164
169
165 QString BarChartModel::label(int category)
170 QString BarChartModel::categoryName(int category)
166 {
171 {
167 return mCategory.at(category);
172 return mCategory.at(category);
168 }
173 }
169
174
175 BarCategory* BarChartModel::categoryObject(int category)
176 {
177 return mCategoryObjects.at(category);
178 }
179
170 #include "moc_barchartmodel_p.cpp"
180 #include "moc_barchartmodel_p.cpp"
171
181
172 QTCOMMERCIALCHART_END_NAMESPACE
182 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,59 +1,62
1 #ifndef BARCHARTMODEL_H
1 #ifndef BARCHARTMODEL_H
2 #define BARCHARTMODEL_H
2 #define BARCHARTMODEL_H
3
3
4 #include <QObject>
4 #include <QObject>
5 #include <QStringList>
5 #include <QStringList>
6 #include "qchartglobal.h"
6 #include "qchartglobal.h"
7 #include <qseries.h>
7 #include <qseries.h>
8
8
9 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9 QTCOMMERCIALCHART_BEGIN_NAMESPACE
10
10
11 // Model for bar chart. Internal class.
11 // Model for bar chart. Internal class.
12 // TODO: Implement as QAbstractItemModel?
12 // TODO: Implement as QAbstractItemModel?
13
13
14 class QBarSet;
14 class QBarSet;
15 class BarCategory;
15
16
16 class BarChartModel : public QObject //, public QAbstractItemModel
17 class BarChartModel : public QObject //, public QAbstractItemModel
17 {
18 {
18 Q_OBJECT
19 Q_OBJECT
19 public:
20 public:
20 explicit BarChartModel(QStringList categories, QObject *parent = 0);
21 explicit BarChartModel(QStringList categories, QObject *parent = 0);
21
22
22 QStringList category();
23 QStringList category();
23 void addBarSet(QBarSet *set);
24 void addBarSet(QBarSet *set);
24 void removeBarSet(QBarSet *set);
25 void removeBarSet(QBarSet *set);
25 QBarSet *setAt(int index);
26 QBarSet *setAt(int index);
26 QList<QBarSet*> barSets();
27 QList<QBarSet*> barSets();
27
28
28 QList<QSeries::Legend> legend();
29 QList<QSeries::Legend> legend();
29
30
30 int barsetCount(); // Number of sets in model
31 int barsetCount(); // Number of sets in model
31 int categoryCount(); // Number of categories
32 int categoryCount(); // Number of categories
32
33
33 qreal max(); // Maximum value of all sets
34 qreal max(); // Maximum value of all sets
34 qreal min(); // Minimum value of all sets
35 qreal min(); // Minimum value of all sets
35 qreal valueAt(int set, int category);
36 qreal valueAt(int set, int category);
36 qreal percentageAt(int set, int category);
37 qreal percentageAt(int set, int category);
37
38
38 qreal categorySum(int category);
39 qreal categorySum(int category);
39 qreal maxCategorySum(); // returns maximum sum of sets in all categories.
40 qreal maxCategorySum(); // returns maximum sum of sets in all categories.
40
41
41 QString label(int category);
42 QString categoryName(int category);
43 BarCategory* categoryObject(int category);
42
44
43 signals:
45 signals:
44 void modelUpdated();
46 void modelUpdated();
45
47
46 public slots:
48 public slots:
47
49
48 private:
50 private:
49
51
50 QList<QBarSet*> mDataModel;
52 QList<QBarSet*> mDataModel;
51 QStringList mCategory;
53 QStringList mCategory;
54 QList<BarCategory*> mCategoryObjects;
52
55
53 int mCurrentSet;
56 int mCurrentSet;
54
57
55 };
58 };
56
59
57 QTCOMMERCIALCHART_END_NAMESPACE
60 QTCOMMERCIALCHART_END_NAMESPACE
58
61
59 #endif // BARCHARTMODEL_H
62 #endif // BARCHARTMODEL_H
@@ -1,158 +1,161
1 #include "barpresenterbase_p.h"
1 #include "barpresenterbase_p.h"
2 #include "bar_p.h"
2 #include "bar_p.h"
3 #include "barvalue_p.h"
3 #include "barvalue_p.h"
4 #include "barlabel_p.h"
4 #include "barlabel_p.h"
5 #include "separator_p.h"
5 #include "separator_p.h"
6 #include "barcategory_p.h"
6 #include "qbarset.h"
7 #include "qbarset.h"
7 #include "qbarseries.h"
8 #include "qbarseries.h"
8 #include <QDebug>
9 #include <QDebug>
9 #include <QToolTip>
10 #include <QToolTip>
10
11
11 QTCOMMERCIALCHART_BEGIN_NAMESPACE
12 QTCOMMERCIALCHART_BEGIN_NAMESPACE
12
13
13 BarPresenterBase::BarPresenterBase(QBarSeries *series, QGraphicsItem *parent)
14 BarPresenterBase::BarPresenterBase(QBarSeries *series, QGraphicsItem *parent)
14 : ChartItem(parent)
15 : ChartItem(parent)
15 ,mBarDefaultWidth(20) // TODO: remove hard coding, when we have layout code ready
16 ,mBarDefaultWidth(20) // TODO: remove hard coding, when we have layout code ready
16 ,mLayoutSet(false)
17 ,mLayoutSet(false)
17 ,mLayoutDirty(true)
18 ,mLayoutDirty(true)
18 ,mSeparatorsEnabled(false)
19 ,mSeparatorsEnabled(false)
19 ,mSeries(series)
20 ,mSeries(series)
20 {
21 {
21 connect(series,SIGNAL(showToolTip(QPoint,QString)),this,SLOT(showToolTip(QPoint,QString)));
22 connect(series,SIGNAL(showToolTip(QPoint,QString)),this,SLOT(showToolTip(QPoint,QString)));
22 connect(series,SIGNAL(separatorsEnabled(bool)),this,SLOT(enableSeparators(bool)));
23 connect(series,SIGNAL(separatorsEnabled(bool)),this,SLOT(enableSeparators(bool)));
23 dataChanged();
24 dataChanged();
24 }
25 }
25
26
26 BarPresenterBase::~BarPresenterBase()
27 BarPresenterBase::~BarPresenterBase()
27 {
28 {
28 disconnect(this,SLOT(showToolTip(QPoint,QString)));
29 disconnect(this,SLOT(showToolTip(QPoint,QString)));
29 delete mSeries;
30 delete mSeries;
30 }
31 }
31
32
32 void BarPresenterBase::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
33 void BarPresenterBase::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
33 {
34 {
34 if (!mLayoutSet) {
35 if (!mLayoutSet) {
35 qDebug() << "BarPresenterBase::paint called without layout set. Aborting.";
36 qDebug() << "BarPresenterBase::paint called without layout set. Aborting.";
36 return;
37 return;
37 }
38 }
38 // if (mLayoutDirty) {
39 // if (mLayoutDirty) {
39 // Layout or data has changed. Need to redraw.
40 // Layout or data has changed. Need to redraw.
40 foreach(QGraphicsItem* i, childItems()) {
41 foreach(QGraphicsItem* i, childItems()) {
41 i->paint(painter,option,widget);
42 i->paint(painter,option,widget);
42 }
43 }
43 // }
44 // }
44 }
45 }
45
46
46 QRectF BarPresenterBase::boundingRect() const
47 QRectF BarPresenterBase::boundingRect() const
47 {
48 {
48 return QRectF(0,0,mWidth,mHeight);
49 return QRectF(0,0,mWidth,mHeight);
49 }
50 }
50
51
51 void BarPresenterBase::setBarWidth( int w )
52 void BarPresenterBase::setBarWidth( int w )
52 {
53 {
53 mBarDefaultWidth = w;
54 mBarDefaultWidth = w;
54 }
55 }
55
56
56 void BarPresenterBase::dataChanged()
57 void BarPresenterBase::dataChanged()
57 {
58 {
58 // TODO: performance optimizations. Do we really need to delete and create items every time data is changed or can we reuse them?
59 // TODO: performance optimizations. Do we really need to delete and create items every time data is changed or can we reuse them?
59 qDebug() << "datachanged";
60 // qDebug() << "datachanged";
60 // Delete old bars
61 // Delete old bars
61 foreach (QGraphicsItem* item, childItems()) {
62 foreach (QGraphicsItem* item, childItems()) {
62 delete item;
63 delete item;
63 }
64 }
64
65
65 mBars.clear();
66 mBars.clear();
66 mLabels.clear();
67 mLabels.clear();
67 mSeparators.clear();
68 mSeparators.clear();
68 mFloatingValues.clear();
69 mFloatingValues.clear();
69
70
70 // Create new graphic items for bars
71 // Create new graphic items for bars
71 for (int c=0; c<mSeries->categoryCount(); c++) {
72 for (int c=0; c<mSeries->categoryCount(); c++) {
73 BarCategory *category = mSeries->categoryObject(c);
72 for (int s=0; s<mSeries->barsetCount(); s++) {
74 for (int s=0; s<mSeries->barsetCount(); s++) {
73 QBarSet *set = mSeries->barsetAt(s);
75 QBarSet *set = mSeries->barsetAt(s);
74 Bar *bar = new Bar(this);
76 Bar *bar = new Bar(this);
75 childItems().append(bar);
77 childItems().append(bar);
76 mBars.append(bar);
78 mBars.append(bar);
77 connect(bar,SIGNAL(clicked()),set,SLOT(barClicked()));
79 connect(bar,SIGNAL(clicked()),set,SLOT(barClickedEvent()));
78 connect(bar,SIGNAL(hoverEntered(QPoint)),set,SLOT(barHoverEntered(QPoint)));
80 connect(bar,SIGNAL(rightClicked()),category,SLOT(barRightClickEvent()));
79 connect(bar,SIGNAL(hoverLeaved()),set,SLOT(barHoverLeaved()));
81 connect(bar,SIGNAL(hoverEntered(QPoint)),set,SLOT(barHoverEnterEvent(QPoint)));
82 connect(bar,SIGNAL(hoverLeaved()),set,SLOT(barHoverLeaveEvent()));
80 }
83 }
81 }
84 }
82
85
83 // Create labels
86 // Create labels
84 int count = mSeries->categoryCount();
87 int count = mSeries->categoryCount();
85 for (int i=0; i<count; i++) {
88 for (int i=0; i<count; i++) {
86 BarLabel* label = new BarLabel(this);
89 BarLabel* label = new BarLabel(this);
87 label->set(mSeries->label(i));
90 label->set(mSeries->categoryName(i));
88 childItems().append(label);
91 childItems().append(label);
89 mLabels.append(label);
92 mLabels.append(label);
90 }
93 }
91
94
92 // Create separators
95 // Create separators
93 count = mSeries->categoryCount() - 1; // There is one less separator than columns
96 count = mSeries->categoryCount() - 1; // There is one less separator than columns
94 for (int i=0; i<count; i++) {
97 for (int i=0; i<count; i++) {
95 Separator* sep = new Separator(this);
98 Separator* sep = new Separator(this);
96 sep->setColor(QColor(255,0,0,255)); // TODO: color for separations from theme
99 sep->setColor(QColor(255,0,0,255)); // TODO: color for separations from theme
97 sep->setVisible(mSeparatorsEnabled);
100 sep->setVisible(mSeparatorsEnabled);
98 childItems().append(sep);
101 childItems().append(sep);
99 mSeparators.append(sep);
102 mSeparators.append(sep);
100 }
103 }
101
104
102 // Create floating values
105 // Create floating values
103 for (int category=0; category<mSeries->categoryCount(); category++) {
106 for (int category=0; category<mSeries->categoryCount(); category++) {
104 for (int s=0; s<mSeries->barsetCount(); s++) {
107 for (int s=0; s<mSeries->barsetCount(); s++) {
105 QBarSet *set = mSeries->barsetAt(s);
108 QBarSet *set = mSeries->barsetAt(s);
106 BarValue *value = new BarValue(*set, this);
109 BarValue *value = new BarValue(*set, this);
107 childItems().append(value);
110 childItems().append(value);
108 mFloatingValues.append(value);
111 mFloatingValues.append(value);
109 connect(set,SIGNAL(toggleFloatingValues()),value,SLOT(toggleVisible()));
112 connect(set,SIGNAL(toggleFloatingValues()),value,SLOT(toggleVisible()));
110 }
113 }
111 }
114 }
112
115
113 // TODO: if (autolayout) { layoutChanged() } or something
116 // TODO: if (autolayout) { layoutChanged() } or something
114 mLayoutDirty = true;
117 mLayoutDirty = true;
115 }
118 }
116
119
117 //handlers
120 //handlers
118
121
119 void BarPresenterBase::handleModelChanged(int index)
122 void BarPresenterBase::handleModelChanged(int index)
120 {
123 {
121 // qDebug() << "BarPresenterBase::handleModelChanged" << index;
124 // qDebug() << "BarPresenterBase::handleModelChanged" << index;
122 dataChanged();
125 dataChanged();
123 }
126 }
124
127
125 void BarPresenterBase::handleDomainChanged(const Domain& domain)
128 void BarPresenterBase::handleDomainChanged(const Domain& domain)
126 {
129 {
127 // qDebug() << "BarPresenterBase::handleDomainChanged";
130 // qDebug() << "BarPresenterBase::handleDomainChanged";
128 // TODO: Figure out the use case for this.
131 // TODO: Figure out the use case for this.
129 // Affects the size of visible item, so layout is changed.
132 // Affects the size of visible item, so layout is changed.
130 // layoutChanged();
133 // layoutChanged();
131 }
134 }
132
135
133 void BarPresenterBase::handleGeometryChanged(const QRectF& rect)
136 void BarPresenterBase::handleGeometryChanged(const QRectF& rect)
134 {
137 {
135 mWidth = rect.width();
138 mWidth = rect.width();
136 mHeight = rect.height();
139 mHeight = rect.height();
137 layoutChanged();
140 layoutChanged();
138 mLayoutSet = true;
141 mLayoutSet = true;
139 setPos(rect.topLeft());
142 setPos(rect.topLeft());
140 }
143 }
141
144
142 void BarPresenterBase::showToolTip(QPoint pos, QString tip)
145 void BarPresenterBase::showToolTip(QPoint pos, QString tip)
143 {
146 {
144 // TODO: cool tooltip instead of default
147 // TODO: cool tooltip instead of default
145 QToolTip::showText(pos,tip);
148 QToolTip::showText(pos,tip);
146 }
149 }
147
150
148 void BarPresenterBase::enableSeparators(bool enabled)
151 void BarPresenterBase::enableSeparators(bool enabled)
149 {
152 {
150 for (int i=0; i<mSeparators.count(); i++) {
153 for (int i=0; i<mSeparators.count(); i++) {
151 mSeparators.at(i)->setVisible(enabled);
154 mSeparators.at(i)->setVisible(enabled);
152 }
155 }
153 mSeparatorsEnabled = enabled;
156 mSeparatorsEnabled = enabled;
154 }
157 }
155
158
156 #include "moc_barpresenterbase_p.cpp"
159 #include "moc_barpresenterbase_p.cpp"
157
160
158 QTCOMMERCIALCHART_END_NAMESPACE
161 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,230 +1,240
1 #include <QDebug>
1 #include <QDebug>
2 #include "qbarseries.h"
2 #include "qbarseries.h"
3 #include "qbarset.h"
3 #include "qbarset.h"
4 #include "barchartmodel_p.h"
4 #include "barchartmodel_p.h"
5
5 #include "barcategory_p.h"
6
6
7 QTCOMMERCIALCHART_BEGIN_NAMESPACE
7 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8
8
9 /*!
9 /*!
10 \class QBarSeries
10 \class QBarSeries
11 \brief part of QtCommercial chart API.
11 \brief part of QtCommercial chart API.
12
12
13 QBarSeries represents a series of data shown as bars. One QBarSeries can contain multible
13 QBarSeries represents a series of data shown as bars. One QBarSeries can contain multible
14 QBarSet data sets. QBarSeries groups the data from sets to categories, which are defined
14 QBarSet data sets. QBarSeries groups the data from sets to categories, which are defined
15 by QStringList.
15 by QStringList.
16
16
17 \mainclass
17 \mainclass
18
18
19 \sa QBarSet, QStackedBarSeries, QPercentBarSeries
19 \sa QBarSet, QStackedBarSeries, QPercentBarSeries
20 */
20 */
21
21
22 /*!
22 /*!
23 \fn virtual QSeriesType QBarSeries::type() const
23 \fn virtual QSeriesType QBarSeries::type() const
24 \brief Returns type of series.
24 \brief Returns type of series.
25 \sa QSeries, QSeriesType
25 \sa QSeries, QSeriesType
26 */
26 */
27 /*!
27 /*!
28 \fn void QBarSeries::changed(int index)
28 \fn void QBarSeries::changed(int index)
29 \brief \internal \a index
29 \brief \internal \a index
30 */
30 */
31 /*!
31 /*!
32 \fn void QBarSeries::floatingValuesEnabled(bool enabled)
32 \fn void QBarSeries::floatingValuesEnabled(bool enabled)
33 \brief \internal \a enabled
33 \brief \internal \a enabled
34 */
34 */
35 /*!
35 /*!
36 \fn void QBarSeries::toolTipEnabled(bool enabled)
36 \fn void QBarSeries::toolTipEnabled(bool enabled)
37 \brief \internal \a enabled
37 \brief \internal \a enabled
38 */
38 */
39 /*!
39 /*!
40 \fn void QBarSeries::separatorsEnabled(bool enabled)
40 \fn void QBarSeries::separatorsEnabled(bool enabled)
41 \brief \internal \a enabled
41 \brief \internal \a enabled
42 */
42 */
43 /*!
43 /*!
44 \fn void QBarSeries::showToolTip(QPoint pos, QString tip)
44 \fn void QBarSeries::showToolTip(QPoint pos, QString tip)
45 \brief \internal \a pos \a tip
45 \brief \internal \a pos \a tip
46 */
46 */
47
47
48 /*!
48 /*!
49 Constructs empty QBarSeries. Parameter \a categories defines the categories for chart.
49 Constructs empty QBarSeries. Parameter \a categories defines the categories for chart.
50 QBarSeries is QObject which is a child of a \a parent.
50 QBarSeries is QObject which is a child of a \a parent.
51 */
51 */
52 QBarSeries::QBarSeries(QStringList categories, QObject *parent)
52 QBarSeries::QBarSeries(QStringList categories, QObject *parent)
53 : QSeries(parent)
53 : QSeries(parent)
54 ,mModel(new BarChartModel(categories, this))
54 ,mModel(new BarChartModel(categories, this))
55 {
55 {
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 }
56 }
60 }
57
61
58 /*!
62 /*!
59 Adds a set of bars to series. Takes ownership of \a set
63 Adds a set of bars to series. Takes ownership of \a set
60 */
64 */
61 void QBarSeries::addBarSet(QBarSet *set)
65 void QBarSeries::addBarSet(QBarSet *set)
62 {
66 {
63 mModel->addBarSet(set);
67 mModel->addBarSet(set);
64 }
68 }
65
69
66 /*!
70 /*!
67 Removes a set of bars from series. Releases ownership of \a set. Doesnt delete \a set.
71 Removes a set of bars from series. Releases ownership of \a set. Doesnt delete \a set.
68 */
72 */
69 void QBarSeries::removeBarSet(QBarSet *set)
73 void QBarSeries::removeBarSet(QBarSet *set)
70 {
74 {
71 mModel->removeBarSet(set);
75 mModel->removeBarSet(set);
72 }
76 }
73
77
74 /*!
78 /*!
75 Returns number of sets in series.
79 Returns number of sets in series.
76 */
80 */
77 int QBarSeries::barsetCount()
81 int QBarSeries::barsetCount()
78 {
82 {
79 return mModel->barsetCount();
83 return mModel->barsetCount();
80 }
84 }
81
85
82 /*!
86 /*!
83 Returns number of categories in series
87 Returns number of categories in series
84 */
88 */
85 int QBarSeries::categoryCount()
89 int QBarSeries::categoryCount()
86 {
90 {
87 return mModel->categoryCount();
91 return mModel->categoryCount();
88 }
92 }
89
93
90 /*!
94 /*!
91 Returns a list of sets in series. Keeps ownership of sets.
95 Returns a list of sets in series. Keeps ownership of sets.
92 */
96 */
93 QList<QBarSet*> QBarSeries::barSets()
97 QList<QBarSet*> QBarSeries::barSets()
94 {
98 {
95 return mModel->barSets();
99 return mModel->barSets();
96 }
100 }
97
101
98 /*!
102 /*!
99 \internal \a index
103 \internal \a index
100 */
104 */
101 QBarSet* QBarSeries::barsetAt(int index)
105 QBarSet* QBarSeries::barsetAt(int index)
102 {
106 {
103 return mModel->setAt(index);
107 return mModel->setAt(index);
104 }
108 }
105
109
106 /*!
110 /*!
107 Returns legend of series.
111 Returns legend of series.
108 */
112 */
109 QList<QSeries::Legend> QBarSeries::legend()
113 QList<QSeries::Legend> QBarSeries::legend()
110 {
114 {
111 return mModel->legend();
115 return mModel->legend();
112 }
116 }
113
117
114 /*!
118 /*!
115 \internal \a category
119 \internal \a category
116 */
120 */
117 QString QBarSeries::label(int category)
121 QString QBarSeries::categoryName(int category)
118 {
122 {
119 return mModel->label(category);
123 return mModel->categoryName(category);
120 }
124 }
121
125
122 /*!
126 /*!
123 Enables or disables floating values depending on parameter \a enabled.
127 Enables or disables floating values depending on parameter \a enabled.
124 Floating values are bar values, that are displayed on top of each bar.
128 Floating values are bar values, that are displayed on top of each bar.
125 Calling without parameter \a enabled, enables the floating values
129 Calling without parameter \a enabled, enables the floating values
126 */
130 */
127 void QBarSeries::setFloatingValuesEnabled(bool enabled)
131 void QBarSeries::setFloatingValuesEnabled(bool enabled)
128 {
132 {
129 if (enabled) {
133 if (enabled) {
130 for (int i=0; i<mModel->barsetCount(); i++) {
134 for (int i=0; i<mModel->barsetCount(); i++) {
131 QBarSet *set = mModel->setAt(i);
135 QBarSet *set = mModel->setAt(i);
132 connect(set,SIGNAL(clicked()),set,SIGNAL(toggleFloatingValues()));
136 connect(set,SIGNAL(clicked()),set,SIGNAL(toggleFloatingValues()));
133 }
137 }
134 } else {
138 } else {
135 for (int i=0; i<mModel->barsetCount(); i++) {
139 for (int i=0; i<mModel->barsetCount(); i++) {
136 QBarSet *set = mModel->setAt(i);
140 QBarSet *set = mModel->setAt(i);
137 disconnect(set,SIGNAL(clicked()),set,SIGNAL(toggleFloatingValues()));
141 disconnect(set,SIGNAL(clicked()),set,SIGNAL(toggleFloatingValues()));
138 }
142 }
139 }
143 }
140 }
144 }
141
145
142 /*!
146 /*!
143 Enables or disables tooltip depending on parameter \a enabled.
147 Enables or disables tooltip depending on parameter \a enabled.
144 Tooltip shows the name of set, when mouse is hovering on top of bar.
148 Tooltip shows the name of set, when mouse is hovering on top of bar.
145 Calling without parameter \a enabled, enables the tooltip
149 Calling without parameter \a enabled, enables the tooltip
146 */
150 */
147 void QBarSeries::setToolTipEnabled(bool enabled)
151 void QBarSeries::setToolTipEnabled(bool enabled)
148 {
152 {
149 if (enabled) {
153 if (enabled) {
150 for (int i=0; i<mModel->barsetCount(); i++) {
154 for (int i=0; i<mModel->barsetCount(); i++) {
151 QBarSet *set = mModel->setAt(i);
155 QBarSet *set = mModel->setAt(i);
152 connect(set,SIGNAL(showToolTip(QPoint,QString)),this,SIGNAL(showToolTip(QPoint,QString)));
156 connect(set,SIGNAL(showToolTip(QPoint,QString)),this,SIGNAL(showToolTip(QPoint,QString)));
153 }
157 }
154 } else {
158 } else {
155 for (int i=0; i<mModel->barsetCount(); i++) {
159 for (int i=0; i<mModel->barsetCount(); i++) {
156 QBarSet *set = mModel->setAt(i);
160 QBarSet *set = mModel->setAt(i);
157 disconnect(set,SIGNAL(showToolTip(QPoint,QString)),this,SIGNAL(showToolTip(QPoint,QString)));
161 disconnect(set,SIGNAL(showToolTip(QPoint,QString)),this,SIGNAL(showToolTip(QPoint,QString)));
158 }
162 }
159 }
163 }
160 }
164 }
161
165
162 /*!
166 /*!
163 Enables or disables separators depending on parameter \a enabled.
167 Enables or disables separators depending on parameter \a enabled.
164 Separators are visual elements that are drawn between categories.
168 Separators are visual elements that are drawn between categories.
165 Calling without parameter \a enabled, enables the separators
169 Calling without parameter \a enabled, enables the separators
166 */
170 */
167 void QBarSeries::setSeparatorsEnabled(bool enabled)
171 void QBarSeries::setSeparatorsEnabled(bool enabled)
168 {
172 {
169 emit separatorsEnabled(enabled);
173 emit separatorsEnabled(enabled);
170 }
174 }
171
175
172 /*!
176 /*!
173 \internal
177 \internal
174 */
178 */
175 qreal QBarSeries::min()
179 qreal QBarSeries::min()
176 {
180 {
177 return mModel->min();
181 return mModel->min();
178 }
182 }
179
183
180 /*!
184 /*!
181 \internal
185 \internal
182 */
186 */
183 qreal QBarSeries::max()
187 qreal QBarSeries::max()
184 {
188 {
185 return mModel->max();
189 return mModel->max();
186 }
190 }
187
191
188 /*!
192 /*!
189 \internal \a set \a category
193 \internal \a set \a category
190 */
194 */
191 qreal QBarSeries::valueAt(int set, int category)
195 qreal QBarSeries::valueAt(int set, int category)
192 {
196 {
193 return mModel->valueAt(set,category);
197 return mModel->valueAt(set,category);
194 }
198 }
195
199
196 /*!
200 /*!
197 \internal \a set \a category
201 \internal \a set \a category
198 */
202 */
199 qreal QBarSeries::percentageAt(int set, int category)
203 qreal QBarSeries::percentageAt(int set, int category)
200 {
204 {
201 return mModel->percentageAt(set,category);
205 return mModel->percentageAt(set,category);
202 }
206 }
203
207
204 /*!
208 /*!
205 \internal \a category
209 \internal \a category
206 */
210 */
207 qreal QBarSeries::categorySum(int category)
211 qreal QBarSeries::categorySum(int category)
208 {
212 {
209 return mModel->categorySum(category);
213 return mModel->categorySum(category);
210 }
214 }
211
215
212 /*!
216 /*!
213 \internal
217 \internal
214 */
218 */
215 qreal QBarSeries::maxCategorySum()
219 qreal QBarSeries::maxCategorySum()
216 {
220 {
217 return mModel->maxCategorySum();
221 return mModel->maxCategorySum();
218 }
222 }
219
223
220 /*!
224 /*!
221 \internal
225 \internal
222 */
226 */
223 BarChartModel& QBarSeries::model()
227 BarChartModel& QBarSeries::model()
224 {
228 {
225 return *mModel;
229 return *mModel;
226 }
230 }
227
231
232 BarCategory* QBarSeries::categoryObject(int category)
233 {
234 return mModel->categoryObject(category);
235 }
236
237
228 #include "moc_qbarseries.cpp"
238 #include "moc_qbarseries.cpp"
229
239
230 QTCOMMERCIALCHART_END_NAMESPACE
240 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,65 +1,68
1 #ifndef BARSERIES_H
1 #ifndef BARSERIES_H
2 #define BARSERIES_H
2 #define BARSERIES_H
3
3
4 #include "qseries.h"
4 #include "qseries.h"
5 #include <QStringList>
5 #include <QStringList>
6
6
7 QTCOMMERCIALCHART_BEGIN_NAMESPACE
7 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8
8
9 class QBarSet;
9 class QBarSet;
10 class BarChartModel;
10 class BarChartModel;
11 class BarCategory;
11
12
12 // Container for series
13 // Container for series
13 class QTCOMMERCIALCHART_EXPORT QBarSeries : public QSeries
14 class QTCOMMERCIALCHART_EXPORT QBarSeries : public QSeries
14 {
15 {
15 Q_OBJECT
16 Q_OBJECT
16 public:
17 public:
17 QBarSeries(QStringList categories, QObject* parent=0);
18 QBarSeries(QStringList categories, QObject* parent=0);
18
19
19 virtual QSeriesType type() const { return QSeries::SeriesTypeBar; }
20 virtual QSeriesType type() const { return QSeries::SeriesTypeBar; }
20
21
21 void addBarSet(QBarSet *set); // Takes ownership of set
22 void addBarSet(QBarSet *set); // Takes ownership of set
22 void removeBarSet(QBarSet *set); // Releases ownership, doesn't delete set
23 void removeBarSet(QBarSet *set); // Releases ownership, doesn't delete set
23 int barsetCount();
24 int barsetCount();
24 int categoryCount();
25 int categoryCount();
25 QList<QBarSet*> barSets();
26 QList<QBarSet*> barSets();
26 QList<QSeries::Legend> legend();
27 QList<QSeries::Legend> legend();
27
28
28 public:
29 public:
29 // TODO: Functions below this are not part of api and will be moved
30 // TODO: Functions below this are not part of api and will be moved
30 // to private implementation, when we start using it
31 // to private implementation, when we start using it
31 // TODO: TO PIMPL --->
32 // TODO: TO PIMPL --->
32 QBarSet *barsetAt(int index);
33 QBarSet* barsetAt(int index);
33 QString label(int category);
34 QString categoryName(int category);
34 qreal min();
35 qreal min();
35 qreal max();
36 qreal max();
36 qreal valueAt(int set, int category);
37 qreal valueAt(int set, int category);
37 qreal percentageAt(int set, int category);
38 qreal percentageAt(int set, int category);
38 qreal categorySum(int category);
39 qreal categorySum(int category);
39 qreal maxCategorySum();
40 qreal maxCategorySum();
40 BarChartModel& model();
41 BarChartModel& model();
42 BarCategory* categoryObject(int category);
41 // <--- TO PIMPL
43 // <--- TO PIMPL
42
44
43 signals:
45 signals:
44 void changed(int index);
46 void changed(int index);
47 void categoryRightClicked(QString category);
45
48
46 // TODO: internal signals, these to private implementation.
49 // TODO: internal signals, these to private implementation.
47 // TODO: TO PIMPL --->
50 // TODO: TO PIMPL --->
48 void floatingValuesEnabled(bool enabled);
51 void floatingValuesEnabled(bool enabled);
49 void toolTipEnabled(bool enabled);
52 void toolTipEnabled(bool enabled);
50 void separatorsEnabled(bool enabled);
53 void separatorsEnabled(bool enabled);
51 void showToolTip(QPoint pos, QString tip);
54 void showToolTip(QPoint pos, QString tip);
52 // <--- TO PIMPL
55 // <--- TO PIMPL
53
56
54 public Q_SLOTS:
57 public Q_SLOTS:
55 void setFloatingValuesEnabled(bool enabled=true); // enables floating values on top of bars
58 void setFloatingValuesEnabled(bool enabled=true); // enables floating values on top of bars
56 void setToolTipEnabled(bool enabled=true); // enables tooltips
59 void setToolTipEnabled(bool enabled=true); // enables tooltips
57 void setSeparatorsEnabled(bool enabled=true); // enables separators between categories
60 void setSeparatorsEnabled(bool enabled=true); // enables separators between categories
58
61
59 protected:
62 protected:
60 BarChartModel* mModel;
63 BarChartModel* mModel;
61 };
64 };
62
65
63 QTCOMMERCIALCHART_END_NAMESPACE
66 QTCOMMERCIALCHART_END_NAMESPACE
64
67
65 #endif // BARSERIES_H
68 #endif // BARSERIES_H
@@ -1,167 +1,162
1 #include "qbarset.h"
1 #include "qbarset.h"
2 #include <QDebug>
2 #include <QDebug>
3 #include <QToolTip>
3 #include <QToolTip>
4
4
5 QTCOMMERCIALCHART_BEGIN_NAMESPACE
5 QTCOMMERCIALCHART_BEGIN_NAMESPACE
6
6
7 /*!
7 /*!
8 \class QBarSet
8 \class QBarSet
9 \brief part of QtCommercial chart API.
9 \brief part of QtCommercial chart API.
10
10
11 QBarSet represents one set of bars. Set of bars contains one data value for each category.
11 QBarSet represents one set of bars. Set of bars contains one data value for each category.
12 First value of set is assumed to belong to first category, second to second category and so on.
12 First value of set is assumed to belong to first category, second to second category and so on.
13 If set has fewer values than there are categories, then the missing values are assumed to be
13 If set has fewer values than there are categories, then the missing values are assumed to be
14 at the end of set. For missing values in middle of a set, numerical value of zero is used.
14 at the end of set. For missing values in middle of a set, numerical value of zero is used.
15
15
16 \mainclass
16 \mainclass
17
17
18 \sa QBarSeries, QStackedBarSeries, QPercentBarSeries
18 \sa QBarSeries, QStackedBarSeries, QPercentBarSeries
19 */
19 */
20
20
21 /*!
21 /*!
22 \fn void QBarSet::clicked()
22 \fn void QBarSet::clicked()
23 \brief signals that set has been clicked
23 \brief signals that set has been clicked
24 */
24 */
25 /*!
25 /*!
26 \fn void QBarSet::hoverEnter(QPoint pos)
26 \fn void QBarSet::hoverEnter(QPoint pos)
27 \brief signals that mouse has entered over the set at position \a pos.
27 \brief signals that mouse has entered over the set at position \a pos.
28 */
28 */
29 /*!
29 /*!
30 \fn void QBarSet::hoverLeave()
30 \fn void QBarSet::hoverLeave()
31 \brief signals that mouse has left from the set.
31 \brief signals that mouse has left from the set.
32 */
32 */
33 /*!
33 /*!
34 \fn void QBarSet::toggleFloatingValues()
34 \fn void QBarSet::toggleFloatingValues()
35 \brief \internal
35 \brief \internal
36 */
36 */
37 /*!
37 /*!
38 \fn void QBarSet::showToolTip(QPoint pos, QString tip)
38 \fn void QBarSet::showToolTip(QPoint pos, QString tip)
39 \brief \internal \a pos \a tip
39 \brief \internal \a pos \a tip
40 */
40 */
41
41
42
42
43 /*!
43 /*!
44 Constructs QBarSet with a name of \a name and with parent of \a parent
44 Constructs QBarSet with a name of \a name and with parent of \a parent
45 */
45 */
46 QBarSet::QBarSet(QString name, QObject *parent)
46 QBarSet::QBarSet(QString name, QObject *parent)
47 : QObject(parent)
47 : QObject(parent)
48 ,mName(name)
48 ,mName(name)
49 {
49 {
50 }
50 }
51
51
52 /*!
52 /*!
53 Sets new \a name for set.
53 Sets new \a name for set.
54 */
54 */
55 void QBarSet::setName(QString name)
55 void QBarSet::setName(QString name)
56 {
56 {
57 mName = name;
57 mName = name;
58 }
58 }
59
59
60 /*!
60 /*!
61 Returns name of the set.
61 Returns name of the set.
62 */
62 */
63 QString QBarSet::name()
63 QString QBarSet::name()
64 {
64 {
65 return mName;
65 return mName;
66 }
66 }
67
67
68 /*!
68 /*!
69 Appends new value \a value to the end of set.
69 Appends new value \a value to the end of set.
70 */
70 */
71 QBarSet& QBarSet::operator << (const qreal &value)
71 QBarSet& QBarSet::operator << (const qreal &value)
72 {
72 {
73 mValues.append(value);
73 mValues.append(value);
74 return *this;
74 return *this;
75 }
75 }
76
76
77 /*!
77 /*!
78 Returns count of values in set.
78 Returns count of values in set.
79 */
79 */
80 int QBarSet::count()
80 int QBarSet::count()
81 {
81 {
82 return mValues.count();
82 return mValues.count();
83 }
83 }
84
84
85 /*!
85 /*!
86 Returns value of set indexed by \a index
86 Returns value of set indexed by \a index
87 */
87 */
88 qreal QBarSet::valueAt(int index)
88 qreal QBarSet::valueAt(int index)
89 {
89 {
90 return mValues.at(index);
90 return mValues.at(index);
91 }
91 }
92
92
93 /*!
93 /*!
94 Sets a new value \a value to set, indexed by \a index
94 Sets a new value \a value to set, indexed by \a index
95 */
95 */
96 void QBarSet::setValue(int index, qreal value)
96 void QBarSet::setValue(int index, qreal value)
97 {
97 {
98 mValues.replace(index,value);
98 mValues.replace(index,value);
99 }
99 }
100
100
101 /*!
101 /*!
102 Sets pen for set. Bars of this set are drawn using \a pen
102 Sets pen for set. Bars of this set are drawn using \a pen
103 */
103 */
104 void QBarSet::setPen(QPen pen)
104 void QBarSet::setPen(QPen pen)
105 {
105 {
106 mPen = pen;
106 mPen = pen;
107 }
107 }
108
108
109 /*!
109 /*!
110 Returns pen of the set.
110 Returns pen of the set.
111 */
111 */
112 QPen QBarSet::pen()
112 QPen QBarSet::pen()
113 {
113 {
114 return mPen;
114 return mPen;
115 }
115 }
116
116
117 /*!
117 /*!
118 Sets brush for the set. Bars of this set are drawn using \a brush
118 Sets brush for the set. Bars of this set are drawn using \a brush
119 */
119 */
120 void QBarSet::setBrush(QBrush brush)
120 void QBarSet::setBrush(QBrush brush)
121 {
121 {
122 mBrush = brush;
122 mBrush = brush;
123 }
123 }
124
124
125 /*!
125 /*!
126 Returns brush of the set.
126 Returns brush of the set.
127 */
127 */
128 QBrush QBarSet::brush()
128 QBrush QBarSet::brush()
129 {
129 {
130 return mBrush;
130 return mBrush;
131 }
131 }
132
132
133 /*!
133 /*!
134 \internal
134 \internal
135 */
135 */
136 void QBarSet::barClicked()
136 void QBarSet::barClickedEvent()
137 {
137 {
138 // qDebug() << "QBarset::barClicked" << this;
139 // Some bar of this set has been clicked
138 // Some bar of this set has been clicked
140 // TODO: What happens then?
139 // TODO: What happens then?
141 emit clicked(); // Notify that set has been clicked
140 emit clicked(); // Notify that set has been clicked
142 }
141 }
143
142
144 /*!
143 /*!
145 \internal \a pos
144 \internal \a pos
146 */
145 */
147 void QBarSet::barHoverEntered(QPoint pos)
146 void QBarSet::barHoverEnterEvent(QPoint pos)
148 {
147 {
149 emit showToolTip(pos, mName);
148 emit showToolTip(pos, mName);
150 emit hoverEnter(pos);
149 emit hoverEnter(pos);
151 }
150 }
152
151
153 /*!
152 /*!
154 \internal
153 \internal
155 */
154 */
156 void QBarSet::barHoverLeaved()
155 void QBarSet::barHoverLeaveEvent()
157 {
156 {
158 // qDebug() << "QBarset::barHoverLeaved" << this;
159 // if (mToolTipEnabled) {
160 // TODO: do what?
161 // }
162 // Emit signal to user of charts
157 // Emit signal to user of charts
163 emit hoverLeave();
158 emit hoverLeave();
164 }
159 }
165
160
166 #include "moc_qbarset.cpp"
161 #include "moc_qbarset.cpp"
167 QTCOMMERCIALCHART_END_NAMESPACE
162 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,60 +1,60
1 #ifndef QBARSET_H
1 #ifndef QBARSET_H
2 #define QBARSET_H
2 #define QBARSET_H
3
3
4 #include <qchartglobal.h>
4 #include <qchartglobal.h>
5 #include <QPen>
5 #include <QPen>
6 #include <QBrush>
6 #include <QBrush>
7
7
8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9
9
10 class QTCOMMERCIALCHART_EXPORT QBarSet : public QObject
10 class QTCOMMERCIALCHART_EXPORT QBarSet : public QObject
11 {
11 {
12 Q_OBJECT
12 Q_OBJECT
13 public:
13 public:
14 QBarSet(QString name, QObject *parent = 0);
14 QBarSet(QString name, QObject *parent = 0);
15
15
16 void setName(QString name);
16 void setName(QString name);
17 QString name();
17 QString name();
18 QBarSet& operator << (const qreal &value); // appends new value to set
18 QBarSet& operator << (const qreal &value); // appends new value to set
19
19
20 int count(); // count of values in set
20 int count(); // count of values in set
21 qreal valueAt(int index); // for modifying individual values
21 qreal valueAt(int index); // for modifying individual values
22 void setValue(int index, qreal value); // setter for individual value
22 void setValue(int index, qreal value); // setter for individual value
23
23
24 void setPen(QPen pen);
24 void setPen(QPen pen);
25 QPen pen();
25 QPen pen();
26
26
27 void setBrush(QBrush brush);
27 void setBrush(QBrush brush);
28 QBrush brush();
28 QBrush brush();
29
29
30 Q_SIGNALS:
30 Q_SIGNALS:
31 void clicked(); // Clicked and hover signals exposed to user
31 void clicked(); // Clicked and hover signals exposed to user
32 void hoverEnter(QPoint pos);
32 void hoverEnter(QPoint pos);
33 void hoverLeave();
33 void hoverLeave();
34
34
35 // TODO: Expose this to user or not?
35 // TODO: Expose this to user or not?
36 // TODO: TO PIMPL --->
36 // TODO: TO PIMPL --->
37 void toggleFloatingValues();
37 void toggleFloatingValues();
38 void showToolTip(QPoint pos, QString tip); // Private signal
38 void showToolTip(QPoint pos, QString tip); // Private signal
39 // <--- TO PIMPL
39 // <--- TO PIMPL
40
40
41 public Q_SLOTS:
41 public Q_SLOTS:
42 // These are for internal communication
42 // These are for internal communication
43 // TODO: TO PIMPL --->
43 // TODO: TO PIMPL --->
44 void barClicked();
44 void barClickedEvent();
45 void barHoverEntered(QPoint pos);
45 void barHoverEnterEvent(QPoint pos);
46 void barHoverLeaved();
46 void barHoverLeaveEvent();
47 // <--- TO PIMPL
47 // <--- TO PIMPL
48
48
49 private:
49 private:
50
50
51 QString mName;
51 QString mName;
52 QList<qreal> mValues;
52 QList<qreal> mValues;
53 QPen mPen;
53 QPen mPen;
54 QBrush mBrush;
54 QBrush mBrush;
55
55
56 };
56 };
57
57
58 QTCOMMERCIALCHART_END_NAMESPACE
58 QTCOMMERCIALCHART_END_NAMESPACE
59
59
60 #endif // QBARSET_H
60 #endif // QBARSET_H
@@ -1,379 +1,404
1 #include "chartdataset_p.h"
1 #include "chartdataset_p.h"
2 #include "qchartaxis.h"
2 #include "qchartaxis.h"
3 //series
3 //series
4 #include "qlineseries.h"
4 #include "qlineseries.h"
5 #include "qbarseries.h"
5 #include "qbarseries.h"
6 #include "qstackedbarseries.h"
6 #include "qstackedbarseries.h"
7 #include "qpercentbarseries.h"
7 #include "qpercentbarseries.h"
8 #include "qpieseries.h"
8 #include "qpieseries.h"
9 #include "qscatterseries.h"
9 #include "qscatterseries.h"
10
10
11 QTCOMMERCIALCHART_BEGIN_NAMESPACE
11 QTCOMMERCIALCHART_BEGIN_NAMESPACE
12
12
13 ChartDataSet::ChartDataSet(QObject *parent):QObject(parent),
13 ChartDataSet::ChartDataSet(QObject *parent):QObject(parent),
14 m_axisX(new QChartAxis(this)),
14 m_axisX(new QChartAxis(this)),
15 m_axisY(new QChartAxis(this)),
15 m_axisY(new QChartAxis(this)),
16 m_domainIndex(0),
16 m_domainIndex(0),
17 m_axisXInitialized(false)
17 m_axisXInitialized(false)
18 {
18 {
19 }
19 }
20
20
21 ChartDataSet::~ChartDataSet()
21 ChartDataSet::~ChartDataSet()
22 {
22 {
23 // TODO Auto-generated destructor stub
23 // TODO Auto-generated destructor stub
24 }
24 }
25
25
26 const Domain ChartDataSet::domain(QChartAxis *axisY) const
26 const Domain ChartDataSet::domain(QChartAxis *axisY) const
27 {
27 {
28 int i = m_domainMap.count(axisY);
28 int i = m_domainMap.count(axisY);
29 if(i == 0){
29 if(i == 0){
30 return Domain();
30 return Domain();
31 }
31 }
32 i = i - m_domainIndex -1;
32 i = i - m_domainIndex -1;
33 return m_domainMap.values(axisY).at(i);
33 return m_domainMap.values(axisY).at(i);
34 }
34 }
35
35
36 void ChartDataSet::addSeries(QSeries* series, QChartAxis *axisY)
36 void ChartDataSet::addSeries(QSeries* series, QChartAxis *axisY)
37 {
37 {
38 // TODO: we should check the series not already added
38 // TODO: we should check the series not already added
39
39
40 series->setParent(this); // take ownership
40 series->setParent(this); // take ownership
41 clearDomains();
41 clearDomains();
42
42
43 if(axisY==0) axisY = m_axisY;
43 if(axisY==0) axisY = m_axisY;
44 axisY->setParent(this); // take ownership
44 axisY->setParent(this); // take ownership
45
45
46 QList<QSeries*> seriesList = m_seriesMap.values(axisY);
46 QList<QSeries*> seriesList = m_seriesMap.values(axisY);
47
47
48 QList<Domain> domainList = m_domainMap.values(axisY);
48 QList<Domain> domainList = m_domainMap.values(axisY);
49
49
50 Q_ASSERT(domainList.size()<=1);
50 Q_ASSERT(domainList.size()<=1);
51
51
52 Domain domain;
52 Domain domain;
53
53
54 if(domainList.size()>0) domain = domainList.at(0);
54 if(domainList.size()>0) domain = domainList.at(0);
55
55
56 switch(series->type())
56 switch(series->type())
57 {
57 {
58 case QSeries::SeriesTypeLine: {
58 case QSeries::SeriesTypeLine: {
59
59
60 QLineSeries* xyseries = static_cast<QLineSeries*>(series);
60 QLineSeries* xyseries = static_cast<QLineSeries*>(series);
61
61
62 for (int i = 0; i < xyseries->count(); i++)
62 for (int i = 0; i < xyseries->count(); i++)
63 {
63 {
64 qreal x = xyseries->x(i);
64 qreal x = xyseries->x(i);
65 qreal y = xyseries->y(i);
65 qreal y = xyseries->y(i);
66 domain.m_minX = qMin(domain.m_minX,x);
66 domain.m_minX = qMin(domain.m_minX,x);
67 domain.m_minY = qMin(domain.m_minY,y);
67 domain.m_minY = qMin(domain.m_minY,y);
68 domain.m_maxX = qMax(domain.m_maxX,x);
68 domain.m_maxX = qMax(domain.m_maxX,x);
69 domain.m_maxY = qMax(domain.m_maxY,y);
69 domain.m_maxY = qMax(domain.m_maxY,y);
70 }
70 }
71 break;
71 break;
72 }
72 }
73 case QSeries::SeriesTypeBar: {
73 case QSeries::SeriesTypeBar: {
74 qDebug() << "QChartSeries::SeriesTypeBar";
74 qDebug() << "QChartSeries::SeriesTypeBar";
75 QBarSeries* barSeries = static_cast<QBarSeries*>(series);
75 QBarSeries* barSeries = static_cast<QBarSeries*>(series);
76 qreal x = barSeries->categoryCount();
76 qreal x = barSeries->categoryCount();
77 qreal y = barSeries->max();
77 qreal y = barSeries->max();
78 domain.m_minX = qMin(domain.m_minX,x);
78 domain.m_minX = qMin(domain.m_minX,x);
79 domain.m_minY = qMin(domain.m_minY,y);
79 domain.m_minY = qMin(domain.m_minY,y);
80 domain.m_maxX = qMax(domain.m_maxX,x);
80 domain.m_maxX = qMax(domain.m_maxX,x);
81 domain.m_maxY = qMax(domain.m_maxY,y);
81 domain.m_maxY = qMax(domain.m_maxY,y);
82 break;
82 break;
83 }
83 }
84 case QSeries::SeriesTypeStackedBar: {
84 case QSeries::SeriesTypeStackedBar: {
85 qDebug() << "QChartSeries::SeriesTypeStackedBar";
85 qDebug() << "QChartSeries::SeriesTypeStackedBar";
86
86
87 QStackedBarSeries* stackedBarSeries = static_cast<QStackedBarSeries*>(series);
87 QStackedBarSeries* stackedBarSeries = static_cast<QStackedBarSeries*>(series);
88 qreal x = stackedBarSeries->categoryCount();
88 qreal x = stackedBarSeries->categoryCount();
89 qreal y = stackedBarSeries->maxCategorySum();
89 qreal y = stackedBarSeries->maxCategorySum();
90 domain.m_minX = qMin(domain.m_minX,x);
90 domain.m_minX = qMin(domain.m_minX,x);
91 domain.m_minY = qMin(domain.m_minY,y);
91 domain.m_minY = qMin(domain.m_minY,y);
92 domain.m_maxX = qMax(domain.m_maxX,x);
92 domain.m_maxX = qMax(domain.m_maxX,x);
93 domain.m_maxY = qMax(domain.m_maxY,y);
93 domain.m_maxY = qMax(domain.m_maxY,y);
94 break;
94 break;
95 }
95 }
96 case QSeries::SeriesTypePercentBar: {
96 case QSeries::SeriesTypePercentBar: {
97 qDebug() << "QChartSeries::SeriesTypePercentBar";
97 qDebug() << "QChartSeries::SeriesTypePercentBar";
98
98
99 QPercentBarSeries* percentBarSeries = static_cast<QPercentBarSeries*>(series);
99 QPercentBarSeries* percentBarSeries = static_cast<QPercentBarSeries*>(series);
100 qreal x = percentBarSeries->categoryCount();
100 qreal x = percentBarSeries->categoryCount();
101 domain.m_minX = qMin(domain.m_minX,x);
101 domain.m_minX = qMin(domain.m_minX,x);
102 domain.m_minY = 0;
102 domain.m_minY = 0;
103 domain.m_maxX = qMax(domain.m_maxX,x);
103 domain.m_maxX = qMax(domain.m_maxX,x);
104 domain.m_maxY = 100;
104 domain.m_maxY = 100;
105 break;
105 break;
106 }
106 }
107
107
108 case QSeries::SeriesTypePie: {
108 case QSeries::SeriesTypePie: {
109 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
109 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
110 // TODO: domain stuff
110 // TODO: domain stuff
111 break;
111 break;
112 }
112 }
113
113
114 case QSeries::SeriesTypeScatter: {
114 case QSeries::SeriesTypeScatter: {
115 QScatterSeries *scatterSeries = qobject_cast<QScatterSeries *>(series);
115 QScatterSeries *scatterSeries = qobject_cast<QScatterSeries *>(series);
116 Q_ASSERT(scatterSeries);
116 Q_ASSERT(scatterSeries);
117 foreach (QPointF point, scatterSeries->data()) {
117 foreach (QPointF point, scatterSeries->data()) {
118 domain.m_minX = qMin(domain.m_minX, point.x());
118 domain.m_minX = qMin(domain.m_minX, point.x());
119 domain.m_maxX = qMax(domain.m_maxX, point.x());
119 domain.m_maxX = qMax(domain.m_maxX, point.x());
120 domain.m_minY = qMin(domain.m_minY, point.y());
120 domain.m_minY = qMin(domain.m_minY, point.y());
121 domain.m_maxY = qMax(domain.m_maxY, point.y());
121 domain.m_maxY = qMax(domain.m_maxY, point.y());
122 }
122 }
123 break;
123 break;
124 }
124 }
125
125
126 default: {
126 default: {
127 qDebug()<<__FUNCTION__<<"type" << series->type()<<"not supported";
127 qDebug()<<__FUNCTION__<<"type" << series->type()<<"not supported";
128 return;
128 return;
129 break;
129 break;
130 }
130 }
131
131
132 }
132 }
133
133
134 if(!m_domainMap.contains(axisY))
134 if(!m_domainMap.contains(axisY))
135 {
135 {
136 emit axisAdded(axisY);
136 emit axisAdded(axisY);
137 QObject::connect(axisY,SIGNAL(rangeChanged(QChartAxis*)),this,SLOT(handleRangeChanged(QChartAxis*)));
137 QObject::connect(axisY,SIGNAL(rangeChanged(QChartAxis*)),this,SLOT(handleRangeChanged(QChartAxis*)));
138 QObject::connect(axisY,SIGNAL(ticksChanged(QChartAxis*)),this,SLOT(handleTickChanged(QChartAxis*)));
138 QObject::connect(axisY,SIGNAL(ticksChanged(QChartAxis*)),this,SLOT(handleTickChanged(QChartAxis*)));
139 }
139 }
140
140
141 if(!m_axisXInitialized)
141 if(!m_axisXInitialized)
142 {
142 {
143 emit axisAdded(axisX());
143 emit axisAdded(axisX());
144 QObject::connect(axisX(),SIGNAL(rangeChanged(QChartAxis*)),this,SLOT(handleRangeChanged(QChartAxis*)));
144 QObject::connect(axisX(),SIGNAL(rangeChanged(QChartAxis*)),this,SLOT(handleRangeChanged(QChartAxis*)));
145 QObject::connect(axisX(),SIGNAL(ticksChanged(QChartAxis*)),this,SLOT(handleTickChanged(QChartAxis*)));
145 QObject::connect(axisX(),SIGNAL(ticksChanged(QChartAxis*)),this,SLOT(handleTickChanged(QChartAxis*)));
146 m_axisXInitialized=true;
146 m_axisXInitialized=true;
147 }
147 }
148
148
149 m_domainMap.replace(axisY,domain);
149 m_domainMap.replace(axisY,domain);
150 m_seriesMap.insert(axisY,series);
150 m_seriesMap.insert(axisY,series);
151 emit seriesAdded(series);
151 emit seriesAdded(series);
152 setDomain(m_domainIndex);
152 setDomain(m_domainIndex,axisY);
153
153
154 }
154 }
155
155
156 void ChartDataSet::removeSeries(QSeries* series)
156 void ChartDataSet::removeSeries(QSeries* series)
157 {
157 {
158 QList<QChartAxis*> keys = m_seriesMap.uniqueKeys();
158 QList<QChartAxis*> keys = m_seriesMap.uniqueKeys();
159 foreach(QChartAxis* axis , keys) {
159 foreach(QChartAxis* axis , keys) {
160 if(m_seriesMap.contains(axis,series)){
160 if(m_seriesMap.contains(axis,series)){
161 emit seriesRemoved(series);
161 emit seriesRemoved(series);
162 m_seriesMap.remove(axis,series);
162 m_seriesMap.remove(axis,series);
163 //remove axis if no longer there
163 //remove axis if no longer there
164 if(!m_seriesMap.contains(axis)){
164 if(!m_seriesMap.contains(axis)){
165 emit axisRemoved(axis);
165 emit axisRemoved(axis);
166 m_domainMap.remove(axis);
166 m_domainMap.remove(axis);
167 if(axis != m_axisY)
167 if(axis != m_axisY)
168 delete axis;
168 delete axis;
169 }
169 }
170 series->setParent(0);
170 series->setParent(0);
171 break;
171 break;
172 }
172 }
173 }
173 }
174 }
174 }
175
175
176 void ChartDataSet::removeAllSeries()
176 void ChartDataSet::removeAllSeries()
177 {
177 {
178 QList<QChartAxis*> keys = m_seriesMap.uniqueKeys();
178 QList<QChartAxis*> keys = m_seriesMap.uniqueKeys();
179 foreach(QChartAxis* axis , keys) {
179 foreach(QChartAxis* axis , keys) {
180 QList<QSeries*> seriesList = m_seriesMap.values(axis);
180 QList<QSeries*> seriesList = m_seriesMap.values(axis);
181 for(int i =0 ; i < seriesList.size();i++ )
181 for(int i =0 ; i < seriesList.size();i++ )
182 {
182 {
183 emit seriesRemoved(seriesList.at(i));
183 emit seriesRemoved(seriesList.at(i));
184 delete(seriesList.at(i));
184 delete(seriesList.at(i));
185 }
185 }
186 m_seriesMap.remove(axis);
186 m_seriesMap.remove(axis);
187 m_domainMap.remove(axis);
187 m_domainMap.remove(axis);
188 emit axisRemoved(axis);
188 emit axisRemoved(axis);
189 if(axis != m_axisY) delete axis;
189 if(axis != m_axisY) delete axis;
190 }
190 }
191 m_domainIndex=0;
191 m_domainIndex=0;
192 }
192 }
193
193
194 bool ChartDataSet::nextDomain()
194 bool ChartDataSet::nextDomain()
195 {
195 {
196 int limit = (m_domainMap.values().size()/m_domainMap.uniqueKeys().size())-1;
196 int limit = (m_domainMap.values().size()/m_domainMap.uniqueKeys().size())-1;
197
197
198 if (m_domainIndex < limit) {
198 if (m_domainIndex < limit) {
199 m_domainIndex++;
199 m_domainIndex++;
200 setDomain(m_domainIndex);
200 setDomain(m_domainIndex);
201 return true;
201 return true;
202 }
202 }
203 else {
203 else {
204 return false;
204 return false;
205 }
205 }
206 }
206 }
207
207
208 bool ChartDataSet::previousDomain()
208 bool ChartDataSet::previousDomain()
209 {
209 {
210 if (m_domainIndex > 0) {
210 if (m_domainIndex > 0) {
211 m_domainIndex--;
211 m_domainIndex--;
212 setDomain(m_domainIndex);
212 setDomain(m_domainIndex);
213 return true;
213 return true;
214 }
214 }
215 else {
215 else {
216 return false;
216 return false;
217 }
217 }
218 }
218 }
219
219
220 void ChartDataSet::setDomain(int index)
220 void ChartDataSet::setDomain(int index)
221 {
221 {
222 QList<QChartAxis*> domainList = m_domainMap.uniqueKeys();
222 QList<QChartAxis*> domainList = m_domainMap.uniqueKeys();
223
223
224 if(domainList.count()==0) return;
224 if(domainList.count()==0) return;
225
225
226 Domain domain;
226 Domain domain;
227
227
228 foreach (QChartAxis* axis , domainList) {
228 foreach (QChartAxis* axis , domainList) {
229 int i = m_domainMap.count(axis) - index -1;
229 int i = m_domainMap.count(axis) - index -1;
230 Q_ASSERT(i>=0);
230 Q_ASSERT(i>=0);
231 domain = m_domainMap.values(axis).at(i);
231 domain = m_domainMap.values(axis).at(i);
232 QStringList labels = createLabels(axis,domain.m_minY,domain.m_maxY);
232 QStringList labels = createLabels(axis,domain.m_minY,domain.m_maxY);
233 QList<QSeries*> seriesList = m_seriesMap.values(axis);
233 QList<QSeries*> seriesList = m_seriesMap.values(axis);
234 foreach(QSeries* series, seriesList) {
234 foreach(QSeries* series, seriesList) {
235 emit seriesDomainChanged(series,domain);
235 emit seriesDomainChanged(series,domain);
236 }
236 }
237 axis->updateRange(domain.m_minY,domain.m_maxY);
237 axis->updateRange(domain.m_minY,domain.m_maxY);
238 emit axisRangeChanged(axis,labels);
238 emit axisRangeChanged(axis,labels);
239
239
240 }
240 }
241
241
242 QStringList labels = createLabels(axisX(),domain.m_minX,domain.m_maxX);
242 QStringList labels = createLabels(axisX(),domain.m_minX,domain.m_maxX);
243 axisX()->updateRange(domain.m_minX,domain.m_maxY);
243 axisX()->updateRange(domain.m_minX,domain.m_maxY);
244 emit axisRangeChanged(axisX(),labels);
244 emit axisRangeChanged(axisX(),labels);
245 }
245 }
246
246
247 void ChartDataSet::setDomain(int index,QChartAxis* axis)
248 {
249 int i = m_domainMap.count(axis) - index -1;
250 Q_ASSERT(i>=0);
251 Domain domain = m_domainMap.values(axis).at(i);
252 {
253 QStringList labels = createLabels(axis,domain.m_minY,domain.m_maxY);
254 QList<QSeries*> seriesList = m_seriesMap.values(axis);
255 foreach(QSeries* series, seriesList) {
256 emit seriesDomainChanged(series,domain);
257 }
258 axis->updateRange(domain.m_minY,domain.m_maxY);
259 emit axisRangeChanged(axis,labels);
260 }
261
262 QStringList labels = createLabels(axisX(),domain.m_minX,domain.m_maxX);
263 axisX()->updateRange(domain.m_minX,domain.m_maxY);
264 emit axisRangeChanged(axisX(),labels);
265 }
266
267
247 void ChartDataSet::clearDomains(int toIndex)
268 void ChartDataSet::clearDomains(int toIndex)
248 {
269 {
249 Q_ASSERT(toIndex>=0);
270 Q_ASSERT(toIndex>=0);
250
271
251 m_domainIndex = toIndex;
272 m_domainIndex = toIndex;
252
273
253 QList<QChartAxis*> keys = m_domainMap.uniqueKeys();
274 QList<QChartAxis*> keys = m_domainMap.uniqueKeys();
254
275
255 foreach (QChartAxis* key , keys)
276 foreach (QChartAxis* key , keys)
256 {
277 {
257 QList<Domain> domains = m_domainMap.values(key);
278 QList<Domain> domains = m_domainMap.values(key);
258 m_domainMap.remove(key);
279 m_domainMap.remove(key);
259 int i = domains.size() - toIndex - 1;
280 int i = domains.size() - toIndex - 1;
260 while(i--){
281 while(i--){
261 domains.removeFirst();
282 domains.removeFirst();
262 }
283 }
263 for(int j=domains.size()-1; j>=0 ;j--)
284 for(int j=domains.size()-1; j>=0 ;j--)
264 m_domainMap.insert(key,domains.at(j));
285 m_domainMap.insert(key,domains.at(j));
265 }
286 }
266 }
287 }
267
288
268 void ChartDataSet::addDomain(const QRectF& rect, const QRectF& viewport)
289 void ChartDataSet::addDomain(const QRectF& rect, const QRectF& viewport)
269 {
290 {
270 Q_ASSERT(rect.isValid());
291 Q_ASSERT(rect.isValid());
271 Q_ASSERT(viewport.isValid());
292 Q_ASSERT(viewport.isValid());
272
293
273 clearDomains(m_domainIndex);
294 clearDomains(m_domainIndex);
274
295
275 QList<QChartAxis*> domainList = m_domainMap.uniqueKeys();
296 QList<QChartAxis*> domainList = m_domainMap.uniqueKeys();
276
297
277 Domain domain;
298 Domain domain;
278
299
279 foreach (QChartAxis* axis , domainList){
300 foreach (QChartAxis* axis , domainList){
280 domain = m_domainMap.value(axis).subDomain(rect,viewport.width(),viewport.height());
301 domain = m_domainMap.value(axis).subDomain(rect,viewport.width(),viewport.height());
281 m_domainMap.insert(axis,domain);
302 m_domainMap.insert(axis,domain);
282 }
303 }
283
304
284 setDomain(++m_domainIndex);
305 setDomain(++m_domainIndex);
285 }
306 }
286
307
287 QChartAxis* ChartDataSet::axisY(QSeries* series) const
308 QChartAxis* ChartDataSet::axisY(QSeries* series) const
288 {
309 {
289 if(series == 0) return m_axisY;
310 if(series == 0) return m_axisY;
290
311
291 QList<QChartAxis*> keys = m_seriesMap.uniqueKeys();
312 QList<QChartAxis*> keys = m_seriesMap.uniqueKeys();
292
313
293 foreach(QChartAxis* axis , keys) {
314 foreach(QChartAxis* axis , keys) {
294 if(m_seriesMap.contains(axis,series)){
315 if(m_seriesMap.contains(axis,series)){
295 return axis;
316 return axis;
296 }
317 }
297 }
318 }
298 return 0;
319 return 0;
299 }
320 }
300
321
301 QStringList ChartDataSet::createLabels(QChartAxis* axis,qreal min, qreal max)
322 QStringList ChartDataSet::createLabels(QChartAxis* axis,qreal min, qreal max)
302 {
323 {
303 Q_ASSERT(max>=min);
324 Q_ASSERT(max>=min);
304
325
305 QStringList labels;
326 QStringList labels;
306
327
307 int ticks = axis->ticksCount()-1;
328 int ticks = axis->ticksCount()-1;
308
329
309 for(int i=0; i<= ticks; i++){
330 for(int i=0; i<= ticks; i++){
310 qreal value = min + (i * (max - min)/ ticks);
331 qreal value = min + (i * (max - min)/ ticks);
311 QString label = axis->axisTickLabel(value);
332 QString label = axis->axisTickLabel(value);
312 if(label.isEmpty()){
333 if(label.isEmpty()){
313 labels << QString::number(value);
334 labels << QString::number(value);
314 }else{
335 }else{
315 labels << label;
336 labels << label;
316 }
337 }
317 }
338 }
318 return labels;
339 return labels;
319 }
340 }
320
341
321
342
322 void ChartDataSet::handleRangeChanged(QChartAxis* axis)
343 void ChartDataSet::handleRangeChanged(QChartAxis* axis)
323 {
344 {
324 qreal min = axis->min();
345 qreal min = axis->min();
325 qreal max = axis->max();
346 qreal max = axis->max();
326
347
327 if(axis==axisX()) {
348 if(axis==axisX()) {
328
349
329 m_domainIndex=0;
350 m_domainIndex=0;
330
351
331 clearDomains(m_domainIndex);
352 clearDomains(m_domainIndex);
332
353
333 QList<QChartAxis*> domainList = m_domainMap.uniqueKeys();
354 QList<QChartAxis*> domainList = m_domainMap.uniqueKeys();
334
355
335 foreach (QChartAxis* axis , domainList) {
356 foreach (QChartAxis* axis , domainList) {
336
357
337 Q_ASSERT(m_domainMap.values(axis).size()==1);
358 Q_ASSERT(m_domainMap.values(axis).size()==1);
338
359
339 Domain domain = m_domainMap.value(axis);
360 Domain domain = m_domainMap.value(axis);
340 domain.m_minX=min;
361 domain.m_minX=min;
341 domain.m_maxX=max;
362 domain.m_maxX=max;
342 m_domainMap.replace(axis,domain);
363 m_domainMap.replace(axis,domain);
343 }
364 }
344
365
366 setDomain(m_domainIndex);
367
345 }
368 }
346 else {
369 else {
347
370
348 QList<Domain> domains = m_domainMap.values(axis);
371 QList<Domain> domains = m_domainMap.values(axis);
349 m_domainMap.remove(axis);
372 m_domainMap.remove(axis);
350
373
351 for(int i=0;i<domains.size();i++)
374 for(int i=0;i<domains.size();i++)
352 {
375 {
353 domains[i].m_minY=min;
376 domains[i].m_minY=min;
354 domains[i].m_maxY=max;
377 domains[i].m_maxY=max;
355 }
378 }
356
379
357 for(int j=domains.size()-1; j>=0;j--)
380 for(int j=domains.size()-1; j>=0;j--)
358 m_domainMap.insert(axis,domains.at(j));
381 m_domainMap.insert(axis,domains.at(j));
382
383 setDomain(m_domainIndex,axis);
359 }
384 }
360
385
361 setDomain(m_domainIndex);
386
362 }
387 }
363
388
364 void ChartDataSet::handleTickChanged(QChartAxis* axis)
389 void ChartDataSet::handleTickChanged(QChartAxis* axis)
365 {
390 {
366 if(axis==axisX()){
391 if(axis==axisX()){
367 Domain domain = m_domainMap.value(axisY());
392 Domain domain = m_domainMap.value(axisY());
368 QStringList labels = createLabels(axis,domain.m_minX,domain.m_maxX);
393 QStringList labels = createLabels(axis,domain.m_minX,domain.m_maxX);
369 emit axisRangeChanged(axis,labels);
394 emit axisRangeChanged(axis,labels);
370 }else{
395 }else{
371 Domain domain = m_domainMap.value(axis);
396 Domain domain = m_domainMap.value(axis);
372 QStringList labels = createLabels(axis,domain.m_minY,domain.m_maxY);
397 QStringList labels = createLabels(axis,domain.m_minY,domain.m_maxY);
373 emit axisRangeChanged(axis,labels);
398 emit axisRangeChanged(axis,labels);
374 }
399 }
375 }
400 }
376
401
377 #include "moc_chartdataset_p.cpp"
402 #include "moc_chartdataset_p.cpp"
378
403
379 QTCOMMERCIALCHART_END_NAMESPACE
404 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,59 +1,60
1 #ifndef CHARTDATASET_P_H_
1 #ifndef CHARTDATASET_P_H_
2 #define CHARTDATASET_P_H_
2 #define CHARTDATASET_P_H_
3
3
4 #include "qseries.h"
4 #include "qseries.h"
5 #include "domain_p.h"
5 #include "domain_p.h"
6 #include <QVector>
6 #include <QVector>
7
7
8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9
9
10 class QChartAxis;
10 class QChartAxis;
11
11
12 class ChartDataSet : public QObject
12 class ChartDataSet : public QObject
13 {
13 {
14 Q_OBJECT
14 Q_OBJECT
15 public:
15 public:
16 ChartDataSet(QObject* parent=0);
16 ChartDataSet(QObject* parent=0);
17 virtual ~ChartDataSet();
17 virtual ~ChartDataSet();
18
18
19 void addSeries(QSeries* series,QChartAxis *axisY = 0);
19 void addSeries(QSeries* series,QChartAxis *axisY = 0);
20 void removeSeries(QSeries* series);
20 void removeSeries(QSeries* series);
21 void removeAllSeries();
21 void removeAllSeries();
22 void addDomain(const QRectF& rect, const QRectF& viewport);
22 void addDomain(const QRectF& rect, const QRectF& viewport);
23 bool nextDomain();
23 bool nextDomain();
24 bool previousDomain();
24 bool previousDomain();
25 void clearDomains(int toIndex =0);
25 void clearDomains(int toIndex =0);
26 const Domain domain(QChartAxis *axisY) const;
26 const Domain domain(QChartAxis *axisY) const;
27 int domainIndex() const {return m_domainIndex;}
27 int domainIndex() const {return m_domainIndex;}
28 void setDomain(int index);
28 void setDomain(int index);
29 void setDomain(int index,QChartAxis* axis);
29
30
30 QChartAxis* axisX() const { return m_axisX;};
31 QChartAxis* axisX() const { return m_axisX;};
31 QChartAxis* axisY(QSeries* series = 0) const;
32 QChartAxis* axisY(QSeries* series = 0) const;
32
33
33 signals:
34 signals:
34 void seriesAdded(QSeries* series);
35 void seriesAdded(QSeries* series);
35 void seriesRemoved(QSeries* series);
36 void seriesRemoved(QSeries* series);
36 void axisAdded(QChartAxis* axis);
37 void axisAdded(QChartAxis* axis);
37 void axisRemoved(QChartAxis* axis);
38 void axisRemoved(QChartAxis* axis);
38 void axisRangeChanged(QChartAxis* axis, const QStringList& labels);
39 void axisRangeChanged(QChartAxis* axis, const QStringList& labels);
39 void seriesDomainChanged(QSeries* series,const Domain& domain);
40 void seriesDomainChanged(QSeries* series,const Domain& domain);
40
41
41 private slots:
42 private slots:
42 void handleRangeChanged(QChartAxis*);
43 void handleRangeChanged(QChartAxis*);
43 void handleTickChanged(QChartAxis*);
44 void handleTickChanged(QChartAxis*);
44
45
45 private:
46 private:
46 QStringList createLabels(QChartAxis* axis,qreal min, qreal max);
47 QStringList createLabels(QChartAxis* axis,qreal min, qreal max);
47
48
48 private:
49 private:
49 QMultiMap<QChartAxis*, Domain> m_domainMap;
50 QMultiMap<QChartAxis*, Domain> m_domainMap;
50 QMultiMap<QChartAxis*, QSeries*> m_seriesMap;
51 QMultiMap<QChartAxis*, QSeries*> m_seriesMap;
51 QChartAxis* m_axisX;
52 QChartAxis* m_axisX;
52 QChartAxis* m_axisY;
53 QChartAxis* m_axisY;
53 int m_domainIndex;
54 int m_domainIndex;
54 bool m_axisXInitialized;
55 bool m_axisXInitialized;
55 };
56 };
56
57
57 QTCOMMERCIALCHART_END_NAMESPACE
58 QTCOMMERCIALCHART_END_NAMESPACE
58
59
59 #endif /* CHARTENGINE_P_H_ */
60 #endif /* CHARTENGINE_P_H_ */
@@ -1,210 +1,220
1
1
2 #include "piepresenter_p.h"
2 #include "piepresenter_p.h"
3 #include "pieslice_p.h"
3 #include "pieslice_p.h"
4 #include "qpieslice.h"
4 #include "qpieslice.h"
5 #include "pieslicelabel_p.h"
5 #include "pieslicelabel_p.h"
6 #include "qpieseries.h"
6 #include "qpieseries.h"
7 #include <qmath.h>
7 #include <qmath.h>
8 #include <QDebug>
8 #include <QDebug>
9 #include <QFontMetrics>
9 #include <QFontMetrics>
10
10
11
11
12 QTCOMMERCIALCHART_BEGIN_NAMESPACE
12 QTCOMMERCIALCHART_BEGIN_NAMESPACE
13
13
14 PiePresenter::PiePresenter(QGraphicsItem *parent, QPieSeries *series)
14 PiePresenter::PiePresenter(QGraphicsItem *parent, QPieSeries *series)
15 :ChartItem(parent),
15 :ChartItem(parent),
16 m_series(series)
16 m_series(series)
17 {
17 {
18 Q_ASSERT(series);
18 Q_ASSERT(series);
19 connect(series, SIGNAL(changed(const QPieSeries::ChangeSet&)), this, SLOT(handleSeriesChanged(const QPieSeries::ChangeSet&)));
19 connect(series, SIGNAL(changed(const QPieSeries::ChangeSet&)), this, SLOT(handleSeriesChanged(const QPieSeries::ChangeSet&)));
20 connect(series, SIGNAL(sizeFactorChanged()), this, SLOT(updateGeometry()));
20 connect(series, SIGNAL(sizeFactorChanged()), this, SLOT(updateGeometry()));
21 connect(series, SIGNAL(positionChanged()), this, SLOT(updateGeometry()));
21 connect(series, SIGNAL(positionChanged()), this, SLOT(updateGeometry()));
22
22
23 if (m_series->count()) {
23 if (m_series->count()) {
24 QPieSeries::ChangeSet changeSet;
24 QPieSeries::ChangeSet changeSet;
25 changeSet.appendAdded(m_series->m_slices);
25 changeSet.appendAdded(m_series->m_slices);
26 handleSeriesChanged(changeSet);
26 handleSeriesChanged(changeSet);
27 }
27 }
28 }
28 }
29
29
30 PiePresenter::~PiePresenter()
30 PiePresenter::~PiePresenter()
31 {
31 {
32 // slices deleted automatically through QGraphicsItem
32 // slices deleted automatically through QGraphicsItem
33 }
33 }
34
34
35 void PiePresenter::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
35 void PiePresenter::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
36 {
36 {
37 // TODO: paint shadows for all components
37 // TODO: paint shadows for all components
38 // - get paths from items & merge & offset and draw with shadow color?
38 // - get paths from items & merge & offset and draw with shadow color?
39 }
39 }
40
40
41 void PiePresenter::handleSeriesChanged(const QPieSeries::ChangeSet& changeSet)
41 void PiePresenter::handleSeriesChanged(const QPieSeries::ChangeSet& changeSet)
42 {
42 {
43 //qDebug() << "PiePresenter::handleSeriesChanged()";
43 //qDebug() << "PiePresenter::handleSeriesChanged()";
44 //qDebug() << " added : " << changeSet.added();
44 //qDebug() << " added : " << changeSet.added();
45 //qDebug() << " changed: " << changeSet.changed();
45 //qDebug() << " changed: " << changeSet.changed();
46 //qDebug() << " removed: " << changeSet.removed();
46 //qDebug() << " removed: " << changeSet.removed();
47
47
48 foreach (QPieSlice* s, changeSet.added())
48 foreach (QPieSlice* s, changeSet.added())
49 addSlice(s);
49 addSlice(s);
50
50
51 foreach (QPieSlice* s, changeSet.changed())
51 foreach (QPieSlice* s, changeSet.changed())
52 updateSlice(s);
52 updateSlice(s);
53
53
54 foreach (QPieSlice* s, changeSet.removed())
54 foreach (QPieSlice* s, changeSet.removed())
55 deleteSlice(s);
55 deleteSlice(s);
56
56
57 // every change possibly changes the actual pie size
57 // every change possibly changes the actual pie size
58 updateGeometry();
58 updateGeometry();
59 }
59 }
60
60
61 void PiePresenter::handleDomainChanged(const Domain& domain)
61 void PiePresenter::handleDomainChanged(const Domain& domain)
62 {
62 {
63 // TODO
63 // TODO
64 }
64 }
65
65
66 void PiePresenter::handleGeometryChanged(const QRectF& rect)
66 void PiePresenter::handleGeometryChanged(const QRectF& rect)
67 {
67 {
68 m_rect = rect;
68 m_rect = rect;
69 prepareGeometryChange();
69 prepareGeometryChange();
70 updateGeometry();
70 updateGeometry();
71 }
71 }
72
72
73 void PiePresenter::updateGeometry()
73 void PiePresenter::updateGeometry()
74 {
74 {
75 if (!m_rect.isValid() || m_rect.isEmpty())
75 if (!m_rect.isValid() || m_rect.isEmpty())
76 return;
76 return;
77
77
78 // calculate maximum rectangle for pie
78 // calculate maximum rectangle for pie
79 QRectF pieRect = m_rect;
79 QRectF pieRect = m_rect;
80 if (pieRect.width() < pieRect.height()) {
80 if (pieRect.width() < pieRect.height()) {
81 pieRect.setWidth(pieRect.width() * m_series->sizeFactor());
81 pieRect.setWidth(pieRect.width() * m_series->sizeFactor());
82 pieRect.setHeight(pieRect.width());
82 pieRect.setHeight(pieRect.width());
83 pieRect.moveCenter(m_rect.center());
83 pieRect.moveCenter(m_rect.center());
84 } else {
84 } else {
85 pieRect.setHeight(pieRect.height() * m_series->sizeFactor());
85 pieRect.setHeight(pieRect.height() * m_series->sizeFactor());
86 pieRect.setWidth(pieRect.height());
86 pieRect.setWidth(pieRect.height());
87 pieRect.moveCenter(m_rect.center());
87 pieRect.moveCenter(m_rect.center());
88 }
88 }
89
89
90 // position the pie rectangle
90 // position the pie rectangle
91 switch (m_series->position()) {
91 switch (m_series->position()) {
92 case QPieSeries::PiePositionTopLeft: {
92 case QPieSeries::PiePositionTopLeft: {
93 pieRect.setHeight(pieRect.height() / 2);
93 pieRect.setHeight(pieRect.height() / 2);
94 pieRect.setWidth(pieRect.height());
94 pieRect.setWidth(pieRect.height());
95 pieRect.moveCenter(QPointF(m_rect.center().x() / 2, m_rect.center().y() / 2));
95 pieRect.moveCenter(QPointF(m_rect.center().x() / 2, m_rect.center().y() / 2));
96 break;
96 break;
97 }
97 }
98 case QPieSeries::PiePositionTopRight: {
98 case QPieSeries::PiePositionTopRight: {
99 pieRect.setHeight(pieRect.height() / 2);
99 pieRect.setHeight(pieRect.height() / 2);
100 pieRect.setWidth(pieRect.height());
100 pieRect.setWidth(pieRect.height());
101 pieRect.moveCenter(QPointF((m_rect.center().x() / 2) * 3, m_rect.center().y() / 2));
101 pieRect.moveCenter(QPointF((m_rect.center().x() / 2) * 3, m_rect.center().y() / 2));
102 break;
102 break;
103 }
103 }
104 case QPieSeries::PiePositionBottomLeft: {
104 case QPieSeries::PiePositionBottomLeft: {
105 pieRect.setHeight(pieRect.height() / 2);
105 pieRect.setHeight(pieRect.height() / 2);
106 pieRect.setWidth(pieRect.height());
106 pieRect.setWidth(pieRect.height());
107 pieRect.moveCenter(QPointF(m_rect.center().x() / 2, (m_rect.center().y() / 2) * 3));
107 pieRect.moveCenter(QPointF(m_rect.center().x() / 2, (m_rect.center().y() / 2) * 3));
108 break;
108 break;
109 }
109 }
110 case QPieSeries::PiePositionBottomRight: {
110 case QPieSeries::PiePositionBottomRight: {
111 pieRect.setHeight(pieRect.height() / 2);
111 pieRect.setHeight(pieRect.height() / 2);
112 pieRect.setWidth(pieRect.height());
112 pieRect.setWidth(pieRect.height());
113 pieRect.moveCenter(QPointF((m_rect.center().x() / 2) * 3, (m_rect.center().y() / 2) * 3));
113 pieRect.moveCenter(QPointF((m_rect.center().x() / 2) * 3, (m_rect.center().y() / 2) * 3));
114 break;
114 break;
115 }
115 }
116 default:
116 default:
117 break;
117 break;
118 }
118 }
119
119
120 // calculate how much space we need around the pie rectangle (labels & exploding)
120 // calculate how much space we need around the pie rectangle (labels & exploding)
121 qreal delta = 0;
121 qreal delta = 0;
122 qreal pieRadius = pieRect.height() / 2;
122 qreal pieRadius = pieRect.height() / 2;
123 foreach (QPieSlice* s, m_series->m_slices) {
123 foreach (QPieSlice* s, m_series->m_slices) {
124
124
125 // calculate the farthest point in the slice from the pie center
125 // calculate the farthest point in the slice from the pie center
126
127 // the arm
126 qreal centerAngle = s->m_startAngle + (s->m_angleSpan / 2);
128 qreal centerAngle = s->m_startAngle + (s->m_angleSpan / 2);
127 qreal len = pieRadius + s->labelArmLength() + s->explodeDistance();
129 qreal len = pieRadius + PIESLICE_LABEL_GAP + s->labelArmLength() + s->explodeDistance();
128 QPointF dp(qSin(centerAngle*(PI/180)) * len, -qCos(centerAngle*(PI/180)) * len);
130 QPointF dp(qSin(centerAngle*(PI/180)) * len, -qCos(centerAngle*(PI/180)) * len);
129 QPointF p = pieRect.center() + dp;
131 QPointF p = pieRect.center() + dp;
130
132
131 // TODO: consider the label text
133 // the label text
134 QFontMetricsF fm(s->labelFont());
135 QRectF labelRect = fm.boundingRect(s->label());
136 if (centerAngle < 90 || centerAngle > 270)
137 p += QPointF(0, -labelRect.height());
138 if (centerAngle < 180)
139 p += QPointF(labelRect.width(), 0);
140 else
141 p += QPointF(-labelRect.width(), 0);
132
142
133 // calculate how much the radius must get smaller to fit that point in the base rectangle
143 // calculate how much the radius must get smaller to fit that point in the base rectangle
134 qreal dt = m_rect.top() - p.y();
144 qreal dt = m_rect.top() - p.y();
135 if (dt > delta) delta = dt;
145 if (dt > delta) delta = dt;
136 qreal dl = m_rect.left() - p.x();
146 qreal dl = m_rect.left() - p.x();
137 if (dl > delta) delta = dl;
147 if (dl > delta) delta = dl;
138 qreal dr = p.x() - m_rect.right();
148 qreal dr = p.x() - m_rect.right();
139 if (dr > delta) delta = dr;
149 if (dr > delta) delta = dr;
140 qreal db = p.y() - m_rect.bottom();
150 qreal db = p.y() - m_rect.bottom();
141 if (db > delta) delta = db;
151 if (db > delta) delta = db;
142
152
143 //if (!m_rect.contains(p)) qDebug() << s->label() << dt << dl << dr << db << "delta" << delta;
153 //if (!m_rect.contains(p)) qDebug() << s->label() << dt << dl << dr << db << "delta" << delta;
144 }
154 }
145
155
146 // shrink the pie rectangle so that everything outside it fits the base rectangle
156 // shrink the pie rectangle so that everything outside it fits the base rectangle
147 pieRect.adjust(delta, delta, -delta, -delta);
157 pieRect.adjust(delta, delta, -delta, -delta);
148
158
149 // update slices
159 // update slices
150 if (m_pieRect != pieRect) {
160 if (m_pieRect != pieRect) {
151 m_pieRect = pieRect;
161 m_pieRect = pieRect;
152 //qDebug() << "PiePresenter::updateGeometry()" << m_rect << m_pieRect;
162 //qDebug() << "PiePresenter::updateGeometry()" << m_rect << m_pieRect;
153 foreach (PieSlice* s, m_slices.values()) {
163 foreach (PieSlice* s, m_slices.values()) {
154 s->setPieRect(m_pieRect);
164 s->setPieRect(m_pieRect);
155 s->updateGeometry();
165 s->updateGeometry();
156 s->update();
166 s->update();
157 }
167 }
158 }
168 }
159 }
169 }
160
170
161 void PiePresenter::addSlice(QPieSlice* sliceData)
171 void PiePresenter::addSlice(QPieSlice* sliceData)
162 {
172 {
163 //qDebug() << "PiePresenter::addSlice()" << sliceData;
173 //qDebug() << "PiePresenter::addSlice()" << sliceData;
164
174
165 if (m_slices.keys().contains(sliceData)) {
175 if (m_slices.keys().contains(sliceData)) {
166 Q_ASSERT(0); // TODO: how to handle this nicely?
176 Q_ASSERT(0); // TODO: how to handle this nicely?
167 return;
177 return;
168 }
178 }
169
179
170 // create slice
180 // create slice
171 PieSlice *slice = new PieSlice(this);
181 PieSlice *slice = new PieSlice(this);
172 slice->setPieRect(m_pieRect);
182 slice->setPieRect(m_pieRect);
173 slice->updateData(sliceData);
183 slice->updateData(sliceData);
174 slice->updateGeometry();
184 slice->updateGeometry();
175 slice->update();
185 slice->update();
176 m_slices.insert(sliceData, slice);
186 m_slices.insert(sliceData, slice);
177
187
178 // connect signals
188 // connect signals
179 connect(slice, SIGNAL(clicked()), sliceData, SIGNAL(clicked()));
189 connect(slice, SIGNAL(clicked()), sliceData, SIGNAL(clicked()));
180 connect(slice, SIGNAL(hoverEnter()), sliceData, SIGNAL(hoverEnter()));
190 connect(slice, SIGNAL(hoverEnter()), sliceData, SIGNAL(hoverEnter()));
181 connect(slice, SIGNAL(hoverLeave()), sliceData, SIGNAL(hoverLeave()));
191 connect(slice, SIGNAL(hoverLeave()), sliceData, SIGNAL(hoverLeave()));
182 }
192 }
183
193
184 void PiePresenter::updateSlice(QPieSlice* sliceData)
194 void PiePresenter::updateSlice(QPieSlice* sliceData)
185 {
195 {
186 //qDebug() << "PiePresenter::updateSlice()" << sliceData;
196 //qDebug() << "PiePresenter::updateSlice()" << sliceData;
187
197
188 if (!m_slices.contains(sliceData)) {
198 if (!m_slices.contains(sliceData)) {
189 Q_ASSERT(0); // TODO: how to handle this nicely?
199 Q_ASSERT(0); // TODO: how to handle this nicely?
190 return;
200 return;
191 }
201 }
192
202
193 m_slices[sliceData]->updateData(sliceData);
203 m_slices[sliceData]->updateData(sliceData);
194 }
204 }
195
205
196 void PiePresenter::deleteSlice(QPieSlice* sliceData)
206 void PiePresenter::deleteSlice(QPieSlice* sliceData)
197 {
207 {
198 //qDebug() << "PiePresenter::deleteSlice()" << sliceData;
208 //qDebug() << "PiePresenter::deleteSlice()" << sliceData;
199
209
200 if (!m_slices.contains(sliceData)) {
210 if (!m_slices.contains(sliceData)) {
201 Q_ASSERT(0); // TODO: how to handle this nicely?
211 Q_ASSERT(0); // TODO: how to handle this nicely?
202 return;
212 return;
203 }
213 }
204
214
205 delete m_slices.take(sliceData);
215 delete m_slices.take(sliceData);
206 }
216 }
207
217
208 #include "moc_piepresenter_p.cpp"
218 #include "moc_piepresenter_p.cpp"
209
219
210 QTCOMMERCIALCHART_END_NAMESPACE
220 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,135 +1,135
1 #include "pieslice_p.h"
1 #include "pieslice_p.h"
2 #include "pieslicelabel_p.h"
2 #include "pieslicelabel_p.h"
3 #include "piepresenter_p.h"
3 #include "piepresenter_p.h"
4 #include "qpieseries.h"
4 #include "qpieseries.h"
5 #include "qpieslice.h"
5 #include "qpieslice.h"
6 #include <QPainter>
6 #include <QPainter>
7 #include <QDebug>
7 #include <QDebug>
8 #include <qmath.h>
8 #include <qmath.h>
9 #include <QGraphicsSceneEvent>
9 #include <QGraphicsSceneEvent>
10 #include <QTime>
10 #include <QTime>
11
11
12 QTCOMMERCIALCHART_BEGIN_NAMESPACE
12 QTCOMMERCIALCHART_BEGIN_NAMESPACE
13
13
14 QPointF offset(qreal angle, qreal length)
14 QPointF offset(qreal angle, qreal length)
15 {
15 {
16 qreal dx = qSin(angle*(PI/180)) * length;
16 qreal dx = qSin(angle*(PI/180)) * length;
17 qreal dy = qCos(angle*(PI/180)) * length;
17 qreal dy = qCos(angle*(PI/180)) * length;
18 return QPointF(dx, -dy);
18 return QPointF(dx, -dy);
19 }
19 }
20
20
21 PieSlice::PieSlice(QGraphicsItem* parent)
21 PieSlice::PieSlice(QGraphicsItem* parent)
22 :QGraphicsObject(parent),
22 :QGraphicsObject(parent),
23 m_slicelabel(new PieSliceLabel(this)),
23 m_slicelabel(new PieSliceLabel(this)),
24 m_startAngle(0),
24 m_startAngle(0),
25 m_angleSpan(0),
25 m_angleSpan(0),
26 m_isExploded(false),
26 m_isExploded(false),
27 m_explodeDistance(0)
27 m_explodeDistance(0)
28 {
28 {
29 setAcceptHoverEvents(true);
29 setAcceptHoverEvents(true);
30 setAcceptedMouseButtons(Qt::LeftButton);
30 setAcceptedMouseButtons(Qt::LeftButton);
31 }
31 }
32
32
33 PieSlice::~PieSlice()
33 PieSlice::~PieSlice()
34 {
34 {
35
35
36 }
36 }
37
37
38 QRectF PieSlice::boundingRect() const
38 QRectF PieSlice::boundingRect() const
39 {
39 {
40 return m_path.boundingRect();
40 return m_path.boundingRect();
41 }
41 }
42
42
43 QPainterPath PieSlice::shape() const
43 QPainterPath PieSlice::shape() const
44 {
44 {
45 return m_path;
45 return m_path;
46 }
46 }
47
47
48 void PieSlice::paint(QPainter* painter, const QStyleOptionGraphicsItem* /*option*/, QWidget* /*widget*/)
48 void PieSlice::paint(QPainter* painter, const QStyleOptionGraphicsItem* /*option*/, QWidget* /*widget*/)
49 {
49 {
50 painter->setPen(m_pen);
50 painter->setPen(m_pen);
51 painter->setBrush(m_brush);
51 painter->setBrush(m_brush);
52 painter->drawPath(m_path);
52 painter->drawPath(m_path);
53 }
53 }
54
54
55 void PieSlice::hoverEnterEvent(QGraphicsSceneHoverEvent* /*event*/)
55 void PieSlice::hoverEnterEvent(QGraphicsSceneHoverEvent* /*event*/)
56 {
56 {
57 emit hoverEnter();
57 emit hoverEnter();
58 }
58 }
59
59
60 void PieSlice::hoverLeaveEvent(QGraphicsSceneHoverEvent* /*event*/)
60 void PieSlice::hoverLeaveEvent(QGraphicsSceneHoverEvent* /*event*/)
61 {
61 {
62 emit hoverLeave();
62 emit hoverLeave();
63 }
63 }
64
64
65 void PieSlice::mousePressEvent(QGraphicsSceneMouseEvent* /*event*/)
65 void PieSlice::mousePressEvent(QGraphicsSceneMouseEvent* /*event*/)
66 {
66 {
67 emit clicked();
67 emit clicked();
68 }
68 }
69
69
70 void PieSlice::setPieRect(QRectF rect)
70 void PieSlice::setPieRect(QRectF rect)
71 {
71 {
72 m_pieRect = rect;
72 m_pieRect = rect;
73 }
73 }
74
74
75 void PieSlice::updateGeometry()
75 void PieSlice::updateGeometry()
76 {
76 {
77 if (!m_pieRect.isValid() || m_pieRect.isEmpty())
77 if (!m_pieRect.isValid() || m_pieRect.isEmpty())
78 return;
78 return;
79
79
80 prepareGeometryChange();
80 prepareGeometryChange();
81
81
82 // calculate center angle
82 // calculate center angle
83 qreal centerAngle = m_startAngle + (m_angleSpan/2);
83 qreal centerAngle = m_startAngle + (m_angleSpan/2);
84
84
85 // adjust rect for exploding
85 // adjust rect for exploding
86 QRectF rect = m_pieRect;
86 QRectF rect = m_pieRect;
87 if (m_isExploded) {
87 if (m_isExploded) {
88 qreal dx = qSin(centerAngle*(PI/180)) * m_explodeDistance;
88 qreal dx = qSin(centerAngle*(PI/180)) * m_explodeDistance;
89 qreal dy = -qCos(centerAngle*(PI/180)) * m_explodeDistance;
89 qreal dy = -qCos(centerAngle*(PI/180)) * m_explodeDistance;
90 rect.translate(dx, dy);
90 rect.translate(dx, dy);
91 }
91 }
92
92
93 // update slice path
93 // update slice path
94 // TODO: draw the shape so that it might have a hole in the center
94 // TODO: draw the shape so that it might have a hole in the center
95 QPainterPath path;
95 QPainterPath path;
96 path.moveTo(rect.center());
96 path.moveTo(rect.center());
97 path.arcTo(rect, -m_startAngle + 90, -m_angleSpan);
97 path.arcTo(rect, -m_startAngle + 90, -m_angleSpan);
98 path.closeSubpath();
98 path.closeSubpath();
99 m_path = path;
99 m_path = path;
100
100
101 // update label position
101 // update label position
102 qreal radius = rect.height() / 2;
102 qreal radius = rect.height() / 2;
103 QPointF edgeCenter = rect.center() + offset(centerAngle, radius + 5);
103 QPointF edgeCenter = rect.center() + offset(centerAngle, radius + PIESLICE_LABEL_GAP);
104 m_slicelabel->setArmStartPoint(edgeCenter);
104 m_slicelabel->setArmStartPoint(edgeCenter);
105 m_slicelabel->setArmAngle(centerAngle);
105 m_slicelabel->setArmAngle(centerAngle);
106 m_slicelabel->updateGeometry();
106 m_slicelabel->updateGeometry();
107 m_slicelabel->update();
107 m_slicelabel->update();
108
108
109 //qDebug() << "PieSlice::updateGeometry" << m_slicelabel->text() << boundingRect() << m_angle << m_span;
109 //qDebug() << "PieSlice::updateGeometry" << m_slicelabel->text() << boundingRect() << m_angle << m_span;
110 }
110 }
111
111
112 void PieSlice::updateData(const QPieSlice* sliceData)
112 void PieSlice::updateData(const QPieSlice* sliceData)
113 {
113 {
114 // TODO: compare what has changes to avoid unneccesary geometry updates
114 // TODO: compare what has changes to avoid unneccesary geometry updates
115
115
116 m_startAngle = sliceData->startAngle();
116 m_startAngle = sliceData->startAngle();
117 m_angleSpan = sliceData->m_angleSpan;
117 m_angleSpan = sliceData->m_angleSpan;
118 m_isExploded = sliceData->isExploded();
118 m_isExploded = sliceData->isExploded();
119 m_explodeDistance = sliceData->explodeDistance(); // TODO: expose to public API
119 m_explodeDistance = sliceData->explodeDistance(); // TODO: expose to public API
120 m_pen = sliceData->pen();
120 m_pen = sliceData->pen();
121 m_brush = sliceData->brush();
121 m_brush = sliceData->brush();
122
122
123 m_slicelabel->setVisible(sliceData->isLabelVisible());
123 m_slicelabel->setVisible(sliceData->isLabelVisible());
124 m_slicelabel->setText(sliceData->label());
124 m_slicelabel->setText(sliceData->label());
125 m_slicelabel->setPen(sliceData->labelPen());
125 m_slicelabel->setPen(sliceData->labelPen());
126 m_slicelabel->setFont(sliceData->labelFont());
126 m_slicelabel->setFont(sliceData->labelFont());
127 m_slicelabel->setArmLength(sliceData->labelArmLength());
127 m_slicelabel->setArmLength(sliceData->labelArmLength());
128
128
129 updateGeometry();
129 updateGeometry();
130 update();
130 update();
131 }
131 }
132
132
133 #include "moc_pieslice_p.cpp"
133 #include "moc_pieslice_p.cpp"
134
134
135 QTCOMMERCIALCHART_END_NAMESPACE
135 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,64 +1,66
1 #ifndef PIESLICE_H
1 #ifndef PIESLICE_H
2 #define PIESLICE_H
2 #define PIESLICE_H
3
3
4 #include "qchartglobal.h"
4 #include "qchartglobal.h"
5 #include "charttheme_p.h"
5 #include "charttheme_p.h"
6 #include "qpieseries.h"
6 #include "qpieseries.h"
7 #include <QGraphicsItem>
7 #include <QGraphicsItem>
8 #include <QRectF>
8 #include <QRectF>
9 #include <QColor>
9 #include <QColor>
10 #include <QPen>
10 #include <QPen>
11
11
12 #define PIESLICE_LABEL_GAP 5
13
12 QTCOMMERCIALCHART_BEGIN_NAMESPACE
14 QTCOMMERCIALCHART_BEGIN_NAMESPACE
13 class PiePresenter;
15 class PiePresenter;
14 class PieSliceLabel;
16 class PieSliceLabel;
15 class QPieSlice;
17 class QPieSlice;
16
18
17 class PieSlice : public QGraphicsObject
19 class PieSlice : public QGraphicsObject
18 {
20 {
19 Q_OBJECT
21 Q_OBJECT
20
22
21 public:
23 public:
22 PieSlice(QGraphicsItem* parent = 0);
24 PieSlice(QGraphicsItem* parent = 0);
23 ~PieSlice();
25 ~PieSlice();
24
26
25 public: // from QGraphicsItem
27 public: // from QGraphicsItem
26 QRectF boundingRect() const;
28 QRectF boundingRect() const;
27 QPainterPath shape() const;
29 QPainterPath shape() const;
28 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
30 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
29 void hoverEnterEvent(QGraphicsSceneHoverEvent *event);
31 void hoverEnterEvent(QGraphicsSceneHoverEvent *event);
30 void hoverLeaveEvent(QGraphicsSceneHoverEvent *event);
32 void hoverLeaveEvent(QGraphicsSceneHoverEvent *event);
31 void mousePressEvent(QGraphicsSceneMouseEvent *event);
33 void mousePressEvent(QGraphicsSceneMouseEvent *event);
32
34
33 Q_SIGNALS:
35 Q_SIGNALS:
34 void clicked();
36 void clicked();
35 void hoverEnter();
37 void hoverEnter();
36 void hoverLeave();
38 void hoverLeave();
37
39
38 public Q_SLOTS:
40 public Q_SLOTS:
39 void setPieRect(QRectF rect);
41 void setPieRect(QRectF rect);
40 void updateGeometry();
42 void updateGeometry();
41 void updateData(const QPieSlice *sliceData);
43 void updateData(const QPieSlice *sliceData);
42
44
43 public:
45 public:
44 PieSliceLabel* label() { return m_slicelabel; }
46 PieSliceLabel* label() { return m_slicelabel; }
45
47
46 private:
48 private:
47 PieSliceLabel* m_slicelabel;
49 PieSliceLabel* m_slicelabel;
48
50
49 QRectF m_pieRect;
51 QRectF m_pieRect;
50 QPainterPath m_path;
52 QPainterPath m_path;
51
53
52 qreal m_startAngle;
54 qreal m_startAngle;
53 qreal m_angleSpan;
55 qreal m_angleSpan;
54
56
55 bool m_isExploded;
57 bool m_isExploded;
56 qreal m_explodeDistance;
58 qreal m_explodeDistance;
57
59
58 QPen m_pen;
60 QPen m_pen;
59 QBrush m_brush;
61 QBrush m_brush;
60 };
62 };
61
63
62 QTCOMMERCIALCHART_END_NAMESPACE
64 QTCOMMERCIALCHART_END_NAMESPACE
63
65
64 #endif // PIESLICE_H
66 #endif // PIESLICE_H
@@ -1,72 +1,72
1 #include "pieslicelabel_p.h"
1 #include "pieslicelabel_p.h"
2 #include <QPainter>
2 #include <QPainter>
3 #include <qmath.h>
3 #include <qmath.h>
4 #include <QGraphicsTextItem>
4 #include <QGraphicsTextItem>
5 #include <QDebug>
5 #include <QDebug>
6
6
7 QTCOMMERCIALCHART_BEGIN_NAMESPACE
7 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8
8
9 #define PI 3.14159265
9 #define PI 3.14159265
10
10
11 PieSliceLabel::PieSliceLabel(QGraphicsItem* parent)
11 PieSliceLabel::PieSliceLabel(QGraphicsItem* parent)
12 :QGraphicsItem(parent),
12 :QGraphicsItem(parent),
13 m_armAngle(0),
13 m_armAngle(0),
14 m_armLength(0)
14 m_armLength(0)
15 {
15 {
16
16
17 }
17 }
18
18
19 void PieSliceLabel::paint(QPainter *painter, const QStyleOptionGraphicsItem* /*option*/, QWidget* /*widget*/)
19 void PieSliceLabel::paint(QPainter *painter, const QStyleOptionGraphicsItem* /*option*/, QWidget* /*widget*/)
20 {
20 {
21 painter->setPen(m_pen);
21 painter->setPen(m_pen);
22 painter->drawPath(m_armPath);
22 painter->drawPath(m_armPath);
23
23
24 // TODO: do we need a pen for text?
24 // TODO: do we need a pen for text?
25 painter->setFont(m_font);
25 painter->setFont(m_font);
26 painter->drawText(m_textRect.bottomLeft(), m_text);
26 painter->drawText(m_textRect.bottomLeft(), m_text);
27
27
28 //qDebug() << "PieSliceLabel::paint" << m_text << m_textRect;
28 //qDebug() << "PieSliceLabel::paint" << m_text << m_textRect;
29 }
29 }
30
30
31 void PieSliceLabel::updateGeometry()
31 void PieSliceLabel::updateGeometry()
32 {
32 {
33 prepareGeometryChange();
33 prepareGeometryChange();
34
34
35 // calculate text size
35 // calculate text size
36 QFontMetricsF fm(m_font);
36 QFontMetricsF fm(m_font);
37 QRectF textRect = fm.boundingRect(m_text);
37 QRectF textRect = fm.boundingRect(m_text);
38
38
39 // calculate path for arm and text start point
39 // calculate path for arm and text start point
40 qreal dx = qSin(m_armAngle*(PI/180)) * m_armLength;
40 qreal dx = qSin(m_armAngle*(PI/180)) * m_armLength;
41 qreal dy = -qCos(m_armAngle*(PI/180)) * m_armLength;
41 qreal dy = -qCos(m_armAngle*(PI/180)) * m_armLength;
42 QPointF parm1 = m_armStartPoint + QPointF(dx, dy);
42 QPointF parm1 = m_armStartPoint + QPointF(dx, dy);
43
43
44 // calculate horizontal arm and text position
44 // calculate horizontal arm and text position
45 QPointF parm2 = parm1;
45 QPointF parm2 = parm1;
46 textRect.moveBottomLeft(parm1);
46 textRect.moveBottomLeft(parm1);
47 if (m_armAngle < 180) { // arm swings the other way on the left side
47 if (m_armAngle < 180) { // arm swings the other way on the left side
48 parm2 += QPointF(m_textRect.width(), 0);
48 parm2 += QPointF(textRect.width(), 0);
49 } else {
49 } else {
50 parm2 += QPointF(-m_textRect.width(),0);
50 parm2 += QPointF(-textRect.width(),0);
51 textRect.moveBottomLeft(parm2);
51 textRect.moveBottomLeft(parm2);
52 }
52 }
53
53
54 // add a little offset to text so that it does not touch the arm
54 // add a little offset to text so that it does not touch the arm
55 qreal yOffset = m_pen.widthF() ? m_pen.widthF() : 2;
55 qreal yOffset = m_pen.widthF() ? m_pen.widthF() : 2;
56 textRect.translate(0, -yOffset);
56 textRect.translate(0, -yOffset);
57
57
58 // update arm path
58 // update arm path
59 QPainterPath path;
59 QPainterPath path;
60 path.moveTo(m_armStartPoint);
60 path.moveTo(m_armStartPoint);
61 path.lineTo(parm1);
61 path.lineTo(parm1);
62 path.lineTo(parm2);
62 path.lineTo(parm2);
63
63
64 // update paths & rects
64 // update paths & rects
65 m_armPath = path;
65 m_armPath = path;
66 m_textRect = textRect;
66 m_textRect = textRect;
67 m_rect = path.boundingRect().united(m_textRect);
67 m_rect = path.boundingRect().united(m_textRect);
68
68
69 //qDebug() << "PieSliceLabel::updateGeometry" << m_text << m_armStartPoint << m_armLength << m_armAngle << m_textRect;
69 //qDebug() << "PieSliceLabel::updateGeometry" << m_text << m_armStartPoint << m_armLength << m_armAngle << m_textRect;
70 }
70 }
71
71
72 QTCOMMERCIALCHART_END_NAMESPACE
72 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,516 +1,534
1 #include "qpieseries.h"
1 #include "qpieseries.h"
2 #include "qpieslice.h"
2 #include "qpieslice.h"
3 #include <QDebug>
3 #include <QDebug>
4
4
5 QTCOMMERCIALCHART_BEGIN_NAMESPACE
5 QTCOMMERCIALCHART_BEGIN_NAMESPACE
6
6
7
7
8 /*!
8 /*!
9 \class QPieSeries::ChangeSet
9 \class QPieSeries::ChangeSet
10 \brief Defines the changes in the series.
10 \brief Defines the changes in the series.
11
11
12 Contains the changes that have occurred in the series. Lists of added, changed and removed slices.
12 Contains the changes that have occurred in the series. Lists of added, changed and removed slices.
13
13
14 \sa QPieSeries::changed()
14 \sa QPieSeries::changed()
15 */
15 */
16
16
17 /*!
17 /*!
18 \internal
18 \internal
19 */
19 */
20 void QPieSeries::ChangeSet::appendAdded(QPieSlice* slice)
20 void QPieSeries::ChangeSet::appendAdded(QPieSlice* slice)
21 {
21 {
22 if (!m_added.contains(slice))
22 if (!m_added.contains(slice))
23 m_added << slice;
23 m_added << slice;
24 }
24 }
25
25
26 /*!
26 /*!
27 \internal
27 \internal
28 */
28 */
29 void QPieSeries::ChangeSet::appendAdded(QList<QPieSlice*> slices)
29 void QPieSeries::ChangeSet::appendAdded(QList<QPieSlice*> slices)
30 {
30 {
31 foreach (QPieSlice* s, slices)
31 foreach (QPieSlice* s, slices)
32 appendAdded(s);
32 appendAdded(s);
33 }
33 }
34
34
35 /*!
35 /*!
36 \internal
36 \internal
37 */
37 */
38 void QPieSeries::ChangeSet::appendChanged(QPieSlice* slice)
38 void QPieSeries::ChangeSet::appendChanged(QPieSlice* slice)
39 {
39 {
40 if (!m_changed.contains(slice))
40 if (!m_changed.contains(slice))
41 m_changed << slice;
41 m_changed << slice;
42 }
42 }
43
43
44 /*!
44 /*!
45 \internal
45 \internal
46 */
46 */
47 void QPieSeries::ChangeSet::appendRemoved(QPieSlice* slice)
47 void QPieSeries::ChangeSet::appendRemoved(QPieSlice* slice)
48 {
48 {
49 if (!m_removed.contains(slice))
49 if (!m_removed.contains(slice))
50 m_removed << slice;
50 m_removed << slice;
51 }
51 }
52
52
53 /*!
53 /*!
54 Returns a list of slices that have been added to the series.
54 Returns a list of slices that have been added to the series.
55 \sa QPieSeries::changed()
55 \sa QPieSeries::changed()
56 */
56 */
57 QList<QPieSlice*> QPieSeries::ChangeSet::added() const
57 QList<QPieSlice*> QPieSeries::ChangeSet::added() const
58 {
58 {
59 return m_added;
59 return m_added;
60 }
60 }
61
61
62 /*!
62 /*!
63 Returns a list of slices that have been changed in the series.
63 Returns a list of slices that have been changed in the series.
64 \sa QPieSeries::changed()
64 \sa QPieSeries::changed()
65 */
65 */
66 QList<QPieSlice*> QPieSeries::ChangeSet::changed() const
66 QList<QPieSlice*> QPieSeries::ChangeSet::changed() const
67 {
67 {
68 return m_changed;
68 return m_changed;
69 }
69 }
70
70
71 /*!
71 /*!
72 Returns a list of slices that have been removed from the series.
72 Returns a list of slices that have been removed from the series.
73 \sa QPieSeries::changed()
73 \sa QPieSeries::changed()
74 */
74 */
75 QList<QPieSlice*> QPieSeries::ChangeSet::removed() const
75 QList<QPieSlice*> QPieSeries::ChangeSet::removed() const
76 {
76 {
77 return m_removed;
77 return m_removed;
78 }
78 }
79
79
80
80
81 /*!
81 /*!
82 Returns true if there are no added/changed or removed slices in the change set.
82 Returns true if there are no added/changed or removed slices in the change set.
83 */
83 */
84 bool QPieSeries::ChangeSet::isEmpty() const
84 bool QPieSeries::ChangeSet::isEmpty() const
85 {
85 {
86 if (m_added.count() || m_changed.count() || m_removed.count())
86 if (m_added.count() || m_changed.count() || m_removed.count())
87 return false;
87 return false;
88 return true;
88 return true;
89 }
89 }
90
90
91 /*!
91 /*!
92 \enum QPieSeries::PiePosition
92 \enum QPieSeries::PiePosition
93
93
94 This enum describes pie position within its bounding rectangle
94 This enum describes pie position within its bounding rectangle
95
95
96 \value PiePositionMaximized
96 \value PiePositionMaximized
97 \value PiePositionTopLeft
97 \value PiePositionTopLeft
98 \value PiePositionTopRight
98 \value PiePositionTopRight
99 \value PiePositionBottomLeft
99 \value PiePositionBottomLeft
100 \value PiePositionBottomRight
100 \value PiePositionBottomRight
101 */
101 */
102
102
103 /*!
103 /*!
104 \class QPieSeries
104 \class QPieSeries
105 \brief Pie series API for QtCommercial Charts
105 \brief Pie series API for QtCommercial Charts
106
106
107 The pie series defines a pie chart which consists of pie slices which are QPieSlice objects.
107 The pie series defines a pie chart which consists of pie slices which are QPieSlice objects.
108 The slices can have any values as the QPieSeries will calculate its relative value to the sum of all slices.
108 The slices can have any values as the QPieSeries will calculate its relative value to the sum of all slices.
109 The actual slice size is determined by that relative value.
109 The actual slice size is determined by that relative value.
110
110
111 By default the pie is defined as a full pie but it can be a partial pie.
111 By default the pie is defined as a full pie but it can be a partial pie.
112 This can be done by setting a starting angle and angle span to the series.
112 This can be done by setting a starting angle and angle span to the series.
113
113
114 To help with the most common user interaction scenarions there some convenience functions.
114 To help with the most common user interaction scenarions there some convenience functions.
115 Like exploding a slice when clicked and higlighting when user hovers over a slice.
115 Like exploding a slice when clicked and higlighting when user hovers over a slice.
116 */
116 */
117
117
118 /*!
118 /*!
119 Constructs a series object which is a child of \a parent.
119 Constructs a series object which is a child of \a parent.
120 */
120 */
121 QPieSeries::QPieSeries(QObject *parent) :
121 QPieSeries::QPieSeries(QObject *parent) :
122 QSeries(parent),
122 QSeries(parent),
123 m_sizeFactor(1.0),
123 m_sizeFactor(1.0),
124 m_position(PiePositionMaximized),
124 m_position(PiePositionMaximized),
125 m_pieStartAngle(0),
125 m_pieStartAngle(0),
126 m_pieAngleSpan(360)
126 m_pieAngleSpan(360)
127 {
127 {
128
128
129 }
129 }
130
130
131 /*!
131 /*!
132 Destroys the object. Note that adding series to QChart transfers the ownership to the chart.
132 Destroys the object. Note that adding series to QChart transfers the ownership to the chart.
133 */
133 */
134 QPieSeries::~QPieSeries()
134 QPieSeries::~QPieSeries()
135 {
135 {
136
136
137 }
137 }
138
138
139 /*!
139 /*!
140 Returns QChartSeries::SeriesTypePie.
140 Returns QChartSeries::SeriesTypePie.
141 */
141 */
142 QSeries::QSeriesType QPieSeries::type() const
142 QSeries::QSeriesType QPieSeries::type() const
143 {
143 {
144 return QSeries::SeriesTypePie;
144 return QSeries::SeriesTypePie;
145 }
145 }
146
146
147 /*!
147 /*!
148 Sets an array of \a slices to the series replacing the existing slices.
148 Sets an array of \a slices to the series replacing the existing slices.
149 Slice ownership is passed to the series.
149 Slice ownership is passed to the series.
150 */
150 */
151 void QPieSeries::replace(QList<QPieSlice*> slices)
151 void QPieSeries::replace(QList<QPieSlice*> slices)
152 {
152 {
153 clear();
153 clear();
154 add(slices);
154 add(slices);
155 }
155 }
156
156
157 /*!
157 /*!
158 Adds an array of \a slices to the series.
158 Adds an array of \a slices to the series.
159 Slice ownership is passed to the series.
159 Slice ownership is passed to the series.
160 */
160 */
161 void QPieSeries::add(QList<QPieSlice*> slices)
161 void QPieSeries::add(QList<QPieSlice*> slices)
162 {
162 {
163 ChangeSet changeSet;
163 ChangeSet changeSet;
164 foreach (QPieSlice* s, slices) {
164 foreach (QPieSlice* s, slices) {
165 s->setParent(this);
165 s->setParent(this);
166 m_slices << s;
166 m_slices << s;
167 changeSet.appendAdded(s);
167 changeSet.appendAdded(s);
168 }
168 }
169
169
170 updateDerivativeData();
170 updateDerivativeData();
171
171
172 foreach (QPieSlice* s, slices) {
172 foreach (QPieSlice* s, slices) {
173 connect(s, SIGNAL(changed()), this, SLOT(sliceChanged()));
173 connect(s, SIGNAL(changed()), this, SLOT(sliceChanged()));
174 connect(s, SIGNAL(clicked()), this, SLOT(sliceClicked()));
174 connect(s, SIGNAL(clicked()), this, SLOT(sliceClicked()));
175 connect(s, SIGNAL(hoverEnter()), this, SLOT(sliceHoverEnter()));
175 connect(s, SIGNAL(hoverEnter()), this, SLOT(sliceHoverEnter()));
176 connect(s, SIGNAL(hoverLeave()), this, SLOT(sliceHoverLeave()));
176 connect(s, SIGNAL(hoverLeave()), this, SLOT(sliceHoverLeave()));
177 }
177 }
178
178
179 emit changed(changeSet);
179 emit changed(changeSet);
180 }
180 }
181
181
182 /*!
182 /*!
183 Adds a single \a slice to the series.
183 Adds a single \a slice to the series.
184 Slice ownership is passed to the series.
184 Slice ownership is passed to the series.
185 */
185 */
186 void QPieSeries::add(QPieSlice* slice)
186 void QPieSeries::add(QPieSlice* slice)
187 {
187 {
188 add(QList<QPieSlice*>() << slice);
188 add(QList<QPieSlice*>() << slice);
189 }
189 }
190
190
191 /*!
192 Adds a single \a slice to the series and returns a reference to the series.
193 Slice ownership is passed to the series.
194 */
195 QPieSeries& QPieSeries::operator << (QPieSlice* slice)
196 {
197 add(slice);
198 return *this;
199 }
200
191
201
192 /*!
202 /*!
193 Adds a single slice to the series with give \a value and \a name.
203 Adds a single slice to the series with give \a value and \a name.
194 Slice ownership is passed to the series.
204 Slice ownership is passed to the series.
195 */
205 */
196 QPieSlice* QPieSeries::add(qreal value, QString name)
206 QPieSlice* QPieSeries::add(qreal value, QString name)
197 {
207 {
198 QPieSlice* slice = new QPieSlice(value, name);
208 QPieSlice* slice = new QPieSlice(value, name);
199 add(slice);
209 add(slice);
200 return slice;
210 return slice;
201 }
211 }
202
212
203 /*!
213 /*!
204 Removes a single \a slice from the series and deletes the slice.
214 Removes a single \a slice from the series and deletes the slice.
205
215
206 Do not reference this pointer after this call.
216 Do not reference this pointer after this call.
207 */
217 */
208 void QPieSeries::remove(QPieSlice* slice)
218 void QPieSeries::remove(QPieSlice* slice)
209 {
219 {
210 if (!m_slices.removeOne(slice)) {
220 if (!m_slices.removeOne(slice)) {
211 Q_ASSERT(0); // TODO: how should this be reported?
221 Q_ASSERT(0); // TODO: how should this be reported?
212 return;
222 return;
213 }
223 }
214
224
215 ChangeSet changeSet;
225 ChangeSet changeSet;
216 changeSet.appendRemoved(slice);
226 changeSet.appendRemoved(slice);
217 emit changed(changeSet);
227 emit changed(changeSet);
218
228
219 delete slice;
229 delete slice;
220 slice = NULL;
230 slice = NULL;
221
231
222 updateDerivativeData();
232 updateDerivativeData();
223 }
233 }
224
234
225 /*!
235 /*!
226 Clears all slices from the series.
236 Clears all slices from the series.
227 */
237 */
228 void QPieSeries::clear()
238 void QPieSeries::clear()
229 {
239 {
230 if (m_slices.count() == 0)
240 if (m_slices.count() == 0)
231 return;
241 return;
232
242
233 ChangeSet changeSet;
243 ChangeSet changeSet;
234 foreach (QPieSlice* s, m_slices) {
244 foreach (QPieSlice* s, m_slices) {
235 changeSet.appendRemoved(s);
245 changeSet.appendRemoved(s);
236 m_slices.removeOne(s);
246 m_slices.removeOne(s);
237 delete s;
247 delete s;
238 }
248 }
239 emit changed(changeSet);
249 emit changed(changeSet);
240 updateDerivativeData();
250 updateDerivativeData();
241 }
251 }
242
252
243 /*!
253 /*!
244 Counts the number of the slices in this series.
254 Counts the number of the slices in this series.
245 */
255 */
246 int QPieSeries::count() const
256 int QPieSeries::count() const
247 {
257 {
248 return m_slices.count();
258 return m_slices.count();
249 }
259 }
250
260
251 /*!
261 /*!
252 Returns a list of slices that belong to this series.
262 Returns a list of slices that belong to this series.
253 */
263 */
254 QList<QPieSlice*> QPieSeries::slices() const
264 QList<QPieSlice*> QPieSeries::slices() const
255 {
265 {
256 return m_slices;
266 return m_slices;
257 }
267 }
258
268
259 /*!
269 /*!
260 Sets the size \a factor of the pie. 1.0 is the default value.
270 Sets the size \a factor of the pie. 1.0 is the default value.
261 Note that the pie will not grow beyond its absolute maximum size.
271 Note that the pie will not grow beyond its absolute maximum size.
262 In practice its use is to make the pie appear smaller.
272 In practice its use is to make the pie appear smaller.
263 \sa sizeFactor()
273 \sa sizeFactor()
264 */
274 */
265 void QPieSeries::setSizeFactor(qreal factor)
275 void QPieSeries::setSizeFactor(qreal factor)
266 {
276 {
267 if (factor < 0.0)
277 if (factor < 0.0)
268 return;
278 return;
269
279
270 if (m_sizeFactor != factor) {
280 if (m_sizeFactor != factor) {
271 m_sizeFactor = factor;
281 m_sizeFactor = factor;
272 emit sizeFactorChanged();
282 emit sizeFactorChanged();
273 }
283 }
274 }
284 }
275
285
276 /*!
286 /*!
277 Gets the size factor of the pie.
287 Gets the size factor of the pie.
278 \sa setSizeFactor()
288 \sa setSizeFactor()
279 */
289 */
280 qreal QPieSeries::sizeFactor() const
290 qreal QPieSeries::sizeFactor() const
281 {
291 {
282 return m_sizeFactor;
292 return m_sizeFactor;
283 }
293 }
284
294
285 /*!
295 /*!
286 Sets the \a position of the pie within its bounding rectangle.
296 Sets the \a position of the pie within its bounding rectangle.
287 \sa PiePosition, position()
297 \sa PiePosition, position()
288 */
298 */
289 void QPieSeries::setPosition(PiePosition position)
299 void QPieSeries::setPosition(PiePosition position)
290 {
300 {
291 if (m_position != position) {
301 if (m_position != position) {
292 m_position = position;
302 m_position = position;
293 emit positionChanged();
303 emit positionChanged();
294 }
304 }
295 }
305 }
296
306
297 /*!
307 /*!
298 Gets the position of the pie within its bounding rectangle.
308 Gets the position of the pie within its bounding rectangle.
299 \sa PiePosition, setPosition()
309 \sa PiePosition, setPosition()
300 */
310 */
301 QPieSeries::PiePosition QPieSeries::position() const
311 QPieSeries::PiePosition QPieSeries::position() const
302 {
312 {
303 return m_position;
313 return m_position;
304 }
314 }
305
315
306
316
307 /*!
317 /*!
308 Sets the \a startAngle and \a angleSpan of this series.
318 Sets the \a startAngle and \a angleSpan of this series.
309
319
310 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
320 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
311 */
321 */
312 void QPieSeries::setSpan(qreal startAngle, qreal angleSpan)
322 void QPieSeries::setSpan(qreal startAngle, qreal angleSpan)
313 {
323 {
314 if (startAngle >= 0 && startAngle < 360 &&
324 if (startAngle >= 0 && startAngle < 360 &&
315 angleSpan > 0 && angleSpan <= 360) {
325 angleSpan > 0 && angleSpan <= 360) {
316 m_pieStartAngle = startAngle;
326 m_pieStartAngle = startAngle;
317 m_pieAngleSpan = angleSpan;
327 m_pieAngleSpan = angleSpan;
318 updateDerivativeData();
328 updateDerivativeData();
319 }
329 }
320 }
330 }
321
331
322 /*!
332 /*!
323 Sets the all the slice labels \a visible or invisible.
333 Sets the all the slice labels \a visible or invisible.
324
334
325 \sa QPieSlice::isLabelVisible(), QPieSlice::setLabelVisible()
335 \sa QPieSlice::isLabelVisible(), QPieSlice::setLabelVisible()
326 */
336 */
327 void QPieSeries::setLabelsVisible(bool visible)
337 void QPieSeries::setLabelsVisible(bool visible)
328 {
338 {
329 foreach (QPieSlice* s, m_slices)
339 foreach (QPieSlice* s, m_slices)
330 s->setLabelVisible(visible);
340 s->setLabelVisible(visible);
331 }
341 }
332
342
333 /*!
343 /*!
334 Convenience method for exploding a slice when user clicks the pie. Set \a enable to true to
344 Convenience method for exploding a slice when user clicks the pie. Set \a enable to true to
335 explode slices by clicking.
345 explode slices by clicking.
336
346
337 \sa QPieSlice::isExploded(), QPieSlice::setExploded(), QPieSlice::setExplodeDistance()
347 \sa QPieSlice::isExploded(), QPieSlice::setExploded(), QPieSlice::setExplodeDistance()
338 */
348 */
339 void QPieSeries::setClickExplodes(bool enable)
349 void QPieSeries::setClickExplodes(bool enable)
340 {
350 {
341 if (enable)
351 if (enable)
342 connect(this, SIGNAL(clicked(QPieSlice*)), this, SLOT(toggleExploded(QPieSlice*)));
352 connect(this, SIGNAL(clicked(QPieSlice*)), this, SLOT(toggleExploded(QPieSlice*)));
343 else
353 else
344 disconnect(this, SLOT(toggleExploded(QPieSlice*)));
354 disconnect(this, SLOT(toggleExploded(QPieSlice*)));
345 }
355 }
346
356
347 /*!
357 /*!
348 Convenience method for highlighting a slice when user hovers over the slice.
358 Convenience method for highlighting a slice when user hovers over the slice.
349 It changes the slice color to be lighter and shows the label of the slice.
359 It changes the slice color to be lighter and shows the label of the slice.
350 Set \a enable to true to highlight a slice when user hovers on top of it.
360 Set \a enable to true to highlight a slice when user hovers on top of it.
351
352 \sa QPieSlice::isExploded(), QPieSlice::setExploded()
353 */
361 */
354
355 void QPieSeries::setHoverHighlighting(bool enable)
362 void QPieSeries::setHoverHighlighting(bool enable)
356 {
363 {
357 if (enable) {
364 if (enable) {
358 connect(this, SIGNAL(hoverEnter(QPieSlice*)), this, SLOT(highlightOn(QPieSlice*)));
365 connect(this, SIGNAL(hoverEnter(QPieSlice*)), this, SLOT(highlightOn(QPieSlice*)));
359 connect(this, SIGNAL(hoverLeave(QPieSlice*)), this, SLOT(highlightOff(QPieSlice*)));
366 connect(this, SIGNAL(hoverLeave(QPieSlice*)), this, SLOT(highlightOff(QPieSlice*)));
360 } else {
367 } else {
361 disconnect(this, SLOT(hoverEnter(QPieSlice*)));
368 disconnect(this, SLOT(hoverEnter(QPieSlice*)));
362 disconnect(this, SLOT(hoverLeave(QPieSlice*)));
369 disconnect(this, SLOT(hoverLeave(QPieSlice*)));
363 }
370 }
364 }
371 }
365
372
366 /*!
373 /*!
374 Returns the sum of all slice values in this series.
375
376 \sa QPieSlice::value(), QPieSlice::setValue()
377 */
378 qreal QPieSeries::total() const
379 {
380 return m_total;
381 }
382
383 /*!
367 \fn void QPieSeries::changed(const QPieSeries::ChangeSet& changeSet)
384 \fn void QPieSeries::changed(const QPieSeries::ChangeSet& changeSet)
368
385
369 This signal emitted when something has changed in the series.
386 This signal emitted when something has changed in the series.
370 The \a changeSet contains the details of which slices have been added, changed or removed.
387 The \a changeSet contains the details of which slices have been added, changed or removed.
371
388
372 \sa QPieSeries::ChangeSet, QPieSlice::changed()
389 \sa QPieSeries::ChangeSet, QPieSlice::changed()
373 */
390 */
374
391
375 /*!
392 /*!
376 \fn void QPieSeries::clicked(QPieSlice* slice)
393 \fn void QPieSeries::clicked(QPieSlice* slice)
377
394
378 This signal is emitted when a \a slice has been clicked.
395 This signal is emitted when a \a slice has been clicked.
379
396
380 \sa QPieSlice::clicked()
397 \sa QPieSlice::clicked()
381 */
398 */
382
399
383 /*!
400 /*!
384 \fn void QPieSeries::hoverEnter(QPieSlice* slice)
401 \fn void QPieSeries::hoverEnter(QPieSlice* slice)
385
402
386 This signal is emitted when user has hovered over a \a slice.
403 This signal is emitted when user has hovered over a \a slice.
387
404
388 \sa QPieSlice::hoverEnter()
405 \sa QPieSlice::hoverEnter()
389 */
406 */
390
407
391 /*!
408 /*!
392 \fn void QPieSeries::hoverLeave(QPieSlice* slice)
409 \fn void QPieSeries::hoverLeave(QPieSlice* slice)
393
410
394 This signal is emitted when user has hovered away from a \a slice.
411 This signal is emitted when user has hovered away from a \a slice.
395
412
396 \sa QPieSlice::hoverLeave()
413 \sa QPieSlice::hoverLeave()
397 */
414 */
398
415
399 /*!
416 /*!
400 \fn void QPieSeries::sizeFactorChanged()
417 \fn void QPieSeries::sizeFactorChanged()
401
418
402 This signal is emitted when size factor has been changed.
419 This signal is emitted when size factor has been changed.
403
420
404 \sa sizeFactor(), setSizeFactor()
421 \sa sizeFactor(), setSizeFactor()
405 */
422 */
406
423
407 /*!
424 /*!
408 \fn void QPieSeries::positionChanged()
425 \fn void QPieSeries::positionChanged()
409
426
410 This signal is emitted when position of the pie has been changed.
427 This signal is emitted when position of the pie has been changed.
411
428
412 \sa position(), setPosition()
429 \sa position(), setPosition()
413 */
430 */
414
431
415 void QPieSeries::sliceChanged()
432 void QPieSeries::sliceChanged()
416 {
433 {
417 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
434 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
418 Q_ASSERT(m_slices.contains(slice));
435 Q_ASSERT(m_slices.contains(slice));
419
436
420 ChangeSet changeSet;
437 ChangeSet changeSet;
421 changeSet.appendChanged(slice);
438 changeSet.appendChanged(slice);
422 emit changed(changeSet);
439 emit changed(changeSet);
423
440
424 updateDerivativeData();
441 updateDerivativeData();
425 }
442 }
426
443
427 void QPieSeries::sliceClicked()
444 void QPieSeries::sliceClicked()
428 {
445 {
429 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
446 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
430 Q_ASSERT(m_slices.contains(slice));
447 Q_ASSERT(m_slices.contains(slice));
431 emit clicked(slice);
448 emit clicked(slice);
432 }
449 }
433
450
434 void QPieSeries::sliceHoverEnter()
451 void QPieSeries::sliceHoverEnter()
435 {
452 {
436 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
453 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
437 Q_ASSERT(m_slices.contains(slice));
454 Q_ASSERT(m_slices.contains(slice));
438 emit hoverEnter(slice);
455 emit hoverEnter(slice);
439 }
456 }
440
457
441 void QPieSeries::sliceHoverLeave()
458 void QPieSeries::sliceHoverLeave()
442 {
459 {
443 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
460 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
444 Q_ASSERT(m_slices.contains(slice));
461 Q_ASSERT(m_slices.contains(slice));
445 emit hoverLeave(slice);
462 emit hoverLeave(slice);
446 }
463 }
447
464
448 void QPieSeries::toggleExploded(QPieSlice* slice)
465 void QPieSeries::toggleExploded(QPieSlice* slice)
449 {
466 {
450 Q_ASSERT(slice);
467 Q_ASSERT(slice);
451 slice->setExploded(!slice->isExploded());
468 slice->setExploded(!slice->isExploded());
452 }
469 }
453
470
454 void QPieSeries::highlightOn(QPieSlice* slice)
471 void QPieSeries::highlightOn(QPieSlice* slice)
455 {
472 {
456 Q_ASSERT(slice);
473 Q_ASSERT(slice);
457 QColor c = slice->brush().color().lighter();
474 QColor c = slice->brush().color().lighter();
458 slice->setBrush(c);
475 slice->setBrush(c);
459 slice->setLabelVisible(true);
460 }
476 }
461
477
462 void QPieSeries::highlightOff(QPieSlice* slice)
478 void QPieSeries::highlightOff(QPieSlice* slice)
463 {
479 {
464 Q_ASSERT(slice);
480 Q_ASSERT(slice);
465 QColor c = slice->brush().color().darker(150);
481 QColor c = slice->brush().color().darker(150);
466 slice->setBrush(c);
482 slice->setBrush(c);
467 slice->setLabelVisible(false);
468 }
483 }
469
484
470 void QPieSeries::updateDerivativeData()
485 void QPieSeries::updateDerivativeData()
471 {
486 {
472 m_total = 0;
487 m_total = 0;
473
488
474 // nothing to do?
489 // nothing to do?
475 if (m_slices.count() == 0)
490 if (m_slices.count() == 0)
476 return;
491 return;
477
492
478 // calculate total
493 // calculate total
479 foreach (QPieSlice* s, m_slices)
494 foreach (QPieSlice* s, m_slices)
480 m_total += s->value();
495 m_total += s->value();
481
496
482 // we must have some values
497 // we must have some values
483 Q_ASSERT(m_total > 0); // TODO: is this the correct way to handle this?
498 if (m_total == 0) {
499 qDebug() << "QPieSeries::updateDerivativeData() total == 0";
500 Q_ASSERT(m_total > 0); // TODO: is this the correct way to handle this?
501 }
484
502
485 // update slice attributes
503 // update slice attributes
486 qreal sliceAngle = m_pieStartAngle;
504 qreal sliceAngle = m_pieStartAngle;
487 foreach (QPieSlice* s, m_slices) {
505 foreach (QPieSlice* s, m_slices) {
488
506
489 bool changed = false;
507 bool changed = false;
490
508
491 qreal percentage = s->value() / m_total;
509 qreal percentage = s->value() / m_total;
492 if (s->m_percentage != percentage) {
510 if (s->m_percentage != percentage) {
493 s->m_percentage = percentage;
511 s->m_percentage = percentage;
494 changed = true;
512 changed = true;
495 }
513 }
496
514
497 qreal sliceSpan = m_pieAngleSpan * percentage;
515 qreal sliceSpan = m_pieAngleSpan * percentage;
498 if (s->m_angleSpan != sliceSpan) {
516 if (s->m_angleSpan != sliceSpan) {
499 s->m_angleSpan = sliceSpan;
517 s->m_angleSpan = sliceSpan;
500 changed = true;
518 changed = true;
501 }
519 }
502
520
503 if (s->m_startAngle != sliceAngle) {
521 if (s->m_startAngle != sliceAngle) {
504 s->m_startAngle = sliceAngle;
522 s->m_startAngle = sliceAngle;
505 changed = true;
523 changed = true;
506 }
524 }
507 sliceAngle += sliceSpan;
525 sliceAngle += sliceSpan;
508
526
509 if (changed)
527 if (changed)
510 emit s->changed();
528 emit s->changed();
511 }
529 }
512 }
530 }
513
531
514 #include "moc_qpieseries.cpp"
532 #include "moc_qpieseries.cpp"
515
533
516 QTCOMMERCIALCHART_END_NAMESPACE
534 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,129 +1,132
1 #ifndef PIESERIES_H
1 #ifndef PIESERIES_H
2 #define PIESERIES_H
2 #define PIESERIES_H
3
3
4 #include "qseries.h"
4 #include "qseries.h"
5 #include <QObject>
5 #include <QObject>
6 #include <QRectF>
6 #include <QRectF>
7 #include <QColor>
7 #include <QColor>
8 #include <QPen>
8 #include <QPen>
9 #include <QBrush>
9 #include <QBrush>
10 #include <QSignalMapper>
10 #include <QSignalMapper>
11
11
12 class QGraphicsObject;
12 class QGraphicsObject;
13 QTCOMMERCIALCHART_BEGIN_NAMESPACE
13 QTCOMMERCIALCHART_BEGIN_NAMESPACE
14 class PiePresenter;
14 class PiePresenter;
15 class PieSlice;
15 class PieSlice;
16 class QPieSlice;
16 class QPieSlice;
17
17
18 class QTCOMMERCIALCHART_EXPORT QPieSeries : public QSeries
18 class QTCOMMERCIALCHART_EXPORT QPieSeries : public QSeries
19 {
19 {
20 Q_OBJECT
20 Q_OBJECT
21
21
22 public:
22 public:
23 enum PiePosition {
23 enum PiePosition {
24 PiePositionMaximized = 0,
24 PiePositionMaximized = 0,
25 PiePositionTopLeft,
25 PiePositionTopLeft,
26 PiePositionTopRight,
26 PiePositionTopRight,
27 PiePositionBottomLeft,
27 PiePositionBottomLeft,
28 PiePositionBottomRight
28 PiePositionBottomRight
29 };
29 };
30
30
31 class ChangeSet
31 class ChangeSet
32 {
32 {
33 public:
33 public:
34
34
35 // TODO: these should not really be exposed to the public API
35 // TODO: these should not really be exposed to the public API
36 void appendAdded(QPieSlice* slice);
36 void appendAdded(QPieSlice* slice);
37 void appendAdded(QList<QPieSlice*> slices);
37 void appendAdded(QList<QPieSlice*> slices);
38 void appendChanged(QPieSlice* slice);
38 void appendChanged(QPieSlice* slice);
39 void appendRemoved(QPieSlice* slice);
39 void appendRemoved(QPieSlice* slice);
40
40
41 QList<QPieSlice*> added() const;
41 QList<QPieSlice*> added() const;
42 QList<QPieSlice*> changed() const;
42 QList<QPieSlice*> changed() const;
43 QList<QPieSlice*> removed() const;
43 QList<QPieSlice*> removed() const;
44
44
45 bool isEmpty() const;
45 bool isEmpty() const;
46
46
47 private:
47 private:
48 QList<QPieSlice*> m_added;
48 QList<QPieSlice*> m_added;
49 QList<QPieSlice*> m_changed;
49 QList<QPieSlice*> m_changed;
50 QList<QPieSlice*> m_removed;
50 QList<QPieSlice*> m_removed;
51 };
51 };
52
52
53 public:
53 public:
54 QPieSeries(QObject *parent = 0);
54 QPieSeries(QObject *parent = 0);
55 virtual ~QPieSeries();
55 virtual ~QPieSeries();
56
56
57 public: // from QChartSeries
57 public: // from QChartSeries
58 QSeriesType type() const;
58 QSeriesType type() const;
59
59
60 public:
60 public:
61 void replace(QList<QPieSlice*> slices);
61 void replace(QList<QPieSlice*> slices);
62 void add(QList<QPieSlice*> slices);
62 void add(QList<QPieSlice*> slices);
63 void add(QPieSlice* slice);
63 void add(QPieSlice* slice);
64 QPieSlice* add(qreal value, QString name);
64 QPieSlice* add(qreal value, QString name);
65 QPieSeries& operator << (QPieSlice* slice);
65 void remove(QPieSlice* slice);
66 void remove(QPieSlice* slice);
66 void clear();
67 void clear();
67
68
68 int count() const;
69 int count() const;
69 QList<QPieSlice*> slices() const;
70 QList<QPieSlice*> slices() const;
70
71
71 void setSizeFactor(qreal sizeFactor);
72 void setSizeFactor(qreal sizeFactor);
72 qreal sizeFactor() const;
73 qreal sizeFactor() const;
73 void setPosition(PiePosition position);
74 void setPosition(PiePosition position);
74 PiePosition position() const;
75 PiePosition position() const;
75 void setSpan(qreal startAngle, qreal angleSpan);
76 void setSpan(qreal startAngle, qreal angleSpan);
76
77
77 void setLabelsVisible(bool visible = true);
78 void setLabelsVisible(bool visible = true);
78 void setClickExplodes(bool enable = true);
79 void setClickExplodes(bool enable = true);
79 void setHoverHighlighting(bool enable = true);
80 void setHoverHighlighting(bool enable = true);
80
81
82 qreal total() const;
83
81 // TODO: find slices?
84 // TODO: find slices?
82 // QList<QPieSlice*> findByValue(qreal value);
85 // QList<QPieSlice*> findByValue(qreal value);
83 // ...
86 // ...
84
87
85 // TODO: sorting slices?
88 // TODO: sorting slices?
86 // void sort(QPieSeries::SortByValue|label|??)
89 // void sort(QPieSeries::SortByValue|label|??)
87
90
88 // TODO: general graphics customization
91 // TODO: general graphics customization
89 // setDrawStyle(2d|3d)
92 // setDrawStyle(2d|3d)
90 // setDropShadows(bool)
93 // setDropShadows(bool)
91
94
92 Q_SIGNALS:
95 Q_SIGNALS:
93 void changed(const QPieSeries::ChangeSet& changeSet);
96 void changed(const QPieSeries::ChangeSet& changeSet);
94 void clicked(QPieSlice* slice);
97 void clicked(QPieSlice* slice);
95 void hoverEnter(QPieSlice* slice);
98 void hoverEnter(QPieSlice* slice);
96 void hoverLeave(QPieSlice* slice);
99 void hoverLeave(QPieSlice* slice);
97 void sizeFactorChanged();
100 void sizeFactorChanged();
98 void positionChanged();
101 void positionChanged();
99
102
100 private Q_SLOTS: // TODO: should be private and not visible in the interface at all
103 private Q_SLOTS: // TODO: should be private and not visible in the interface at all
101 void sliceChanged();
104 void sliceChanged();
102 void sliceClicked();
105 void sliceClicked();
103 void sliceHoverEnter();
106 void sliceHoverEnter();
104 void sliceHoverLeave();
107 void sliceHoverLeave();
105 void toggleExploded(QPieSlice* slice);
108 void toggleExploded(QPieSlice* slice);
106 void highlightOn(QPieSlice* slice);
109 void highlightOn(QPieSlice* slice);
107 void highlightOff(QPieSlice* slice);
110 void highlightOff(QPieSlice* slice);
108
111
109 private:
112 private:
110 void updateDerivativeData();
113 void updateDerivativeData();
111
114
112 private:
115 private:
113 Q_DISABLE_COPY(QPieSeries)
116 Q_DISABLE_COPY(QPieSeries)
114
117
115 // TODO: use PIML
118 // TODO: use PIML
116 friend class PiePresenter;
119 friend class PiePresenter;
117 friend class PieSlice;
120 friend class PieSlice;
118
121
119 QList<QPieSlice*> m_slices;
122 QList<QPieSlice*> m_slices;
120 qreal m_sizeFactor;
123 qreal m_sizeFactor;
121 PiePosition m_position;
124 PiePosition m_position;
122 qreal m_total;
125 qreal m_total;
123 qreal m_pieStartAngle;
126 qreal m_pieStartAngle;
124 qreal m_pieAngleSpan;
127 qreal m_pieAngleSpan;
125 };
128 };
126
129
127 QTCOMMERCIALCHART_END_NAMESPACE
130 QTCOMMERCIALCHART_END_NAMESPACE
128
131
129 #endif // PIESERIES_H
132 #endif // PIESERIES_H
@@ -1,57 +1,71
1 #include "qseries.h"
1 #include "qseries.h"
2
2
3 /*!
3 /*!
4 \class QSeries
4 \class QSeries
5 \brief Base class for all QtCommercial Chart series.
5 \brief Base class for all QtCommercial Chart series.
6 \mainclass
6 \mainclass
7
7
8 Usually you use the series type specific inherited classes instead of the base class.
8 Usually you use the series type specific inherited classes instead of the base class.
9 \sa QScatterSeries
9 \sa QScatterSeries
10 */
10 */
11
11
12 /*!
12 /*!
13 \enum QSeries::QSeriesType
13 \enum QSeries::QSeriesType
14
14
15 The type of the series object.
15 The type of the series object.
16
16
17 \value SeriesTypeLine
17 \value SeriesTypeLine
18 \value SeriesTypeArea
18 \value SeriesTypeArea
19 \value SeriesTypeBar
19 \value SeriesTypeBar
20 \value SeriesTypeStackedBar
20 \value SeriesTypeStackedBar
21 \value SeriesTypePercentBar
21 \value SeriesTypePercentBar
22 \value SeriesTypePie
22 \value SeriesTypePie
23 \value SeriesTypeScatter
23 \value SeriesTypeScatter
24 \value SeriesTypeSpline
24 \value SeriesTypeSpline
25 */
25 */
26
26
27 /*!
27 /*!
28 \fn QSeries::QSeries(QObject *parent)
28 \fn QSeries::QSeries(QObject *parent)
29 \brief Constructs ChartSeries object with \a parent.
29 \brief Constructs ChartSeries object with \a parent.
30 */
30 */
31
31
32 /*!
32 /*!
33 \fn QSeries::~QSeries()
33 \fn QSeries::~QSeries()
34 \brief Virtual destructor for the chart series.
34 \brief Virtual destructor for the chart series.
35 */
35 */
36
36
37 /*!
37 /*!
38 \fn QSeriesType QSeries::type() const
38 \fn QSeriesType QSeries::type() const
39 \brief The type of the series.
39 \brief The type of the series.
40 */
40 */
41
41
42 /*!
42 /*!
43 \fn bool QSeries::setModel(QAbstractItemModel *model)
43 \fn bool QSeries::setModel(QAbstractItemModel *model)
44 \brief Use the \a model to provide data for the series. The model overrides possible user data
44 \brief Use the \a model to provide data for the series. The model overrides possible user data
45 set with QChartSeries type specific data setters. For example if you call both
45 set with QChartSeries type specific data setters. For example if you call both
46 QScatterSeries::addData() and QScatterSeries::setModel, only the data provided by the model is
46 QScatterSeries::addData() and QScatterSeries::setModel, only the data provided by the model is
47 used by the series. Returns true if the model is valid for the series.
47 used by the series. Returns true if the model is valid for the series.
48 */
48 */
49
49
50 /*!
50 /*!
51 \fn QList<QSeries::Legend> QSeries::legend()
51 \fn QList<QSeries::Legend> QSeries::legend()
52 \brief Returns the legend of the series. If series is empty, empty list is returned.
52 \brief Returns the legend of the series. If series is empty, empty list is returned.
53 */
53 */
54
54
55 /*!
56 \fn void QSeries::setTitle(QString title)
57 \brief Sets a \a title for the series.
58
59 This is not used directly by the chart itself. It is up to the user to use this as for example
60 chart title.
61 \sa QChart::setChartTitle()
62 */
63
64 /*!
65 \fn QString QSeries::title()
66 \brief Returns the title of the series.
67 */
68
55 QTCOMMERCIALCHART_BEGIN_NAMESPACE
69 QTCOMMERCIALCHART_BEGIN_NAMESPACE
56 #include "moc_qseries.cpp"
70 #include "moc_qseries.cpp"
57 QTCOMMERCIALCHART_END_NAMESPACE
71 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,49 +1,55
1 #ifndef QSERIES_H
1 #ifndef QSERIES_H
2 #define QSERIES_H
2 #define QSERIES_H
3
3
4 #include "qchartglobal.h"
4 #include "qchartglobal.h"
5 #include <QObject>
5 #include <QObject>
6 #include <QAbstractItemModel>
6 #include <QAbstractItemModel>
7 #include <QPen>
7 #include <QPen>
8
8
9 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9 QTCOMMERCIALCHART_BEGIN_NAMESPACE
10
10
11 class QTCOMMERCIALCHART_EXPORT QSeries : public QObject
11 class QTCOMMERCIALCHART_EXPORT QSeries : public QObject
12 {
12 {
13 Q_OBJECT
13 Q_OBJECT
14 public:
14 public:
15 enum QSeriesType {
15 enum QSeriesType {
16 SeriesTypeLine,
16 SeriesTypeLine,
17 SeriesTypeArea,
17 SeriesTypeArea,
18 SeriesTypeBar,
18 SeriesTypeBar,
19 SeriesTypeStackedBar,
19 SeriesTypeStackedBar,
20 SeriesTypePercentBar,
20 SeriesTypePercentBar,
21 SeriesTypePie,
21 SeriesTypePie,
22 SeriesTypeScatter,
22 SeriesTypeScatter,
23 SeriesTypeSpline
23 SeriesTypeSpline
24 };
24 };
25
25
26 // Helper class to contain legend and color for it
26 // Helper class to contain legend and color for it
27 // TODO: This as private class? Or should we expose this to user of API
27 // TODO: This as private class? Or should we expose this to user of API
28 class Legend {
28 class Legend {
29 public:
29 public:
30 QString mName;
30 QString mName;
31 QPen mPen;
31 QPen mPen;
32 };
32 };
33
33
34 protected:
34 protected:
35 QSeries(QObject *parent = 0) : QObject(parent) {}
35 QSeries(QObject *parent = 0) : QObject(parent) {}
36
36
37 public:
37 public:
38 virtual ~QSeries() {}
38 virtual ~QSeries() {}
39 virtual QSeriesType type() const = 0;
39 virtual QSeriesType type() const = 0;
40 // TODO
40 // TODO
41 virtual bool setModel(QAbstractItemModel* /*model*/) { return false; }
41 virtual bool setModel(QAbstractItemModel* /*model*/) { return false; }
42
42
43 // TODO: should this be internal?
43 // TODO: should this be internal?
44 virtual QList<QSeries::Legend> legend() { QList<QSeries::Legend> l; return l; }
44 virtual QList<QSeries::Legend> legend() { QList<QSeries::Legend> l; return l; }
45
46 void setTitle(QString title) { m_title = title; }
47 QString title() { return m_title; }
48
49 private:
50 QString m_title;
45 };
51 };
46
52
47 QTCOMMERCIALCHART_END_NAMESPACE
53 QTCOMMERCIALCHART_END_NAMESPACE
48
54
49 #endif
55 #endif
@@ -1,598 +1,614
1 #include <QtTest/QtTest>
1 #include <QtTest/QtTest>
2 #include <qchartaxis.h>
2 #include <qchartaxis.h>
3 #include <qlineseries.h>
3 #include <qlineseries.h>
4 #include <private/chartdataset_p.h>
4 #include <private/chartdataset_p.h>
5 #include <private/domain_p.h>
5 #include <private/domain_p.h>
6
6
7 QTCOMMERCIALCHART_USE_NAMESPACE
7 QTCOMMERCIALCHART_USE_NAMESPACE
8
8
9 Q_DECLARE_METATYPE(Domain)
9 Q_DECLARE_METATYPE(Domain)
10 Q_DECLARE_METATYPE(QChartAxis*)
10 Q_DECLARE_METATYPE(QChartAxis*)
11 Q_DECLARE_METATYPE(QSeries*)
11 Q_DECLARE_METATYPE(QSeries*)
12 Q_DECLARE_METATYPE(QLineSeries*)
12 Q_DECLARE_METATYPE(QLineSeries*)
13
13
14 class tst_ChartDataSet: public QObject {
14 class tst_ChartDataSet: public QObject {
15 Q_OBJECT
15 Q_OBJECT
16
16
17 public slots:
17 public slots:
18 void initTestCase();
18 void initTestCase();
19 void cleanupTestCase();
19 void cleanupTestCase();
20 void init();
20 void init();
21 void cleanup();
21 void cleanup();
22
22
23 private slots:
23 private slots:
24 void chartdataset_data();
24 void chartdataset_data();
25 void chartdataset();
25 void chartdataset();
26
26
27 void addDomain_data();
27 void addDomain_data();
28 void addDomain();
28 void addDomain();
29 void addSeries_data();
29 void addSeries_data();
30 void addSeries();
30 void addSeries();
31 void axisY_data();
31 void axisY_data();
32 void axisY();
32 void axisY();
33 void clearDomains_data();
33 void clearDomains_data();
34 void clearDomains();
34 void clearDomains();
35 void domain_data();
35 void domain_data();
36 void domain();
36 void domain();
37 void nextpreviousDomain_data();
37 void nextpreviousDomain_data();
38 void nextpreviousDomain();
38 void nextpreviousDomain();
39 void removeSeries_data();
39 void removeSeries_data();
40 void removeSeries();
40 void removeSeries();
41 void removeAllSeries_data();
41 void removeAllSeries_data();
42 void removeAllSeries();
42 void removeAllSeries();
43 };
43 };
44
44
45 void tst_ChartDataSet::initTestCase()
45 void tst_ChartDataSet::initTestCase()
46 {
46 {
47 qRegisterMetaType<Domain>("Domain");
47 qRegisterMetaType<Domain>("Domain");
48 qRegisterMetaType<QChartAxis*>();
48 qRegisterMetaType<QChartAxis*>();
49 qRegisterMetaType<QSeries*>();
49 qRegisterMetaType<QSeries*>();
50 }
50 }
51
51
52 void tst_ChartDataSet::cleanupTestCase()
52 void tst_ChartDataSet::cleanupTestCase()
53 {
53 {
54 }
54 }
55
55
56 void tst_ChartDataSet::init()
56 void tst_ChartDataSet::init()
57 {
57 {
58 }
58 }
59
59
60 void tst_ChartDataSet::cleanup()
60 void tst_ChartDataSet::cleanup()
61 {
61 {
62 }
62 }
63
63
64 void tst_ChartDataSet::chartdataset_data()
64 void tst_ChartDataSet::chartdataset_data()
65 {
65 {
66 }
66 }
67
67
68 void tst_ChartDataSet::chartdataset()
68 void tst_ChartDataSet::chartdataset()
69 {
69 {
70 ChartDataSet dataSet;
70 ChartDataSet dataSet;
71 QVERIFY2(dataSet.axisX(), "Missing axisX.");
71 QVERIFY2(dataSet.axisX(), "Missing axisX.");
72 QVERIFY2(dataSet.axisY(), "Missing axisY.");
72 QVERIFY2(dataSet.axisY(), "Missing axisY.");
73 //check if not dangling pointer
73 //check if not dangling pointer
74 dataSet.axisX()->objectName();
74 dataSet.axisX()->objectName();
75 dataSet.axisY()->objectName();
75 dataSet.axisY()->objectName();
76 QVERIFY(dataSet.domain(dataSet.axisX())==Domain());
76 QVERIFY(dataSet.domain(dataSet.axisX())==Domain());
77 QVERIFY(dataSet.domain(dataSet.axisY())==Domain());
77 QVERIFY(dataSet.domain(dataSet.axisY())==Domain());
78 QCOMPARE(dataSet.domainIndex(), 0);
78 QCOMPARE(dataSet.domainIndex(), 0);
79 }
79 }
80
80
81 void tst_ChartDataSet::addDomain_data()
81 void tst_ChartDataSet::addDomain_data()
82 {
82 {
83 QTest::addColumn<QRectF>("rect");
83 QTest::addColumn<QRectF>("rect");
84 QTest::addColumn<QRectF>("viewport");
84 QTest::addColumn<QRectF>("viewport");
85 QTest::newRow("400x400,1000x1000") << QRectF(200, 200, 600, 600)
85 QTest::newRow("400x400,1000x1000") << QRectF(200, 200, 600, 600)
86 << QRectF(0, 0, 1000, 1000);
86 << QRectF(0, 0, 1000, 1000);
87 QTest::newRow("600x600,1000x1000") << QRectF(100, 100, 700, 700)
87 QTest::newRow("600x600,1000x1000") << QRectF(100, 100, 700, 700)
88 << QRectF(0, 0, 1000, 1000);
88 << QRectF(0, 0, 1000, 1000);
89 QTest::newRow("200x200,1000x1000") << QRectF(400, 400, 600, 600)
89 QTest::newRow("200x200,1000x1000") << QRectF(400, 400, 600, 600)
90 << QRectF(0, 0, 1000, 1000);
90 << QRectF(0, 0, 1000, 1000);
91 }
91 }
92
92
93 void tst_ChartDataSet::addDomain()
93 void tst_ChartDataSet::addDomain()
94 {
94 {
95 QFETCH(QRectF, rect);
95 QFETCH(QRectF, rect);
96 QFETCH(QRectF, viewport);
96 QFETCH(QRectF, viewport);
97
97
98 ChartDataSet dataSet;
98 ChartDataSet dataSet;
99
99
100 Domain domain1(0, 1000, 0, 1000);
100 Domain domain1(0, 1000, 0, 1000);
101 QLineSeries series;
101 QLineSeries series;
102 series.add(0, 0);
102 series.add(0, 0);
103 series.add(1000, 1000);
103 series.add(1000, 1000);
104
104
105 dataSet.addSeries(&series);
105 dataSet.addSeries(&series);
106
106
107 QCOMPARE(dataSet.domainIndex(), 0);
107 QCOMPARE(dataSet.domainIndex(), 0);
108
108
109 QSignalSpy spy0(&dataSet, SIGNAL(axisAdded(QChartAxis*)));
109 QSignalSpy spy0(&dataSet, SIGNAL(axisAdded(QChartAxis*)));
110 QSignalSpy spy1(&dataSet,
110 QSignalSpy spy1(&dataSet,
111 SIGNAL(axisRangeChanged(QChartAxis*, QStringList const&)));
111 SIGNAL(axisRangeChanged(QChartAxis*, QStringList const&)));
112 QSignalSpy spy2(&dataSet, SIGNAL(axisRemoved(QChartAxis*)));
112 QSignalSpy spy2(&dataSet, SIGNAL(axisRemoved(QChartAxis*)));
113 QSignalSpy spy3(&dataSet, SIGNAL(seriesAdded(QSeries*)));
113 QSignalSpy spy3(&dataSet, SIGNAL(seriesAdded(QSeries*)));
114 QSignalSpy spy4(&dataSet,
114 QSignalSpy spy4(&dataSet,
115 SIGNAL(seriesDomainChanged(QSeries*, Domain const&)));
115 SIGNAL(seriesDomainChanged(QSeries*, Domain const&)));
116 QSignalSpy spy5(&dataSet, SIGNAL(seriesRemoved(QSeries*)));
116 QSignalSpy spy5(&dataSet, SIGNAL(seriesRemoved(QSeries*)));
117
117
118 Domain domain2 = dataSet.domain(dataSet.axisY());
118 Domain domain2 = dataSet.domain(dataSet.axisY());
119 QVERIFY(domain1 == domain2);
119 QVERIFY(domain1 == domain2);
120
120
121 dataSet.addDomain(rect, viewport);
121 dataSet.addDomain(rect, viewport);
122 QCOMPARE(dataSet.domainIndex(), 1);
122 QCOMPARE(dataSet.domainIndex(), 1);
123 Domain domain3 = dataSet.domain(dataSet.axisY());
123 Domain domain3 = dataSet.domain(dataSet.axisY());
124 Domain domain4 = domain1.subDomain(rect, viewport.width(),
124 Domain domain4 = domain1.subDomain(rect, viewport.width(),
125 viewport.height());
125 viewport.height());
126 QVERIFY(domain3 == domain4);
126 QVERIFY(domain3 == domain4);
127
127
128 QCOMPARE(spy0.count(), 0);
128 QCOMPARE(spy0.count(), 0);
129 QCOMPARE(spy1.count(), 2);
129 QCOMPARE(spy1.count(), 2);
130 QCOMPARE(spy2.count(), 0);
130 QCOMPARE(spy2.count(), 0);
131 QCOMPARE(spy3.count(), 0);
131 QCOMPARE(spy3.count(), 0);
132 QCOMPARE(spy4.count(), 1);
132 QCOMPARE(spy4.count(), 1);
133 QCOMPARE(spy5.count(), 0);
133 QCOMPARE(spy5.count(), 0);
134 }
134 }
135
135
136 void tst_ChartDataSet::addSeries_data()
136 void tst_ChartDataSet::addSeries_data()
137 {
137 {
138 QTest::addColumn<int>("seriesCount");
138 QTest::addColumn<int>("defaultAxisCount");
139 QTest::addColumn<int>("axisYCount");
139 QTest::addColumn<int>("firstAxisCount");
140 QTest::newRow("2 series, default axis") << 2 << 0;
140 QTest::addColumn<int>("secoundAxisCount");
141 QTest::newRow("2 series, 2 new axis") << 2 << 2;
141 QTest::newRow("2 ,1 ,0") << 2 << 1 << 0;
142 QTest::newRow("2 series, 1 new axis") << 2 << 2;
142 QTest::newRow("2 series, 2 new axis") << 2 << 0 << 2;
143 QTest::newRow("3 series, 3 new axis") << 3 << 3;
143 QTest::newRow("2 series, 1 new axis") << 2 << 0 << 2;
144 QTest::newRow("3 series, 2 new axis") << 3 << 2;
144 QTest::newRow("3 series, 3 new axis") << 3 << 0 << 3;
145 QTest::newRow("3 series, 1 new axis") << 3 << 1;
145 QTest::newRow("3 series, 2 new axis") << 3 << 0 << 2;
146 QTest::newRow("3 series, 1 new axis") << 3 << 0 << 1;
147 QTest::newRow("3 series, default + 1 new axis") << 3 << 0 << 1;
146 }
148 }
147
149
148 void tst_ChartDataSet::addSeries()
150 void tst_ChartDataSet::addSeries()
149 {
151 {
150 QFETCH(int, seriesCount);
152 QFETCH(int, defaultAxisCount);
151 QFETCH(int, axisYCount);
153 QFETCH(int, firstAxisCount);
154 QFETCH(int, secoundAxisCount);
152
155
153 ChartDataSet dataSet;
156 ChartDataSet dataSet;
154
157
155 QSignalSpy spy0(&dataSet, SIGNAL(axisAdded(QChartAxis*)));
158 QSignalSpy spy0(&dataSet, SIGNAL(axisAdded(QChartAxis*)));
156 QSignalSpy spy1(&dataSet,
159 QSignalSpy spy1(&dataSet, SIGNAL(axisRangeChanged(QChartAxis*, QStringList const&)));
157 SIGNAL(axisRangeChanged(QChartAxis*, QStringList const&)));
160 QSignalSpy spy2(&dataSet, SIGNAL(axisRemoved(QChartAxis*)));
158 QSignalSpy spy2(&dataSet, SIGNAL(axisRemoved(QChartAxis*)));
161 QSignalSpy spy3(&dataSet, SIGNAL(seriesAdded(QSeries*)));
159 QSignalSpy spy3(&dataSet, SIGNAL(seriesAdded(QSeries*)));
162 QSignalSpy spy4(&dataSet, SIGNAL(seriesDomainChanged(QSeries*, Domain const&)));
160 QSignalSpy spy4(&dataSet,
163 QSignalSpy spy5(&dataSet, SIGNAL(seriesRemoved(QSeries*)));
161 SIGNAL(seriesDomainChanged(QSeries*, Domain const&)));
162 QSignalSpy spy5(&dataSet, SIGNAL(seriesRemoved(QSeries*)));
163
164
164 QList<QChartAxis*> axisList;
165 for (int i = 0; i < defaultAxisCount; i++) {
166 QLineSeries* series = new QLineSeries();
167 dataSet.addSeries(series);
168 }
165
169
166 for (int i = 0; i < axisYCount; i++) {
170 QChartAxis* firstAxis = new QChartAxis();
167 QChartAxis* axis = new QChartAxis();
168 axisList << axis;
169 }
170
171
171 QList<QChartAxis*>::iterator iterator = axisList.begin();
172 for (int i = 0; i < firstAxisCount; i++) {
173 QLineSeries* series = new QLineSeries();
174 dataSet.addSeries(series, firstAxis);
175 }
172
176
173 for (int i = 0; i < seriesCount; i++) {
177 QChartAxis* secoundAxis = new QChartAxis();
174 QChartAxis* axisY = 0;
178
175 QLineSeries* series = new QLineSeries();
179 for (int i = 0; i < secoundAxisCount; i++) {
176 if (iterator != axisList.end()) {
180 QLineSeries* series = new QLineSeries();
177 axisY = *iterator;
181 dataSet.addSeries(series, secoundAxis);
178 iterator++;
182 }
179 } else if (axisList.count() > 0) {
180 iterator--;
181 axisY = *iterator;
182 iterator++;
183 }
184 dataSet.addSeries(series, axisY);
185 }
186
183
187 //default axis
184 int axisCount = 1;
188 if (axisYCount == 0)
189 axisYCount+=2;
190 else
191 axisYCount++;
192
185
193 QCOMPARE(spy0.count(), axisYCount);
186 if (defaultAxisCount > 0)
194 QCOMPARE(spy1.count(), seriesCount*2);
187 axisCount++;
195 QCOMPARE(spy2.count(), 0);
188 if (firstAxisCount > 0)
196 QCOMPARE(spy3.count(), seriesCount);
189 axisCount++;
197 QCOMPARE(spy4.count(), seriesCount);
190 if (secoundAxisCount > 0)
198 QCOMPARE(spy5.count(), 0);
191 axisCount++;
199
192
200 QCOMPARE(dataSet.domainIndex(), 0);
193 QCOMPARE(spy0.count(), axisCount);
194 QCOMPARE(spy1.count(), (defaultAxisCount + firstAxisCount + secoundAxisCount)*2);
195 QCOMPARE(spy2.count(), 0);
196 QCOMPARE(spy3.count(), defaultAxisCount + firstAxisCount + secoundAxisCount);
197
198 int i = 0;
199 while (defaultAxisCount) {
200 i+=defaultAxisCount;
201 defaultAxisCount--;
202 }
203 int j = 0;
204 while (firstAxisCount>0) {
205 j += firstAxisCount;
206 firstAxisCount--;
207 }
208 int k = 0;
209 while (secoundAxisCount>0) {
210 k += secoundAxisCount;
211 secoundAxisCount--;
212 }
213 QCOMPARE(spy4.count(),i + j + k);
214 QCOMPARE(spy5.count(), 0);
215
216 QCOMPARE(dataSet.domainIndex(), 0);
201 }
217 }
202
218
203 void tst_ChartDataSet::axisY_data()
219 void tst_ChartDataSet::axisY_data()
204 {
220 {
205 QTest::addColumn<QChartAxis*>("axisY");
221 QTest::addColumn<QChartAxis*>("axisY");
206 QTest::newRow("axisY1") << new QChartAxis();
222 QTest::newRow("axisY1") << new QChartAxis();
207 QTest::newRow("axisY2") << new QChartAxis();
223 QTest::newRow("axisY2") << new QChartAxis();
208 }
224 }
209
225
210 void tst_ChartDataSet::axisY()
226 void tst_ChartDataSet::axisY()
211 {
227 {
212 QFETCH(QChartAxis*, axisY);
228 QFETCH(QChartAxis*, axisY);
213
229
214 ChartDataSet dataSet;
230 ChartDataSet dataSet;
215
231
216 QChartAxis* defaultAxisY = dataSet.axisY();
232 QChartAxis* defaultAxisY = dataSet.axisY();
217
233
218 QVERIFY2(defaultAxisY, "Missing axisY.");
234 QVERIFY2(defaultAxisY, "Missing axisY.");
219
235
220 QLineSeries* series1 = new QLineSeries();
236 QLineSeries* series1 = new QLineSeries();
221 dataSet.addSeries(series1);
237 dataSet.addSeries(series1);
222
238
223 QLineSeries* series2 = new QLineSeries();
239 QLineSeries* series2 = new QLineSeries();
224 dataSet.addSeries(series2, axisY);
240 dataSet.addSeries(series2, axisY);
225
241
226 QVERIFY(dataSet.axisY(series1) == defaultAxisY);
242 QVERIFY(dataSet.axisY(series1) == defaultAxisY);
227 QVERIFY(dataSet.axisY(series2) == axisY);
243 QVERIFY(dataSet.axisY(series2) == axisY);
228
244
229
245
230 }
246 }
231
247
232 void tst_ChartDataSet::clearDomains_data()
248 void tst_ChartDataSet::clearDomains_data()
233 {
249 {
234 QTest::addColumn<int>("indexCount");
250 QTest::addColumn<int>("indexCount");
235 QTest::newRow("0") << 0;
251 QTest::newRow("0") << 0;
236 QTest::newRow("1") << 1;
252 QTest::newRow("1") << 1;
237 QTest::newRow("5") << 2;
253 QTest::newRow("5") << 2;
238 QTest::newRow("8") << 3;
254 QTest::newRow("8") << 3;
239 }
255 }
240
256
241 void tst_ChartDataSet::clearDomains()
257 void tst_ChartDataSet::clearDomains()
242 {
258 {
243 QFETCH(int, indexCount);
259 QFETCH(int, indexCount);
244
260
245 Domain domain1(0, 100, 0, 100);
261 Domain domain1(0, 100, 0, 100);
246 QLineSeries* series = new QLineSeries();
262 QLineSeries* series = new QLineSeries();
247 series->add(0, 0);
263 series->add(0, 0);
248 series->add(100, 100);
264 series->add(100, 100);
249
265
250 ChartDataSet dataSet;
266 ChartDataSet dataSet;
251
267
252 QCOMPARE(dataSet.domainIndex(), 0);
268 QCOMPARE(dataSet.domainIndex(), 0);
253
269
254 dataSet.addSeries(series);
270 dataSet.addSeries(series);
255
271
256 Domain domain2 = dataSet.domain(dataSet.axisY());
272 Domain domain2 = dataSet.domain(dataSet.axisY());
257
273
258 QVERIFY(domain2 == domain1);
274 QVERIFY(domain2 == domain1);
259
275
260 QList<Domain> domains;
276 QList<Domain> domains;
261
277
262 domains << domain1;
278 domains << domain1;
263
279
264 for (int i = 0; i < indexCount; i++) {
280 for (int i = 0; i < indexCount; i++) {
265 dataSet.addDomain(QRect(0, 0, 10, 10), QRect(0, 0, 100, 100));
281 dataSet.addDomain(QRect(0, 0, 10, 10), QRect(0, 0, 100, 100));
266 domains << dataSet.domain(dataSet.axisY());
282 domains << dataSet.domain(dataSet.axisY());
267 }
283 }
268
284
269 QSignalSpy spy0(&dataSet, SIGNAL(axisAdded(QChartAxis*)));
285 QSignalSpy spy0(&dataSet, SIGNAL(axisAdded(QChartAxis*)));
270 QSignalSpy spy1(&dataSet,
286 QSignalSpy spy1(&dataSet,
271 SIGNAL(axisRangeChanged(QChartAxis*, QStringList const&)));
287 SIGNAL(axisRangeChanged(QChartAxis*, QStringList const&)));
272 QSignalSpy spy2(&dataSet, SIGNAL(axisRemoved(QChartAxis*)));
288 QSignalSpy spy2(&dataSet, SIGNAL(axisRemoved(QChartAxis*)));
273 QSignalSpy spy3(&dataSet, SIGNAL(seriesAdded(QSeries*)));
289 QSignalSpy spy3(&dataSet, SIGNAL(seriesAdded(QSeries*)));
274 QSignalSpy spy4(&dataSet,
290 QSignalSpy spy4(&dataSet,
275 SIGNAL(seriesDomainChanged(QSeries*, Domain const&)));
291 SIGNAL(seriesDomainChanged(QSeries*, Domain const&)));
276 QSignalSpy spy5(&dataSet, SIGNAL(seriesRemoved(QSeries*)));
292 QSignalSpy spy5(&dataSet, SIGNAL(seriesRemoved(QSeries*)));
277
293
278 dataSet.clearDomains(indexCount);
294 dataSet.clearDomains(indexCount);
279
295
280 QCOMPARE(dataSet.domainIndex(), indexCount);
296 QCOMPARE(dataSet.domainIndex(), indexCount);
281
297
282 domain2 = dataSet.domain(dataSet.axisY());
298 domain2 = dataSet.domain(dataSet.axisY());
283
299
284 QVERIFY(domain2 == domains.at(indexCount));
300 QVERIFY(domain2 == domains.at(indexCount));
285
301
286 QCOMPARE(spy0.count(), 0);
302 QCOMPARE(spy0.count(), 0);
287 QCOMPARE(spy1.count(), 0);
303 QCOMPARE(spy1.count(), 0);
288 QCOMPARE(spy2.count(), 0);
304 QCOMPARE(spy2.count(), 0);
289 QCOMPARE(spy3.count(), 0);
305 QCOMPARE(spy3.count(), 0);
290 QCOMPARE(spy4.count(), 0);
306 QCOMPARE(spy4.count(), 0);
291 QCOMPARE(spy5.count(), 0);
307 QCOMPARE(spy5.count(), 0);
292 }
308 }
293
309
294 void tst_ChartDataSet::domain_data()
310 void tst_ChartDataSet::domain_data()
295 {
311 {
296 QTest::addColumn<Domain>("domain1");
312 QTest::addColumn<Domain>("domain1");
297 QTest::addColumn<Domain>("domain2");
313 QTest::addColumn<Domain>("domain2");
298 QTest::addColumn<Domain>("domain3");
314 QTest::addColumn<Domain>("domain3");
299 QTest::addColumn<Domain>("domain");
315 QTest::addColumn<Domain>("domain");
300 QTest::newRow("Domain(0,10,0,10)") << Domain(0, 10, 0, 10)
316 QTest::newRow("Domain(0,10,0,10)") << Domain(0, 10, 0, 10)
301 << Domain(0, 5, 0, 5) << Domain(0, 3, 0, 3) << Domain(0, 10, 0, 10);
317 << Domain(0, 5, 0, 5) << Domain(0, 3, 0, 3) << Domain(0, 10, 0, 10);
302 QTest::newRow("Domain(-1,11,0,11)") << Domain(-1, 10, 0, 10)
318 QTest::newRow("Domain(-1,11,0,11)") << Domain(-1, 10, 0, 10)
303 << Domain(0, 11, 0, 11) << Domain(0, 3, 0, 3)
319 << Domain(0, 11, 0, 11) << Domain(0, 3, 0, 3)
304 << Domain(-1, 11, 0, 11);
320 << Domain(-1, 11, 0, 11);
305 QTest::newRow("Domain(-5,5,1,8)") << Domain(-5, 0, 1, 1)
321 QTest::newRow("Domain(-5,5,1,8)") << Domain(-5, 0, 1, 1)
306 << Domain(0, 5, 0, 8) << Domain(1, 2, 1, 2) << Domain(-5, 5, 0, 8);
322 << Domain(0, 5, 0, 8) << Domain(1, 2, 1, 2) << Domain(-5, 5, 0, 8);
307 }
323 }
308
324
309 void tst_ChartDataSet::domain()
325 void tst_ChartDataSet::domain()
310 {
326 {
311 QFETCH(Domain, domain1);
327 QFETCH(Domain, domain1);
312 QFETCH(Domain, domain2);
328 QFETCH(Domain, domain2);
313 QFETCH(Domain, domain3);
329 QFETCH(Domain, domain3);
314 QFETCH(Domain, domain);
330 QFETCH(Domain, domain);
315
331
316 ChartDataSet dataSet;
332 ChartDataSet dataSet;
317 QLineSeries* series1 = new QLineSeries();
333 QLineSeries* series1 = new QLineSeries();
318 series1->add(domain1.m_minX, domain1.m_minY);
334 series1->add(domain1.m_minX, domain1.m_minY);
319 series1->add(domain1.m_maxX, domain1.m_maxY);
335 series1->add(domain1.m_maxX, domain1.m_maxY);
320 QLineSeries* series2 = new QLineSeries();
336 QLineSeries* series2 = new QLineSeries();
321 series2->add(domain2.m_minX, domain2.m_minY);
337 series2->add(domain2.m_minX, domain2.m_minY);
322 series2->add(domain2.m_maxX, domain2.m_maxY);
338 series2->add(domain2.m_maxX, domain2.m_maxY);
323 QLineSeries* series3 = new QLineSeries();
339 QLineSeries* series3 = new QLineSeries();
324 series3->add(domain3.m_minX, domain3.m_minY);
340 series3->add(domain3.m_minX, domain3.m_minY);
325 series3->add(domain3.m_maxX, domain3.m_maxY);
341 series3->add(domain3.m_maxX, domain3.m_maxY);
326
342
327 QSignalSpy spy0(&dataSet, SIGNAL(axisAdded(QChartAxis*)));
343 QSignalSpy spy0(&dataSet, SIGNAL(axisAdded(QChartAxis*)));
328 QSignalSpy spy1(&dataSet,
344 QSignalSpy spy1(&dataSet,
329 SIGNAL(axisRangeChanged(QChartAxis*, QStringList const&)));
345 SIGNAL(axisRangeChanged(QChartAxis*, QStringList const&)));
330 QSignalSpy spy2(&dataSet, SIGNAL(axisRemoved(QChartAxis*)));
346 QSignalSpy spy2(&dataSet, SIGNAL(axisRemoved(QChartAxis*)));
331 QSignalSpy spy3(&dataSet, SIGNAL(seriesAdded(QSeries*)));
347 QSignalSpy spy3(&dataSet, SIGNAL(seriesAdded(QSeries*)));
332 QSignalSpy spy4(&dataSet,
348 QSignalSpy spy4(&dataSet,
333 SIGNAL(seriesDomainChanged(QSeries*, Domain const&)));
349 SIGNAL(seriesDomainChanged(QSeries*, Domain const&)));
334 QSignalSpy spy5(&dataSet, SIGNAL(seriesRemoved(QSeries*)));
350 QSignalSpy spy5(&dataSet, SIGNAL(seriesRemoved(QSeries*)));
335
351
336 dataSet.addSeries(series1);
352 dataSet.addSeries(series1);
337 dataSet.addSeries(series2);
353 dataSet.addSeries(series2);
338 dataSet.addSeries(series3);
354 dataSet.addSeries(series3);
339
355
340 QCOMPARE(dataSet.domainIndex(), 0);
356 QCOMPARE(dataSet.domainIndex(), 0);
341 QVERIFY2(dataSet.domain(dataSet.axisY()) == domain, "Domain not equal");
357 QVERIFY2(dataSet.domain(dataSet.axisY()) == domain, "Domain not equal");
342
358
343 QCOMPARE(spy0.count(), 2);
359 QCOMPARE(spy0.count(), 2);
344 QCOMPARE(spy1.count(), 6);
360 QCOMPARE(spy1.count(), 6);
345 QCOMPARE(spy2.count(), 0);
361 QCOMPARE(spy2.count(), 0);
346 QCOMPARE(spy3.count(), 3);
362 QCOMPARE(spy3.count(), 3);
347 QCOMPARE(spy4.count(), 3);
363 QCOMPARE(spy4.count(), 6);
348 QCOMPARE(spy5.count(), 0);
364 QCOMPARE(spy5.count(), 0);
349 }
365 }
350
366
351 void tst_ChartDataSet::nextpreviousDomain_data()
367 void tst_ChartDataSet::nextpreviousDomain_data()
352 {
368 {
353 QTest::addColumn<QRectF>("rect");
369 QTest::addColumn<QRectF>("rect");
354 QTest::addColumn<QRectF>("viewport");
370 QTest::addColumn<QRectF>("viewport");
355 QTest::newRow("400x400,1000x1000") << QRectF(200, 200, 600, 600)
371 QTest::newRow("400x400,1000x1000") << QRectF(200, 200, 600, 600)
356 << QRectF(0, 0, 1000, 1000);
372 << QRectF(0, 0, 1000, 1000);
357 QTest::newRow("600x600,1000x1000") << QRectF(100, 100, 700, 700)
373 QTest::newRow("600x600,1000x1000") << QRectF(100, 100, 700, 700)
358 << QRectF(0, 0, 1000, 1000);
374 << QRectF(0, 0, 1000, 1000);
359 QTest::newRow("200x200,1000x1000") << QRectF(400, 400, 600, 600)
375 QTest::newRow("200x200,1000x1000") << QRectF(400, 400, 600, 600)
360 << QRectF(0, 0, 1000, 1000);
376 << QRectF(0, 0, 1000, 1000);
361 }
377 }
362
378
363 void tst_ChartDataSet::nextpreviousDomain()
379 void tst_ChartDataSet::nextpreviousDomain()
364 {
380 {
365
381
366 QFETCH(QRectF, rect);
382 QFETCH(QRectF, rect);
367 QFETCH(QRectF, viewport);
383 QFETCH(QRectF, viewport);
368
384
369 ChartDataSet dataSet;
385 ChartDataSet dataSet;
370
386
371 Domain domain1(0, 1000, 0, 1000);
387 Domain domain1(0, 1000, 0, 1000);
372 QLineSeries* series = new QLineSeries();
388 QLineSeries* series = new QLineSeries();
373 series->add(0, 0);
389 series->add(0, 0);
374 series->add(1000, 1000);
390 series->add(1000, 1000);
375
391
376 dataSet.addSeries(series);
392 dataSet.addSeries(series);
377
393
378 QCOMPARE(dataSet.domainIndex(), 0);
394 QCOMPARE(dataSet.domainIndex(), 0);
379
395
380 Domain domain2 = dataSet.domain(dataSet.axisY());
396 Domain domain2 = dataSet.domain(dataSet.axisY());
381 QVERIFY(domain1 == domain2);
397 QVERIFY(domain1 == domain2);
382
398
383 dataSet.addDomain(rect, viewport);
399 dataSet.addDomain(rect, viewport);
384 QCOMPARE(dataSet.domainIndex(), 1);
400 QCOMPARE(dataSet.domainIndex(), 1);
385 Domain domain3 = dataSet.domain(dataSet.axisY());
401 Domain domain3 = dataSet.domain(dataSet.axisY());
386 Domain domain4 = domain1.subDomain(rect, viewport.width(),
402 Domain domain4 = domain1.subDomain(rect, viewport.width(),
387 viewport.height());
403 viewport.height());
388 QVERIFY(domain3 == domain4);
404 QVERIFY(domain3 == domain4);
389
405
390 dataSet.addDomain(rect, viewport);
406 dataSet.addDomain(rect, viewport);
391 QCOMPARE(dataSet.domainIndex(), 2);
407 QCOMPARE(dataSet.domainIndex(), 2);
392 Domain domain5 = dataSet.domain(dataSet.axisY());
408 Domain domain5 = dataSet.domain(dataSet.axisY());
393 Domain domain6 = domain3.subDomain(rect, viewport.width(),
409 Domain domain6 = domain3.subDomain(rect, viewport.width(),
394 viewport.height());
410 viewport.height());
395 QVERIFY(domain5 == domain6);
411 QVERIFY(domain5 == domain6);
396
412
397 dataSet.addDomain(rect, viewport);
413 dataSet.addDomain(rect, viewport);
398 QCOMPARE(dataSet.domainIndex(), 3);
414 QCOMPARE(dataSet.domainIndex(), 3);
399 Domain domain7 = dataSet.domain(dataSet.axisY());
415 Domain domain7 = dataSet.domain(dataSet.axisY());
400 Domain domain8 = domain5.subDomain(rect, viewport.width(),
416 Domain domain8 = domain5.subDomain(rect, viewport.width(),
401 viewport.height());
417 viewport.height());
402 QVERIFY(domain7 == domain8);
418 QVERIFY(domain7 == domain8);
403
419
404 QSignalSpy spy0(&dataSet, SIGNAL(axisAdded(QChartAxis*)));
420 QSignalSpy spy0(&dataSet, SIGNAL(axisAdded(QChartAxis*)));
405 QSignalSpy spy1(&dataSet,
421 QSignalSpy spy1(&dataSet,
406 SIGNAL(axisRangeChanged(QChartAxis*, QStringList const&)));
422 SIGNAL(axisRangeChanged(QChartAxis*, QStringList const&)));
407 QSignalSpy spy2(&dataSet, SIGNAL(axisRemoved(QChartAxis*)));
423 QSignalSpy spy2(&dataSet, SIGNAL(axisRemoved(QChartAxis*)));
408 QSignalSpy spy3(&dataSet, SIGNAL(seriesAdded(QSeries*)));
424 QSignalSpy spy3(&dataSet, SIGNAL(seriesAdded(QSeries*)));
409 QSignalSpy spy4(&dataSet,
425 QSignalSpy spy4(&dataSet,
410 SIGNAL(seriesDomainChanged(QSeries*, Domain const&)));
426 SIGNAL(seriesDomainChanged(QSeries*, Domain const&)));
411 QSignalSpy spy5(&dataSet, SIGNAL(seriesRemoved(QSeries*)));
427 QSignalSpy spy5(&dataSet, SIGNAL(seriesRemoved(QSeries*)));
412
428
413 Domain domain;
429 Domain domain;
414
430
415 bool previous = dataSet.previousDomain();
431 bool previous = dataSet.previousDomain();
416 QCOMPARE(previous, true);
432 QCOMPARE(previous, true);
417 QCOMPARE(dataSet.domainIndex(), 2);
433 QCOMPARE(dataSet.domainIndex(), 2);
418 domain = dataSet.domain(dataSet.axisY());
434 domain = dataSet.domain(dataSet.axisY());
419 QVERIFY(domain == domain5);
435 QVERIFY(domain == domain5);
420 previous = dataSet.previousDomain();
436 previous = dataSet.previousDomain();
421 QCOMPARE(previous, true);
437 QCOMPARE(previous, true);
422 QCOMPARE(dataSet.domainIndex(), 1);
438 QCOMPARE(dataSet.domainIndex(), 1);
423 domain = dataSet.domain(dataSet.axisY());
439 domain = dataSet.domain(dataSet.axisY());
424 QVERIFY(domain == domain3);
440 QVERIFY(domain == domain3);
425 previous = dataSet.previousDomain();
441 previous = dataSet.previousDomain();
426 QCOMPARE(previous, true);
442 QCOMPARE(previous, true);
427 QCOMPARE(dataSet.domainIndex(), 0);
443 QCOMPARE(dataSet.domainIndex(), 0);
428 domain = dataSet.domain(dataSet.axisY());
444 domain = dataSet.domain(dataSet.axisY());
429 QVERIFY(domain == domain1);
445 QVERIFY(domain == domain1);
430 previous = dataSet.previousDomain();
446 previous = dataSet.previousDomain();
431 QCOMPARE(previous, false);
447 QCOMPARE(previous, false);
432 QCOMPARE(dataSet.domainIndex(), 0);
448 QCOMPARE(dataSet.domainIndex(), 0);
433 domain = dataSet.domain(dataSet.axisY());
449 domain = dataSet.domain(dataSet.axisY());
434 QVERIFY(domain == domain1);
450 QVERIFY(domain == domain1);
435
451
436 bool next = dataSet.nextDomain();
452 bool next = dataSet.nextDomain();
437 QCOMPARE(next, true);
453 QCOMPARE(next, true);
438 QCOMPARE(dataSet.domainIndex(),1);
454 QCOMPARE(dataSet.domainIndex(),1);
439 next = dataSet.nextDomain();
455 next = dataSet.nextDomain();
440 QCOMPARE(next, true);
456 QCOMPARE(next, true);
441 QCOMPARE(dataSet.domainIndex(),2);
457 QCOMPARE(dataSet.domainIndex(),2);
442 next = dataSet.nextDomain();
458 next = dataSet.nextDomain();
443 QCOMPARE(next, true);
459 QCOMPARE(next, true);
444 QCOMPARE(dataSet.domainIndex(),3);
460 QCOMPARE(dataSet.domainIndex(),3);
445 next = dataSet.nextDomain();
461 next = dataSet.nextDomain();
446 QCOMPARE(next, false);
462 QCOMPARE(next, false);
447 QCOMPARE(dataSet.domainIndex(),3);
463 QCOMPARE(dataSet.domainIndex(),3);
448
464
449
465
450 QCOMPARE(spy0.count(), 0);
466 QCOMPARE(spy0.count(), 0);
451 QCOMPARE(spy1.count(), 12);
467 QCOMPARE(spy1.count(), 12);
452 QCOMPARE(spy2.count(), 0);
468 QCOMPARE(spy2.count(), 0);
453 QCOMPARE(spy3.count(), 0);
469 QCOMPARE(spy3.count(), 0);
454 QCOMPARE(spy4.count(), 6);
470 QCOMPARE(spy4.count(), 6);
455 QCOMPARE(spy5.count(), 0);
471 QCOMPARE(spy5.count(), 0);
456 }
472 }
457
473
458 void tst_ChartDataSet::removeSeries_data()
474 void tst_ChartDataSet::removeSeries_data()
459 {
475 {
460 QTest::addColumn<int>("seriesCount");
476 QTest::addColumn<int>("seriesCount");
461 QTest::addColumn<int>("axisYCount");
477 QTest::addColumn<int>("axisYCount");
462 QTest::newRow("2 series, default axis") << 2 << 0;
478 QTest::newRow("2 series, default axis") << 2 << 0;
463 QTest::newRow("2 series, 2 new axis") << 2 << 2;
479 QTest::newRow("2 series, 2 new axis") << 2 << 2;
464 QTest::newRow("2 series, 1 new axis") << 2 << 2;
480 QTest::newRow("2 series, 1 new axis") << 2 << 2;
465 QTest::newRow("3 series, 3 new axis") << 3 << 3;
481 QTest::newRow("3 series, 3 new axis") << 3 << 3;
466 QTest::newRow("3 series, 2 new axis") << 3 << 2;
482 QTest::newRow("3 series, 2 new axis") << 3 << 2;
467 QTest::newRow("3 series, 1 new axis") << 3 << 1;
483 QTest::newRow("3 series, 1 new axis") << 3 << 1;
468 }
484 }
469
485
470 void tst_ChartDataSet::removeSeries()
486 void tst_ChartDataSet::removeSeries()
471 {
487 {
472 QFETCH(int, seriesCount);
488 QFETCH(int, seriesCount);
473 QFETCH(int, axisYCount);
489 QFETCH(int, axisYCount);
474
490
475 ChartDataSet dataSet;
491 ChartDataSet dataSet;
476
492
477 QList<QChartAxis*> axisList;
493 QList<QChartAxis*> axisList;
478 QList<QSeries*> seriesList;
494 QList<QSeries*> seriesList;
479
495
480 for (int i = 0; i < axisYCount; i++) {
496 for (int i = 0; i < axisYCount; i++) {
481 QChartAxis* axis = new QChartAxis();
497 QChartAxis* axis = new QChartAxis();
482 axisList << axis;
498 axisList << axis;
483 }
499 }
484
500
485 QList<QChartAxis*>::iterator iterator = axisList.begin();
501 QList<QChartAxis*>::iterator iterator = axisList.begin();
486
502
487 for (int i = 0; i < seriesCount; i++) {
503 for (int i = 0; i < seriesCount; i++) {
488 QChartAxis* axisY = 0;
504 QChartAxis* axisY = 0;
489 QLineSeries* series = new QLineSeries();
505 QLineSeries* series = new QLineSeries();
490 if (iterator != axisList.end()) {
506 if (iterator != axisList.end()) {
491 axisY = *iterator;
507 axisY = *iterator;
492 iterator++;
508 iterator++;
493 } else if (axisList.count() > 0) {
509 } else if (axisList.count() > 0) {
494 iterator--;
510 iterator--;
495 axisY = *iterator;
511 axisY = *iterator;
496 iterator++;
512 iterator++;
497 }
513 }
498 dataSet.addSeries(series, axisY);
514 dataSet.addSeries(series, axisY);
499 seriesList << series;
515 seriesList << series;
500 }
516 }
501
517
502 QSignalSpy spy0(&dataSet, SIGNAL(axisAdded(QChartAxis*)));
518 QSignalSpy spy0(&dataSet, SIGNAL(axisAdded(QChartAxis*)));
503 QSignalSpy spy1(&dataSet,
519 QSignalSpy spy1(&dataSet,
504 SIGNAL(axisRangeChanged(QChartAxis*, QStringList const&)));
520 SIGNAL(axisRangeChanged(QChartAxis*, QStringList const&)));
505 QSignalSpy spy2(&dataSet, SIGNAL(axisRemoved(QChartAxis*)));
521 QSignalSpy spy2(&dataSet, SIGNAL(axisRemoved(QChartAxis*)));
506 QSignalSpy spy3(&dataSet, SIGNAL(seriesAdded(QSeries*)));
522 QSignalSpy spy3(&dataSet, SIGNAL(seriesAdded(QSeries*)));
507 QSignalSpy spy4(&dataSet,
523 QSignalSpy spy4(&dataSet,
508 SIGNAL(seriesDomainChanged(QSeries*, Domain const&)));
524 SIGNAL(seriesDomainChanged(QSeries*, Domain const&)));
509 QSignalSpy spy5(&dataSet, SIGNAL(seriesRemoved(QSeries*)));
525 QSignalSpy spy5(&dataSet, SIGNAL(seriesRemoved(QSeries*)));
510
526
511 for (int i = 0; i < seriesCount; i++) {
527 for (int i = 0; i < seriesCount; i++) {
512 dataSet.removeSeries(seriesList.at(i));
528 dataSet.removeSeries(seriesList.at(i));
513 }
529 }
514
530
515 //default axis
531 //default axis
516 if (axisYCount == 0)
532 if (axisYCount == 0)
517 axisYCount++;
533 axisYCount++;
518
534
519 QCOMPARE(spy0.count(), 0);
535 QCOMPARE(spy0.count(), 0);
520 QCOMPARE(spy1.count(), 0);
536 QCOMPARE(spy1.count(), 0);
521 QCOMPARE(spy2.count(), axisYCount);
537 QCOMPARE(spy2.count(), axisYCount);
522 QCOMPARE(spy3.count(), 0);
538 QCOMPARE(spy3.count(), 0);
523 QCOMPARE(spy4.count(), 0);
539 QCOMPARE(spy4.count(), 0);
524 QCOMPARE(spy5.count(), seriesCount);
540 QCOMPARE(spy5.count(), seriesCount);
525
541
526 QCOMPARE(dataSet.domainIndex(), 0);
542 QCOMPARE(dataSet.domainIndex(), 0);
527
543
528 qDeleteAll(seriesList);
544 qDeleteAll(seriesList);
529 }
545 }
530
546
531 void tst_ChartDataSet::removeAllSeries_data()
547 void tst_ChartDataSet::removeAllSeries_data()
532 {
548 {
533 QTest::addColumn<int>("seriesCount");
549 QTest::addColumn<int>("seriesCount");
534 QTest::addColumn<int>("axisYCount");
550 QTest::addColumn<int>("axisYCount");
535 QTest::newRow("2 series, default axis") << 2 << 0;
551 QTest::newRow("2 series, default axis") << 2 << 0;
536 QTest::newRow("2 series, 2 new axis") << 2 << 2;
552 QTest::newRow("2 series, 2 new axis") << 2 << 2;
537 QTest::newRow("2 series, 1 new axis") << 2 << 2;
553 QTest::newRow("2 series, 1 new axis") << 2 << 2;
538 QTest::newRow("3 series, 3 new axis") << 3 << 3;
554 QTest::newRow("3 series, 3 new axis") << 3 << 3;
539 QTest::newRow("3 series, 2 new axis") << 3 << 2;
555 QTest::newRow("3 series, 2 new axis") << 3 << 2;
540 QTest::newRow("3 series, 1 new axis") << 3 << 1;
556 QTest::newRow("3 series, 1 new axis") << 3 << 1;
541 }
557 }
542
558
543 void tst_ChartDataSet::removeAllSeries()
559 void tst_ChartDataSet::removeAllSeries()
544 {
560 {
545 QFETCH(int, seriesCount);
561 QFETCH(int, seriesCount);
546 QFETCH(int, axisYCount);
562 QFETCH(int, axisYCount);
547
563
548 ChartDataSet dataSet;
564 ChartDataSet dataSet;
549
565
550 QList<QChartAxis*> axisList;
566 QList<QChartAxis*> axisList;
551
567
552 for (int i = 0; i < axisYCount; i++) {
568 for (int i = 0; i < axisYCount; i++) {
553 QChartAxis* axis = new QChartAxis();
569 QChartAxis* axis = new QChartAxis();
554 axisList << axis;
570 axisList << axis;
555 }
571 }
556
572
557 QList<QChartAxis*>::iterator iterator = axisList.begin();
573 QList<QChartAxis*>::iterator iterator = axisList.begin();
558
574
559 for (int i = 0; i < seriesCount; i++) {
575 for (int i = 0; i < seriesCount; i++) {
560 QChartAxis* axisY = 0;
576 QChartAxis* axisY = 0;
561 QLineSeries* series = new QLineSeries();
577 QLineSeries* series = new QLineSeries();
562 if (iterator != axisList.end()) {
578 if (iterator != axisList.end()) {
563 axisY = *iterator;
579 axisY = *iterator;
564 iterator++;
580 iterator++;
565 } else if (axisList.count() > 0) {
581 } else if (axisList.count() > 0) {
566 iterator--;
582 iterator--;
567 axisY = *iterator;
583 axisY = *iterator;
568 iterator++;
584 iterator++;
569 }
585 }
570 dataSet.addSeries(series, axisY);
586 dataSet.addSeries(series, axisY);
571 }
587 }
572
588
573 QSignalSpy spy0(&dataSet, SIGNAL(axisAdded(QChartAxis*)));
589 QSignalSpy spy0(&dataSet, SIGNAL(axisAdded(QChartAxis*)));
574 QSignalSpy spy1(&dataSet, SIGNAL(axisRangeChanged(QChartAxis*, QStringList const&)));
590 QSignalSpy spy1(&dataSet, SIGNAL(axisRangeChanged(QChartAxis*, QStringList const&)));
575 QSignalSpy spy2(&dataSet, SIGNAL(axisRemoved(QChartAxis*)));
591 QSignalSpy spy2(&dataSet, SIGNAL(axisRemoved(QChartAxis*)));
576 QSignalSpy spy3(&dataSet, SIGNAL(seriesAdded(QSeries*)));
592 QSignalSpy spy3(&dataSet, SIGNAL(seriesAdded(QSeries*)));
577 QSignalSpy spy4(&dataSet, SIGNAL(seriesDomainChanged(QSeries*, Domain const&)));
593 QSignalSpy spy4(&dataSet, SIGNAL(seriesDomainChanged(QSeries*, Domain const&)));
578 QSignalSpy spy5(&dataSet, SIGNAL(seriesRemoved(QSeries*)));
594 QSignalSpy spy5(&dataSet, SIGNAL(seriesRemoved(QSeries*)));
579
595
580 dataSet.removeAllSeries();
596 dataSet.removeAllSeries();
581 //default axis
597 //default axis
582 if (axisYCount == 0)
598 if (axisYCount == 0)
583 axisYCount++;
599 axisYCount++;
584
600
585 QCOMPARE(spy0.count(), 0);
601 QCOMPARE(spy0.count(), 0);
586 QCOMPARE(spy1.count(), 0);
602 QCOMPARE(spy1.count(), 0);
587 QCOMPARE(spy2.count(), axisYCount);
603 QCOMPARE(spy2.count(), axisYCount);
588 QCOMPARE(spy3.count(), 0);
604 QCOMPARE(spy3.count(), 0);
589 QCOMPARE(spy4.count(), 0);
605 QCOMPARE(spy4.count(), 0);
590 QCOMPARE(spy5.count(), seriesCount);
606 QCOMPARE(spy5.count(), seriesCount);
591
607
592 QCOMPARE(dataSet.domainIndex(), 0);
608 QCOMPARE(dataSet.domainIndex(), 0);
593 }
609 }
594
610
595
611
596 QTEST_MAIN(tst_ChartDataSet)
612 QTEST_MAIN(tst_ChartDataSet)
597 #include "tst_chartdataset.moc"
613 #include "tst_chartdataset.moc"
598
614
General Comments 0
You need to be logged in to leave comments. Login now