##// END OF EJS Templates
Refactored series creation with QChart
Tero Ahola -
r61:45d3de5e814a
parent child
Show More
@@ -1,166 +1,165
1 1 #include "qchart.h"
2 2 #include "qchartseries.h"
3 3 #include "qscatterseries.h"
4 4 #include "qscatterseries_p.h"
5 5 #include "qpieseries.h"
6 6 #include "qxychartseries.h"
7 7
8 8 #include "barchartseries.h"
9 9 #include "bargroup.h"
10 10
11 11 #include "xylinechartitem_p.h"
12 12 #include "xyplotdomain_p.h"
13 13 #include "axis_p.h"
14 14 #include "xygrid_p.h"
15 15 #include <QGraphicsScene>
16 16 #include <QDebug>
17 17
18 18 QTCOMMERCIALCHART_BEGIN_NAMESPACE
19 19
20 20 QChart::QChart(QGraphicsObject* parent) : QGraphicsObject(parent),
21 21 m_axisX(new Axis(this)),
22 22 m_axisY(new Axis(this)),
23 23 m_grid(new XYGrid(this)),
24 24 m_plotDataIndex(0),
25 25 m_marginSize(0)
26 26 {
27 27 // setFlags(QGraphicsItem::ItemClipsChildrenToShape);
28 28 // set axis
29 29 m_axisY->rotate(90);
30 30 }
31 31
32 32 QChart::~QChart(){}
33 33
34 34 QRectF QChart::boundingRect() const
35 35 {
36 36 return m_rect;
37 37 }
38 38
39 39 void QChart::addSeries(QChartSeries* series)
40 40 {
41 41 // TODO: we should check the series not already added
42 42
43 43 m_series<<series;
44 44
45 45 switch(series->type())
46 46 {
47 47 case QChartSeries::SeriesTypeLine: {
48 48
49 49 QXYChartSeries* xyseries = static_cast<QXYChartSeries*>(series);
50 50
51 51 XYPlotDomain domain;
52 52 //TODO "nice numbers algorithm"
53 53 domain.m_ticksX=4;
54 54 domain.m_ticksY=4;
55 55
56 56 for (int i = 0 ; i < xyseries->count() ; i++)
57 57 {
58 58 qreal x = xyseries->x(i);
59 59 qreal y = xyseries->y(i);
60 60 domain.m_minX = qMin(domain.m_minX,x);
61 61 domain.m_minY = qMin(domain.m_minY,y);
62 62 domain.m_maxX = qMax(domain.m_maxX,x);
63 63 domain.m_maxY = qMax(domain.m_maxY,y);
64 64 }
65 65
66 66 XYLineChartItem* item = new XYLineChartItem(xyseries,this);
67 67 item->updateXYPlotDomain(domain);
68 68 m_plotDomainList<<domain;
69 69 m_xyLineChartItems<<item;
70 70 break;
71 71 }
72 72 // TODO: Not tested:
73 73 // case QChartSeries::SeriesTypeScatter: {
74 74 // QScatterSeries *scatter = qobject_cast<QScatterSeries *>(series);
75 75 // if (scatter) {
76 76 // scatter->d->setParentItem(this);
77 77 // scene()->addItem(scatter->d);
78 78 // }
79 79 // break;
80 80 // }
81 81
82 82 case QChartSeries::SeriesTypeBar: {
83 83
84 84 qDebug() << "barSeries added";
85 85 BarChartSeries* barSeries = static_cast<BarChartSeries*>(series);
86 86
87 87 // Who owns the series?
88 88 BarGroup* group = new BarGroup(*barSeries, this);
89 89 scene()->addItem(group);
90 90 m_BarGroupItems.append(group); // If we need to access group later
91 91 break;
92 92 }
93 93 }
94 94 }
95 95
96 QChartSeries* QChart::createSeries(QList<qreal> x, QList<qreal> y, QChartSeries::QChartSeriesType type)
96 QChartSeries* QChart::createSeries(QChartSeries::QChartSeriesType type)
97 97 {
98 98 // TODO: support also other types; not only scatter and pie
99 Q_ASSERT(type == QChartSeries::SeriesTypeScatter
100 || type == QChartSeries::SeriesTypePie);
101 99
102 100 switch (type) {
103 101 case QChartSeries::SeriesTypeScatter: {
104 QScatterSeries *scatterSeries = new QScatterSeries(x, y, this);
102 QScatterSeries *scatterSeries = new QScatterSeries(this);
105 103 connect(this, SIGNAL(sizeChanged(QRectF)),
106 104 scatterSeries, SLOT(chartSizeChanged(QRectF)));
107 105 scatterSeries->d->setParentItem(this);
108 106 return scatterSeries;
109 107 }
110 108 case QChartSeries::SeriesTypePie: {
111 109 // TODO: we now have also a list of y values as a parameter, it is ignored
112 110 // we should use a generic data class instead of list of x and y values
113 QPieSeries *pieSeries = new QPieSeries(x, this);
111 QPieSeries *pieSeries = new QPieSeries(this);
114 112 connect(this, SIGNAL(sizeChanged(QRectF)),
115 113 pieSeries, SLOT(chartSizeChanged(QRectF)));
116 114 return pieSeries;
117 115 }
118 116 default:
117 Q_ASSERT(false);
119 118 break;
120 119 }
121 120
122 121 return 0;
123 122 }
124 123
125 124 void QChart::setSize(const QSizeF& size)
126 125 {
127 126 m_rect = QRect(QPoint(0,0),size.toSize());
128 127 m_rect.adjust(margin(),margin(), -margin(), -margin());
129 128 m_grid->setPos(m_rect.topLeft());
130 129 m_grid->setSize(m_rect.size());
131 130
132 131 // TODO: TTD for setting scale
133 132 //emit scaleChanged(100, 100);
134 133 // TODO: calculate the origo
135 134 // TODO: not sure if emitting a signal here is the best from performance point of view
136 135 emit sizeChanged(QRectF(0, 0, size.width(), size.height()));
137 136
138 137 for (int i(0); i < m_plotDomainList.size(); i++)
139 138 m_plotDomainList[i].m_viewportRect = m_rect;
140 139
141 140 // TODO: line chart items are updated separately as they don't support update
142 141 // via sizeChanged signal
143 142 foreach(XYLineChartItem* item ,m_xyLineChartItems)
144 143 item->updateXYPlotDomain(m_plotDomainList.at(m_plotDataIndex));
145 144
146 145
147 146 if (m_plotDomainList.count())
148 147 m_grid->setXYPlotData(m_plotDomainList.at(m_plotDataIndex));
149 148
150 149 update();
151 150 }
152 151
153 152 int QChart::margin() const
154 153 {
155 154 return m_marginSize;
156 155 }
157 156
158 157 void QChart::setMargin(int margin)
159 158 {
160 159 m_marginSize = margin;
161 160 }
162 161
163 162 #include "moc_qchart.cpp"
164 163
165 164
166 165 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,67 +1,67
1 1 #ifndef CHART_H
2 2 #define CHART_H
3 3
4 4 #include <qchartglobal.h>
5 5 #include <qchartseries.h>
6 6 #include <QGraphicsObject>
7 7
8 8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9 9
10 10 class Axis;
11 11 class XYGrid;
12 12 class QChartSeries;
13 13 class XYPlotDomain;
14 14 class XYLineChartItem;
15 15 class BarGroup;
16 16
17 17 // TODO: We don't need to have QChart tied to QGraphicsItem:
18 18 //class QTCOMMERCIALCHART_EXPORT QChart
19 19 //class QTCOMMERCIALCHART_EXPORT QChartGraphicsItem : public QGraphicsItem {
20 20 // public: QChartGraphicsItem(QChart &chart);
21 21
22 22 /*!
23 23 * TODO: define the responsibilities
24 24 */
25 25 class QTCOMMERCIALCHART_EXPORT QChart : public QGraphicsObject
26 26 {
27 27 Q_OBJECT
28 28 public:
29 29 QChart(QGraphicsObject* parent = 0);
30 30 ~QChart();
31 31
32 32 //from QGraphicsItem
33 33 QRectF boundingRect() const;
34 34 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget){};
35 35
36 36 void addSeries(QChartSeries* series);
37 37 //TODO: QChartSeries* createSeries(QSeriesData *data, QChartSeries::QChartSeriesType type);
38 38 // TODO: who owns the series now? maybe owned by chart and returned a reference instead...
39 QChartSeries* createSeries(QList<qreal> x, QList<qreal> y, QChartSeries::QChartSeriesType type);
39 QChartSeries* createSeries(QChartSeries::QChartSeriesType type);
40 40
41 41 virtual void setSize(const QSizeF& rect);
42 42 void setMargin(int margin);
43 43 int margin() const;
44 44
45 45 signals:
46 46 void sizeChanged(QRectF rect);
47 47 void scaleChanged(qreal xscale, qreal yscale);
48 48
49 49 private:
50 50 Q_DISABLE_COPY(QChart)
51 51 Axis* m_axisX;
52 52 Axis* m_axisY;
53 53 XYGrid* m_grid;
54 54 QRect m_rect;
55 55 QList<const QChartSeries*> m_series;
56 56 QList<XYPlotDomain> m_plotDomainList;
57 57 QList<XYLineChartItem*> m_xyLineChartItems;
58 58 QList<QGraphicsItem*> m_items;
59 59 int m_plotDataIndex;
60 60 int m_marginSize;
61 61
62 62 QList<BarGroup*> m_BarGroupItems;
63 63 };
64 64
65 65 QTCOMMERCIALCHART_END_NAMESPACE
66 66
67 67 #endif
@@ -1,38 +1,41
1 1 #ifndef QCHARTSERIES_H
2 2 #define QCHARTSERIES_H
3 3
4 4 #include "qchartglobal.h"
5 5 #include <QObject>
6 6
7 7 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8 8
9 9 class QTCOMMERCIALCHART_EXPORT QChartSeries : public QObject
10 10 {
11 11
12 12 public:
13 13 enum QChartSeriesType {
14 14 SeriesTypeLine = 0,
15 15 // SeriesTypeArea,
16 16 SeriesTypeBar,
17 17 SeriesTypePie,
18 18 SeriesTypeScatter
19 19 // SeriesTypeSpline
20 20 };
21 21
22 22 protected:
23 23 QChartSeries(QObject *parent = 0):QObject(parent){};
24 24
25 25 public:
26 26 virtual ~QChartSeries(){};
27 27
28 //factory method
28 // Factory method
29 29 static QChartSeries* create(QObject* parent = 0 ){ return 0;}
30 //pure virtual
30 // Pure virtual
31 31 virtual QChartSeriesType type() const = 0;
32 32
33 virtual bool setData(QList<int> data) { return false; }
34 virtual bool setData(QList<qreal> data) { return false; }
35 virtual bool setData(QList<qreal> x, QList<qreal> y){ return false; }
33 36 };
34 37
35 38 QTCOMMERCIALCHART_END_NAMESPACE
36 39
37 40 #endif
38 41
@@ -1,81 +1,81
1 1 #include "qchartview.h"
2 2 #include "qchart.h"
3 3 #include <QGraphicsView>
4 4 #include <QGraphicsScene>
5 5 #include <QRubberBand>
6 6 #include <QResizeEvent>
7 7 #include <QDebug>
8 8
9 9 QTCOMMERCIALCHART_BEGIN_NAMESPACE
10 10
11 11 QChartView::QChartView(QWidget *parent) :
12 12 QGraphicsView(parent),
13 13 m_scene(new QGraphicsScene()),
14 14 m_chart(new QChart()),
15 15 m_rubberBand(0),
16 16 m_showRubberBand(false)
17 17 {
18 18 setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
19 19 setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
20 20 setScene(m_scene);
21 21 m_chart->setMargin(50);
22 22 m_scene->addItem(m_chart);
23 23 setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
24 24 }
25 25
26 26 QChartView::~QChartView()
27 27 {
28 28 }
29 29
30 30 void QChartView::resizeEvent(QResizeEvent *event)
31 31 {
32 32 m_scene->setSceneRect(0,0,size().width(),size().height());
33 33 m_chart->setSize(size());
34 34 QWidget::resizeEvent(event);
35 35 }
36 36
37 37
38 38 void QChartView::addSeries(QChartSeries* series)
39 39 {
40 40 m_chart->addSeries(series);
41 41 }
42 42
43 QChartSeries* QChartView::createSeries(QList<qreal> x, QList<qreal> y, QChartSeries::QChartSeriesType type)
43 QChartSeries* QChartView::createSeries(QChartSeries::QChartSeriesType type)
44 44 {
45 45
46 return m_chart->createSeries(x, y, type);
46 return m_chart->createSeries(type);
47 47 }
48 48
49 49 void QChartView::mousePressEvent(QMouseEvent *event)
50 50 {
51 51 int margin = m_chart->margin();
52 52
53 53 QRect rect(margin,margin,width()-2*margin,height()-2*margin);
54 54
55 55 m_origin = event->pos();
56 56
57 57 if (!rect.contains(m_origin)) return;
58 58
59 59 if (!m_rubberBand)
60 60 m_rubberBand = new QRubberBand(QRubberBand::Rectangle, this);
61 61 m_rubberBand->setGeometry(QRect(m_origin, QSize()));
62 62 m_showRubberBand=true;
63 63 m_rubberBand->show();
64 64
65 65 }
66 66
67 67 void QChartView::mouseMoveEvent(QMouseEvent *event)
68 68 {
69 69 if(m_showRubberBand)
70 70 m_rubberBand->setGeometry(QRect(m_origin, event->pos()).normalized());
71 71 }
72 72
73 73 void QChartView::mouseReleaseEvent(QMouseEvent *event)
74 74 {
75 75 if(m_showRubberBand) {
76 76 m_rubberBand->hide();
77 77 m_showRubberBand=false;
78 78 }
79 79 }
80 80
81 81 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,46 +1,46
1 1 #ifndef QCHARTWIDGET_H
2 2 #define QCHARTWIDGET_H
3 3
4 4 #include "qchartglobal.h"
5 5 #include "qchartseries.h"
6 6 #include <QGraphicsView>
7 7
8 8 class QGraphicsScene;
9 9 class QRubberBand;
10 10
11 11 QTCOMMERCIALCHART_BEGIN_NAMESPACE
12 12
13 13 class QChart;
14 14
15 15 class QTCOMMERCIALCHART_EXPORT QChartView : public QGraphicsView
16 16 {
17 17 public:
18 18 explicit QChartView(QWidget *parent = 0);
19 19 ~QChartView();
20 20
21 21 //implement from QWidget
22 22 void resizeEvent(QResizeEvent *event);
23 23
24 // TODO: addSeries and createSeries are optional solutions
25 24 void addSeries(QChartSeries* series);
26 QChartSeries* createSeries(QList<qreal> x, QList<qreal> y, QChartSeries::QChartSeriesType type);
25 // Convenience function
26 QChartSeries* createSeries(QChartSeries::QChartSeriesType type);
27 27
28 28 protected:
29 29 void mouseMoveEvent (QMouseEvent *event);
30 30 void mousePressEvent (QMouseEvent *event);
31 31 void mouseReleaseEvent (QMouseEvent *event);
32 32
33 33 private:
34 34 QGraphicsScene *m_scene;
35 35 QChart* m_chart;
36 36 QRubberBand *m_rubberBand;
37 37 QPoint m_origin;
38 38 bool m_showRubberBand;
39 39 Q_DISABLE_COPY(QChartView)
40 40
41 41
42 42 };
43 43
44 44 QTCOMMERCIALCHART_END_NAMESPACE
45 45
46 46 #endif // QCHARTWIDGET_H
@@ -1,51 +1,51
1 1 #include "qchartwidget.h"
2 2 #include "qchartseries.h"
3 3 #include <QGraphicsView>
4 4 #include <QGraphicsScene>
5 5 #include <QResizeEvent>
6 6
7 7 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8 8
9 9 QChartWidget::QChartWidget(QWidget *parent) :
10 10 QGraphicsView(parent)
11 11 {
12 12 setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
13 13 m_scene = new QGraphicsScene();
14 14 setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
15 15 setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
16 16 setScene(m_scene);
17
17
18 18 m_chart = new QChart();
19 19 m_scene->addItem(m_chart);
20 20 show();
21 21 }
22 22
23 23 QChartWidget::~QChartWidget()
24 24 {
25 25 }
26 26
27 27 void QChartWidget::resizeEvent(QResizeEvent *event)
28 28 {
29 29 m_scene->setSceneRect(0,0,size().width(),size().height());
30 30 m_chart->setSize(size());
31 31 QWidget::resizeEvent(event);
32 32 }
33 33
34 34 QSize QChartWidget::sizeHint() const
35 35 {
36 36 // TODO: calculate size hint based on contents?
37 37 return QSize(100, 100);
38 38 }
39 39
40 40 void QChartWidget::addSeries(QChartSeries* series)
41 41 {
42 42 m_chart->addSeries(series);
43 43 }
44 44
45 QChartSeries* QChartWidget::createSeries(QList<qreal> x, QList<qreal> y, QChartSeries::QChartSeriesType type)
45 QChartSeries* QChartWidget::createSeries(QChartSeries::QChartSeriesType type)
46 46 {
47 return m_chart->createSeries(x, y, type);
47 return m_chart->createSeries(type);
48 48 }
49 49 #include "moc_qchartwidget.cpp"
50 50
51 51 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,40 +1,40
1 1 #ifndef QCHARTWIDGET_H
2 2 #define QCHARTWIDGET_H
3 3
4 4 #include "qchartglobal.h"
5 5 #include "qchart.h"
6 6 #include <QGraphicsView>
7 7
8 8 class QGraphicsScene;
9 9
10 10 QTCOMMERCIALCHART_BEGIN_NAMESPACE
11 11
12 12 class QChartSeries;
13 13 class QChartWidgetPrivate;
14 14
15 15 class QTCOMMERCIALCHART_EXPORT QChartWidget : public QGraphicsView
16 16 {
17 17 Q_OBJECT
18 18 public:
19 19 explicit QChartWidget(QWidget *parent = 0);
20 20 ~QChartWidget();
21 21
22 22 //implement from QWidget
23 23 void resizeEvent(QResizeEvent *event);
24 24 QSize sizeHint() const;
25 25
26 26 // TODO: addSeries and createSeries are optional solutions
27 27 // TODO: currently createSeries assumes x, y value pairs. This isn't case with all charts. So is there another createSeries for other types (for example one list of ints)?
28 28 void addSeries(QChartSeries* series);
29 QChartSeries* createSeries(QList<qreal> x, QList<qreal> y, QChartSeries::QChartSeriesType type);
29 QChartSeries* createSeries(QChartSeries::QChartSeriesType type);
30 30
31 31 private:
32 32 Q_DISABLE_COPY(QChartWidget)
33 33 QGraphicsScene *m_scene;
34 34 QChart* m_chart;
35 35
36 36 };
37 37
38 38 QTCOMMERCIALCHART_END_NAMESPACE
39 39
40 40 #endif // QCHARTWIDGET_H
@@ -1,91 +1,97
1 1 #include "qpieseries.h"
2 2 #include "pieslice.h"
3 3 #include <QGraphicsObject>
4 4 #include <QDebug>
5 5
6 6 QTCOMMERCIALCHART_BEGIN_NAMESPACE
7 7
8 QPieSeries::QPieSeries(QList<qreal> x, QGraphicsObject *parent) :
8 QPieSeries::QPieSeries(QGraphicsObject *parent) :
9 9 QChartSeries(parent),
10 m_x(x),
11 10 m_sizeFactor(1.0)
12 11 {
12 }
13
14 QPieSeries::~QPieSeries()
15 {
16 while (m_slices.count())
17 delete m_slices.takeLast();
18 }
19
20 bool QPieSeries::setData(QList<qreal> data)
21 {
22 m_data = data;
23
13 24 // Create slices
14 25 qreal fullPie = 360;
15 26 qreal total = 0;
16 foreach (qreal value, m_x)
27 foreach (qreal value, m_data)
17 28 total += value;
18 29
19 QGraphicsItem *parentItem = qobject_cast<QGraphicsItem *>(parent);
30 QGraphicsItem *parentItem = qobject_cast<QGraphicsItem *>(parent());
20 31 Q_ASSERT(parentItem);
21 32 m_chartSize = parentItem->boundingRect();
22 33 qreal angle = 0;
23 34 // TODO: no need to create new slices in case size changed; we should re-use the existing ones
24 foreach (qreal value, m_x) {
35 foreach (qreal value, m_data) {
25 36 qreal span = value / total * fullPie;
26 37 PieSlice *slice = new PieSlice(randomColor(), angle, span, parentItem->boundingRect());
27 38 slice->setParentItem(parentItem);
28 39 m_slices.append(slice);
29 40 angle += span;
30 41 }
31 42
32 43 resizeSlices(m_chartSize);
33 }
34
35 QPieSeries::~QPieSeries()
36 {
37 while (m_slices.count())
38 delete m_slices.takeLast();
44 return true;
39 45 }
40 46
41 47 void QPieSeries::chartSizeChanged(QRectF chartRect)
42 48 {
43 49 // TODO: allow user setting the size?
44 50 // TODO: allow user defining the margins?
45 51 m_chartSize = chartRect;
46 52 resizeSlices(m_chartSize);
47 53 }
48 54
49 55 void QPieSeries::resizeSlices(QRectF rect)
50 56 {
51 57 QRectF tempRect = rect;
52 58 if (tempRect.width() < tempRect.height()) {
53 59 tempRect.setWidth(tempRect.width() * m_sizeFactor);
54 60 tempRect.setHeight(tempRect.width());
55 61 tempRect.moveCenter(rect.center());
56 62 } else {
57 63 tempRect.setHeight(tempRect.height() * m_sizeFactor);
58 64 tempRect.setWidth(tempRect.height());
59 65 tempRect.moveCenter(rect.center());
60 66 }
61 67
62 68 foreach (PieSlice *slice, m_slices)
63 69 slice->m_rect = tempRect;
64 70 }
65 71
66 72 void QPieSeries::setSizeFactor(qreal factor)
67 73 {
68 74 if (factor > 0.0)
69 75 m_sizeFactor = factor;
70 76 resizeSlices(m_chartSize);
71 77
72 78 // Initiate update via the parent graphics item
73 79 // TODO: potential issue: what if this function is called from the parent context?
74 80 QGraphicsItem *parentItem = qobject_cast<QGraphicsItem *>(parent());
75 81 Q_ASSERT(parentItem);
76 82 parentItem->update();
77 83 }
78 84
79 85 QColor QPieSeries::randomColor()
80 86 {
81 87 QColor c;
82 88 c.setRed(qrand() % 255);
83 89 c.setGreen(qrand() % 255);
84 90 c.setBlue(qrand() % 255);
85 91 return c;
86 92 }
87 93
88 94
89 95 #include "moc_qpieseries.cpp"
90 96
91 97 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,44 +1,45
1 1 #ifndef PIESERIES_H
2 2 #define PIESERIES_H
3 3
4 4 #include "qchartseries.h"
5 5 #include <QObject>
6 6 #include <QRectF>
7 7 #include <QColor>
8 8
9 9 class QGraphicsObject;
10 10 QTCOMMERCIALCHART_BEGIN_NAMESPACE
11 11 class PieSlice;
12 12
13 13 class QTCOMMERCIALCHART_EXPORT QPieSeries : public QChartSeries
14 14 {
15 15 Q_OBJECT
16 16
17 17 public:
18 18 // TODO: use a generic data class instead of x and y
19 QPieSeries(QList<qreal> x, QGraphicsObject *parent = 0);
19 QPieSeries(QGraphicsObject *parent = 0);
20 20 ~QPieSeries();
21 21 QColor randomColor();
22 22 void setSizeFactor(qreal sizeFactor);
23 23 qreal sizeFactor() { return m_sizeFactor; }
24 24
25 25 public: // from QChartSeries
26 26 QChartSeriesType type() const { return QChartSeries::SeriesTypePie; }
27 bool setData(QList<qreal> data);
27 28
28 29 public Q_SLOTS:
29 30 void chartSizeChanged(QRectF rect);
30 31
31 32 private:
32 33 void resizeSlices(QRectF rect);
33 34 //Q_DECLARE_PRIVATE(QPieSeries)
34 35 Q_DISABLE_COPY(QPieSeries)
35 36 // TODO: move the followin to internal impl
36 QList<qreal> m_x;
37 QList<qreal> m_data;
37 38 QList<PieSlice*> m_slices;
38 39 QRectF m_chartSize;
39 40 qreal m_sizeFactor;
40 41 };
41 42
42 43 QTCOMMERCIALCHART_END_NAMESPACE
43 44
44 45 #endif // PIESERIES_H
@@ -1,88 +1,96
1 1 #include "qscatterseries.h"
2 2 #include "qscatterseries_p.h"
3 3 #include "qchart.h"
4 4 #include <QPainter>
5 5 #include <QGraphicsScene>
6 6 #include <QDebug>
7 7
8 8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9 9
10 10 //#define QSeriesData QList<qreal>
11 11
12 QScatterSeriesPrivate::QScatterSeriesPrivate(QList<qreal> x, QList<qreal> y, QGraphicsItem *parent) :
12 QScatterSeriesPrivate::QScatterSeriesPrivate(QGraphicsItem *parent) :
13 13 QGraphicsItem(parent),
14 m_x(x),
15 m_y(y),
16 14 m_scalex(100), // TODO: let the use define the scale (or autoscaled)
17 15 m_scaley(100)
18 16 {
19 resize(parent->boundingRect());
20 17 }
21 18
22 19 void QScatterSeriesPrivate::resize(QRectF rect)
23 20 {
24 21 m_scenex.clear();
25 22 m_sceney.clear();
26 23
27 24 foreach(qreal x, m_x)
28 25 m_scenex.append(rect.left() + x * (rect.width() / m_scalex));
29 26
30 27 foreach(qreal y, m_y)
31 28 m_sceney.append(rect.bottom() - y * (rect.height() / m_scaley));
32 29 }
33 30
34 31 // TODO:
35 32 //void QScatterSeriesPrivate::setAxisScale(qreal xscale, qreal yscale)
36 33
37 34 QRectF QScatterSeriesPrivate::boundingRect() const
38 35 {
39 36 return QRectF(0, 0, 55, 100);
40 37 }
41 38
42 39 void QScatterSeriesPrivate::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
43 40 {
44 41 QPen pen = painter->pen();
45 42 QBrush brush = pen.brush();
46 43 // TODO: The opacity should be user definable...
47 44 brush.setColor(QColor(255, 82, 0, 100));
48 45 pen.setBrush(brush);
49 46 pen.setWidth(4);
50 47 painter->setPen(pen);
51 48
52 49 // TODO: m_scenex and m_sceny are left empty during construction -> we would need a resize
53 50 // event right after construction or maybe given a size during initialization
54 51 for (int i(0); i < m_scenex.count() && i < m_sceney.count(); i++) {
55 52 if (scene()->width() > m_scenex.at(i) && scene()->height() > m_sceney.at(i))
56 53 //painter->drawArc(m_scenex.at(i), m_sceney.at(i), 2, 2, 0, 5760);
57 54 painter->drawPoint(m_scenex.at(i), m_sceney.at(i));
58 55 }
59 56 }
60 57
61 QScatterSeries::QScatterSeries(QList<qreal> x, QList<qreal> y, QObject *parent) :
58 QScatterSeries::QScatterSeries(QObject *parent) :
62 59 QChartSeries(parent),
63 d(new QScatterSeriesPrivate(x, y, qobject_cast<QGraphicsItem *> (parent)))
60 d(new QScatterSeriesPrivate(qobject_cast<QGraphicsItem *> (parent)))
64 61 {
65 62 }
66 63
64 bool QScatterSeries::setData(QList<qreal> x, QList<qreal> y)
65 {
66 // TODO: validate data
67 d->m_x = x;
68 d->m_y = y;
69 QGraphicsItem *parentItem = qobject_cast<QGraphicsItem *>(parent());
70 Q_ASSERT(parentItem);
71 d->resize(parentItem->boundingRect());
72 return true;
73 }
74
67 75 void QScatterSeries::chartSizeChanged(QRectF rect)
68 76 {
69 77 // Recalculate scatter data point locations on the scene
70 78 // d->transform().reset();
71 79 // d->transform().translate();
72 80 d->resize(rect);
73 81 }
74 82
75 83 // TODO:
76 84 //void QScatterSeries::chartScaleChanged(qreal xscale, qreal yscale)
77 85 //{
78 86 // d->rescale(xscale, yscale);
79 87 //}
80 88
81 89 QScatterSeries::~QScatterSeries()
82 90 {
83 91 delete d;
84 92 }
85 93
86 94 #include "moc_qscatterseries.cpp"
87 95
88 96 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,34 +1,35
1 1 #ifndef QSCATTERSERIES_H
2 2 #define QSCATTERSERIES_H
3 3
4 4 #include "qchartseries.h"
5 5 #include <QRectF>
6 6
7 7 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8 8 class QScatterSeriesPrivate;
9 9
10 10 class QTCOMMERCIALCHART_EXPORT QScatterSeries : public QChartSeries
11 11 {
12 12 Q_OBJECT
13 13 public:
14 14 //QScatterSeries(QSeriesData *data, QObject *chart);
15 QScatterSeries(QList<qreal> x, QList<qreal> y, QObject *parent = 0);
15 QScatterSeries(QObject *parent = 0);
16 16 ~QScatterSeries();
17 17
18 18 public: // from QChartSeries
19 19 QChartSeriesType type() const { return QChartSeries::SeriesTypeScatter; }
20 bool setData(QList<qreal> x, QList<qreal> y);
20 21
21 22 public Q_SLOTS:
22 23 void chartSizeChanged(QRectF rect);
23 24 //void chartScaleChanged(qreal xscale, qreal yscale);
24 25
25 26 private:
26 27 Q_DECLARE_PRIVATE(QScatterSeries)
27 28 Q_DISABLE_COPY(QScatterSeries)
28 29 friend class QChart;
29 30 QScatterSeriesPrivate *const d;
30 31 };
31 32
32 33 QTCOMMERCIALCHART_END_NAMESPACE
33 34
34 35 #endif // QSCATTERSERIES_H
@@ -1,33 +1,33
1 1 #ifndef QSCATTERSERIESPRIVATE_H
2 2 #define QSCATTERSERIESPRIVATE_H
3 3
4 4 #include "qchartseries.h"
5 5 #include <QGraphicsItem>
6 6
7 7 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8 8
9 9 /*!
10 10 * The PIMPL class of QScatterSeries.
11 11 */
12 12 class QScatterSeriesPrivate : public QGraphicsItem
13 13 {
14 14 public:
15 QScatterSeriesPrivate(QList<qreal> x, QList<qreal> y, QGraphicsItem *parent);
15 QScatterSeriesPrivate(QGraphicsItem *parent);
16 16
17 17 public: // from QGraphicsItem
18 18 void resize(QRectF rect);
19 19 QRectF boundingRect() const;
20 20 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
21 21
22 22 // TODO: use the chart data class instead of list of x and y values?
23 23 QList<qreal> m_x;
24 24 QList<qreal> m_y;
25 25 qreal m_scalex;
26 26 qreal m_scaley;
27 27 QList<qreal> m_scenex;
28 28 QList<qreal> m_sceney;
29 29 };
30 30
31 31 QTCOMMERCIALCHART_END_NAMESPACE
32 32
33 33 #endif // QSCATTERSERIES_H
@@ -1,271 +1,267
1 1 #include "mainwidget.h"
2 2 #include "dataseriedialog.h"
3 3 #include "qchartseries.h"
4 4 #include "qpieseries.h"
5 5 #include <qxychartseries.h>
6 6 #include <QPushButton>
7 7 #include <QComboBox>
8 8 #include <QSpinBox>
9 9 #include <QCheckBox>
10 10 #include <QGridLayout>
11 11 #include <QHBoxLayout>
12 12 #include <QLabel>
13 13 #include <QSpacerItem>
14 14 #include <QMessageBox>
15 15 #include <cmath>
16 16 #include <QDebug>
17 17
18 18 QTCOMMERCIALCHART_USE_NAMESPACE
19 19
20 20 MainWidget::MainWidget(QWidget *parent) :
21 21 QWidget(parent)
22 22 {
23 23 QPushButton *addSeriesButton = new QPushButton("Add series");
24 24 connect(addSeriesButton, SIGNAL(clicked()), this, SLOT(addSeries()));
25 25
26 26 // Chart background
27 27 QComboBox *backgroundCombo = new QComboBox(this);
28 28 backgroundCombo->addItem("None");
29 29 backgroundCombo->addItem("TODO Grid");
30 30 backgroundCombo->addItem("TODO Image");
31 31 connect(backgroundCombo, SIGNAL(currentIndexChanged(int)),
32 32 this, SLOT(backgroundChanged(int)));
33 33
34 34 // Axis
35 35 // TODO: multiple axes?
36 36 m_autoScaleCheck = new QCheckBox("Automatic scaling");
37 37 connect(m_autoScaleCheck, SIGNAL(stateChanged(int)), this, SLOT(autoScaleChanged(int)));
38 38 // Allow setting also non-sense values (like -2147483648 and 2147483647)
39 39 m_xMinSpin = new QSpinBox();
40 40 m_xMinSpin->setMinimum(INT_MIN);
41 41 m_xMinSpin->setMaximum(INT_MAX);
42 42 m_xMinSpin->setValue(0);
43 43 connect(m_xMinSpin, SIGNAL(valueChanged(int)), this, SLOT(xMinChanged(int)));
44 44 m_xMaxSpin = new QSpinBox();
45 45 m_xMaxSpin->setMinimum(INT_MIN);
46 46 m_xMaxSpin->setMaximum(INT_MAX);
47 47 m_xMaxSpin->setValue(10);
48 48 connect(m_xMaxSpin, SIGNAL(valueChanged(int)), this, SLOT(xMaxChanged(int)));
49 49 m_yMinSpin = new QSpinBox();
50 50 m_yMinSpin->setMinimum(INT_MIN);
51 51 m_yMinSpin->setMaximum(INT_MAX);
52 52 m_yMinSpin->setValue(0);
53 53 connect(m_yMinSpin, SIGNAL(valueChanged(int)), this, SLOT(yMinChanged(int)));
54 54 m_yMaxSpin = new QSpinBox();
55 55 m_yMaxSpin->setMinimum(INT_MIN);
56 56 m_yMaxSpin->setMaximum(INT_MAX);
57 57 m_yMaxSpin->setValue(10);
58 58 connect(m_yMaxSpin, SIGNAL(valueChanged(int)), this, SLOT(yMaxChanged(int)));
59 59
60 60 QGridLayout *grid = new QGridLayout();
61 61 QGridLayout *mainLayout = new QGridLayout();
62 62 //grid->addWidget(new QLabel("Add series:"), 0, 0);
63 63 grid->addWidget(addSeriesButton, 0, 1);
64 64 grid->addWidget(new QLabel("Background:"), 2, 0);
65 65 grid->addWidget(backgroundCombo, 2, 1);
66 66 grid->addWidget(m_autoScaleCheck, 3, 0);
67 67 grid->addWidget(new QLabel("x min:"), 4, 0);
68 68 grid->addWidget(m_xMinSpin, 4, 1);
69 69 grid->addWidget(new QLabel("x max:"), 5, 0);
70 70 grid->addWidget(m_xMaxSpin, 5, 1);
71 71 grid->addWidget(new QLabel("y min:"), 6, 0);
72 72 grid->addWidget(m_yMinSpin, 6, 1);
73 73 grid->addWidget(new QLabel("y max:"), 7, 0);
74 74 grid->addWidget(m_yMaxSpin, 7, 1);
75 75 // add row with empty label to make all the other rows static
76 76 grid->addWidget(new QLabel(""), 8, 0);
77 77 grid->setRowStretch(8, 1);
78 78
79 79 mainLayout->addLayout(grid, 0, 0);
80 80
81 81 // Scatter specific settings
82 82 m_scatterLayout = new QGridLayout();
83 83 m_scatterLayout->addWidget(new QLabel("scatter"), 0, 0);
84 84 m_scatterLayout->setEnabled(false);
85 85
86 86 // Pie specific settings
87 87 m_pieLayout = new QGridLayout();
88 88 m_pieLayout->addWidget(new QLabel("Pie size factor"), 0, 0);
89 89 QDoubleSpinBox *pieSizeSpin = new QDoubleSpinBox();
90 90 pieSizeSpin->setMinimum(LONG_MIN);
91 91 pieSizeSpin->setMaximum(LONG_MAX);
92 92 pieSizeSpin->setValue(1.0);
93 93 pieSizeSpin->setSingleStep(0.1);
94 94 connect(pieSizeSpin, SIGNAL(valueChanged(double)), this, SLOT(setPieSizeFactor(double)));
95 95 m_pieLayout->setEnabled(false);
96 96 m_pieLayout->addWidget(pieSizeSpin, 0, 1);
97 97
98 98 mainLayout->addLayout(m_scatterLayout, 1, 0);
99 99 mainLayout->addLayout(m_pieLayout, 2, 0);
100 100
101 101 m_chartWidget = new QChartWidget(this);
102 102 //m_chartWidget->setColor(Qt::red);
103 103 mainLayout->addWidget(m_chartWidget, 0, 1, 3, 1);
104 104 // hbox->setStretch(1, 1);
105 105
106 106 setLayout(mainLayout);
107 107
108 108 m_autoScaleCheck->setChecked(true);
109 109 testDataChanged(0);
110 110 }
111 111
112 112 void MainWidget::addSeries()
113 113 {
114 114 DataSerieDialog dialog(m_defaultSeriesName, this);
115 115 connect(&dialog, SIGNAL(accepted(QString, QString)), this, SLOT(addSeries(QString, QString)));
116 116 dialog.exec();
117 117 }
118 118
119 119 void MainWidget::addSeries(QString series, QString data)
120 120 {
121 121 qDebug() << "addSeries: " << series << " data: " << data;
122 122 m_defaultSeriesName = series;
123 QChartSeries *newSeries = QXYChartSeries::create();
124 123
125 124 // TODO: a dedicated data class for storing x and y values
126 125 QList<qreal> x;
127 126 QList<qreal> y;
128 127
129 128 if (data == "linear") {
130 129 for (int i = 0; i < 20; i++) {
131 130 x.append(i);
132 131 y.append(i);
133 132 }
134 for (int i = 0; i < 20; i++)
135 ((QXYChartSeries *)newSeries)->add(i, i);
136 133 } else if (data == "linear, 1M") {
137 134 for (int i = 0; i < 10000; i++) {
138 135 x.append(i);
139 136 y.append(20);
140 137 }
141 for (int i = 0; i < 1000000; i++)
142 ((QXYChartSeries *)newSeries)->add(i, 10);
143 138 } else if (data == "SIN") {
144 139 for (int i = 0; i < 100; i++) {
145 140 x.append(i);
146 141 y.append(abs(sin(3.14159265358979 / 50 * i) * 100));
147 142 }
148 for (int i = 0; i < 100; i++)
149 ((QXYChartSeries *)newSeries)->add(i, abs(sin(3.14159265358979 / 50 * i) * 100));
150 143 } else if (data == "SIN + random") {
151 144 for (qreal i = 0; i < 100; i += 0.1) {
152 145 x.append(i + (rand() % 5));
153 146 y.append(abs(sin(3.14159265358979 / 50 * i) * 100) + (rand() % 5));
154 147 }
155 for (qreal i = 0; i < 100; i += 0.1)
156 ((QXYChartSeries *)newSeries)->add(i + (rand() % 5), abs(sin(3.14159265358979 / 50 * i) * 100) + (rand() % 5));
157 148 } else {
158 149 // TODO: check if data has a valid file name
150 Q_ASSERT(false);
159 151 }
160 152
161 153 // TODO: color of the series
154 QChartSeries *newSeries = 0;
162 155 if (series == "Scatter") {
163 newSeries = m_chartWidget->createSeries(x, y, QChartSeries::SeriesTypeScatter);
156 newSeries = m_chartWidget->createSeries(QChartSeries::SeriesTypeScatter);
157 Q_ASSERT(newSeries->setData(x, y));
164 158 } else if (series == "Pie") {
165 newSeries = m_chartWidget->createSeries(x, y, QChartSeries::SeriesTypePie);
159 newSeries = m_chartWidget->createSeries(QChartSeries::SeriesTypePie);
160 Q_ASSERT(newSeries->setData(y));
166 161 } else if (series == "Line") {
167 m_chartWidget->addSeries(newSeries);
162 newSeries = m_chartWidget->createSeries(QChartSeries::SeriesTypePie);
163 Q_ASSERT(newSeries->setData(x, y));
168 164 } else {
169 165 // TODO
170 166 }
171 167
172 168 setCurrentSeries(newSeries);
173 169 }
174 170
175 171 void MainWidget::setCurrentSeries(QChartSeries *series)
176 172 {
177 173 m_currentSeries = series;
178 174 switch (m_currentSeries->type()) {
179 175 case QChartSeries::SeriesTypeLine:
180 176 break;
181 177 case QChartSeries::SeriesTypeScatter:
182 178 break;
183 179 case QChartSeries::SeriesTypePie:
184 180 break;
185 181 default:
186 182 Q_ASSERT(false);
187 183 break;
188 184 }
189 185 }
190 186
191 187 void MainWidget::testDataChanged(int itemIndex)
192 188 {
193 189 qDebug() << "testDataChanged: " << itemIndex;
194 190
195 191 // switch (itemIndex) {
196 192 // case 0: {
197 193 // QList<QChartDataPoint> data;
198 194 // for (int x = 0; x < 20; x++) {
199 195 // data.append(QChartDataPoint() << x << x / 2);
200 196 // }
201 197 // m_chartWidget->setData(data);
202 198 // break;
203 199 // }
204 200 // case 1: {
205 201 // QList<QChartDataPoint> data;
206 202 // for (int x = 0; x < 100; x++) {
207 203 // data.append(QChartDataPoint() << x - 200 << 2 * (uint(sin(3.14159/50*x)*80) % 100));
208 204 // }
209 205 // m_chartWidget->setData(data);
210 206 // break;
211 207 // }
212 208 // case 2: {
213 209 // QList<QChartDataPoint> data;
214 210 // for (int x = 0; x < 1000; x++) {
215 211 // data.append(QChartDataPoint() << x - 200 << 2 * (uint(sin(3.14159/50*x)*80) % 100) + (rand() % 100 * 0.2));
216 212 // data.append(QChartDataPoint() << x - 200 << 2 * (uint(sin(3.14159/50*x)*80) % 100) + (rand() % 100 * 0.2));
217 213 // data.append(QChartDataPoint() << x - 200 << 2 * (uint(sin(3.14159/50*x)*80) % 100) + (rand() % 100 * 0.2));
218 214 // }
219 215 // m_chartWidget->setData(data);
220 216 // break;
221 217 // }
222 218 // default:
223 219 // break;
224 220 // }
225 221 }
226 222
227 223 void MainWidget::backgroundChanged(int itemIndex)
228 224 {
229 225 qDebug() << "backgroundChanged: " << itemIndex;
230 226 }
231 227
232 228 void MainWidget::autoScaleChanged(int value)
233 229 {
234 230 if (value) {
235 231 // TODO: enable auto scaling
236 232 } else {
237 233 // TODO: set scaling manually (and disable auto scaling)
238 234 }
239 235
240 236 m_xMinSpin->setEnabled(!value);
241 237 m_xMaxSpin->setEnabled(!value);
242 238 m_yMinSpin->setEnabled(!value);
243 239 m_yMaxSpin->setEnabled(!value);
244 240 }
245 241
246 242 void MainWidget::xMinChanged(int value)
247 243 {
248 244 qDebug() << "xMinChanged: " << value;
249 245 }
250 246
251 247 void MainWidget::xMaxChanged(int value)
252 248 {
253 249 qDebug() << "xMaxChanged: " << value;
254 250 }
255 251
256 252 void MainWidget::yMinChanged(int value)
257 253 {
258 254 qDebug() << "yMinChanged: " << value;
259 255 }
260 256
261 257 void MainWidget::yMaxChanged(int value)
262 258 {
263 259 qDebug() << "yMaxChanged: " << value;
264 260 }
265 261
266 262 void MainWidget::setPieSizeFactor(double size)
267 263 {
268 264 QPieSeries *pie = qobject_cast<QPieSeries *>(m_currentSeries);
269 265 Q_ASSERT(pie);
270 266 pie->setSizeFactor(qreal(size));
271 267 }
General Comments 0
You need to be logged in to leave comments. Login now