##// END OF EJS Templates
Improved bar chart series
sauimone -
r71:1f789ed92d7b
parent child
Show More
@@ -1,55 +1,90
1 #include <QDebug>
1 #include "barchartseries.h"
2 #include "barchartseries.h"
2 QTCOMMERCIALCHART_BEGIN_NAMESPACE
3 QTCOMMERCIALCHART_BEGIN_NAMESPACE
3
4
4 BarChartSeries::BarChartSeries(QObject *parent)
5 BarChartSeries::BarChartSeries(QObject *parent)
5 : QChartSeries(parent)
6 : QChartSeries(parent)
6 {
7 {
7 }
8 }
8
9
9 bool BarChartSeries::setData(QList<int> data)
10 bool BarChartSeries::setData(QAbstractItemModel* model)
10 {
11 {
11 mData = data;
12 mModel = model;
12 return true;
13 }
13 }
14
14
15
15 int BarChartSeries::min()
16 int BarChartSeries::min()
16 {
17 {
17 Q_ASSERT(mData.count() > 0);
18 Q_ASSERT(mModel->rowCount() > 0);
19 Q_ASSERT(mModel->columnCount() > 0);
18
20
19 // TODO: make min and max members and update them when data changes.
21 // TODO: make min and max members and update them when data changes.
20 // This is slower since they are checked every time, even if data is same since previous call.
22 // This is slower since they are checked every time, even if data is same since previous call.
21 int min = mData.at(0);
23 QModelIndex modelIndex = mModel->index(0,0);
24 int min = mModel->data(modelIndex).toInt();
22
25
23 for (int i=0; i <mData.count(); i++) {
26 for (int i=0; i <mModel->rowCount(); i++) {
24 if (mData.at(i) < min) {
27 for(int j=0; j<mModel->columnCount(); j++) {
25 min = mData.at(i);
28 modelIndex = mModel->index(i,j);
29 int temp = mModel->data(modelIndex).toInt();
30 if (temp < min) {
31 min = temp;
32 }
26 }
33 }
27 }
34 }
28 return min;
35 return min;
29 }
36 }
30
37
31 int BarChartSeries::max()
38 int BarChartSeries::max()
32 {
39 {
33 Q_ASSERT(mData.count() > 0);
40 Q_ASSERT(mModel->rowCount() > 0);
41 Q_ASSERT(mModel->columnCount() > 0);
34
42
35 int max = mData.at(0);
43 // TODO: make min and max members and update them when data changes.
44 // This is slower since they are checked every time, even if data is same since previous call.
45 QModelIndex modelIndex = mModel->index(0,0);
46 int max = mModel->data(modelIndex).toInt();
36
47
37 for (int i=0; i <mData.count(); i++) {
48 for (int i=0; i <mModel->rowCount(); i++) {
38 if (mData.at(i) > max) {
49 for(int j=0; j<mModel->columnCount(); j++) {
39 max = mData.at(i);
50 modelIndex = mModel->index(i,j);
51 int temp = mModel->data(modelIndex).toInt();
52 if (temp > max) {
53 max = temp;
54 }
40 }
55 }
41 }
56 }
42 return max;
57 return max;
43 }
58 }
44
59
45 int BarChartSeries::count()
60
61 int BarChartSeries::countSeries()
62 {
63 return mModel->rowCount();
64 }
65
66 int BarChartSeries::countItemsInSeries()
46 {
67 {
47 return mData.count();
68 return mModel->columnCount();
48 }
69 }
49
70
50 int BarChartSeries::valueAt(int i)
71 int BarChartSeries::countTotalItems()
51 {
72 {
52 return mData.at(i);
73 return mModel->rowCount() * mModel->columnCount();
53 }
74 }
54
75
76 int BarChartSeries::valueAt(int series, int item)
77 {
78 QModelIndex index = mModel->index(series,item);
79 return mModel->data(index).toInt();
80 }
81
82
83 void BarChartSeries::chartSizeChanged(QRectF rect)
84 {
85 qDebug() << "barchart size changed:" << rect;
86 }
87
88 #include "moc_barchartseries.cpp"
89
55 QTCOMMERCIALCHART_END_NAMESPACE
90 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,39 +1,45
1 #ifndef BARCHARTSERIES_H
1 #ifndef BARCHARTSERIES_H
2 #define BARCHARTSERIES_H
2 #define BARCHARTSERIES_H
3
3
4 #include <QList>
4 #include <QList>
5 #include <QRectF>
6 #include <QAbstractItemModel>
5 #include "qchartseries.h"
7 #include "qchartseries.h"
6 #include "qchartglobal.h"
8 #include "qchartglobal.h"
7
9
8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
10 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9
11
10 // Container for series
12 // Container for series
11 class QTCOMMERCIALCHART_EXPORT BarChartSeries : public QChartSeries
13 class QTCOMMERCIALCHART_EXPORT BarChartSeries : public QChartSeries
12 {
14 {
13 // TODO:
15 Q_OBJECT
14 // Q_OBJECT
15 public:
16 public:
16 BarChartSeries(QObject* parent=0);
17 BarChartSeries(QObject* parent=0);
17
18
18 // from QChartSeries
19 // from QChartSeries
19 virtual QChartSeriesType type() const { return QChartSeries::SeriesTypeBar; }
20 virtual QChartSeriesType type() const { return QChartSeries::SeriesTypeBar; }
20
21
21 virtual bool setData(QList<int> data);
22 // TODO: This as dataModel instead of n different setters. (data model itself can accept lists and whatnot)
22 virtual bool setData(QList<qreal> data) {return false;}
23 virtual bool setData(QAbstractItemModel* model);
23 virtual bool setData(QList<qreal> x, QList<qreal> y) {return false;}
24
25
24
26 // Methods to find out minimum and maximum values of data
25 // Methods to find out minimum and maximum values of data
27 int min();
26 int min();
28 int max();
27 int max();
29 int count();
28 int countSeries();
30 int valueAt(int i);
29 int countItemsInSeries(); // Count items in one series.
30 int countTotalItems();
31 int valueAt(int series, int item);
32
33 public Q_SLOTS:
34
35 void chartSizeChanged(QRectF rect);
31
36
32 private:
37 private:
33
38
34 QList<int> mData;
39 //QList<int> mData;
40 QAbstractItemModel* mModel;
35 };
41 };
36
42
37 QTCOMMERCIALCHART_END_NAMESPACE
43 QTCOMMERCIALCHART_END_NAMESPACE
38
44
39 #endif // BARCHARTSERIES_H
45 #endif // BARCHARTSERIES_H
@@ -1,106 +1,117
1 #include "bargroup.h"
1 #include "bargroup.h"
2 #include "bar.h"
2 #include "bar.h"
3 #include <QDebug>
3 #include <QDebug>
4
4
5 QTCOMMERCIALCHART_BEGIN_NAMESPACE
5 QTCOMMERCIALCHART_BEGIN_NAMESPACE
6
6
7 // TODO: singleton?
8 //BarGroup* BarGroup::mBarGroupInstance = NULL;
9
10 //BarGroup::BarGroup(QGraphicsItem *parent) :
11 // QGraphicsItem(parent)
12 // ,mSeries(series)
7 BarGroup::BarGroup(BarChartSeries& series, QGraphicsItem *parent) :
13 BarGroup::BarGroup(BarChartSeries& series, QGraphicsItem *parent) :
8 QGraphicsItem(parent)
14 QGraphicsItem(parent)
9 ,mSeries(series)
15 ,mSeries(series)
10 ,mLayoutSet(false)
16 ,mLayoutSet(false)
11 ,mLayoutDirty(true)
17 ,mLayoutDirty(true)
12 {
18 {
13 dataChanged();
19 dataChanged();
14 }
20 }
15
21
16 void BarGroup::resize( int w, int h )
22 void BarGroup::resize( int w, int h )
17 {
23 {
18 qDebug() << "QBarChart::resize";
24 qDebug() << "QBarChart::resize";
19 mWidth = w;
25 mWidth = w;
20 mHeight = h;
26 mHeight = h;
21 layoutChanged();
27 layoutChanged();
22 mLayoutSet = true;
28 mLayoutSet = true;
23 }
29 }
24
30
25 void BarGroup::setBarWidth( int w )
31 void BarGroup::setBarWidth( int w )
26 {
32 {
27 mBarDefaultWidth = w;
33 mBarDefaultWidth = w;
28 }
34 }
29
35
30 void BarGroup::setColor( QColor color )
36 void BarGroup::setColor( QColor color )
31 {
37 {
32 mColor = color;
38 mColor = color;
33 }
39 }
34
40
35 void BarGroup::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
41 void BarGroup::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
36 {
42 {
37 if (!mLayoutSet) {
43 if (!mLayoutSet) {
38 qDebug() << "QBarChart::paint called without layout set. Aborting.";
44 qDebug() << "QBarChart::paint called without layout set. Aborting.";
39 return;
45 return;
40 }
46 }
41 if (mLayoutDirty) {
47 if (mLayoutDirty) {
42 // Layout or data has changed. Need to redraw.
48 // Layout or data has changed. Need to redraw.
43 foreach(QGraphicsItem* i, childItems()) {
49 foreach(QGraphicsItem* i, childItems()) {
44 i->paint(painter,option,widget);
50 i->paint(painter,option,widget);
45 }
51 }
46 }
52 }
47 }
53 }
48
54
49 QRectF BarGroup::boundingRect() const
55 QRectF BarGroup::boundingRect() const
50 {
56 {
51 // TODO: correct this (currently ignores position)
57 // TODO: correct this (currently ignores position)
52 return QRectF(0,0,mWidth,mHeight);
58 return QRectF(0,0,mWidth,mHeight);
53 }
59 }
54
60
55
61
56 void BarGroup::dataChanged()
62 void BarGroup::dataChanged()
57 {
63 {
58 qDebug() << "QBarChart::dataChanged mSeries";
64 qDebug() << "QBarChart::dataChanged mSeries";
59
65
60 // Find out maximum and minimum of all series
66 // Find out maximum and minimum of all series
61 mMax = mSeries.max();
67 mMax = mSeries.max();
62 mMin = mSeries.min();
68 mMin = mSeries.min();
63
69
64 // Delete old bars
70 // Delete old bars
65 // Is this correct way to delete childItems?
71 // Is this correct way to delete childItems?
66 foreach (QGraphicsItem* item, childItems()) {
72 foreach (QGraphicsItem* item, childItems()) {
67 delete item;
73 delete item;
68 }
74 }
69
75
70 // Create new graphic items for bars
76 // Create new graphic items for bars
71 for (int i=0; i<mSeries.count(); i++) {
77 int totalItems = mSeries.countTotalItems();
78 for (int i=0; i<totalItems; i++) {
72 Bar *bar = new Bar(this);
79 Bar *bar = new Bar(this);
73 childItems().append(bar);
80 childItems().append(bar);
74 }
81 }
75
82
76 mLayoutDirty = true;
83 mLayoutDirty = true;
77 }
84 }
78
85
79 void BarGroup::layoutChanged()
86 void BarGroup::layoutChanged()
80 {
87 {
81 // Scale bars to new layout
88 // Scale bars to new layout
82 // Layout for bars:
89 // Layout for bars:
83 int count = mSeries.count();
90 int count = mSeries.countSeries();
84 if (count <= 0) {
91 if (count <= 0) {
85 // Nothing to do.
92 // Nothing to do.
86 return;
93 return;
87 }
94 }
88
95
89 // Align center
96 // Align center
90 int posStep = (mWidth / (count));
97 int posStep = (mWidth / (count));
91 int startPos = (mWidth / count+1);
98 int startPos = (mWidth / count+1);
92 qDebug() << "startpos" << startPos;
99 qDebug() << "startpos" << startPos;
93
100
94 // Scaling. TODO: better one.
101 // Scaling. TODO: better one.
95 for (int i=0; i<count; i++) {
102 int itemIndex(0);
96 int barHeight = mSeries.valueAt(i) * mHeight / mMax;
103 for (int series = 0; series < count; series++) {
97 Bar* bar = reinterpret_cast<Bar*> (childItems().at(i));
104 for (int item=0; item < count; item++) {
98
105 int barHeight = mSeries.valueAt(series, item) * mHeight / mMax;
99 bar->resize(mBarDefaultWidth, barHeight); // TODO: width settable per bar
106 Bar* bar = reinterpret_cast<Bar*> (childItems().at(itemIndex));
100 bar->setColor(mColor);
107
101 bar->setPos(i*posStep+startPos, 0);
108 bar->resize(mBarDefaultWidth, barHeight); // TODO: width settable per bar
109 bar->setColor(mColor);
110 bar->setPos(itemIndex*posStep+startPos, 0);
111 itemIndex++;
112 }
102 }
113 }
103 mLayoutDirty = true;
114 mLayoutDirty = true;
104 }
115 }
105
116
106 QTCOMMERCIALCHART_END_NAMESPACE
117 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,55 +1,69
1 #ifndef QBARCHART_H
1 #ifndef QBARCHART_H
2 #define QBARCHART_H
2 #define QBARCHART_H
3
3
4 #include <QGraphicsItem>
4 #include <QGraphicsObject>
5
5
6 #include "bar.h"
6 #include "bar.h"
7 //#include "qbarchartview.h"
7 //#include "qbarchartview.h"
8 #include "barchartseries.h"
8 #include "barchartseries.h"
9
9
10 QTCOMMERCIALCHART_BEGIN_NAMESPACE
10 QTCOMMERCIALCHART_BEGIN_NAMESPACE
11
11
12 // TODO: Better name for this? The function of this class is to know where each bar in series is laid out.
12 // TODO: Better name for this? The function of this class is to know where each bar in series is laid out.
13 // Class has knowledge of single series of data (owns vs reference?)
13 //class BarGroup : public QGraphicsItemGroup
14
14 class BarGroup : public QGraphicsItem
15 class BarGroup : public QGraphicsItem
15 {
16 {
17 /* // TODO: implement as singleton?
18 private:
19 static BarGroup* mBarGroupInstance;
16
20
17 public:
21 public:
22 static BarGroup* instance()
23 {
24 if (mBarGroupInstance == NULL) {
25 mBarGroupInstance = new BarGroup();
26 }
27 return mBarGroupInstance;
28 }
29 private:
30 */
31 public:
18 explicit BarGroup(BarChartSeries& series, QGraphicsItem *parent = 0);
32 explicit BarGroup(BarChartSeries& series, QGraphicsItem *parent = 0);
19
33
20 // Layout "api"
34 // Layout "api"
21 void resize( int w, int h ); // Size for whole series. Single bars are drawn inside this area
35 void resize( int w, int h ); // Size for whole series. Single bars are drawn inside this area
22 void setPos(qreal x, qreal y);
36 void setPos(qreal x, qreal y);
23 void setBarWidth( int w ); // Default width for each bar
37 void setBarWidth( int w ); // Default width for each bar
24 void setColor( QColor color ); // Default color for each bar
38 void setColor( QColor color ); // Default color for each bar
25
39
26 // From QGraphicsItem
40 // From QGraphicsItem
27 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
41 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
28 QRectF boundingRect() const;
42 QRectF boundingRect() const;
29
43
30 private:
44 private:
31
45
32 void dataChanged(); // data of series has changed -> need to recalculate bar sizes
46 void dataChanged(); // data of series has changed -> need to recalculate bar sizes
33 void layoutChanged(); // layout has changed -> need to recalculate bar sizes
47 void layoutChanged(); // layout has changed -> need to recalculate bar sizes
34
48
35 private:
49 private:
36
50
37 // Data
51 // Data
38 BarChartSeries& mSeries;
52 BarChartSeries& mSeries;
39 int mMin; // Min and max values of data. (updated when data is changed, used when drawing)
53 int mMin; // Min and max values of data. (updated when data is changed, used when drawing)
40 int mMax;
54 int mMax;
41
55
42 int mHeight; // Layout spesific
56 int mHeight; // Layout spesific
43 int mWidth;
57 int mWidth;
44 int mBarDefaultWidth;
58 int mBarDefaultWidth;
45
59
46 QColor mColor;
60 QColor mColor;
47
61
48 bool mLayoutSet; // True, if component has been laid out.
62 bool mLayoutSet; // True, if component has been laid out.
49 bool mLayoutDirty;
63 bool mLayoutDirty;
50
64
51 };
65 };
52
66
53 QTCOMMERCIALCHART_END_NAMESPACE
67 QTCOMMERCIALCHART_END_NAMESPACE
54
68
55 #endif // QBARCHART_H
69 #endif // QBARCHART_H
@@ -1,287 +1,285
1 #include "qchart.h"
1 #include "qchart.h"
2 #include "qchartseries.h"
2 #include "qchartseries.h"
3 #include "qscatterseries.h"
3 #include "qscatterseries.h"
4 #include "qscatterseries_p.h"
4 #include "qscatterseries_p.h"
5 #include "qpieseries.h"
5 #include "qpieseries.h"
6 #include "qxychartseries.h"
6 #include "qxychartseries.h"
7
7
8 #include "barchartseries.h"
8 #include "barchartseries.h"
9 #include "bargroup.h"
9 #include "bargroup.h"
10
10
11 #include "xylinechartitem_p.h"
11 #include "xylinechartitem_p.h"
12 #include "plotdomain_p.h"
12 #include "plotdomain_p.h"
13 #include "axisitem_p.h"
13 #include "axisitem_p.h"
14 #include <QGraphicsScene>
14 #include <QGraphicsScene>
15 #include <QDebug>
15 #include <QDebug>
16
16
17 QTCOMMERCIALCHART_BEGIN_NAMESPACE
17 QTCOMMERCIALCHART_BEGIN_NAMESPACE
18
18
19 QChart::QChart(QGraphicsObject* parent) : QGraphicsObject(parent),
19 QChart::QChart(QGraphicsObject* parent) : QGraphicsObject(parent),
20 m_background(new QGraphicsRectItem(this)),
20 m_background(new QGraphicsRectItem(this)),
21 m_title(new QGraphicsTextItem(this)),
21 m_title(new QGraphicsTextItem(this)),
22 m_axisX(new AxisItem(AxisItem::X_AXIS,this)),
22 m_axisX(new AxisItem(AxisItem::X_AXIS,this)),
23 m_axisY(new AxisItem(AxisItem::Y_AXIS,this)),
23 m_axisY(new AxisItem(AxisItem::Y_AXIS,this)),
24 m_plotDataIndex(0),
24 m_plotDataIndex(0),
25 m_marginSize(0)
25 m_marginSize(0)
26 {
26 {
27 // TODO: the default theme?
27 // TODO: the default theme?
28 setTheme(QChart::ChartThemeVanilla);
28 setTheme(QChart::ChartThemeVanilla);
29 // setFlags(QGraphicsItem::ItemClipsChildrenToShape);
29 // setFlags(QGraphicsItem::ItemClipsChildrenToShape);
30 PlotDomain domain;
30 PlotDomain domain;
31 m_plotDomainList<<domain;
31 m_plotDomainList<<domain;
32
32
33 m_chartItems<<m_axisX;
33 m_chartItems<<m_axisX;
34 m_chartItems<<m_axisY;
34 m_chartItems<<m_axisY;
35 }
35 }
36
36
37 QChart::~QChart(){}
37 QChart::~QChart(){}
38
38
39 QRectF QChart::boundingRect() const
39 QRectF QChart::boundingRect() const
40 {
40 {
41 return m_rect;
41 return m_rect;
42 }
42 }
43
43
44 void QChart::addSeries(QChartSeries* series)
44 void QChart::addSeries(QChartSeries* series)
45 {
45 {
46 // TODO: we should check the series not already added
46 // TODO: we should check the series not already added
47
47
48 m_series<<series;
48 m_series<<series;
49
49
50 switch(series->type())
50 switch(series->type())
51 {
51 {
52 case QChartSeries::SeriesTypeLine: {
52 case QChartSeries::SeriesTypeLine: {
53
53
54 QXYChartSeries* xyseries = static_cast<QXYChartSeries*>(series);
54 QXYChartSeries* xyseries = static_cast<QXYChartSeries*>(series);
55 // Use color defined by theme in case the series does not define a custom color
55 // Use color defined by theme in case the series does not define a custom color
56 if (!xyseries->color().isValid() && m_themeColors.count())
56 if (!xyseries->color().isValid() && m_themeColors.count())
57 xyseries->setColor(m_themeColors.takeFirst());
57 xyseries->setColor(m_themeColors.takeFirst());
58
58
59 m_plotDataIndex = 0 ;
59 m_plotDataIndex = 0 ;
60 m_plotDomainList.resize(1);
60 m_plotDomainList.resize(1);
61
61
62 PlotDomain& domain = m_plotDomainList[m_plotDataIndex];
62 PlotDomain& domain = m_plotDomainList[m_plotDataIndex];
63
63
64 for (int i = 0 ; i < xyseries->count() ; i++)
64 for (int i = 0 ; i < xyseries->count() ; i++)
65 {
65 {
66 qreal x = xyseries->x(i);
66 qreal x = xyseries->x(i);
67 qreal y = xyseries->y(i);
67 qreal y = xyseries->y(i);
68 domain.m_minX = qMin(domain.m_minX,x);
68 domain.m_minX = qMin(domain.m_minX,x);
69 domain.m_minY = qMin(domain.m_minY,y);
69 domain.m_minY = qMin(domain.m_minY,y);
70 domain.m_maxX = qMax(domain.m_maxX,x);
70 domain.m_maxX = qMax(domain.m_maxX,x);
71 domain.m_maxY = qMax(domain.m_maxY,y);
71 domain.m_maxY = qMax(domain.m_maxY,y);
72 }
72 }
73
73
74 XYLineChartItem* item = new XYLineChartItem(xyseries,this);
74 XYLineChartItem* item = new XYLineChartItem(xyseries,this);
75
75
76 m_chartItems<<item;
76 m_chartItems<<item;
77
77
78 foreach(ChartItem* i ,m_chartItems)
78 foreach(ChartItem* i ,m_chartItems)
79 i->setPlotDomain(m_plotDomainList.at(m_plotDataIndex));
79 i->setPlotDomain(m_plotDomainList.at(m_plotDataIndex));
80
80
81 break;
81 break;
82 }
82 }
83 case QChartSeries::SeriesTypeBar: {
83 case QChartSeries::SeriesTypeBar: {
84
84
85 qDebug() << "barSeries added";
85 qDebug() << "barSeries added";
86 BarChartSeries* barSeries = static_cast<BarChartSeries*>(series);
86 BarChartSeries* barSeries = static_cast<BarChartSeries*>(series);
87 connect(this, SIGNAL(sizeChanged(QRectF)),
88 barSeries, SLOT(chartSizeChanged(QRectF)));
87
89
88 // Who owns the series?
89 BarGroup* group = new BarGroup(*barSeries, this);
90 scene()->addItem(group);
91 m_BarGroupItems.append(group); // If we need to access group later
92 break;
90 break;
93 }
91 }
94 case QChartSeries::SeriesTypeScatter: {
92 case QChartSeries::SeriesTypeScatter: {
95 QScatterSeries *scatterSeries = qobject_cast<QScatterSeries *>(series);
93 QScatterSeries *scatterSeries = qobject_cast<QScatterSeries *>(series);
96 connect(this, SIGNAL(sizeChanged(QRectF)),
94 connect(this, SIGNAL(sizeChanged(QRectF)),
97 scatterSeries, SLOT(chartSizeChanged(QRectF)));
95 scatterSeries, SLOT(chartSizeChanged(QRectF)));
98 scatterSeries->d->setParentItem(this);
96 scatterSeries->d->setParentItem(this);
99 QColor nextColor = m_themeColors.takeFirst();
97 QColor nextColor = m_themeColors.takeFirst();
100 nextColor.setAlpha(150); // TODO: default opacity?
98 nextColor.setAlpha(150); // TODO: default opacity?
101 scatterSeries->setMarkerColor(nextColor);
99 scatterSeries->setMarkerColor(nextColor);
102 }
100 }
103 case QChartSeries::SeriesTypePie: {
101 case QChartSeries::SeriesTypePie: {
104 // TODO: we now have also a list of y values as a parameter, it is ignored
102 // TODO: we now have also a list of y values as a parameter, it is ignored
105 // we should use a generic data class instead of list of x and y values
103 // we should use a generic data class instead of list of x and y values
106 QPieSeries *pieSeries = qobject_cast<QPieSeries *>(series);
104 QPieSeries *pieSeries = qobject_cast<QPieSeries *>(series);
107 connect(this, SIGNAL(sizeChanged(QRectF)),
105 connect(this, SIGNAL(sizeChanged(QRectF)),
108 pieSeries, SLOT(chartSizeChanged(QRectF)));
106 pieSeries, SLOT(chartSizeChanged(QRectF)));
109 // TODO: how to define the color for all the slices of a pie?
107 // TODO: how to define the color for all the slices of a pie?
110 }
108 }
111 }
109 }
112 }
110 }
113
111
114 QChartSeries* QChart::createSeries(QChartSeries::QChartSeriesType type)
112 QChartSeries* QChart::createSeries(QChartSeries::QChartSeriesType type)
115 {
113 {
116 // TODO: support also other types; not only scatter and pie
114 // TODO: support also other types; not only scatter and pie
117
115
118 QChartSeries *series(0);
116 QChartSeries *series(0);
119
117
120 switch (type) {
118 switch (type) {
121 case QChartSeries::SeriesTypeLine: {
119 case QChartSeries::SeriesTypeLine: {
122 series = QXYChartSeries::create();
120 series = QXYChartSeries::create();
123 break;
121 break;
124 }
122 }
125 case QChartSeries::SeriesTypeBar: {
123 case QChartSeries::SeriesTypeBar: {
126 series = new BarChartSeries(this);
124 series = new BarChartSeries(this);
127 break;
125 break;
128 }
126 }
129 case QChartSeries::SeriesTypeScatter: {
127 case QChartSeries::SeriesTypeScatter: {
130 series = new QScatterSeries(this);
128 series = new QScatterSeries(this);
131 break;
129 break;
132 }
130 }
133 case QChartSeries::SeriesTypePie: {
131 case QChartSeries::SeriesTypePie: {
134 series = new QPieSeries(this);
132 series = new QPieSeries(this);
135 break;
133 break;
136 }
134 }
137 default:
135 default:
138 Q_ASSERT(false);
136 Q_ASSERT(false);
139 break;
137 break;
140 }
138 }
141
139
142 addSeries(series);
140 addSeries(series);
143 return series;
141 return series;
144 }
142 }
145
143
146 void QChart::setSize(const QSize& size)
144 void QChart::setSize(const QSize& size)
147 {
145 {
148 m_rect = QRect(QPoint(0,0),size);
146 m_rect = QRect(QPoint(0,0),size);
149 QRect rect = m_rect.adjusted(margin(),margin(), -margin(), -margin());
147 QRect rect = m_rect.adjusted(margin(),margin(), -margin(), -margin());
150
148
151
149
152 //recalculate background gradient
150 //recalculate background gradient
153 m_background->setRect(rect);
151 m_background->setRect(rect);
154 m_backgroundGradient.setFinalStop(0,m_background->rect().height());
152 m_backgroundGradient.setFinalStop(0,m_background->rect().height());
155 m_background->setBrush(m_backgroundGradient);
153 m_background->setBrush(m_backgroundGradient);
156
154
157 //resize elements
155 //resize elements
158 foreach (ChartItem* item ,m_chartItems) {
156 foreach (ChartItem* item ,m_chartItems) {
159 item->setPos(rect.topLeft());
157 item->setPos(rect.topLeft());
160 item->setSize(rect.size());
158 item->setSize(rect.size());
161
159
162 }
160 }
163 // TODO: TTD for setting scale
161 // TODO: TTD for setting scale
164 //emit scaleChanged(100, 100);
162 //emit scaleChanged(100, 100);
165 // TODO: calculate the origo
163 // TODO: calculate the origo
166 // TODO: not sure if emitting a signal here is the best from performance point of view
164 // TODO: not sure if emitting a signal here is the best from performance point of view
167 emit sizeChanged(QRectF(0, 0, size.width(), size.height()));
165 emit sizeChanged(QRectF(0, 0, size.width(), size.height()));
168
166
169 update();
167 update();
170 }
168 }
171
169
172 void QChart::setBackgroundColor(const QColor& color)
170 void QChart::setBackgroundColor(const QColor& color)
173 {
171 {
174 m_backgroundGradient.setColorAt( 0.0, Qt::white);
172 m_backgroundGradient.setColorAt( 0.0, Qt::white);
175 m_backgroundGradient.setColorAt( 1.0, color);
173 m_backgroundGradient.setColorAt( 1.0, color);
176 m_background->setBrush(m_backgroundGradient);
174 m_background->setBrush(m_backgroundGradient);
177 m_background->setPen(Qt::NoPen);
175 m_background->setPen(Qt::NoPen);
178 m_background->update();
176 m_background->update();
179 }
177 }
180
178
181 void QChart::setTitle(const QString& title)
179 void QChart::setTitle(const QString& title)
182 {
180 {
183 m_title->setPlainText(title);
181 m_title->setPlainText(title);
184 }
182 }
185
183
186 int QChart::margin() const
184 int QChart::margin() const
187 {
185 {
188 return m_marginSize;
186 return m_marginSize;
189 }
187 }
190
188
191 void QChart::setMargin(int margin)
189 void QChart::setMargin(int margin)
192 {
190 {
193 m_marginSize = margin;
191 m_marginSize = margin;
194 }
192 }
195
193
196 void QChart::setTheme(QChart::ChartTheme theme)
194 void QChart::setTheme(QChart::ChartTheme theme)
197 {
195 {
198 // TODO: define color themes
196 // TODO: define color themes
199 switch (theme) {
197 switch (theme) {
200 case ChartThemeVanilla:
198 case ChartThemeVanilla:
201 m_themeColors.append(QColor(255, 238, 174));
199 m_themeColors.append(QColor(255, 238, 174));
202 m_themeColors.append(QColor(228, 228, 160));
200 m_themeColors.append(QColor(228, 228, 160));
203 m_themeColors.append(QColor(228, 179, 160));
201 m_themeColors.append(QColor(228, 179, 160));
204 m_themeColors.append(QColor(180, 151, 18));
202 m_themeColors.append(QColor(180, 151, 18));
205 m_themeColors.append(QColor(252, 252, 37));
203 m_themeColors.append(QColor(252, 252, 37));
206 break;
204 break;
207 case ChartThemeIcy:
205 case ChartThemeIcy:
208 m_themeColors.append(QColor(255, 238, 174));
206 m_themeColors.append(QColor(255, 238, 174));
209 m_themeColors.append(QColor(228, 228, 160));
207 m_themeColors.append(QColor(228, 228, 160));
210 m_themeColors.append(QColor(228, 179, 160));
208 m_themeColors.append(QColor(228, 179, 160));
211 m_themeColors.append(QColor(180, 151, 18));
209 m_themeColors.append(QColor(180, 151, 18));
212 m_themeColors.append(QColor(252, 252, 37));
210 m_themeColors.append(QColor(252, 252, 37));
213 break;
211 break;
214 case ChartThemeGrayscale:
212 case ChartThemeGrayscale:
215 m_themeColors.append(QColor(255, 238, 174));
213 m_themeColors.append(QColor(255, 238, 174));
216 m_themeColors.append(QColor(228, 228, 160));
214 m_themeColors.append(QColor(228, 228, 160));
217 m_themeColors.append(QColor(228, 179, 160));
215 m_themeColors.append(QColor(228, 179, 160));
218 m_themeColors.append(QColor(180, 151, 18));
216 m_themeColors.append(QColor(180, 151, 18));
219 m_themeColors.append(QColor(252, 252, 37));
217 m_themeColors.append(QColor(252, 252, 37));
220 break;
218 break;
221 default:
219 default:
222 Q_ASSERT(false);
220 Q_ASSERT(false);
223 break;
221 break;
224 }
222 }
225
223
226 // TODO: update coloring of different elements to match the selected theme
224 // TODO: update coloring of different elements to match the selected theme
227 }
225 }
228
226
229 void QChart::zoomInToRect(const QRect& rectangle)
227 void QChart::zoomInToRect(const QRect& rectangle)
230 {
228 {
231
229
232 if(!rectangle.isValid()) return;
230 if(!rectangle.isValid()) return;
233
231
234 qreal margin = this->margin();
232 qreal margin = this->margin();
235
233
236 QRect rect = rectangle.normalized();
234 QRect rect = rectangle.normalized();
237 rect.translate(-margin, -margin);
235 rect.translate(-margin, -margin);
238
236
239 PlotDomain& oldDomain = m_plotDomainList[m_plotDataIndex];
237 PlotDomain& oldDomain = m_plotDomainList[m_plotDataIndex];
240 PlotDomain newDomain;
238 PlotDomain newDomain;
241
239
242 qreal dx = oldDomain.spanX() / (m_rect.width() - 2 * margin);
240 qreal dx = oldDomain.spanX() / (m_rect.width() - 2 * margin);
243 qreal dy = oldDomain.spanY() / (m_rect.height() - 2 * margin);
241 qreal dy = oldDomain.spanY() / (m_rect.height() - 2 * margin);
244
242
245 newDomain.m_minX = oldDomain.m_minX + dx * rect.left();
243 newDomain.m_minX = oldDomain.m_minX + dx * rect.left();
246 newDomain.m_maxX = oldDomain.m_minX + dx * rect.right();
244 newDomain.m_maxX = oldDomain.m_minX + dx * rect.right();
247 newDomain.m_minY = oldDomain.m_maxY - dy * rect.bottom();
245 newDomain.m_minY = oldDomain.m_maxY - dy * rect.bottom();
248 newDomain.m_maxY = oldDomain.m_maxY - dy * rect.top();
246 newDomain.m_maxY = oldDomain.m_maxY - dy * rect.top();
249
247
250 m_plotDomainList.resize(m_plotDataIndex + 1);
248 m_plotDomainList.resize(m_plotDataIndex + 1);
251 m_plotDomainList<<newDomain;
249 m_plotDomainList<<newDomain;
252 m_plotDataIndex++;
250 m_plotDataIndex++;
253
251
254 foreach (ChartItem* item ,m_chartItems)
252 foreach (ChartItem* item ,m_chartItems)
255 item->setPlotDomain(m_plotDomainList[m_plotDataIndex]);
253 item->setPlotDomain(m_plotDomainList[m_plotDataIndex]);
256 update();
254 update();
257 }
255 }
258
256
259 void QChart::zoomIn()
257 void QChart::zoomIn()
260 {
258 {
261 if (m_plotDataIndex < m_plotDomainList.count() - 1) {
259 if (m_plotDataIndex < m_plotDomainList.count() - 1) {
262 m_plotDataIndex++;
260 m_plotDataIndex++;
263 foreach (ChartItem* item ,m_chartItems)
261 foreach (ChartItem* item ,m_chartItems)
264 item->setPlotDomain(m_plotDomainList[m_plotDataIndex]);
262 item->setPlotDomain(m_plotDomainList[m_plotDataIndex]);
265 update();
263 update();
266 }else{
264 }else{
267 QRect rect = m_rect.adjusted(margin(),margin(), -margin(), -margin());
265 QRect rect = m_rect.adjusted(margin(),margin(), -margin(), -margin());
268 rect.setWidth(rect.width()/2);
266 rect.setWidth(rect.width()/2);
269 rect.setHeight(rect.height()/2);
267 rect.setHeight(rect.height()/2);
270 rect.moveCenter(m_rect.center());
268 rect.moveCenter(m_rect.center());
271 zoomInToRect(rect);
269 zoomInToRect(rect);
272 }
270 }
273 }
271 }
274
272
275 void QChart::zoomOut()
273 void QChart::zoomOut()
276 {
274 {
277 if (m_plotDataIndex > 0) {
275 if (m_plotDataIndex > 0) {
278 m_plotDataIndex--;
276 m_plotDataIndex--;
279 foreach (ChartItem* item ,m_chartItems)
277 foreach (ChartItem* item ,m_chartItems)
280 item->setPlotDomain(m_plotDomainList[m_plotDataIndex]);
278 item->setPlotDomain(m_plotDomainList[m_plotDataIndex]);
281 update();
279 update();
282 }
280 }
283 }
281 }
284
282
285 #include "moc_qchart.cpp"
283 #include "moc_qchart.cpp"
286
284
287 QTCOMMERCIALCHART_END_NAMESPACE
285 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,86 +1,85
1 #ifndef CHART_H
1 #ifndef CHART_H
2 #define CHART_H
2 #define CHART_H
3
3
4 #include <qchartglobal.h>
4 #include <qchartglobal.h>
5 #include <qchartseries.h>
5 #include <qchartseries.h>
6 #include <QGraphicsObject>
6 #include <QGraphicsObject>
7 #include <QLinearGradient>
7 #include <QLinearGradient>
8
8
9 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9 QTCOMMERCIALCHART_BEGIN_NAMESPACE
10
10
11 class AxisItem;
11 class AxisItem;
12 class QChartSeries;
12 class QChartSeries;
13 class PlotDomain;
13 class PlotDomain;
14 class ChartItem;
14 class ChartItem;
15 class BarGroup;
15 class BarGroup;
16
16
17 // TODO: We don't need to have QChart tied to QGraphicsItem:
17 // TODO: We don't need to have QChart tied to QGraphicsItem:
18 //class QTCOMMERCIALCHART_EXPORT QChart
18 //class QTCOMMERCIALCHART_EXPORT QChart
19 //class QTCOMMERCIALCHART_EXPORT QChartGraphicsItem : public QGraphicsItem {
19 //class QTCOMMERCIALCHART_EXPORT QChartGraphicsItem : public QGraphicsItem {
20 // public: QChartGraphicsItem(QChart &chart);
20 // public: QChartGraphicsItem(QChart &chart);
21
21
22 /*!
22 /*!
23 * TODO: define the responsibilities
23 * TODO: define the responsibilities
24 */
24 */
25 class QTCOMMERCIALCHART_EXPORT QChart : public QGraphicsObject
25 class QTCOMMERCIALCHART_EXPORT QChart : public QGraphicsObject
26 {
26 {
27 Q_OBJECT
27 Q_OBJECT
28 public:
28 public:
29 enum ChartTheme {
29 enum ChartTheme {
30 ChartThemeVanilla = 0,
30 ChartThemeVanilla = 0,
31 ChartThemeIcy,
31 ChartThemeIcy,
32 ChartThemeGrayscale
32 ChartThemeGrayscale
33 };
33 };
34
34
35 public:
35 public:
36 QChart(QGraphicsObject* parent = 0);
36 QChart(QGraphicsObject* parent = 0);
37 ~QChart();
37 ~QChart();
38
38
39 //from QGraphicsItem
39 //from QGraphicsItem
40 QRectF boundingRect() const;
40 QRectF boundingRect() const;
41 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget){};
41 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget){};
42
42
43 void addSeries(QChartSeries* series);
43 void addSeries(QChartSeries* series);
44 //TODO: QChartSeries* createSeries(QSeriesData *data, QChartSeries::QChartSeriesType type);
44 //TODO: QChartSeries* createSeries(QSeriesData *data, QChartSeries::QChartSeriesType type);
45 // TODO: who owns the series now? maybe owned by chart and returned a reference instead...
45 // TODO: who owns the series now? maybe owned by chart and returned a reference instead...
46 QChartSeries* createSeries(QChartSeries::QChartSeriesType type);
46 QChartSeries* createSeries(QChartSeries::QChartSeriesType type);
47
47
48 void setSize(const QSize& size);
48 void setSize(const QSize& size);
49 void setMargin(int margin);
49 void setMargin(int margin);
50 int margin() const;
50 int margin() const;
51 void setTheme(QChart::ChartTheme theme);
51 void setTheme(QChart::ChartTheme theme);
52
52
53 void setTitle(const QString& title);
53 void setTitle(const QString& title);
54 void setBackgroundColor(const QColor& color);
54 void setBackgroundColor(const QColor& color);
55
55
56 void zoomInToRect(const QRect& rectangle);
56 void zoomInToRect(const QRect& rectangle);
57 void zoomIn();
57 void zoomIn();
58 void zoomOut();
58 void zoomOut();
59
59
60 signals:
60 signals:
61 //TODO chage to const QSize& size
61 //TODO chage to const QSize& size
62 void sizeChanged(QRectF rect);
62 void sizeChanged(QRectF rect);
63 void scaleChanged(qreal xscale, qreal yscale);
63 void scaleChanged(qreal xscale, qreal yscale);
64
64
65 private:
65 private:
66 Q_DISABLE_COPY(QChart)
66 Q_DISABLE_COPY(QChart)
67 QGraphicsRectItem* m_background;
67 QGraphicsRectItem* m_background;
68 QLinearGradient m_backgroundGradient;
68 QLinearGradient m_backgroundGradient;
69 QGraphicsTextItem* m_title;
69 QGraphicsTextItem* m_title;
70 AxisItem* m_axisX;
70 AxisItem* m_axisX;
71 AxisItem* m_axisY;
71 AxisItem* m_axisY;
72 QRect m_rect;
72 QRect m_rect;
73 QList<const QChartSeries*> m_series;
73 QList<const QChartSeries*> m_series;
74 QVector<PlotDomain> m_plotDomainList;
74 QVector<PlotDomain> m_plotDomainList;
75 QList<ChartItem*> m_chartItems;
75 QList<ChartItem*> m_chartItems;
76 //TODO: remove
76 //TODO: remove
77 QList<QGraphicsItem*> m_items;
77 QList<QGraphicsItem*> m_items;
78 int m_plotDataIndex;
78 int m_plotDataIndex;
79 int m_marginSize;
79 int m_marginSize;
80 QList<QColor> m_themeColors;
80 QList<QColor> m_themeColors;
81 QList<BarGroup*> m_BarGroupItems;
82 };
81 };
83
82
84 QTCOMMERCIALCHART_END_NAMESPACE
83 QTCOMMERCIALCHART_END_NAMESPACE
85
84
86 #endif
85 #endif
@@ -1,32 +1,34
1 #include "qchartglobal.h"
1 #include "qchartglobal.h"
2 #include "qchartseries.h"
2 #include "qchartseries.h"
3
3
4 #include "barchartseries.h"
4 #include "barchartseries.h"
5 #include "qxychartseries.h"
5 #include "qxychartseries.h"
6
6
7 QTCOMMERCIALCHART_BEGIN_NAMESPACE
7 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8
8
9 QChartSeries* QChartSeries::create(QChartSeriesType type, QObject* parent)
9 QChartSeries* QChartSeries::create(QChartSeriesType type, QObject* parent)
10 {
10 {
11 qDebug() << "QChartSeries::create";
11 // TODO: Other types
12 // TODO: Other types
12 switch (type) {
13 switch (type) {
13 case QChartSeries::SeriesTypeLine: {
14 case QChartSeries::SeriesTypeLine: {
14 QXYChartSeries* s = QXYChartSeries::create(parent); // TODO: do we need create method for derived implementations?
15 QXYChartSeries* s = QXYChartSeries::create(parent); // TODO: do we need create method for derived implementations?
15 return s;
16 return s;
16 }
17 }
17 case QChartSeries::SeriesTypePie: {
18 case QChartSeries::SeriesTypePie: {
18 return 0;
19 return 0;
19 }
20 }
20 case QChartSeries::SeriesTypeScatter: {
21 case QChartSeries::SeriesTypeScatter: {
21 return 0;
22 return 0;
22 }
23 }
23 case QChartSeries::SeriesTypeBar: {
24 case QChartSeries::SeriesTypeBar: {
24 BarChartSeries* s = new BarChartSeries(parent);
25 BarChartSeries* s = new BarChartSeries(parent);
25 return s;
26 return s;
26 }
27 }
27 default:
28 default:
28 return 0;
29 return 0;
29 }
30 }
30 }
31 }
31
32
33 #include "moc_qchartseries.cpp"
32 QTCOMMERCIALCHART_END_NAMESPACE
34 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,43 +1,47
1 #ifndef QCHARTSERIES_H
1 #ifndef QCHARTSERIES_H
2 #define QCHARTSERIES_H
2 #define QCHARTSERIES_H
3
3
4 #include "qchartglobal.h"
4 #include "qchartglobal.h"
5 #include <QObject>
5 #include <QObject>
6 #include <QAbstractItemModel>
6
7
7 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8
9
9 class QTCOMMERCIALCHART_EXPORT QChartSeries : public QObject
10 class QTCOMMERCIALCHART_EXPORT QChartSeries : public QObject
10 {
11 {
11 //TODO:
12 Q_OBJECT
12 //Q_OBJECT
13 public:
13 public:
14 enum QChartSeriesType {
14 enum QChartSeriesType {
15 SeriesTypeLine = 0,
15 SeriesTypeLine = 0,
16 // SeriesTypeArea,
16 // SeriesTypeArea,
17 SeriesTypeBar,
17 SeriesTypeBar,
18 SeriesTypePie,
18 SeriesTypePie,
19 SeriesTypeScatter
19 SeriesTypeScatter
20 // SeriesTypeSpline
20 // SeriesTypeSpline
21 };
21 };
22
22
23 protected:
23 protected:
24 QChartSeries(QObject *parent = 0):QObject(parent){};
24 QChartSeries(QObject *parent = 0):QObject(parent){};
25
25
26 public:
26 public:
27 virtual ~QChartSeries(){};
27 virtual ~QChartSeries(){};
28
28
29 // Factory method
29 // Factory method
30 static QChartSeries* create(QChartSeriesType type, QObject* parent = 0 );
30 static QChartSeries* create(QChartSeriesType type, QObject* parent = 0 );
31
31
32 // Pure virtual
32 // Pure virtual
33 virtual QChartSeriesType type() const = 0;
33 virtual QChartSeriesType type() const = 0;
34
34
35 virtual bool setData(QList<int> data) { return false; }
35 virtual bool setData(QList<int> data) { return false; }
36 virtual bool setData(QList<qreal> data) { return false; }
36 virtual bool setData(QList<qreal> data) { return false; }
37 virtual bool setData(QList<qreal> x, QList<qreal> y){ return false; }
37 virtual bool setData(QList<qreal> x, QList<qreal> y){ return false; }
38
39 // Prototype for data model. TODO: remove the other setData methods and use something like this for now?
40 virtual bool setData(QAbstractItemModel* model) { return false; }
41
38 };
42 };
39
43
40 QTCOMMERCIALCHART_END_NAMESPACE
44 QTCOMMERCIALCHART_END_NAMESPACE
41
45
42 #endif
46 #endif
43
47
@@ -1,314 +1,314
1 #include "mainwidget.h"
1 #include "mainwidget.h"
2 #include "dataseriedialog.h"
2 #include "dataseriedialog.h"
3 #include "qchartseries.h"
3 #include "qchartseries.h"
4 #include "qpieseries.h"
4 #include "qpieseries.h"
5 #include <qxychartseries.h>
5 #include <qxychartseries.h>
6 #include <barchartseries.h>
6 #include <barchartseries.h>
7 #include <QPushButton>
7 #include <QPushButton>
8 #include <QComboBox>
8 #include <QComboBox>
9 #include <QSpinBox>
9 #include <QSpinBox>
10 #include <QCheckBox>
10 #include <QCheckBox>
11 #include <QGridLayout>
11 #include <QGridLayout>
12 #include <QHBoxLayout>
12 #include <QHBoxLayout>
13 #include <QLabel>
13 #include <QLabel>
14 #include <QSpacerItem>
14 #include <QSpacerItem>
15 #include <QMessageBox>
15 #include <QMessageBox>
16 #include <cmath>
16 #include <cmath>
17 #include <QDebug>
17 #include <QDebug>
18
18
19 QTCOMMERCIALCHART_USE_NAMESPACE
19 QTCOMMERCIALCHART_USE_NAMESPACE
20
20
21 MainWidget::MainWidget(QWidget *parent) :
21 MainWidget::MainWidget(QWidget *parent) :
22 QWidget(parent)
22 QWidget(parent)
23 {
23 {
24 QPushButton *addSeriesButton = new QPushButton("Add series");
24 QPushButton *addSeriesButton = new QPushButton("Add series");
25 connect(addSeriesButton, SIGNAL(clicked()), this, SLOT(addSeries()));
25 connect(addSeriesButton, SIGNAL(clicked()), this, SLOT(addSeries()));
26
26
27 // Chart background
27 // Chart background
28 QComboBox *backgroundCombo = new QComboBox(this);
28 QComboBox *backgroundCombo = new QComboBox(this);
29 backgroundCombo->addItem("None");
29 backgroundCombo->addItem("None");
30 backgroundCombo->addItem("TODO Grid");
30 backgroundCombo->addItem("TODO Grid");
31 backgroundCombo->addItem("TODO Image");
31 backgroundCombo->addItem("TODO Image");
32 connect(backgroundCombo, SIGNAL(currentIndexChanged(int)),
32 connect(backgroundCombo, SIGNAL(currentIndexChanged(int)),
33 this, SLOT(backgroundChanged(int)));
33 this, SLOT(backgroundChanged(int)));
34
34
35 // Axis
35 // Axis
36 // TODO: multiple axes?
36 // TODO: multiple axes?
37 m_autoScaleCheck = new QCheckBox("Automatic scaling");
37 m_autoScaleCheck = new QCheckBox("Automatic scaling");
38 connect(m_autoScaleCheck, SIGNAL(stateChanged(int)), this, SLOT(autoScaleChanged(int)));
38 connect(m_autoScaleCheck, SIGNAL(stateChanged(int)), this, SLOT(autoScaleChanged(int)));
39 // Allow setting also non-sense values (like -2147483648 and 2147483647)
39 // Allow setting also non-sense values (like -2147483648 and 2147483647)
40 m_xMinSpin = new QSpinBox();
40 m_xMinSpin = new QSpinBox();
41 m_xMinSpin->setMinimum(INT_MIN);
41 m_xMinSpin->setMinimum(INT_MIN);
42 m_xMinSpin->setMaximum(INT_MAX);
42 m_xMinSpin->setMaximum(INT_MAX);
43 m_xMinSpin->setValue(0);
43 m_xMinSpin->setValue(0);
44 connect(m_xMinSpin, SIGNAL(valueChanged(int)), this, SLOT(xMinChanged(int)));
44 connect(m_xMinSpin, SIGNAL(valueChanged(int)), this, SLOT(xMinChanged(int)));
45 m_xMaxSpin = new QSpinBox();
45 m_xMaxSpin = new QSpinBox();
46 m_xMaxSpin->setMinimum(INT_MIN);
46 m_xMaxSpin->setMinimum(INT_MIN);
47 m_xMaxSpin->setMaximum(INT_MAX);
47 m_xMaxSpin->setMaximum(INT_MAX);
48 m_xMaxSpin->setValue(10);
48 m_xMaxSpin->setValue(10);
49 connect(m_xMaxSpin, SIGNAL(valueChanged(int)), this, SLOT(xMaxChanged(int)));
49 connect(m_xMaxSpin, SIGNAL(valueChanged(int)), this, SLOT(xMaxChanged(int)));
50 m_yMinSpin = new QSpinBox();
50 m_yMinSpin = new QSpinBox();
51 m_yMinSpin->setMinimum(INT_MIN);
51 m_yMinSpin->setMinimum(INT_MIN);
52 m_yMinSpin->setMaximum(INT_MAX);
52 m_yMinSpin->setMaximum(INT_MAX);
53 m_yMinSpin->setValue(0);
53 m_yMinSpin->setValue(0);
54 connect(m_yMinSpin, SIGNAL(valueChanged(int)), this, SLOT(yMinChanged(int)));
54 connect(m_yMinSpin, SIGNAL(valueChanged(int)), this, SLOT(yMinChanged(int)));
55 m_yMaxSpin = new QSpinBox();
55 m_yMaxSpin = new QSpinBox();
56 m_yMaxSpin->setMinimum(INT_MIN);
56 m_yMaxSpin->setMinimum(INT_MIN);
57 m_yMaxSpin->setMaximum(INT_MAX);
57 m_yMaxSpin->setMaximum(INT_MAX);
58 m_yMaxSpin->setValue(10);
58 m_yMaxSpin->setValue(10);
59 connect(m_yMaxSpin, SIGNAL(valueChanged(int)), this, SLOT(yMaxChanged(int)));
59 connect(m_yMaxSpin, SIGNAL(valueChanged(int)), this, SLOT(yMaxChanged(int)));
60
60
61 QComboBox *chartTheme = new QComboBox();
61 QComboBox *chartTheme = new QComboBox();
62 chartTheme->addItem("Vanilla");
62 chartTheme->addItem("Vanilla");
63 chartTheme->addItem("Icy");
63 chartTheme->addItem("Icy");
64 chartTheme->addItem("Grayscale");
64 chartTheme->addItem("Grayscale");
65 chartTheme->addItem("Tobedefined");
65 chartTheme->addItem("Tobedefined");
66 connect(chartTheme, SIGNAL(currentIndexChanged(int)),
66 connect(chartTheme, SIGNAL(currentIndexChanged(int)),
67 this, SLOT(changeChartTheme(int)));
67 this, SLOT(changeChartTheme(int)));
68
68
69 QGridLayout *grid = new QGridLayout();
69 QGridLayout *grid = new QGridLayout();
70 QGridLayout *mainLayout = new QGridLayout();
70 QGridLayout *mainLayout = new QGridLayout();
71 //grid->addWidget(new QLabel("Add series:"), 0, 0);
71 //grid->addWidget(new QLabel("Add series:"), 0, 0);
72 grid->addWidget(addSeriesButton, 0, 1);
72 grid->addWidget(addSeriesButton, 0, 1);
73 grid->addWidget(new QLabel("Background:"), 2, 0);
73 grid->addWidget(new QLabel("Background:"), 2, 0);
74 grid->addWidget(backgroundCombo, 2, 1);
74 grid->addWidget(backgroundCombo, 2, 1);
75 grid->addWidget(m_autoScaleCheck, 3, 0);
75 grid->addWidget(m_autoScaleCheck, 3, 0);
76 grid->addWidget(new QLabel("x min:"), 4, 0);
76 grid->addWidget(new QLabel("x min:"), 4, 0);
77 grid->addWidget(m_xMinSpin, 4, 1);
77 grid->addWidget(m_xMinSpin, 4, 1);
78 grid->addWidget(new QLabel("x max:"), 5, 0);
78 grid->addWidget(new QLabel("x max:"), 5, 0);
79 grid->addWidget(m_xMaxSpin, 5, 1);
79 grid->addWidget(m_xMaxSpin, 5, 1);
80 grid->addWidget(new QLabel("y min:"), 6, 0);
80 grid->addWidget(new QLabel("y min:"), 6, 0);
81 grid->addWidget(m_yMinSpin, 6, 1);
81 grid->addWidget(m_yMinSpin, 6, 1);
82 grid->addWidget(new QLabel("y max:"), 7, 0);
82 grid->addWidget(new QLabel("y max:"), 7, 0);
83 grid->addWidget(m_yMaxSpin, 7, 1);
83 grid->addWidget(m_yMaxSpin, 7, 1);
84 grid->addWidget(new QLabel("Chart theme:"), 8, 0);
84 grid->addWidget(new QLabel("Chart theme:"), 8, 0);
85 grid->addWidget(chartTheme, 8, 1);
85 grid->addWidget(chartTheme, 8, 1);
86 // add row with empty label to make all the other rows static
86 // add row with empty label to make all the other rows static
87 grid->addWidget(new QLabel(""), 9, 0);
87 grid->addWidget(new QLabel(""), 9, 0);
88 grid->setRowStretch(9, 1);
88 grid->setRowStretch(9, 1);
89
89
90 mainLayout->addLayout(grid, 0, 0);
90 mainLayout->addLayout(grid, 0, 0);
91
91
92 // Scatter specific settings
92 // Scatter specific settings
93 m_scatterLayout = new QGridLayout();
93 m_scatterLayout = new QGridLayout();
94 m_scatterLayout->addWidget(new QLabel("scatter"), 0, 0);
94 m_scatterLayout->addWidget(new QLabel("scatter"), 0, 0);
95 m_scatterLayout->setEnabled(false);
95 m_scatterLayout->setEnabled(false);
96
96
97 // Pie specific settings
97 // Pie specific settings
98 m_pieLayout = new QGridLayout();
98 m_pieLayout = new QGridLayout();
99 m_pieLayout->addWidget(new QLabel("Pie size factor"), 0, 0);
99 m_pieLayout->addWidget(new QLabel("Pie size factor"), 0, 0);
100 QDoubleSpinBox *pieSizeSpin = new QDoubleSpinBox();
100 QDoubleSpinBox *pieSizeSpin = new QDoubleSpinBox();
101 pieSizeSpin->setMinimum(LONG_MIN);
101 pieSizeSpin->setMinimum(LONG_MIN);
102 pieSizeSpin->setMaximum(LONG_MAX);
102 pieSizeSpin->setMaximum(LONG_MAX);
103 pieSizeSpin->setValue(1.0);
103 pieSizeSpin->setValue(1.0);
104 pieSizeSpin->setSingleStep(0.1);
104 pieSizeSpin->setSingleStep(0.1);
105 connect(pieSizeSpin, SIGNAL(valueChanged(double)), this, SLOT(setPieSizeFactor(double)));
105 connect(pieSizeSpin, SIGNAL(valueChanged(double)), this, SLOT(setPieSizeFactor(double)));
106 m_pieLayout->setEnabled(false);
106 m_pieLayout->setEnabled(false);
107 m_pieLayout->addWidget(pieSizeSpin, 0, 1);
107 m_pieLayout->addWidget(pieSizeSpin, 0, 1);
108
108
109 mainLayout->addLayout(m_scatterLayout, 1, 0);
109 mainLayout->addLayout(m_scatterLayout, 1, 0);
110 mainLayout->addLayout(m_pieLayout, 2, 0);
110 mainLayout->addLayout(m_pieLayout, 2, 0);
111
111
112 m_chartWidget = new QChartWidget(this);
112 m_chartWidget = new QChartWidget(this);
113 //m_chartWidget->setColor(Qt::red);
113 //m_chartWidget->setColor(Qt::red);
114 mainLayout->addWidget(m_chartWidget, 0, 1, 3, 1);
114 mainLayout->addWidget(m_chartWidget, 0, 1, 3, 1);
115 // hbox->setStretch(1, 1);
115 // hbox->setStretch(1, 1);
116
116
117 setLayout(mainLayout);
117 setLayout(mainLayout);
118
118
119 m_autoScaleCheck->setChecked(true);
119 m_autoScaleCheck->setChecked(true);
120 testDataChanged(0);
120 testDataChanged(0);
121 }
121 }
122
122
123 void MainWidget::addSeries()
123 void MainWidget::addSeries()
124 {
124 {
125 DataSerieDialog dialog(m_defaultSeriesName, this);
125 DataSerieDialog dialog(m_defaultSeriesName, this);
126 connect(&dialog, SIGNAL(accepted(QString, QString)), this, SLOT(addSeries(QString, QString)));
126 connect(&dialog, SIGNAL(accepted(QString, QString)), this, SLOT(addSeries(QString, QString)));
127 dialog.exec();
127 dialog.exec();
128 }
128 }
129
129
130 void MainWidget::addSeries(QString series, QString data)
130 void MainWidget::addSeries(QString series, QString data)
131 {
131 {
132 qDebug() << "addSeries: " << series << " data: " << data;
132 qDebug() << "addSeries: " << series << " data: " << data;
133 m_defaultSeriesName = series;
133 m_defaultSeriesName = series;
134
134
135 // TODO: a dedicated data class for storing x and y values
135 // TODO: a dedicated data class for storing x and y values
136 QList<qreal> x;
136 QList<qreal> x;
137 QList<qreal> y;
137 QList<qreal> y;
138
138
139 if (data == "linear") {
139 if (data == "linear") {
140 for (int i = 0; i < 20; i++) {
140 for (int i = 0; i < 20; i++) {
141 x.append(i);
141 x.append(i);
142 y.append(i);
142 y.append(i);
143 }
143 }
144 } else if (data == "linear, 1M") {
144 } else if (data == "linear, 1M") {
145 for (int i = 0; i < 10000; i++) {
145 for (int i = 0; i < 10000; i++) {
146 x.append(i);
146 x.append(i);
147 y.append(20);
147 y.append(20);
148 }
148 }
149 } else if (data == "SIN") {
149 } else if (data == "SIN") {
150 for (int i = 0; i < 100; i++) {
150 for (int i = 0; i < 100; i++) {
151 x.append(i);
151 x.append(i);
152 y.append(abs(sin(3.14159265358979 / 50 * i) * 100));
152 y.append(abs(sin(3.14159265358979 / 50 * i) * 100));
153 }
153 }
154 } else if (data == "SIN + random") {
154 } else if (data == "SIN + random") {
155 for (qreal i = 0; i < 100; i += 0.1) {
155 for (qreal i = 0; i < 100; i += 0.1) {
156 x.append(i + (rand() % 5));
156 x.append(i + (rand() % 5));
157 y.append(abs(sin(3.14159265358979 / 50 * i) * 100) + (rand() % 5));
157 y.append(abs(sin(3.14159265358979 / 50 * i) * 100) + (rand() % 5));
158 }
158 }
159 } else {
159 } else {
160 // TODO: check if data has a valid file name
160 // TODO: check if data has a valid file name
161 Q_ASSERT(false);
161 Q_ASSERT(false);
162 }
162 }
163
163
164 // TODO: color of the series
164 // TODO: color of the series
165 QChartSeries *newSeries = 0;
165 QChartSeries *newSeries = 0;
166 if (series == "Scatter") {
166 if (series == "Scatter") {
167 newSeries = m_chartWidget->createSeries(QChartSeries::SeriesTypeScatter);
167 newSeries = m_chartWidget->createSeries(QChartSeries::SeriesTypeScatter);
168 Q_ASSERT(newSeries->setData(x, y));
168 Q_ASSERT(newSeries->setData(x, y));
169 } else if (series == "Pie") {
169 } else if (series == "Pie") {
170 newSeries = m_chartWidget->createSeries(QChartSeries::SeriesTypePie);
170 newSeries = m_chartWidget->createSeries(QChartSeries::SeriesTypePie);
171 Q_ASSERT(newSeries->setData(y));
171 Q_ASSERT(newSeries->setData(y));
172 } else if (series == "Line") {
172 } else if (series == "Line") {
173 // TODO: adding data to an existing line series does not give any visuals for some reason
173 // TODO: adding data to an existing line series does not give any visuals for some reason
174 // newSeries = m_chartWidget->createSeries(QChartSeries::SeriesTypeLine);
174 // newSeries = m_chartWidget->createSeries(QChartSeries::SeriesTypeLine);
175 // QXYChartSeries *lineSeries = static_cast<QXYChartSeries *>(newSeries);
175 // QXYChartSeries *lineSeries = static_cast<QXYChartSeries *>(newSeries);
176 // lineSeries->setColor(Qt::blue);
176 // lineSeries->setColor(Qt::blue);
177 // for (int i(0); i < x.count() && i < y.count(); i++) {
177 // for (int i(0); i < x.count() && i < y.count(); i++) {
178 // lineSeries->add(x.at(i), y.at(i));
178 // lineSeries->add(x.at(i), y.at(i));
179 // }
179 // }
180 //Q_ASSERT(newSeries->setData(x, y));
180 //Q_ASSERT(newSeries->setData(x, y));
181 QXYChartSeries* series0 = QXYChartSeries::create();
181 QXYChartSeries* series0 = QXYChartSeries::create();
182 for (int i(0); i < x.count() && i < y.count(); i++)
182 for (int i(0); i < x.count() && i < y.count(); i++)
183 series0->add(x.at(i), y.at(i));
183 series0->add(x.at(i), y.at(i));
184 m_chartWidget->addSeries(series0);
184 m_chartWidget->addSeries(series0);
185 newSeries = series0;
185 newSeries = series0;
186 } else {
186 } else {
187 // TODO
187 // TODO
188 }
188 }
189
189
190 // BarChart
190 // BarChart
191 if (series == "Bar") {
191 if (series == "Bar") {
192 // This is the another way of creating series. Should we create test cases for both ways, if we support them?
192 // This is the another way of creating series. Should we create test cases for both ways, if we support them?
193 qDebug() << "Bar chart series";
193 qDebug() << "Bar chart series";
194 newSeries = QChartSeries::create(QChartSeries::SeriesTypeBar, this);
194 newSeries = QChartSeries::create(QChartSeries::SeriesTypeBar, this);
195 QList<int> barData;
195 QList<int> barData;
196 barData << 1;
196 barData << 1;
197 barData << 12;
197 barData << 12;
198 barData << 5;
198 barData << 5;
199 barData << 8;
199 barData << 8;
200 barData << 17;
200 barData << 17;
201 barData << 9;
201 barData << 9;
202 newSeries->setData(barData);
202 newSeries->setData(barData);
203 m_chartWidget->addSeries(newSeries);
203 m_chartWidget->addSeries(newSeries);
204 }
204 }
205
205
206 setCurrentSeries(newSeries);
206 setCurrentSeries(newSeries);
207 }
207 }
208
208
209 void MainWidget::setCurrentSeries(QChartSeries *series)
209 void MainWidget::setCurrentSeries(QChartSeries *series)
210 {
210 {
211 m_currentSeries = series;
211 m_currentSeries = series;
212 switch (m_currentSeries->type()) {
212 switch (m_currentSeries->type()) {
213 case QChartSeries::SeriesTypeLine:
213 case QChartSeries::SeriesTypeLine:
214 break;
214 break;
215 case QChartSeries::SeriesTypeScatter:
215 case QChartSeries::SeriesTypeScatter:
216 break;
216 break;
217 case QChartSeries::SeriesTypePie:
217 case QChartSeries::SeriesTypePie:
218 break;
218 break;
219 case QChartSeries::SeriesTypeBar:
219 case QChartSeries::SeriesTypeBar:
220 qDebug() << "setCurrentSeries (bar)";
220 qDebug() << "setCurrentSeries (bar)";
221 break;
221 break;
222 default:
222 default:
223 Q_ASSERT(false);
223 Q_ASSERT(false);
224 break;
224 break;
225 }
225 }
226 }
226 }
227
227
228 void MainWidget::testDataChanged(int itemIndex)
228 void MainWidget::testDataChanged(int itemIndex)
229 {
229 {
230 qDebug() << "testDataChanged: " << itemIndex;
230 qDebug() << "testDataChanged: " << itemIndex;
231
231
232 // switch (itemIndex) {
232 // switch (itemIndex) {
233 // case 0: {
233 // case 0: {
234 // QList<QChartDataPoint> data;
234 // QList<QChartDataPoint> data;
235 // for (int x = 0; x < 20; x++) {
235 // for (int x = 0; x < 20; x++) {
236 // data.append(QChartDataPoint() << x << x / 2);
236 // data.append(QChartDataPoint() << x << x / 2);
237 // }
237 // }
238 // m_chartWidget->setData(data);
238 // m_chartWidget->setData(data);
239 // break;
239 // break;
240 // }
240 // }
241 // case 1: {
241 // case 1: {
242 // QList<QChartDataPoint> data;
242 // QList<QChartDataPoint> data;
243 // for (int x = 0; x < 100; x++) {
243 // for (int x = 0; x < 100; x++) {
244 // data.append(QChartDataPoint() << x - 200 << 2 * (uint(sin(3.14159/50*x)*80) % 100));
244 // data.append(QChartDataPoint() << x - 200 << 2 * (uint(sin(3.14159/50*x)*80) % 100));
245 // }
245 // }
246 // m_chartWidget->setData(data);
246 // m_chartWidget->setData(data);
247 // break;
247 // break;
248 // }
248 // }
249 // case 2: {
249 // case 2: {
250 // QList<QChartDataPoint> data;
250 // QList<QChartDataPoint> data;
251 // for (int x = 0; x < 1000; x++) {
251 // for (int x = 0; x < 1000; x++) {
252 // data.append(QChartDataPoint() << x - 200 << 2 * (uint(sin(3.14159/50*x)*80) % 100) + (rand() % 100 * 0.2));
252 // data.append(QChartDataPoint() << x - 200 << 2 * (uint(sin(3.14159/50*x)*80) % 100) + (rand() % 100 * 0.2));
253 // data.append(QChartDataPoint() << x - 200 << 2 * (uint(sin(3.14159/50*x)*80) % 100) + (rand() % 100 * 0.2));
253 // data.append(QChartDataPoint() << x - 200 << 2 * (uint(sin(3.14159/50*x)*80) % 100) + (rand() % 100 * 0.2));
254 // data.append(QChartDataPoint() << x - 200 << 2 * (uint(sin(3.14159/50*x)*80) % 100) + (rand() % 100 * 0.2));
254 // data.append(QChartDataPoint() << x - 200 << 2 * (uint(sin(3.14159/50*x)*80) % 100) + (rand() % 100 * 0.2));
255 // }
255 // }
256 // m_chartWidget->setData(data);
256 // m_chartWidget->setData(data);
257 // break;
257 // break;
258 // }
258 // }
259 // default:
259 // default:
260 // break;
260 // break;
261 // }
261 // }
262 }
262 }
263
263
264 void MainWidget::backgroundChanged(int itemIndex)
264 void MainWidget::backgroundChanged(int itemIndex)
265 {
265 {
266 qDebug() << "backgroundChanged: " << itemIndex;
266 qDebug() << "backgroundChanged: " << itemIndex;
267 }
267 }
268
268
269 void MainWidget::autoScaleChanged(int value)
269 void MainWidget::autoScaleChanged(int value)
270 {
270 {
271 if (value) {
271 if (value) {
272 // TODO: enable auto scaling
272 // TODO: enable auto scaling
273 } else {
273 } else {
274 // TODO: set scaling manually (and disable auto scaling)
274 // TODO: set scaling manually (and disable auto scaling)
275 }
275 }
276
276
277 m_xMinSpin->setEnabled(!value);
277 m_xMinSpin->setEnabled(!value);
278 m_xMaxSpin->setEnabled(!value);
278 m_xMaxSpin->setEnabled(!value);
279 m_yMinSpin->setEnabled(!value);
279 m_yMinSpin->setEnabled(!value);
280 m_yMaxSpin->setEnabled(!value);
280 m_yMaxSpin->setEnabled(!value);
281 }
281 }
282
282
283 void MainWidget::xMinChanged(int value)
283 void MainWidget::xMinChanged(int value)
284 {
284 {
285 qDebug() << "xMinChanged: " << value;
285 qDebug() << "xMinChanged: " << value;
286 }
286 }
287
287
288 void MainWidget::xMaxChanged(int value)
288 void MainWidget::xMaxChanged(int value)
289 {
289 {
290 qDebug() << "xMaxChanged: " << value;
290 qDebug() << "xMaxChanged: " << value;
291 }
291 }
292
292
293 void MainWidget::yMinChanged(int value)
293 void MainWidget::yMinChanged(int value)
294 {
294 {
295 qDebug() << "yMinChanged: " << value;
295 qDebug() << "yMinChanged: " << value;
296 }
296 }
297
297
298 void MainWidget::yMaxChanged(int value)
298 void MainWidget::yMaxChanged(int value)
299 {
299 {
300 qDebug() << "yMaxChanged: " << value;
300 qDebug() << "yMaxChanged: " << value;
301 }
301 }
302
302
303 void MainWidget::changeChartTheme(int themeIndex)
303 void MainWidget::changeChartTheme(int themeIndex)
304 {
304 {
305 qDebug() << "changeChartTheme: " << themeIndex;
305 qDebug() << "changeChartTheme: " << themeIndex;
306 m_chartWidget->setTheme((QChart::ChartTheme) themeIndex);
306 // m_chartWidget->setTheme((QChart::ChartTheme) themeIndex);
307 }
307 }
308
308
309 void MainWidget::setPieSizeFactor(double size)
309 void MainWidget::setPieSizeFactor(double size)
310 {
310 {
311 QPieSeries *pie = qobject_cast<QPieSeries *>(m_currentSeries);
311 QPieSeries *pie = qobject_cast<QPieSeries *>(m_currentSeries);
312 Q_ASSERT(pie);
312 Q_ASSERT(pie);
313 pie->setSizeFactor(qreal(size));
313 pie->setSizeFactor(qreal(size));
314 }
314 }
General Comments 0
You need to be logged in to leave comments. Login now