##// END OF EJS Templates
added labels to series, intergrated with test app. minor hack to test app
sauimone -
r167:023d2c8150a8
parent child
Show More
@@ -1,157 +1,159
1 1 #include <limits.h>
2 2 #include <QVector>
3 3 #include <QDebug>
4 4 #include "barchartmodel_p.h"
5 5
6 6 QTCOMMERCIALCHART_BEGIN_NAMESPACE
7 7
8 8 BarChartModel::BarChartModel(QObject *parent) :
9 9 QObject(parent)
10 10 ,mRunningId(1)
11 11 {
12 12 }
13 13
14 14 BarChartModel::~BarChartModel()
15 15 {
16 16 // qDebug() << "BarChartModel::~BarChartModel";
17 17 foreach (DataContainer* c, mDataModel) {
18 18 delete c;
19 19 }
20 20 }
21 21
22 22 int BarChartModel::addData(QList<qreal> data)
23 23 {
24 24 // qDebug() << "BarChartModel::addData" << data.count();
25 25 DataContainer* c = new DataContainer(data,mRunningId);
26 26 mDataModel.append(c);
27 27 mRunningId++;
28 emit modelUpdated();
28 29 return mRunningId-1;
29 30 }
30 31
31 32 void BarChartModel::removeData(int id)
32 33 {
33 34 // qDebug() << "BarChartModel::removeData";
34 35 foreach(DataContainer* c, mDataModel) {
35 36 if (c->mId == id) {
36 37 mDataModel.removeOne(c);
37 38 delete c;
38 39 }
39 40 }
41 emit modelUpdated();
40 42 }
41 43
42 44 int BarChartModel::countRows()
43 45 {
44 46 // qDebug() << "BarChartModel::countRows";
45 47 return mDataModel.count();
46 48 }
47 49
48 50 int BarChartModel::countColumns()
49 51 {
50 52 // qDebug() << "BarChartModel::countColumns";
51 53 int count(0);
52 54 for (int i=0; i<mDataModel.count(); i++){
53 55 // TODO: can we assume that all series have same number of values? If not. then which values are empty?
54 56 int temp = mDataModel.at(i)->countColumns();
55 57 if (temp > count) {
56 58 count = temp;
57 59 }
58 60 }
59 61 return count;
60 62 }
61 63
62 64 int BarChartModel::countTotalItems()
63 65 {
64 66 // qDebug() << "BarChartModel::countTotalItems";
65 67 int total = mDataModel.count() * countColumns();
66 68 return total;
67 69 }
68 70
69 int BarChartModel::min()
71 qreal BarChartModel::min()
70 72 {
71 73 // qDebug() << "BarChartModel::min";
72 74 Q_ASSERT(mDataModel.count() > 0);
73 75 // TODO: make min and max members and update them when data changes.
74 76 // This is slower since they are checked every time, even if data is same since previous call.
75 int min = INT_MAX;
77 qreal min = INT_MAX;
76 78
77 79 for (int i=0; i <mDataModel.count(); i++) {
78 80 int itemCount = mDataModel.at(i)->countColumns();
79 81 for (int j=0; j<itemCount; j++) {
80 int temp = mDataModel.at(i)->valueAt(j);
82 qreal temp = mDataModel.at(i)->valueAt(j);
81 83 if (temp < min) {
82 84 min = temp;
83 85 }
84 86 }
85 87 }
86 88 return min;
87 89 }
88 90
89 int BarChartModel::max()
91 qreal BarChartModel::max()
90 92 {
91 93 // qDebug() << "BarChartModel::max";
92 94 Q_ASSERT(mDataModel.count() > 0);
93 95
94 96 // TODO: make min and max members and update them when data changes.
95 97 // This is slower since they are checked every time, even if data is same since previous call.
96 int max = INT_MIN;
98 qreal max = INT_MIN;
97 99
98 100 for (int i=0; i <mDataModel.count(); i++) {
99 101 int itemCount = mDataModel.at(i)->countColumns();
100 102 for (int j=0; j<itemCount; j++) {
101 int temp = mDataModel.at(i)->valueAt(j);
103 qreal temp = mDataModel.at(i)->valueAt(j);
102 104 if (temp > max) {
103 105 max = temp;
104 106 }
105 107 }
106 108 }
107 109
108 110 return max;
109 111 }
110 112
111 113 qreal BarChartModel::valueAt(int series, int item)
112 114 {
113 115 // qDebug() << "BarChartModel::valueAt" << series << item;
114 116 if ((series < 0) || (series >= mDataModel.count())) {
115 117 // No series, no value.
116 118 return 0;
117 119 } else if ((item < 0) || (item >= mDataModel.at(series)->countColumns())) {
118 120 // No item, no value.
119 121 return 0;
120 122 }
121 123
122 124 // qDebug() << "ValueAt" << series << item << "=" << mDataModel.at(series)->valueAt(item);
123 125 return mDataModel.at(series)->valueAt(item);
124 126 }
125 127
126 128 qreal BarChartModel::columnSum(int column)
127 129 {
128 130 // qDebug() << "BarChartModel::columnSum";
129 131 int sum(0);
130 132 int count = mDataModel.count(); // Count rows
131 133
132 134 for (int row = 0; row < count; row++) {
133 135 if (column < mDataModel.at(row)->countColumns()) {
134 136 sum += mDataModel.at(row)->valueAt(column);
135 137 }
136 138 }
137 139 return sum;
138 140 }
139 141
140 142 qreal BarChartModel::maxColumnSum()
141 143 {
142 144 // qDebug() << "BarChartModel::maxColumnSum";
143 145 int max = INT_MIN;
144 146 int count = countColumns();
145 147
146 148 for (int col=0; col<count; col++) {
147 149 int sum = columnSum(col);
148 150 if (sum > max) {
149 151 max = sum;
150 152 }
151 153 }
152 154 return max;
153 155 }
154 156
155 157 #include "moc_barchartmodel_p.cpp"
156 158
157 159 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,63 +1,62
1 1 #ifndef BARCHARTMODEL_H
2 2 #define BARCHARTMODEL_H
3 3
4 4 #include <QObject>
5 5 #include "qchartglobal.h"
6 6
7 7 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8 8
9 9 // Model for bar chart. Internal class.
10 10 // TODO: Implement as QAbstractItemModel?
11 11
12 12 class BarChartModel : public QObject //, public QAbstractItemModel
13 13 {
14 14 Q_OBJECT
15 15 public:
16 16 explicit BarChartModel(QObject *parent = 0);
17 17 ~BarChartModel();
18 18
19 19 // Adds data to model. returns id.
20 20 int addData(QList<qreal> data);
21 21 void removeData(int id);
22 22
23 23 int countRows(); // Number of series in model
24 24 int countColumns(); // Maximum number of items in series
25 25 int countTotalItems(); // Total items in all series. Includes empty items.
26 26
27 // TODO: qreal these
28 int max(); // Maximum value of all series
29 int min(); // Minimum value of all series
27 qreal max(); // Maximum value of all series
28 qreal min(); // Minimum value of all series
30 29 qreal valueAt(int series, int item);
31 30
32 31 qreal columnSum(int column);
33 32 qreal maxColumnSum(); // returns maximum sum of items in all columns.
34 33
35 34 signals:
36 35 void modelUpdated();
37 36
38 37 public slots:
39 38
40 39 private:
41 40
42 41 // Little helper class.
43 42 class DataContainer {
44 43 public:
45 44 DataContainer(QList<qreal> data, int id) : mId(id), mData(data) {}
46 45 int countColumns() { return mData.count(); }
47 46 qreal valueAt(int item) { return mData.at(item); }
48 47
49 48 int mId; // TODO: Is this needed?
50 49 private:
51 50 QList<qreal> mData;
52 51 };
53 52
54 53 // Owned. N series. each has a list of values.
55 54 QList<DataContainer*> mDataModel;
56 55 int mRunningId;
57 56 int mMaxColumns; // longest series in datamodel
58 57
59 58 };
60 59
61 60 QTCOMMERCIALCHART_END_NAMESPACE
62 61
63 62 #endif // BARCHARTMODEL_H
@@ -1,59 +1,73
1 1 #include <limits.h>
2 2 #include <QDebug>
3 3 #include "barchartseriesbase.h"
4 4 #include "bargroup.h"
5 5 #include "barchartmodel_p.h"
6 6
7 7 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8 8
9 9 BarChartSeriesBase::BarChartSeriesBase(QObject *parent)
10 10 : QChartSeries(parent)
11 ,mModel(*(new BarChartModel(this))) // TODO: is this ok?
11 ,mModel(new BarChartModel(this))
12 12 {
13 13 }
14 14
15 15 int BarChartSeriesBase::addData(QList<qreal> data)
16 16 {
17 return mModel.addData(data);
17 return mModel->addData(data);
18 18 }
19 19
20 20 void BarChartSeriesBase::removeData(int id)
21 21 {
22 mModel.removeData(id);
22 mModel->removeData(id);
23 }
24
25 void BarChartSeriesBase::setLabels(QList<QString> labels)
26 {
27 mLabels = labels;
23 28 }
24 29
25 30 qreal BarChartSeriesBase::min()
26 31 {
27 return mModel.min();
32 return mModel->min();
28 33 }
29 34
30 35 qreal BarChartSeriesBase::max()
31 36 {
32 return mModel.max();
37 return mModel->max();
33 38 }
34 39
35 40 int BarChartSeriesBase::countColumns()
36 41 {
37 return mModel.countColumns();
42 return mModel->countColumns();
38 43 }
39 44
40 45 qreal BarChartSeriesBase::valueAt(int series, int item)
41 46 {
42 qDebug() << "BarChartSeriesBase::valueAt" << series << item;
43 return mModel.valueAt(series,item);
47 // qDebug() << "BarChartSeriesBase::valueAt" << series << item;
48 return mModel->valueAt(series,item);
44 49 }
45 50
46 51 qreal BarChartSeriesBase::maxColumnSum()
47 52 {
48 qDebug() << "BarChartSeriesBase::maxColumnSum" << mModel.maxColumnSum();
49 return mModel.maxColumnSum();
53 // qDebug() << "BarChartSeriesBase::maxColumnSum" << mModel->maxColumnSum();
54 return mModel->maxColumnSum();
50 55 }
51 56
52 57 BarChartModel& BarChartSeriesBase::model()
53 58 {
54 return mModel;
59 return *mModel;
60 }
61
62 QString BarChartSeriesBase::label(int item)
63 {
64 if ((item>=0) && (item < mLabels.count())) {
65 return mLabels.at(item);
66 }
67
68 return QString("");
55 69 }
56 70
57 71 #include "moc_barchartseriesbase.cpp"
58 72
59 73 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,52 +1,55
1 1 #ifndef BARCHARTSERIESBASE_H
2 2 #define BARCHARTSERIESBASE_H
3 3
4 4 #include <QList>
5 5 #include <QAbstractItemModel>
6 6 #include "qchartseries.h"
7 7 #include "qchartglobal.h"
8 8
9 9 QTCOMMERCIALCHART_BEGIN_NAMESPACE
10 10
11 11 class BarGroupBase;
12 12 class BarChartModel;
13 13
14 14 // Container for series
15 15 class QTCOMMERCIALCHART_EXPORT BarChartSeriesBase : public QChartSeries
16 16 {
17 17 Q_OBJECT
18 18 protected:
19 19 BarChartSeriesBase(QObject* parent=0);
20 20
21 21 public:
22 22 // from QChartSeries
23 23 virtual QChartSeriesType type() const { return QChartSeries::SeriesTypeInvalid; }
24 24
25 25 // TODO: << operator for convinience
26 26 // Returns id for vector.
27 27 int addData(QList<qreal> data);
28 28 void removeData(int id);
29 void setLabels(QList<QString> labels);
29 30
31 // These shouldn't be visible to chart series user. However, ChartDataSet needs to access them, and friends are evil.
30 32 qreal min();
31 33 qreal max();
32 34 int countColumns(); // Count items in one series.
33 35 qreal valueAt(int series, int item);
34 36 qreal maxColumnSum();
35 37
36 38 BarChartModel& model();
39 QString label(int item);
37 40
38 41 signals:
39 42 void changed(int index);
40 43
41 44 public Q_SLOTS:
42 45
43 46 private:
44 47
45 BarChartModel& mModel;
46 BarGroupBase* mBarGroup;
48 BarChartModel* mModel;
47 49
50 QList<QString> mLabels;
48 51 };
49 52
50 53 QTCOMMERCIALCHART_END_NAMESPACE
51 54
52 55 #endif // BARCHARTSERIESBASE_H
@@ -1,70 +1,69
1 1 #include "bargroup.h"
2 2 #include "bar_p.h"
3 3 #include "barlabel_p.h"
4 4 #include <QDebug>
5 5
6 6 QTCOMMERCIALCHART_BEGIN_NAMESPACE
7 7
8 8 BarGroup::BarGroup(BarChartSeries& series, QGraphicsItem *parent) :
9 9 BarGroupBase(series,parent)
10 10 {
11 11 mBarDefaultWidth = 10;
12 12 }
13 13
14 14 void BarGroup::layoutChanged()
15 15 {
16 16 qDebug() << "BarGroup::layoutChanged";
17 17 // Scale bars to new layout
18 18 // Layout for bars:
19 19 if (mModel.countRows() <= 0) {
20 20 return;
21 21 }
22 22
23 23 if (childItems().count() == 0) {
24 24 qDebug() << "WARNING: BarGroup::layoutChanged called before graphics items are created!";
25 25 return;
26 26 }
27 27
28 28 // TODO: better way to auto-layout?
29 29 // Use reals for accurancy (we might get some compiler warnings... :)
30 30 int itemCount = mModel.countColumns();
31 31 int seriesCount = mModel.countRows();
32 32
33 33 qreal tW = mWidth;
34 34 qreal tH = mHeight;
35 qreal tM = mMax;
35 qreal tM = mModel.max();
36 36 qreal scale = (tH/tM);
37
38 37 qreal tC = itemCount+1;
39 38 qreal xStepPerSeries = (tW/tC);
40 39
41 40 // Scaling.
42 41 int itemIndex(0);
43 42 int labelIndex = itemCount * seriesCount;
44 43
45 44 for (int item=0; item < itemCount; item++) {
46 45 qreal xPos = xStepPerSeries * item + ((tW + mBarDefaultWidth*seriesCount)/(itemCount*2));
47 46 qreal yPos = mHeight;
48 47 for (int series = 0; series < seriesCount; series++) {
49 48 qreal barHeight = mModel.valueAt(series, item) * scale;
50 49 Bar* bar = reinterpret_cast<Bar*> (childItems().at(itemIndex));
51 50
52 51 // TODO: width settable per bar?
53 52 bar->resize(mBarDefaultWidth, barHeight);
54 53 bar->setColor(mColors.at(series));
55 54 bar->setPos(xPos, yPos-barHeight); // item*posStep+startPos + series * mBarDefaultWidth, mHeight);
56 55 itemIndex++;
57 56 xPos += mBarDefaultWidth;
58 57 }
59 58
60 59 // TODO: Layout for labels, remove magic number
61 60 xPos = xStepPerSeries * item + ((tW + mBarDefaultWidth*seriesCount)/(itemCount*2));
62 61 BarLabel* label = reinterpret_cast<BarLabel*> (childItems().at(labelIndex));
63 62 label->setPos(xPos, mHeight + 20);
64 63 labelIndex++;
65 64 }
66 65
67 66 mLayoutDirty = true;
68 67 }
69 68
70 69 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,127 +1,131
1 1 #include "bargroupbase.h"
2 2 #include "bar_p.h"
3 3 #include "barlabel_p.h"
4 4 #include "separator_p.h"
5 5 #include "barchartseriesbase.h"
6 6 #include <QDebug>
7 7
8 8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9 9
10 10 BarGroupBase::BarGroupBase(BarChartSeriesBase& series, QGraphicsItem *parent)
11 11 : ChartItem(parent)
12 12 ,mBarDefaultWidth(20) // TODO: remove hard coding, when we have layout code ready
13 13 ,mLayoutSet(false)
14 14 ,mLayoutDirty(true)
15 ,mTheme(0)
16 15 ,mSeparatorsVisible(true)
17 16 ,mModel(series.model())
17 ,mSeries(series)
18 18 {
19 dataChanged();
19 20 }
20 21
21 22 void BarGroupBase::setSeparatorsVisible(bool visible)
22 23 {
23 24 mSeparatorsVisible = visible;
24 25 }
25 26
26 27 void BarGroupBase::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
27 28 {
28 29 // qDebug() << "BarGroupBase::paint" << childItems().count();
29 30 if (!mLayoutSet) {
30 31 qDebug() << "BarGroupBase::paint called without layout set. Aborting.";
31 32 return;
32 33 }
33 34 // if (mLayoutDirty) {
34 35 // Layout or data has changed. Need to redraw.
35 36 foreach(QGraphicsItem* i, childItems()) {
36 37 i->paint(painter,option,widget);
37 38 }
38 39 // }
39 40 }
40 41
41 42 QRectF BarGroupBase::boundingRect() const
42 43 {
43 44 return QRectF(0,0,mWidth,mHeight);
44 45 }
45 46
46 47 void BarGroupBase::setBarWidth( int w )
47 48 {
48 49 mBarDefaultWidth = w;
49 50 }
50 51
51 52 int BarGroupBase::addColor( QColor color )
52 53 {
53 54 // qDebug() << "BarGroupBase::addColor";
54 55 int colorIndex = mColors.count();
55 56 mColors.append(color);
56 57 return colorIndex;
57 58 }
58 59
59 60 void BarGroupBase::resetColors()
60 61 {
61 62 // qDebug() << "BarGroupBase::resetColors";
62 63 mColors.clear();
63 64 }
64 65
65 66 void BarGroupBase::dataChanged()
66 67 {
67 68 // qDebug() << "BarGroupBase::dataChanged";
68 69
69 70 // Delete old bars
70 71 foreach (QGraphicsItem* item, childItems()) {
71 72 delete item;
72 73 }
73 74
74 75 // Create new graphic items for bars
75 76 int totalItems = mModel.countTotalItems(); // mSeries.countTotalItems();
76 77 for (int i=0; i<totalItems; i++) {
77 78 Bar *bar = new Bar(this);
78 79 childItems().append(bar);
79 80 }
80 81
81 82 // TODO: labels from series. This creates just some example labels
82 83 int count = mModel.countColumns(); // mSeries.countColumns();
83 84 for (int i=0; i<count; i++) {
84 85 BarLabel* label = new BarLabel(this);
85 QString text("Label " + QString::number(i));
86 label->set(text);
86 // QString text("Label " + QString::number(i));
87 label->set(mSeries.label(i));
87 88 childItems().append(label);
88 89 }
89 90
90 91 count = mModel.countColumns() - 1; // mSeries.countColumns() - 1; // There is one less separator than columns
91 92 for (int i=0; i<count; i++) {
92 93 Separator* sep = new Separator(this);
93 94 sep->setColor(QColor(255,0,0,255)); // TODO: color for separations from theme
94 95 childItems().append(sep);
95 96 }
96 97
97 98 // TODO: if (autolayout) { layoutChanged() } or something
98 99 mLayoutDirty = true;
99 100 }
100 101
101 102 //handlers
102 103
103 104 void BarGroupBase::handleModelChanged(int index)
104 105 {
105 // qDebug() << "BarGroupBase::handleModelChanged" << index;
106 qDebug() << "BarGroupBase::handleModelChanged" << index;
106 107 dataChanged();
107 108 }
108 109
109 110 void BarGroupBase::handleDomainChanged(const Domain& domain)
110 111 {
111 112 // qDebug() << "BarGroupBase::handleDomainChanged";
112 dataChanged();
113
114 // TODO: Figure out the use case for this.
115 // Affects the size of visible item, so layout is changed.
116 // layoutChanged();
113 117 }
114 118
115 119 void BarGroupBase::handleGeometryChanged(const QRectF& rect)
116 120 {
117 121 // qDebug() << "BarGroupBase::handleGeometryChanged";
118 122 mWidth = rect.width();
119 123 mHeight = rect.height();
120 124 layoutChanged();
121 125 mLayoutSet = true;
122 126 setPos(rect.topLeft());
123 127 }
124 128
125 129 #include "moc_bargroupbase.cpp"
126 130
127 131 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,71 +1,62
1 1 #ifndef BARGROUPBASE_H
2 2 #define BARGROUPBASE_H
3 3
4 #include "charttheme_p.h"
5 4 #include "chartitem_p.h"
6 //#include "barlabel_p.h"
7 //#include "bar_p.h"
8 5 #include "barchartseriesbase.h"
9 6 #include "barchartmodel_p.h"
10 7 #include <QGraphicsItem>
11 8
12 9 QTCOMMERCIALCHART_BEGIN_NAMESPACE
13 10
14 11 // Base Class for bar groups. Common implemantation of different groups. Not to be instantiated.
15 12 class BarGroupBase : public QObject, public ChartItem
16 13 {
17 14 Q_OBJECT
18 15 public:
19 16 BarGroupBase(BarChartSeriesBase& series, QGraphicsItem *parent = 0);
20 17 void setSeparatorsVisible(bool visible = true);
21 18
22 19 public: // From ChartItem
23 void setSize(const QSizeF &size){};
24 void setPlotDomain(const PlotDomain& data){};
20 // void setSize(const QSizeF &size){};
25 21
26 22 // From QGraphicsItem
27 23 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
28 24 QRectF boundingRect() const;
29 25
30 // From ChartThemeObserver
31 // void themeChanged(ChartTheme *theme);
32
33 26 // TODO: these may change with layout awarness.
34 27 void setBarWidth( int w );
35 28 int addColor( QColor color );
36 29 void resetColors();
37 30
31 // TODO: Consider the domain for layoutChanged. May be use case, may not be. If it is, then the derived classes need to implement it
38 32 virtual void dataChanged(); // data of series has changed -> need to recalculate bar sizes
39 33 virtual void layoutChanged() = 0; // layout has changed -> need to recalculate bar sizes
40 34
41 35 protected slots:
42 36 void handleModelChanged(int index);
43 37 void handleDomainChanged(const Domain& domain);
44 38 void handleGeometryChanged(const QRectF& size);
45 39
46
47 40 protected:
48 41
49 42 // TODO: consider these.
50 int mMin; // Min and max values of data. (updated when data is changed, used when drawing)
51 int mMax;
43 //int mMin; // Min and max values of data. (updated when data is changed, used when drawing)
44 //int mMax;
52 45
53 46 int mHeight; // Layout spesific
54 47 int mWidth;
55 48 int mBarDefaultWidth;
56 49
57 50 bool mLayoutSet; // True, if component has been laid out.
58 51 bool mLayoutDirty;
59 52
60 53 QList<QColor> mColors; // List of colors for series for now
61
62 ChartTheme* mTheme;
63 54 bool mSeparatorsVisible;
64
65 55 BarChartModel& mModel;
56 BarChartSeriesBase& mSeries;
66 57
67 58 };
68 59
69 60 QTCOMMERCIALCHART_END_NAMESPACE
70 61
71 62 #endif // BARGROUPBASE_H
@@ -1,86 +1,83
1 1 #include "stackedbargroup.h"
2 2 #include "bar_p.h"
3 3 #include "barlabel_p.h"
4 4 #include "separator_p.h"
5 5 #include <QDebug>
6 6
7 7 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8 8
9 9 StackedBarGroup::StackedBarGroup(StackedBarChartSeries& series, QGraphicsItem *parent) :
10 10 BarGroupBase(series,parent)
11 11 {
12 12 }
13 13
14 14 void StackedBarGroup::layoutChanged()
15 15 {
16 16 qDebug() << "StackedBarGroup::layoutChanged";
17 17 // Scale bars to new layout
18 18 // Layout for bars:
19 19 if (mModel.countRows() <= 0) {
20 20 // Nothing to do.
21 21 return;
22 22 }
23 23
24 24 if (mModel.countColumns() == 0) {
25 25 // Nothing to do
26 26 return;
27 27 }
28 28
29 29 if (childItems().count() == 0) {
30 30 qDebug() << "WARNING: StackedBarGroup::layoutChanged called before graphics items are created!";
31 31 return;
32 32 }
33 33
34 34 // TODO: better way to auto-layout
35 35 // Use reals for accurancy (we might get some compiler warnings... :)
36 36 // TODO: use temp variable for column count...
37 37 qreal maxSum = mModel.maxColumnSum();
38 38 qreal h = mHeight;
39 39 qreal scale = (h / maxSum);
40 40
41 41 int itemIndex(0);
42 42 qreal tW = mWidth;
43 43 qreal tC = mModel.countColumns() + 1;
44 44 qreal xStep = (tW/tC);
45 45 qreal xPos = ((tW/tC) - mBarDefaultWidth / 2);
46 46 int labelIndex = mModel.countRows() * mModel.countColumns();
47 47
48 48 for (int column = 0; column < mModel.countColumns(); column++) {
49 49 qreal yPos = h;
50 50 for (int row=0; row < mModel.countRows(); row++) {
51 51 qreal barHeight = mModel.valueAt(row, column) * scale;
52 52 Bar* bar = reinterpret_cast<Bar*> (childItems().at(itemIndex));
53 53
54 // TODO: width settable per bar?
55 // TODO: theme stuff
56 // mTheme->themeForSeries();
57 54 bar->resize(mBarDefaultWidth, barHeight);
58 55 bar->setColor(mColors.at(row));
59 56 bar->setPos(xPos, yPos-barHeight);
60 57 itemIndex++;
61 58 yPos -= barHeight;
62 59 }
63 60
64 61 // TODO: Layout for labels, remove magic number
65 62 BarLabel* label = reinterpret_cast<BarLabel*> (childItems().at(labelIndex));
66 63 label->setPos(xPos, mHeight + 20);
67 64 labelIndex++;
68 65 xPos += xStep;
69 66 }
70 67
71 68
72 69 // Position separators
73 70 int separatorIndex = labelIndex; // Separators are after labels in childItems(). TODO: better way to store these?
74 71 xPos = xStep + xStep/2; // Initial position is between first and second group. ie one and half steps from left.
75 72 for (int s=0; s < mModel.countColumns() - 1; s++) {
76 73 Separator* sep = reinterpret_cast<Separator*> (childItems().at(separatorIndex));
77 74 sep->setPos(xPos,0);
78 75 sep->setSize(QSizeF(1,mHeight));
79 76 xPos += xStep;
80 77 separatorIndex++;
81 78 }
82 79
83 80 mLayoutDirty = true;
84 81 }
85 82
86 83 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,160 +1,160
1 1 #include "chartdataset_p.h"
2 2 //series
3 3 #include "qlinechartseries.h"
4 4 #include "barchartseries.h"
5 5 #include "stackedbarchartseries.h"
6 6 #include "percentbarchartseries.h"
7 7 #include "qpieseries.h"
8 8 #include "qscatterseries.h"
9 9
10 10 QTCOMMERCIALCHART_BEGIN_NAMESPACE
11 11
12 12 ChartDataSet::ChartDataSet(QObject *parent):QObject(parent)
13 13 {
14 14 Domain domain;
15 15 m_domains<<domain;
16 16 }
17 17
18 18 ChartDataSet::~ChartDataSet()
19 19 {
20 20 // TODO Auto-generated destructor stub
21 21 }
22 22
23 23 const Domain& ChartDataSet::domain() const
24 24 {
25 25 return m_domains[m_domainIndex];
26 26 }
27 27
28 28 void ChartDataSet::addSeries(QChartSeries* series)
29 29 {
30 30 // TODO: we should check the series not already added
31 31 m_chartSeries << series;
32 32 m_domainIndex = 0;
33 33 m_domains.resize(1);
34 34
35 35 Domain& domain = m_domains[m_domainIndex];
36 36
37 37 switch(series->type())
38 38 {
39 39 case QChartSeries::SeriesTypeLine: {
40 40
41 41 QLineChartSeries* xyseries = static_cast<QLineChartSeries*>(series);
42 42
43 43 for (int i = 0; i < xyseries->count(); i++)
44 44 {
45 45 qreal x = xyseries->x(i);
46 46 qreal y = xyseries->y(i);
47 47 domain.m_minX = qMin(domain.m_minX,x);
48 48 domain.m_minY = qMin(domain.m_minY,y);
49 49 domain.m_maxX = qMax(domain.m_maxX,x);
50 50 domain.m_maxY = qMax(domain.m_maxY,y);
51 51 }
52 52 break;
53 53 }
54 54 case QChartSeries::SeriesTypeBar: {
55 55
56 56 BarChartSeries* barSeries = static_cast<BarChartSeries*>(series);
57 57 qreal x = barSeries->countColumns();
58 58 qreal y = barSeries->max();
59 59 domain.m_minX = qMin(domain.m_minX,x);
60 60 domain.m_minY = qMin(domain.m_minY,y);
61 61 domain.m_maxX = qMax(domain.m_maxX,x);
62 62 domain.m_maxY = qMax(domain.m_maxY,y);
63 break;
63 64 }
64 break;
65 65 case QChartSeries::SeriesTypeStackedBar: {
66 66
67 67 StackedBarChartSeries* stackedBarSeries = static_cast<StackedBarChartSeries*>(series);
68 68 qreal x = stackedBarSeries->countColumns();
69 69 qreal y = stackedBarSeries->maxColumnSum();
70 70 domain.m_minX = qMin(domain.m_minX,x);
71 71 domain.m_minY = qMin(domain.m_minY,y);
72 72 domain.m_maxX = qMax(domain.m_maxX,x);
73 73 domain.m_maxY = qMax(domain.m_maxY,y);
74 }
75 74 break;
75 }
76 76 case QChartSeries::SeriesTypePercentBar: {
77 77
78 78 PercentBarChartSeries* percentBarSeries = static_cast<PercentBarChartSeries*>(series);
79 79 qreal x = percentBarSeries->countColumns();
80 80 domain.m_minX = qMin(domain.m_minX,x);
81 81 domain.m_minY = 0;
82 82 domain.m_maxX = qMax(domain.m_maxX,x);
83 83 domain.m_maxY = 100;
84 }
85 84 break;
85 }
86 86
87 87 case QChartSeries::SeriesTypePie: {
88 88 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
89 89 // TODO: domain stuff
90 90 break;
91 91 }
92 92
93 93 case QChartSeries::SeriesTypeScatter: {
94 94 QScatterSeries *scatterSeries = qobject_cast<QScatterSeries *>(series);
95 95 Q_ASSERT(scatterSeries);
96 96 foreach (QPointF point, scatterSeries->data()) {
97 97 domain.m_minX = qMin(domain.m_minX, point.x());
98 98 domain.m_maxX = qMax(domain.m_maxX, point.x());
99 99 domain.m_minY = qMin(domain.m_minY, point.y());
100 100 domain.m_maxY = qMax(domain.m_maxY, point.y());
101 101 }
102 102 break;
103 103 }
104 104
105 105 default: {
106 106 qDebug()<<__FUNCTION__<<"type" << series->type()<<"not supported";
107 107 return;
108 108 break;
109 109 }
110 110
111 111 }
112 112
113 113 emit seriesAdded(series);
114 114 emit domainChanged(domain);
115 115 }
116 116
117 117 bool ChartDataSet::nextDomain()
118 118 {
119 119 if (m_domainIndex < m_domains.count() - 1) {
120 120 m_domainIndex++;
121 121 emit domainChanged(m_domains[m_domainIndex]);
122 122 return true;
123 123 }
124 124 else {
125 125 return false;
126 126 }
127 127 }
128 128
129 129 bool ChartDataSet::previousDomain()
130 130 {
131 131 if (m_domainIndex > 0) {
132 132 m_domainIndex--;
133 133 emit domainChanged(m_domains[m_domainIndex]);
134 134 return true;
135 135 }
136 136 else {
137 137 return false;
138 138 }
139 139 }
140 140
141 141 void ChartDataSet::clearDomains()
142 142 {
143 143 if (m_domainIndex > 0) {
144 144 m_domainIndex = 0;
145 145 emit domainChanged(m_domains[m_domainIndex]);
146 146 }
147 147 }
148 148
149 149 void ChartDataSet::addDomain(const Domain& domain)
150 150 {
151 151 m_domains.resize(m_domainIndex + 1);
152 152 m_domains << domain;
153 153 m_domainIndex++;
154 154
155 155 emit domainChanged(domain);
156 156 }
157 157
158 158 #include "moc_chartdataset_p.cpp"
159 159
160 160 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,209 +1,212
1 1 #include "charttheme_p.h"
2 2 #include "qchart.h"
3 3
4 4
5 5 //series
6 6 #include "barchartseries.h"
7 7 #include "stackedbarchartseries.h"
8 8 #include "percentbarchartseries.h"
9 9 #include "qlinechartseries.h"
10 10 #include "qpieseries.h"
11 11
12 12 //items
13 13 #include "axisitem_p.h"
14 14 #include "bargroup.h"
15 15 #include "stackedbargroup.h"
16 16 #include "linechartitem_p.h"
17 17 #include "percentbargroup.h"
18 18 #include "piepresenter.h"
19 19
20 20 //themes
21 21 #include "chartthemevanilla_p.h"
22 22 #include "chartthemeicy_p.h"
23 23 #include "chartthemegrayscale_p.h"
24 24 #include "chartthemescientific_p.h"
25 25
26 26
27 27 QTCOMMERCIALCHART_BEGIN_NAMESPACE
28 28
29 29 /* TODO
30 30 case QChart::ChartThemeUnnamed1:
31 31 m_seriesThemes.append(SeriesTheme(QColor(QRgb(0xff3fa9f5)), 2));
32 32 m_seriesThemes.append(SeriesTheme(QColor(QRgb(0xff7AC943)), 2));
33 33 m_seriesThemes.append(SeriesTheme(QColor(QRgb(0xffFF931E)), 2));
34 34 m_seriesThemes.append(SeriesTheme(QColor(QRgb(0xffFF1D25)), 2));
35 35 m_seriesThemes.append(SeriesTheme(QColor(QRgb(0xffFF7BAC)), 2));
36 36
37 37 m_gradientStartColor = QColor(QRgb(0xfff3dc9e));
38 38 m_gradientEndColor = QColor(QRgb(0xffafafaf));
39 39 */
40 40
41 41 ChartTheme::ChartTheme(QChart::ChartTheme id)
42 42 {
43 43 m_id = id;
44 44 m_seriesColor.append(QRgb(0xff000000));
45 45 m_seriesColor.append(QRgb(0xff707070));
46 46 m_gradientStartColor = QColor(QRgb(0xffffffff));
47 47 m_gradientEndColor = QColor(QRgb(0xffafafaf));
48 48 }
49 49
50 50
51 51 ChartTheme* ChartTheme::createTheme(QChart::ChartTheme theme)
52 52 {
53 53 switch(theme) {
54 54 case QChart::ChartThemeDefault:
55 55 return new ChartTheme();
56 56 case QChart::ChartThemeVanilla:
57 57 return new ChartThemeVanilla();
58 58 case QChart::ChartThemeIcy:
59 59 return new ChartThemeIcy();
60 60 case QChart::ChartThemeGrayscale:
61 61 return new ChartThemeGrayscale();
62 62 case QChart::ChartThemeScientific:
63 63 return new ChartThemeScientific();
64 64 }
65 65 }
66 66
67 67 void ChartTheme::decorate(QChart* chart)
68 68 {
69 69 QLinearGradient backgroundGradient;
70 70 backgroundGradient.setColorAt(0.0, m_gradientStartColor);
71 71 backgroundGradient.setColorAt(1.0, m_gradientEndColor);
72 72 backgroundGradient.setCoordinateMode(QGradient::ObjectBoundingMode);
73 73 chart->setChartBackgroundBrush(backgroundGradient);
74 74 }
75 75 //TODO helper to by removed later
76 76 void ChartTheme::decorate(ChartItem* item, QChartSeries* series,int count)
77 77 {
78 78 switch(series->type())
79 79 {
80 80 case QChartSeries::SeriesTypeLine: {
81 81 QLineChartSeries* s = static_cast<QLineChartSeries*>(series);
82 82 LineChartItem* i = static_cast<LineChartItem*>(item);
83 83 decorate(i,s,count);
84 84 break;
85 85 }
86 86 case QChartSeries::SeriesTypeBar: {
87 87 BarChartSeries* b = static_cast<BarChartSeries*>(series);
88 88 BarGroup* i = static_cast<BarGroup*>(item);
89 89 decorate(i,b,count);
90 90 break;
91 91 }
92 92 case QChartSeries::SeriesTypeStackedBar: {
93 93 StackedBarChartSeries* s = static_cast<StackedBarChartSeries*>(series);
94 94 StackedBarGroup* i = static_cast<StackedBarGroup*>(item);
95 95 decorate(i,s,count);
96 96 break;
97 97 }
98 98 case QChartSeries::SeriesTypePercentBar: {
99 99 PercentBarChartSeries* s = static_cast<PercentBarChartSeries*>(series);
100 100 PercentBarGroup* i = static_cast<PercentBarGroup*>(item);
101 101 decorate(i,s,count);
102 102 break;
103 103 }
104 104 case QChartSeries::SeriesTypePie: {
105 105 QPieSeries* s = static_cast<QPieSeries*>(series);
106 106 PiePresenter* i = static_cast<PiePresenter*>(item);
107 107 decorate(i,s,count);
108 108 break;
109 109 }
110 110 default:
111 111 qDebug()<<"Wrong item to be decorated by theme";
112 112 break;
113 113 }
114 114
115 115 }
116 116
117 117 void ChartTheme::decorate(LineChartItem* item, QLineChartSeries* series,int count)
118 118 {
119 119 QPen pen;
120 120 if(pen != series->pen()){
121 121 item->setPen(series->pen());
122 122 return;
123 123 }
124 124 pen.setColor(m_seriesColor.at(count%m_seriesColor.size()));
125 125 pen.setWidthF(2);
126 126 item->setPen(pen);
127 127 }
128 128
129 129 void ChartTheme::decorate(BarGroup* item, BarChartSeries* series,int count)
130 130 {
131 for (int i=0; i< m_seriesColor.count(); i++) {
131 item->resetColors();
132 for (int i=0; i<m_seriesColor.count(); i++) {
132 133 item->addColor(m_seriesColor.at(i));
133 134 }
134 135 item->addColor(QColor(255,0,0,128));
135 136 item->addColor(QColor(255,255,0,128));
136 137 item->addColor(QColor(0,255,0,128));
137 138 item->addColor(QColor(0,0,255,128));
138 139 item->addColor(QColor(255,128,0,128));
139 140 }
140 141
141 142 void ChartTheme::decorate(StackedBarGroup* item, StackedBarChartSeries* series,int count)
142 143 {
144 item->resetColors();
143 145 for (int i=0; i< m_seriesColor.count(); i++) {
144 146 item->addColor(m_seriesColor.at(i));
145 147 }
146 148 item->addColor(QColor(255,0,0,128));
147 149 item->addColor(QColor(255,255,0,128));
148 150 item->addColor(QColor(0,255,0,128));
149 151 item->addColor(QColor(0,0,255,128));
150 152 item->addColor(QColor(255,128,0,128));
151 153 }
152 154
153 155 void ChartTheme::decorate(PercentBarGroup* item, PercentBarChartSeries* series,int count)
154 156 {
157 item->resetColors();
155 158 for (int i=0; i< m_seriesColor.count(); i++) {
156 159 item->addColor(m_seriesColor.at(i));
157 160 }
158 161 item->addColor(QColor(255,0,0,128));
159 162 item->addColor(QColor(255,255,0,128));
160 163 item->addColor(QColor(0,255,0,128));
161 164 item->addColor(QColor(0,0,255,128));
162 165 item->addColor(QColor(255,128,0,128));
163 166 }
164 167
165 168 void ChartTheme::decorate(PiePresenter* item, QPieSeries* series, int /*count*/)
166 169 {
167 170 // create a list of slice colors based on current theme
168 171 int i = 0;
169 172 QList<QColor> colors;
170 173 while (colors.count() < series->count()) {
171 174
172 175 // get base color
173 176 QColor c = m_seriesColor[i++];
174 177 i = i % m_seriesColor.count();
175 178
176 179 // -1 means achromatic color -> cannot manipulate lightness
177 180 // TODO: find a better way to randomize lightness
178 181 if (c.toHsv().hue() == -1)
179 182 qWarning() << "ChartTheme::decorate() warning: achromatic theme color";
180 183
181 184 // randomize lightness
182 185 qreal f = 50 + (qrand() % 100); // 50 is 50% darker, 100 is the same, 150 is 50% lighter
183 186 c = c.lighter(f);
184 187
185 188 // find duplicates
186 189 bool isUnique = true;
187 190 foreach (QColor color, colors) {
188 191 if (c == color)
189 192 isUnique = false;
190 193 }
191 194
192 195 // add to array if unique
193 196 //if (isUnique)
194 197 colors << c;
195 198 }
196 199
197 200 // finally update colors
198 201 QList<QPieSlice> slices;
199 202 for (int i=0; i<series->count(); i++) {
200 203 QPieSlice slice = series->slice(i);
201 204 slice.m_color = colors.at(i);
202 205 slices << slice;
203 206 }
204 207
205 208 series->set(slices);
206 209 }
207 210
208 211
209 212 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,401 +1,414
1 1 #include "mainwidget.h"
2 2 #include "dataseriedialog.h"
3 3 #include "qchartseries.h"
4 4 #include "qpieseries.h"
5 5 #include <qlinechartseries.h>
6 6 #include <barchartseries.h>
7 7 #include <stackedbarchartseries.h>
8 8 #include <percentbarchartseries.h>
9 9 #include <QPushButton>
10 10 #include <QComboBox>
11 11 #include <QSpinBox>
12 12 #include <QCheckBox>
13 13 #include <QGridLayout>
14 14 #include <QHBoxLayout>
15 15 #include <QLabel>
16 16 #include <QSpacerItem>
17 17 #include <QMessageBox>
18 18 #include <cmath>
19 19 #include <QDebug>
20 20 #include <QStandardItemModel>
21 21
22 22
23 23 QTCOMMERCIALCHART_USE_NAMESPACE
24 24
25 25 MainWidget::MainWidget(QWidget *parent) :
26 26 QWidget(parent)
27 27 {
28 28 m_chartWidget = new QChartView(this);
29 29 m_chartWidget->setRubberBandPolicy(QChartView::HorizonalRubberBand);
30 30
31 31 // Grid layout for the controls for configuring the chart widget
32 32 QGridLayout *grid = new QGridLayout();
33 33 QPushButton *addSeriesButton = new QPushButton("Add series");
34 34 connect(addSeriesButton, SIGNAL(clicked()), this, SLOT(addSeries()));
35 35 grid->addWidget(addSeriesButton, 0, 1);
36 36 initBackroundCombo(grid);
37 37 initScaleControls(grid);
38 38 initThemeCombo(grid);
39 39 QCheckBox *zoomCheckBox = new QCheckBox("Drag'n drop Zoom");
40 40 connect(zoomCheckBox, SIGNAL(toggled(bool)), m_chartWidget, SLOT(setZoomEnabled(bool)));
41 41 zoomCheckBox->setChecked(true);
42 42 grid->addWidget(zoomCheckBox, grid->rowCount(), 0);
43 43 // add row with empty label to make all the other rows static
44 44 grid->addWidget(new QLabel(""), grid->rowCount(), 0);
45 45 grid->setRowStretch(grid->rowCount() - 1, 1);
46 46
47 47 // Another grid layout as a main layout
48 48 QGridLayout *mainLayout = new QGridLayout();
49 49 mainLayout->addLayout(grid, 0, 0);
50 50
51 51 // Init series type specific controls
52 52 initPieControls();
53 53 mainLayout->addLayout(m_pieLayout, 2, 0);
54 54 // Scatter series specific settings
55 55 // m_scatterLayout = new QGridLayout();
56 56 // m_scatterLayout->addWidget(new QLabel("scatter"), 0, 0);
57 57 // m_scatterLayout->setEnabled(false);
58 58 // mainLayout->addLayout(m_scatterLayout, 1, 0);
59 59
60 60 // Add layouts and the chart widget to the main layout
61 61 mainLayout->addWidget(m_chartWidget, 0, 1, 3, 1);
62 62 setLayout(mainLayout);
63 63
64 64 // force an update to test data
65 65 testDataChanged(0);
66 66 }
67 67
68 68 // Combo box for selecting the chart's background
69 69 void MainWidget::initBackroundCombo(QGridLayout *grid)
70 70 {
71 71 QComboBox *backgroundCombo = new QComboBox(this);
72 72 backgroundCombo->addItem("Color");
73 73 backgroundCombo->addItem("Gradient");
74 74 backgroundCombo->addItem("Image");
75 75 connect(backgroundCombo, SIGNAL(currentIndexChanged(int)),
76 76 this, SLOT(backgroundChanged(int)));
77 77
78 78 grid->addWidget(new QLabel("Background:"), grid->rowCount(), 0);
79 79 grid->addWidget(backgroundCombo, grid->rowCount() - 1, 1);
80 80 }
81 81
82 82 // Scale related controls (auto-scale vs. manual min-max values)
83 83 void MainWidget::initScaleControls(QGridLayout *grid)
84 84 {
85 85 m_autoScaleCheck = new QCheckBox("Automatic scaling");
86 86 connect(m_autoScaleCheck, SIGNAL(stateChanged(int)), this, SLOT(autoScaleChanged(int)));
87 87 // Allow setting also non-sense values (like -2147483648 and 2147483647)
88 88 m_xMinSpin = new QSpinBox();
89 89 m_xMinSpin->setMinimum(INT_MIN);
90 90 m_xMinSpin->setMaximum(INT_MAX);
91 91 m_xMinSpin->setValue(0);
92 92 connect(m_xMinSpin, SIGNAL(valueChanged(int)), this, SLOT(xMinChanged(int)));
93 93 m_xMaxSpin = new QSpinBox();
94 94 m_xMaxSpin->setMinimum(INT_MIN);
95 95 m_xMaxSpin->setMaximum(INT_MAX);
96 96 m_xMaxSpin->setValue(10);
97 97 connect(m_xMaxSpin, SIGNAL(valueChanged(int)), this, SLOT(xMaxChanged(int)));
98 98 m_yMinSpin = new QSpinBox();
99 99 m_yMinSpin->setMinimum(INT_MIN);
100 100 m_yMinSpin->setMaximum(INT_MAX);
101 101 m_yMinSpin->setValue(0);
102 102 connect(m_yMinSpin, SIGNAL(valueChanged(int)), this, SLOT(yMinChanged(int)));
103 103 m_yMaxSpin = new QSpinBox();
104 104 m_yMaxSpin->setMinimum(INT_MIN);
105 105 m_yMaxSpin->setMaximum(INT_MAX);
106 106 m_yMaxSpin->setValue(10);
107 107 connect(m_yMaxSpin, SIGNAL(valueChanged(int)), this, SLOT(yMaxChanged(int)));
108 108
109 109 grid->addWidget(m_autoScaleCheck, grid->rowCount(), 0);
110 110 grid->addWidget(new QLabel("x min:"), grid->rowCount(), 0);
111 111 grid->addWidget(m_xMinSpin, grid->rowCount() - 1, 1);
112 112 grid->addWidget(new QLabel("x max:"), grid->rowCount(), 0);
113 113 grid->addWidget(m_xMaxSpin, grid->rowCount() - 1, 1);
114 114 grid->addWidget(new QLabel("y min:"), grid->rowCount(), 0);
115 115 grid->addWidget(m_yMinSpin, grid->rowCount() - 1, 1);
116 116 grid->addWidget(new QLabel("y max:"), grid->rowCount(), 0);
117 117 grid->addWidget(m_yMaxSpin, grid->rowCount() - 1, 1);
118 118
119 119 m_autoScaleCheck->setChecked(true);
120 120 }
121 121
122 122 // Combo box for selecting theme
123 123 void MainWidget::initThemeCombo(QGridLayout *grid)
124 124 {
125 125 QComboBox *chartTheme = new QComboBox();
126 126 chartTheme->addItem("Default");
127 127 chartTheme->addItem("Vanilla");
128 128 chartTheme->addItem("Icy");
129 129 chartTheme->addItem("Grayscale");
130 130 chartTheme->addItem("Scientific");
131 131 chartTheme->addItem("Unnamed1");
132 132 connect(chartTheme, SIGNAL(currentIndexChanged(int)),
133 133 this, SLOT(changeChartTheme(int)));
134 134 grid->addWidget(new QLabel("Chart theme:"), 8, 0);
135 135 grid->addWidget(chartTheme, 8, 1);
136 136 }
137 137
138 138 void MainWidget::initPieControls()
139 139 {
140 140 // Pie series specific settings
141 141 // Pie size factory
142 142 QDoubleSpinBox *pieSizeSpin = new QDoubleSpinBox();
143 143 pieSizeSpin->setMinimum(LONG_MIN);
144 144 pieSizeSpin->setMaximum(LONG_MAX);
145 145 pieSizeSpin->setValue(1.0);
146 146 pieSizeSpin->setSingleStep(0.1);
147 147 connect(pieSizeSpin, SIGNAL(valueChanged(double)), this, SLOT(setPieSizeFactor(double)));
148 148 // Pie position
149 149 QComboBox *piePosCombo = new QComboBox(this);
150 150 piePosCombo->addItem("Maximized");
151 151 piePosCombo->addItem("Top left");
152 152 piePosCombo->addItem("Top right");
153 153 piePosCombo->addItem("Bottom left");
154 154 piePosCombo->addItem("Bottom right");
155 155 connect(piePosCombo, SIGNAL(currentIndexChanged(int)),
156 156 this, SLOT(setPiePosition(int)));
157 157 m_pieLayout = new QGridLayout();
158 158 m_pieLayout->setEnabled(false);
159 159 m_pieLayout->addWidget(new QLabel("Pie size factor"), 0, 0);
160 160 m_pieLayout->addWidget(pieSizeSpin, 0, 1);
161 161 m_pieLayout->addWidget(new QLabel("Pie position"), 1, 0);
162 162 m_pieLayout->addWidget(piePosCombo, 1, 1);
163 163 }
164 164
165 165 void MainWidget::addSeries()
166 166 {
167 167 DataSerieDialog dialog(m_defaultSeriesName, this);
168 168 connect(&dialog, SIGNAL(accepted(QString, QString)), this, SLOT(addSeries(QString, QString)));
169 169 dialog.exec();
170 170 }
171 171
172 172 void MainWidget::addSeries(QString series, QString data)
173 173 {
174 174 qDebug() << "addSeries: " << series << " data: " << data;
175 175 m_defaultSeriesName = series;
176 176
177 177 // TODO: a dedicated data class for storing x and y values
178 178 QList<qreal> x;
179 179 QList<qreal> y;
180 180
181 181 QList<qreal> data0;
182 182 QList<qreal> data1;
183 183 QList<qreal> data2;
184 184 QList<qreal> data3;
185 185 QList<qreal> data4;
186 186
187 187 if (data == "linear") {
188 188 for (int i = 0; i < 20; i++) {
189 189 x.append(i);
190 190 y.append(i);
191 191 }
192 192 } else if (data == "linear, 1M") {
193 193 // 1 million data points from 0.0001 to 100
194 194 // TODO: What is the requirement? Should we be able to show this kind of data with
195 195 // reasonable performance, or can we expect the application developer to do "data mining"
196 196 // for us, so that the count of data points given to QtCommercial Chart is always
197 197 // reasonable?
198 198 for (qreal i = 0; i < 100; i += 0.0001) {
199 199 x.append(i);
200 200 y.append(20);
201 201 }
202 202 } else if (data == "SIN") {
203 203 for (int i = 0; i < 100; i++) {
204 204 x.append(i);
205 205 y.append(abs(sin(3.14159265358979 / 50 * i) * 100));
206 206 }
207 207 } else if (data == "SIN + random") {
208 208 for (qreal i = 0; i < 100; i += 0.1) {
209 209 x.append(i + (rand() % 5));
210 210 y.append(abs(sin(3.14159265358979 / 50 * i) * 100) + (rand() % 5));
211 211 }
212 212 } else if (data == "Table, 5 series"){
213 213 // Create some test data to chart
214 214 data0 << 1 << 2 << 3 << 4 << 5 << 6 << 7 << 8 << 9 << 10;
215 215 data1 << 5 << 0 << 0 << 4 << 0 << 7 << 8 << 9 << 9 << 0;
216 216 data2 << 3 << 5 << 8 << 13 << 8 << 5 << 3 << 2 << 1 << 1;
217 217 data3 << 5 << 6 << 7 << 3 << 4 << 5 << 8 << 9 << 10 << 5;
218 218 data4 << 9 << 7 << 5 << 3 << 1 << 2 << 4 << 6 << 8 << 10;
219 219 } else {
220 220 // TODO: check if data has a valid file name
221 221 Q_ASSERT(false);
222 222 }
223 223
224 224 // TODO: color of the series
225 225 QChartSeries *newSeries = 0;
226 226 if (series == "Scatter") {
227 227 newSeries = m_chartWidget->createSeries(QChartSeries::SeriesTypeScatter);
228 228 Q_ASSERT(newSeries->setData(x, y));
229 229 } else if (series == "Pie") {
230 230 newSeries = m_chartWidget->createSeries(QChartSeries::SeriesTypePie);
231 231 Q_ASSERT(newSeries->setData(y));
232 232 } else if (series == "Line") {
233 233 // TODO: adding data to an existing line series does not give any visuals for some reason
234 234 // newSeries = m_chartWidget->createSeries(QChartSeries::SeriesTypeLine);
235 235 // QXYChartSeries *lineSeries = static_cast<QXYChartSeries *>(newSeries);
236 236 // lineSeries->setColor(Qt::blue);
237 237 // for (int i(0); i < x.count() && i < y.count(); i++) {
238 238 // lineSeries->add(x.at(i), y.at(i));
239 239 // }
240 240 //Q_ASSERT(newSeries->setData(x, y));
241 241 QLineChartSeries* series0 = new QLineChartSeries();
242 242 for (int i(0); i < x.count() && i < y.count(); i++)
243 243 series0->add(x.at(i), y.at(i));
244 244 m_chartWidget->addSeries(series0);
245 245 newSeries = series0;
246 246 } else if (series == "Bar") {
247 247 qDebug() << "Bar chart series";
248 248 BarChartSeries* series0 = new BarChartSeries(this);
249 249 series0->addData(data0);
250 250 series0->addData(data1);
251 251 series0->addData(data2);
252 252 series0->addData(data3);
253 253 series0->addData(data4);
254 QList<QString> labels;
255 labels << "Jan" << "Feb" << "Mar" << "Apr" << "May" << "June" << "Jul" << "Aug" << "Sep" << "Nov" << "Dec";
256 series0->setLabels(labels);
254 257 m_chartWidget->addSeries(series0);
255 258 newSeries = series0;
256 259 } else if (series == "StackedBar") {
257 260 qDebug() << "Bar chart series";
258 261 StackedBarChartSeries* series0 = new StackedBarChartSeries(this);
259 262 series0->addData(data0);
260 263 series0->addData(data1);
261 264 series0->addData(data2);
262 265 series0->addData(data3);
263 266 series0->addData(data4);
267 QList<QString> labels;
268 labels << "Jan" << "Feb" << "Mar" << "Apr" << "May" << "June" << "Jul" << "Aug" << "Sep" << "Nov" << "Dec";
269 series0->setLabels(labels);
264 270 m_chartWidget->addSeries(series0);
265 271 newSeries = series0;
266 272 } else if (series == "PercentBar") {
267 273 qDebug() << "Bar chart series";
268 274 PercentBarChartSeries* series0 = new PercentBarChartSeries(this);
269 275 series0->addData(data0);
270 276 series0->addData(data1);
271 277 series0->addData(data2);
272 278 series0->addData(data3);
273 279 series0->addData(data4);
280 QList<QString> labels;
281 labels << "Jan" << "Feb" << "Mar" << "Apr" << "May" << "June" << "Jul" << "Aug" << "Sep" << "Nov" << "Dec";
282 series0->setLabels(labels);
274 283 m_chartWidget->addSeries(series0);
275 284 newSeries = series0;
276 285 } else {
277 286 qDebug() << "Something weird going on in MainWidget::addSeries";
278 287 }
279 288
280 289 setCurrentSeries(newSeries);
281 290 }
282 291
283 292 void MainWidget::setCurrentSeries(QChartSeries *series)
284 293 {
285 294 m_currentSeries = series;
286 295 switch (m_currentSeries->type()) {
287 296 case QChartSeries::SeriesTypeLine:
288 297 break;
289 298 case QChartSeries::SeriesTypeScatter:
290 299 break;
291 300 case QChartSeries::SeriesTypePie:
292 301 break;
293 302 case QChartSeries::SeriesTypeBar:
294 303 qDebug() << "setCurrentSeries (bar)";
295 304 break;
296 305 case QChartSeries::SeriesTypeStackedBar:
297 306 qDebug() << "setCurrentSeries (Stackedbar)";
298 307 break;
299 308 case QChartSeries::SeriesTypePercentBar:
300 309 qDebug() << "setCurrentSeries (Percentbar)";
301 310 break;
302 311 default:
303 312 Q_ASSERT(false);
304 313 break;
305 314 }
306 315 }
307 316
308 317 void MainWidget::testDataChanged(int itemIndex)
309 318 {
310 319 qDebug() << "testDataChanged: " << itemIndex;
311 320
312 321 // switch (itemIndex) {
313 322 // case 0: {
314 323 // QList<QChartDataPoint> data;
315 324 // for (int x = 0; x < 20; x++) {
316 325 // data.append(QChartDataPoint() << x << x / 2);
317 326 // }
318 327 // m_chartWidget->setData(data);
319 328 // break;
320 329 // }
321 330 // case 1: {
322 331 // QList<QChartDataPoint> data;
323 332 // for (int x = 0; x < 100; x++) {
324 333 // data.append(QChartDataPoint() << x - 200 << 2 * (uint(sin(3.14159/50*x)*80) % 100));
325 334 // }
326 335 // m_chartWidget->setData(data);
327 336 // break;
328 337 // }
329 338 // case 2: {
330 339 // QList<QChartDataPoint> data;
331 340 // for (int x = 0; x < 1000; x++) {
332 341 // data.append(QChartDataPoint() << x - 200 << 2 * (uint(sin(3.14159/50*x)*80) % 100) + (rand() % 100 * 0.2));
333 342 // data.append(QChartDataPoint() << x - 200 << 2 * (uint(sin(3.14159/50*x)*80) % 100) + (rand() % 100 * 0.2));
334 343 // data.append(QChartDataPoint() << x - 200 << 2 * (uint(sin(3.14159/50*x)*80) % 100) + (rand() % 100 * 0.2));
335 344 // }
336 345 // m_chartWidget->setData(data);
337 346 // break;
338 347 // }
339 348 // default:
340 349 // break;
341 350 // }
342 351 }
343 352
344 353 void MainWidget::backgroundChanged(int itemIndex)
345 354 {
346 355 qDebug() << "backgroundChanged: " << itemIndex;
347 356 }
348 357
349 358 void MainWidget::autoScaleChanged(int value)
350 359 {
351 360 if (value) {
352 361 // TODO: enable auto scaling
353 362 } else {
354 363 // TODO: set scaling manually (and disable auto scaling)
355 364 }
356 365
357 366 m_xMinSpin->setEnabled(!value);
358 367 m_xMaxSpin->setEnabled(!value);
359 368 m_yMinSpin->setEnabled(!value);
360 369 m_yMaxSpin->setEnabled(!value);
361 370 }
362 371
363 372 void MainWidget::xMinChanged(int value)
364 373 {
365 374 qDebug() << "xMinChanged: " << value;
366 375 }
367 376
368 377 void MainWidget::xMaxChanged(int value)
369 378 {
370 379 qDebug() << "xMaxChanged: " << value;
371 380 }
372 381
373 382 void MainWidget::yMinChanged(int value)
374 383 {
375 384 qDebug() << "yMinChanged: " << value;
376 385 }
377 386
378 387 void MainWidget::yMaxChanged(int value)
379 388 {
380 389 qDebug() << "yMaxChanged: " << value;
381 390 }
382 391
383 392 void MainWidget::changeChartTheme(int themeIndex)
384 393 {
385 394 qDebug() << "changeChartTheme: " << themeIndex;
386 395 m_chartWidget->setChartTheme((QChart::ChartTheme) themeIndex);
396 //TODO: remove this hack. This is just to make it so that theme change is seen immediately.
397 QSize s = size();
398 s.setWidth(s.width()+1);
399 resize(s);
387 400 }
388 401
389 402 void MainWidget::setPieSizeFactor(double size)
390 403 {
391 404 QPieSeries *pie = qobject_cast<QPieSeries *>(m_currentSeries);
392 405 if (pie)
393 406 pie->setSizeFactor(qreal(size));
394 407 }
395 408
396 409 void MainWidget::setPiePosition(int position)
397 410 {
398 411 QPieSeries *pie = qobject_cast<QPieSeries *>(m_currentSeries);
399 412 if (pie)
400 413 pie->setPosition((QPieSeries::PiePosition) position);
401 414 }
General Comments 0
You need to be logged in to leave comments. Login now