##// END OF EJS Templates
sauimone -
r66:f1cd31b8c179 merge
parent child
Show More
@@ -1,165 +1,213
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 m_axisX(new Axis(this)),
22 m_axisY(new Axis(this)),
23 m_grid(new XYGrid(this)),
24 m_plotDataIndex(0),
25 m_marginSize(0)
21 m_axisX(new Axis(this)),
22 m_axisY(new Axis(this)),
23 m_grid(new XYGrid(this)),
24 m_plotDataIndex(0),
25 m_marginSize(0)
26 26 {
27 // TODO: the default theme?
28 setTheme(QChart::ChartThemeVanilla);
27 29 // setFlags(QGraphicsItem::ItemClipsChildrenToShape);
28 30 // set axis
29 31 m_axisY->rotate(90);
30 32 }
31 33
32 34 QChart::~QChart(){}
33 35
34 36 QRectF QChart::boundingRect() const
35 37 {
36 38 return m_rect;
37 39 }
38 40
39 41 void QChart::addSeries(QChartSeries* series)
40 42 {
41 43 // TODO: we should check the series not already added
42 44
43 45 m_series<<series;
44 46
45 47 switch(series->type())
46 48 {
47 49 case QChartSeries::SeriesTypeLine: {
48 50
49 51 QXYChartSeries* xyseries = static_cast<QXYChartSeries*>(series);
52 // Use color defined by theme in case the series does not define a custom color
53 if (!xyseries->color().isValid() && m_themeColors.count())
54 xyseries->setColor(m_themeColors.takeFirst());
50 55
51 56 XYPlotDomain domain;
52 57 //TODO "nice numbers algorithm"
53 58 domain.m_ticksX=4;
54 59 domain.m_ticksY=4;
55 60
56 61 for (int i = 0 ; i < xyseries->count() ; i++)
57 62 {
58 63 qreal x = xyseries->x(i);
59 64 qreal y = xyseries->y(i);
60 65 domain.m_minX = qMin(domain.m_minX,x);
61 66 domain.m_minY = qMin(domain.m_minY,y);
62 67 domain.m_maxX = qMax(domain.m_maxX,x);
63 68 domain.m_maxY = qMax(domain.m_maxY,y);
64 69 }
65 70
66 71 XYLineChartItem* item = new XYLineChartItem(xyseries,this);
67 72 item->updateXYPlotDomain(domain);
68 73 m_plotDomainList<<domain;
69 74 m_xyLineChartItems<<item;
70 75 break;
71 76 }
72 // TODO: Not tested:
73 // case QChartSeries::SeriesTypeScatter: {
74 // QScatterSeries *scatter = qobject_cast<QScatterSeries *>(series);
75 // if (scatter) {
76 // scatter->d->setParentItem(this);
77 // scene()->addItem(scatter->d);
78 // }
79 // break;
80 // }
81
82 77 case QChartSeries::SeriesTypeBar: {
83 78
84 79 qDebug() << "barSeries added";
85 80 BarChartSeries* barSeries = static_cast<BarChartSeries*>(series);
86 81
87 82 // Who owns the series?
88 83 BarGroup* group = new BarGroup(*barSeries, this);
89 84 scene()->addItem(group);
90 85 m_BarGroupItems.append(group); // If we need to access group later
91 86 break;
92 87 }
88 case QChartSeries::SeriesTypeScatter: {
89 QScatterSeries *scatterSeries = qobject_cast<QScatterSeries *>(series);
90 connect(this, SIGNAL(sizeChanged(QRectF)),
91 scatterSeries, SLOT(chartSizeChanged(QRectF)));
92 scatterSeries->d->setParentItem(this);
93 QColor nextColor = m_themeColors.takeFirst();
94 nextColor.setAlpha(150); // TODO: default opacity?
95 scatterSeries->setMarkerColor(nextColor);
96 }
97 case QChartSeries::SeriesTypePie: {
98 // TODO: we now have also a list of y values as a parameter, it is ignored
99 // we should use a generic data class instead of list of x and y values
100 QPieSeries *pieSeries = qobject_cast<QPieSeries *>(series);
101 connect(this, SIGNAL(sizeChanged(QRectF)),
102 pieSeries, SLOT(chartSizeChanged(QRectF)));
103 // TODO: how to define the color for all the slices of a pie?
104 }
93 105 }
94 106 }
95 107
96 108 QChartSeries* QChart::createSeries(QChartSeries::QChartSeriesType type)
97 109 {
98 110 // TODO: support also other types; not only scatter and pie
99 111
112 QChartSeries *series(0);
113
100 114 switch (type) {
115 case QChartSeries::SeriesTypeLine: {
116 series = QXYChartSeries::create();
117 break;
118 }
119 case QChartSeries::SeriesTypeBar: {
120 series = new BarChartSeries(this);
121 break;
122 }
101 123 case QChartSeries::SeriesTypeScatter: {
102 QScatterSeries *scatterSeries = new QScatterSeries(this);
103 connect(this, SIGNAL(sizeChanged(QRectF)),
104 scatterSeries, SLOT(chartSizeChanged(QRectF)));
105 scatterSeries->d->setParentItem(this);
106 return scatterSeries;
124 series = new QScatterSeries(this);
125 break;
107 126 }
108 127 case QChartSeries::SeriesTypePie: {
109 // TODO: we now have also a list of y values as a parameter, it is ignored
110 // we should use a generic data class instead of list of x and y values
111 QPieSeries *pieSeries = new QPieSeries(this);
112 connect(this, SIGNAL(sizeChanged(QRectF)),
113 pieSeries, SLOT(chartSizeChanged(QRectF)));
114 return pieSeries;
128 series = new QPieSeries(this);
129 break;
115 130 }
116 131 default:
117 132 Q_ASSERT(false);
118 133 break;
119 134 }
120 135
121 return 0;
136 addSeries(series);
137 return series;
122 138 }
123 139
124 140 void QChart::setSize(const QSizeF& size)
125 141 {
126 142 m_rect = QRect(QPoint(0,0),size.toSize());
127 143 m_rect.adjust(margin(),margin(), -margin(), -margin());
128 144 m_grid->setPos(m_rect.topLeft());
129 145 m_grid->setSize(m_rect.size());
130 146
131 147 // TODO: TTD for setting scale
132 148 //emit scaleChanged(100, 100);
133 149 // TODO: calculate the origo
134 150 // TODO: not sure if emitting a signal here is the best from performance point of view
135 151 emit sizeChanged(QRectF(0, 0, size.width(), size.height()));
136 152
137 153 for (int i(0); i < m_plotDomainList.size(); i++)
138 154 m_plotDomainList[i].m_viewportRect = m_rect;
139 155
140 156 // TODO: line chart items are updated separately as they don't support update
141 157 // via sizeChanged signal
142 158 foreach(XYLineChartItem* item ,m_xyLineChartItems)
143 159 item->updateXYPlotDomain(m_plotDomainList.at(m_plotDataIndex));
144 160
145 161
146 162 if (m_plotDomainList.count())
147 163 m_grid->setXYPlotData(m_plotDomainList.at(m_plotDataIndex));
148 164
149 165 update();
150 166 }
151 167
152 168 int QChart::margin() const
153 169 {
154 170 return m_marginSize;
155 171 }
156 172
157 173 void QChart::setMargin(int margin)
158 174 {
159 175 m_marginSize = margin;
160 176 }
161 177
162 #include "moc_qchart.cpp"
178 void QChart::setTheme(QChart::ChartTheme theme)
179 {
180 // TODO: define color themes
181 switch (theme) {
182 case ChartThemeVanilla:
183 m_themeColors.append(QColor(255, 238, 174));
184 m_themeColors.append(QColor(228, 228, 160));
185 m_themeColors.append(QColor(228, 179, 160));
186 m_themeColors.append(QColor(180, 151, 18));
187 m_themeColors.append(QColor(252, 252, 37));
188 break;
189 case ChartThemeIcy:
190 m_themeColors.append(QColor(255, 238, 174));
191 m_themeColors.append(QColor(228, 228, 160));
192 m_themeColors.append(QColor(228, 179, 160));
193 m_themeColors.append(QColor(180, 151, 18));
194 m_themeColors.append(QColor(252, 252, 37));
195 break;
196 case ChartThemeGrayscale:
197 m_themeColors.append(QColor(255, 238, 174));
198 m_themeColors.append(QColor(228, 228, 160));
199 m_themeColors.append(QColor(228, 179, 160));
200 m_themeColors.append(QColor(180, 151, 18));
201 m_themeColors.append(QColor(252, 252, 37));
202 break;
203 default:
204 Q_ASSERT(false);
205 break;
206 }
163 207
208 // TODO: update coloring of different elements to match the selected theme
209 }
210
211 #include "moc_qchart.cpp"
164 212
165 213 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,67 +1,76
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 enum ChartTheme {
30 ChartThemeVanilla = 0,
31 ChartThemeIcy,
32 ChartThemeGrayscale
33 };
34
35 public:
29 36 QChart(QGraphicsObject* parent = 0);
30 37 ~QChart();
31 38
32 39 //from QGraphicsItem
33 40 QRectF boundingRect() const;
34 41 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget){};
35 42
36 43 void addSeries(QChartSeries* series);
37 44 //TODO: QChartSeries* createSeries(QSeriesData *data, QChartSeries::QChartSeriesType type);
38 45 // TODO: who owns the series now? maybe owned by chart and returned a reference instead...
39 46 QChartSeries* createSeries(QChartSeries::QChartSeriesType type);
40 47
41 48 virtual void setSize(const QSizeF& rect);
42 49 void setMargin(int margin);
43 50 int margin() const;
51 void setTheme(QChart::ChartTheme theme);
44 52
45 53 signals:
46 54 void sizeChanged(QRectF rect);
47 55 void scaleChanged(qreal xscale, qreal yscale);
48 56
49 57 private:
50 58 Q_DISABLE_COPY(QChart)
51 59 Axis* m_axisX;
52 60 Axis* m_axisY;
53 61 XYGrid* m_grid;
54 62 QRect m_rect;
55 63 QList<const QChartSeries*> m_series;
56 64 QList<XYPlotDomain> m_plotDomainList;
57 65 QList<XYLineChartItem*> m_xyLineChartItems;
58 66 QList<QGraphicsItem*> m_items;
59 67 int m_plotDataIndex;
60 68 int m_marginSize;
69 QList<QColor> m_themeColors;
61 70
62 71 QList<BarGroup*> m_BarGroupItems;
63 72 };
64 73
65 74 QTCOMMERCIALCHART_END_NAMESPACE
66 75
67 76 #endif
@@ -1,51 +1,57
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 45 QChartSeries* QChartWidget::createSeries(QChartSeries::QChartSeriesType type)
46 46 {
47 47 return m_chart->createSeries(type);
48 48 }
49
50 void QChartWidget::setTheme(QChart::ChartTheme theme)
51 {
52 m_chart->setTheme(theme);
53 }
54
49 55 #include "moc_qchartwidget.cpp"
50 56
51 57 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,40 +1,46
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 29 QChartSeries* createSeries(QChartSeries::QChartSeriesType type);
30 30
31 /*!
32 * Set color theme for the chart. Themes define harmonic colors for the graphical elements of
33 * the chart.
34 */
35 void setTheme(QChart::ChartTheme theme);
36
31 37 private:
32 38 Q_DISABLE_COPY(QChartWidget)
33 39 QGraphicsScene *m_scene;
34 40 QChart* m_chart;
35 41
36 42 };
37 43
38 44 QTCOMMERCIALCHART_END_NAMESPACE
39 45
40 46 #endif // QCHARTWIDGET_H
@@ -1,96 +1,103
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 12 QScatterSeriesPrivate::QScatterSeriesPrivate(QGraphicsItem *parent) :
13 13 QGraphicsItem(parent),
14 14 m_scalex(100), // TODO: let the use define the scale (or autoscaled)
15 m_scaley(100)
15 m_scaley(100),
16 m_markerColor(QColor())
16 17 {
17 18 }
18 19
19 20 void QScatterSeriesPrivate::resize(QRectF rect)
20 21 {
21 22 m_scenex.clear();
22 23 m_sceney.clear();
23 24
24 25 foreach(qreal x, m_x)
25 26 m_scenex.append(rect.left() + x * (rect.width() / m_scalex));
26 27
27 28 foreach(qreal y, m_y)
28 29 m_sceney.append(rect.bottom() - y * (rect.height() / m_scaley));
29 30 }
30 31
31 32 // TODO:
32 33 //void QScatterSeriesPrivate::setAxisScale(qreal xscale, qreal yscale)
33 34
34 35 QRectF QScatterSeriesPrivate::boundingRect() const
35 36 {
36 37 return QRectF(0, 0, 55, 100);
37 38 }
38 39
39 40 void QScatterSeriesPrivate::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
40 41 {
41 42 QPen pen = painter->pen();
42 43 QBrush brush = pen.brush();
43 44 // TODO: The opacity should be user definable...
44 brush.setColor(QColor(255, 82, 0, 100));
45 //brush.setColor(QColor(255, 82, 0, 100));
46 brush.setColor(m_markerColor);
45 47 pen.setBrush(brush);
46 48 pen.setWidth(4);
47 49 painter->setPen(pen);
48 50
49 51 // TODO: m_scenex and m_sceny are left empty during construction -> we would need a resize
50 52 // event right after construction or maybe given a size during initialization
51 53 for (int i(0); i < m_scenex.count() && i < m_sceney.count(); i++) {
52 54 if (scene()->width() > m_scenex.at(i) && scene()->height() > m_sceney.at(i))
53 55 //painter->drawArc(m_scenex.at(i), m_sceney.at(i), 2, 2, 0, 5760);
54 56 painter->drawPoint(m_scenex.at(i), m_sceney.at(i));
55 57 }
56 58 }
57 59
58 60 QScatterSeries::QScatterSeries(QObject *parent) :
59 61 QChartSeries(parent),
60 62 d(new QScatterSeriesPrivate(qobject_cast<QGraphicsItem *> (parent)))
61 63 {
62 64 }
63 65
64 66 bool QScatterSeries::setData(QList<qreal> x, QList<qreal> y)
65 67 {
66 68 // TODO: validate data
67 69 d->m_x = x;
68 70 d->m_y = y;
69 71 QGraphicsItem *parentItem = qobject_cast<QGraphicsItem *>(parent());
70 72 Q_ASSERT(parentItem);
71 73 d->resize(parentItem->boundingRect());
72 74 return true;
73 75 }
74 76
75 77 void QScatterSeries::chartSizeChanged(QRectF rect)
76 78 {
77 79 // Recalculate scatter data point locations on the scene
78 80 // d->transform().reset();
79 81 // d->transform().translate();
80 82 d->resize(rect);
81 83 }
82 84
85 void QScatterSeries::setMarkerColor(QColor color)
86 {
87 d->m_markerColor = color;
88 }
89
83 90 // TODO:
84 91 //void QScatterSeries::chartScaleChanged(qreal xscale, qreal yscale)
85 92 //{
86 93 // d->rescale(xscale, yscale);
87 94 //}
88 95
89 96 QScatterSeries::~QScatterSeries()
90 97 {
91 98 delete d;
92 99 }
93 100
94 101 #include "moc_qscatterseries.cpp"
95 102
96 103 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,35 +1,37
1 1 #ifndef QSCATTERSERIES_H
2 2 #define QSCATTERSERIES_H
3 3
4 4 #include "qchartseries.h"
5 5 #include <QRectF>
6 #include <QColor>
6 7
7 8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8 9 class QScatterSeriesPrivate;
9 10
10 11 class QTCOMMERCIALCHART_EXPORT QScatterSeries : public QChartSeries
11 12 {
12 13 Q_OBJECT
13 14 public:
14 15 //QScatterSeries(QSeriesData *data, QObject *chart);
15 16 QScatterSeries(QObject *parent = 0);
16 17 ~QScatterSeries();
17 18
18 19 public: // from QChartSeries
19 20 QChartSeriesType type() const { return QChartSeries::SeriesTypeScatter; }
20 21 bool setData(QList<qreal> x, QList<qreal> y);
21 22
22 23 public Q_SLOTS:
23 24 void chartSizeChanged(QRectF rect);
25 void setMarkerColor(QColor color);
24 26 //void chartScaleChanged(qreal xscale, qreal yscale);
25 27
26 28 private:
27 29 Q_DECLARE_PRIVATE(QScatterSeries)
28 30 Q_DISABLE_COPY(QScatterSeries)
29 31 friend class QChart;
30 32 QScatterSeriesPrivate *const d;
31 33 };
32 34
33 35 QTCOMMERCIALCHART_END_NAMESPACE
34 36
35 37 #endif // QSCATTERSERIES_H
@@ -1,33 +1,34
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 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 QColor m_markerColor;
29 30 };
30 31
31 32 QTCOMMERCIALCHART_END_NAMESPACE
32 33
33 34 #endif // QSCATTERSERIES_H
@@ -1,68 +1,68
1 1 #include "qxychartseries.h"
2 2
3 3 QTCOMMERCIALCHART_BEGIN_NAMESPACE
4 4
5 5 QXYChartSeries::QXYChartSeries(QObject* parent):QChartSeries(parent),
6 m_color(Qt::black)
6 m_color()
7 7 {
8 8 }
9 9
10 10 QXYChartSeries::~QXYChartSeries()
11 11 {
12 12 }
13 13
14 14 QXYChartSeries* QXYChartSeries::create(QObject* parent)
15 15 {
16 16 //TODO: here we take QChartData when it is ready
17 17 // return null if malformed;
18 18 return new QXYChartSeries(parent);
19 19 }
20 20
21 21 void QXYChartSeries::setColor(const QColor& color)
22 22 {
23 23 m_color = color;
24 24 }
25 25
26 26 void QXYChartSeries::add(qreal x,qreal y)
27 27 {
28 28 m_x<<x;
29 29 m_y<<y;
30 30 }
31 31
32 32 void QXYChartSeries::clear()
33 33 {
34 34 m_x.clear();
35 35 m_y.clear();
36 36 }
37 37
38 38 qreal QXYChartSeries::x(int pos) const
39 39 {
40 40 return m_x.at(pos);
41 41 }
42 42
43 43 qreal QXYChartSeries::y(int pos) const
44 44 {
45 45 return m_y.at(pos);
46 46 }
47 47
48 48 int QXYChartSeries::count() const
49 49 {
50 50 Q_ASSERT(m_x.size() == m_y.size());
51 51
52 52 return m_x.size();
53 53
54 54 }
55 55
56 56 QDebug operator<< (QDebug debug, const QXYChartSeries series)
57 57 {
58 58 Q_ASSERT(series.m_x.size() == series.m_y.size());
59 59
60 60 int size = series.m_x.size();
61 61
62 62 for (int i=0;i<size;i++) {
63 63 debug.nospace() << "(" << series.m_x.at(i) << ','<< series.m_y.at(i) << ") ";
64 64 }
65 65 return debug.space();
66 66 }
67 67
68 68 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,287 +1,314
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 <barchartseries.h>
7 7 #include <QPushButton>
8 8 #include <QComboBox>
9 9 #include <QSpinBox>
10 10 #include <QCheckBox>
11 11 #include <QGridLayout>
12 12 #include <QHBoxLayout>
13 13 #include <QLabel>
14 14 #include <QSpacerItem>
15 15 #include <QMessageBox>
16 16 #include <cmath>
17 17 #include <QDebug>
18 18
19 19 QTCOMMERCIALCHART_USE_NAMESPACE
20 20
21 21 MainWidget::MainWidget(QWidget *parent) :
22 22 QWidget(parent)
23 23 {
24 24 QPushButton *addSeriesButton = new QPushButton("Add series");
25 25 connect(addSeriesButton, SIGNAL(clicked()), this, SLOT(addSeries()));
26 26
27 27 // Chart background
28 28 QComboBox *backgroundCombo = new QComboBox(this);
29 29 backgroundCombo->addItem("None");
30 30 backgroundCombo->addItem("TODO Grid");
31 31 backgroundCombo->addItem("TODO Image");
32 32 connect(backgroundCombo, SIGNAL(currentIndexChanged(int)),
33 33 this, SLOT(backgroundChanged(int)));
34 34
35 35 // Axis
36 36 // TODO: multiple axes?
37 37 m_autoScaleCheck = new QCheckBox("Automatic scaling");
38 38 connect(m_autoScaleCheck, SIGNAL(stateChanged(int)), this, SLOT(autoScaleChanged(int)));
39 39 // Allow setting also non-sense values (like -2147483648 and 2147483647)
40 40 m_xMinSpin = new QSpinBox();
41 41 m_xMinSpin->setMinimum(INT_MIN);
42 42 m_xMinSpin->setMaximum(INT_MAX);
43 43 m_xMinSpin->setValue(0);
44 44 connect(m_xMinSpin, SIGNAL(valueChanged(int)), this, SLOT(xMinChanged(int)));
45 45 m_xMaxSpin = new QSpinBox();
46 46 m_xMaxSpin->setMinimum(INT_MIN);
47 47 m_xMaxSpin->setMaximum(INT_MAX);
48 48 m_xMaxSpin->setValue(10);
49 49 connect(m_xMaxSpin, SIGNAL(valueChanged(int)), this, SLOT(xMaxChanged(int)));
50 50 m_yMinSpin = new QSpinBox();
51 51 m_yMinSpin->setMinimum(INT_MIN);
52 52 m_yMinSpin->setMaximum(INT_MAX);
53 53 m_yMinSpin->setValue(0);
54 54 connect(m_yMinSpin, SIGNAL(valueChanged(int)), this, SLOT(yMinChanged(int)));
55 55 m_yMaxSpin = new QSpinBox();
56 56 m_yMaxSpin->setMinimum(INT_MIN);
57 57 m_yMaxSpin->setMaximum(INT_MAX);
58 58 m_yMaxSpin->setValue(10);
59 59 connect(m_yMaxSpin, SIGNAL(valueChanged(int)), this, SLOT(yMaxChanged(int)));
60 60
61 QComboBox *chartTheme = new QComboBox();
62 chartTheme->addItem("Vanilla");
63 chartTheme->addItem("Icy");
64 chartTheme->addItem("Grayscale");
65 chartTheme->addItem("Tobedefined");
66 connect(chartTheme, SIGNAL(currentIndexChanged(int)),
67 this, SLOT(changeChartTheme(int)));
68
61 69 QGridLayout *grid = new QGridLayout();
62 70 QGridLayout *mainLayout = new QGridLayout();
63 71 //grid->addWidget(new QLabel("Add series:"), 0, 0);
64 72 grid->addWidget(addSeriesButton, 0, 1);
65 73 grid->addWidget(new QLabel("Background:"), 2, 0);
66 74 grid->addWidget(backgroundCombo, 2, 1);
67 75 grid->addWidget(m_autoScaleCheck, 3, 0);
68 76 grid->addWidget(new QLabel("x min:"), 4, 0);
69 77 grid->addWidget(m_xMinSpin, 4, 1);
70 78 grid->addWidget(new QLabel("x max:"), 5, 0);
71 79 grid->addWidget(m_xMaxSpin, 5, 1);
72 80 grid->addWidget(new QLabel("y min:"), 6, 0);
73 81 grid->addWidget(m_yMinSpin, 6, 1);
74 82 grid->addWidget(new QLabel("y max:"), 7, 0);
75 83 grid->addWidget(m_yMaxSpin, 7, 1);
84 grid->addWidget(new QLabel("Chart theme:"), 8, 0);
85 grid->addWidget(chartTheme, 8, 1);
76 86 // add row with empty label to make all the other rows static
77 grid->addWidget(new QLabel(""), 8, 0);
78 grid->setRowStretch(8, 1);
87 grid->addWidget(new QLabel(""), 9, 0);
88 grid->setRowStretch(9, 1);
79 89
80 90 mainLayout->addLayout(grid, 0, 0);
81 91
82 92 // Scatter specific settings
83 93 m_scatterLayout = new QGridLayout();
84 94 m_scatterLayout->addWidget(new QLabel("scatter"), 0, 0);
85 95 m_scatterLayout->setEnabled(false);
86 96
87 97 // Pie specific settings
88 98 m_pieLayout = new QGridLayout();
89 99 m_pieLayout->addWidget(new QLabel("Pie size factor"), 0, 0);
90 100 QDoubleSpinBox *pieSizeSpin = new QDoubleSpinBox();
91 101 pieSizeSpin->setMinimum(LONG_MIN);
92 102 pieSizeSpin->setMaximum(LONG_MAX);
93 103 pieSizeSpin->setValue(1.0);
94 104 pieSizeSpin->setSingleStep(0.1);
95 105 connect(pieSizeSpin, SIGNAL(valueChanged(double)), this, SLOT(setPieSizeFactor(double)));
96 106 m_pieLayout->setEnabled(false);
97 107 m_pieLayout->addWidget(pieSizeSpin, 0, 1);
98 108
99 109 mainLayout->addLayout(m_scatterLayout, 1, 0);
100 110 mainLayout->addLayout(m_pieLayout, 2, 0);
101 111
102 112 m_chartWidget = new QChartWidget(this);
103 113 //m_chartWidget->setColor(Qt::red);
104 114 mainLayout->addWidget(m_chartWidget, 0, 1, 3, 1);
105 115 // hbox->setStretch(1, 1);
106 116
107 117 setLayout(mainLayout);
108 118
109 119 m_autoScaleCheck->setChecked(true);
110 120 testDataChanged(0);
111 121 }
112 122
113 123 void MainWidget::addSeries()
114 124 {
115 125 DataSerieDialog dialog(m_defaultSeriesName, this);
116 126 connect(&dialog, SIGNAL(accepted(QString, QString)), this, SLOT(addSeries(QString, QString)));
117 127 dialog.exec();
118 128 }
119 129
120 130 void MainWidget::addSeries(QString series, QString data)
121 131 {
122 132 qDebug() << "addSeries: " << series << " data: " << data;
123 133 m_defaultSeriesName = series;
124 134
125 135 // TODO: a dedicated data class for storing x and y values
126 136 QList<qreal> x;
127 137 QList<qreal> y;
128 138
129 139 if (data == "linear") {
130 140 for (int i = 0; i < 20; i++) {
131 141 x.append(i);
132 142 y.append(i);
133 143 }
134 144 } else if (data == "linear, 1M") {
135 145 for (int i = 0; i < 10000; i++) {
136 146 x.append(i);
137 147 y.append(20);
138 148 }
139 149 } else if (data == "SIN") {
140 150 for (int i = 0; i < 100; i++) {
141 151 x.append(i);
142 152 y.append(abs(sin(3.14159265358979 / 50 * i) * 100));
143 153 }
144 154 } else if (data == "SIN + random") {
145 155 for (qreal i = 0; i < 100; i += 0.1) {
146 156 x.append(i + (rand() % 5));
147 157 y.append(abs(sin(3.14159265358979 / 50 * i) * 100) + (rand() % 5));
148 158 }
149 159 } else {
150 160 // TODO: check if data has a valid file name
151 161 Q_ASSERT(false);
152 162 }
153 163
154 164 // TODO: color of the series
155 165 QChartSeries *newSeries = 0;
156 166 if (series == "Scatter") {
157 167 newSeries = m_chartWidget->createSeries(QChartSeries::SeriesTypeScatter);
158 168 Q_ASSERT(newSeries->setData(x, y));
159 169 } else if (series == "Pie") {
160 170 newSeries = m_chartWidget->createSeries(QChartSeries::SeriesTypePie);
161 171 Q_ASSERT(newSeries->setData(y));
162 172 } else if (series == "Line") {
163 newSeries = m_chartWidget->createSeries(QChartSeries::SeriesTypePie);
164 Q_ASSERT(newSeries->setData(x, y));
173 // TODO: adding data to an existing line series does not give any visuals for some reason
174 // newSeries = m_chartWidget->createSeries(QChartSeries::SeriesTypeLine);
175 // QXYChartSeries *lineSeries = static_cast<QXYChartSeries *>(newSeries);
176 // lineSeries->setColor(Qt::blue);
177 // for (int i(0); i < x.count() && i < y.count(); i++) {
178 // lineSeries->add(x.at(i), y.at(i));
179 // }
180 //Q_ASSERT(newSeries->setData(x, y));
181 QXYChartSeries* series0 = QXYChartSeries::create();
182 for (int i(0); i < x.count() && i < y.count(); i++)
183 series0->add(x.at(i), y.at(i));
184 m_chartWidget->addSeries(series0);
185 newSeries = series0;
165 186 } else {
166 187 // TODO
167 188 }
168 189
169 190 // BarChart
170 191 if (series == "Bar") {
171 192 // This is the another way of creating series. Should we create test cases for both ways, if we support them?
172 193 qDebug() << "Bar chart series";
173 194 newSeries = QChartSeries::create(QChartSeries::SeriesTypeBar, this);
174 195 QList<int> barData;
175 196 barData << 1;
176 197 barData << 12;
177 198 barData << 5;
178 199 barData << 8;
179 200 barData << 17;
180 201 barData << 9;
181 202 newSeries->setData(barData);
182 203 m_chartWidget->addSeries(newSeries);
183 204 }
184 205
185 206 setCurrentSeries(newSeries);
186 207 }
187 208
188 209 void MainWidget::setCurrentSeries(QChartSeries *series)
189 210 {
190 211 m_currentSeries = series;
191 212 switch (m_currentSeries->type()) {
192 213 case QChartSeries::SeriesTypeLine:
193 214 break;
194 215 case QChartSeries::SeriesTypeScatter:
195 216 break;
196 217 case QChartSeries::SeriesTypePie:
197 218 break;
198 219 case QChartSeries::SeriesTypeBar:
199 220 qDebug() << "setCurrentSeries (bar)";
200 221 break;
201 222 default:
202 223 Q_ASSERT(false);
203 224 break;
204 225 }
205 226 }
206 227
207 228 void MainWidget::testDataChanged(int itemIndex)
208 229 {
209 230 qDebug() << "testDataChanged: " << itemIndex;
210 231
211 232 // switch (itemIndex) {
212 233 // case 0: {
213 234 // QList<QChartDataPoint> data;
214 235 // for (int x = 0; x < 20; x++) {
215 236 // data.append(QChartDataPoint() << x << x / 2);
216 237 // }
217 238 // m_chartWidget->setData(data);
218 239 // break;
219 240 // }
220 241 // case 1: {
221 242 // QList<QChartDataPoint> data;
222 243 // for (int x = 0; x < 100; x++) {
223 244 // data.append(QChartDataPoint() << x - 200 << 2 * (uint(sin(3.14159/50*x)*80) % 100));
224 245 // }
225 246 // m_chartWidget->setData(data);
226 247 // break;
227 248 // }
228 249 // case 2: {
229 250 // QList<QChartDataPoint> data;
230 251 // for (int x = 0; x < 1000; x++) {
231 252 // data.append(QChartDataPoint() << x - 200 << 2 * (uint(sin(3.14159/50*x)*80) % 100) + (rand() % 100 * 0.2));
232 253 // data.append(QChartDataPoint() << x - 200 << 2 * (uint(sin(3.14159/50*x)*80) % 100) + (rand() % 100 * 0.2));
233 254 // data.append(QChartDataPoint() << x - 200 << 2 * (uint(sin(3.14159/50*x)*80) % 100) + (rand() % 100 * 0.2));
234 255 // }
235 256 // m_chartWidget->setData(data);
236 257 // break;
237 258 // }
238 259 // default:
239 260 // break;
240 261 // }
241 262 }
242 263
243 264 void MainWidget::backgroundChanged(int itemIndex)
244 265 {
245 266 qDebug() << "backgroundChanged: " << itemIndex;
246 267 }
247 268
248 269 void MainWidget::autoScaleChanged(int value)
249 270 {
250 271 if (value) {
251 272 // TODO: enable auto scaling
252 273 } else {
253 274 // TODO: set scaling manually (and disable auto scaling)
254 275 }
255 276
256 277 m_xMinSpin->setEnabled(!value);
257 278 m_xMaxSpin->setEnabled(!value);
258 279 m_yMinSpin->setEnabled(!value);
259 280 m_yMaxSpin->setEnabled(!value);
260 281 }
261 282
262 283 void MainWidget::xMinChanged(int value)
263 284 {
264 285 qDebug() << "xMinChanged: " << value;
265 286 }
266 287
267 288 void MainWidget::xMaxChanged(int value)
268 289 {
269 290 qDebug() << "xMaxChanged: " << value;
270 291 }
271 292
272 293 void MainWidget::yMinChanged(int value)
273 294 {
274 295 qDebug() << "yMinChanged: " << value;
275 296 }
276 297
277 298 void MainWidget::yMaxChanged(int value)
278 299 {
279 300 qDebug() << "yMaxChanged: " << value;
280 301 }
281 302
303 void MainWidget::changeChartTheme(int themeIndex)
304 {
305 qDebug() << "changeChartTheme: " << themeIndex;
306 m_chartWidget->setTheme((QChart::ChartTheme) themeIndex);
307 }
308
282 309 void MainWidget::setPieSizeFactor(double size)
283 310 {
284 311 QPieSeries *pie = qobject_cast<QPieSeries *>(m_currentSeries);
285 312 Q_ASSERT(pie);
286 313 pie->setSizeFactor(qreal(size));
287 314 }
@@ -1,48 +1,49
1 1 #ifndef MAINWIDGET_H
2 2 #define MAINWIDGET_H
3 3
4 4 #include <qchartglobal.h>
5 5 #include <qchartwidget.h>
6 6 #include <QWidget>
7 7
8 8 class QSpinBox;
9 9 class QCheckBox;
10 10 class QGridLayout;
11 11
12 12 QTCOMMERCIALCHART_USE_NAMESPACE
13 13
14 14 class MainWidget : public QWidget
15 15 {
16 16 Q_OBJECT
17 17 public:
18 18 explicit MainWidget(QWidget *parent = 0);
19 19
20 20 signals:
21 21
22 22 private slots:
23 23 void addSeries();
24 24 void addSeries(QString series, QString data);
25 25 void testDataChanged(int itemIndex);
26 26 void backgroundChanged(int itemIndex);
27 27 void autoScaleChanged(int value);
28 28 void xMinChanged(int value);
29 29 void xMaxChanged(int value);
30 30 void yMinChanged(int value);
31 31 void yMaxChanged(int value);
32 32 void setCurrentSeries(QChartSeries *series);
33 void changeChartTheme(int themeIndex);
33 34 void setPieSizeFactor(double margin);
34 35
35 36 private:
36 37 QChartWidget *m_chartWidget;
37 38 QCheckBox *m_autoScaleCheck;
38 39 QSpinBox *m_xMinSpin;
39 40 QSpinBox *m_xMaxSpin;
40 41 QSpinBox *m_yMinSpin;
41 42 QSpinBox *m_yMaxSpin;
42 43 QString m_defaultSeriesName;
43 44 QChartSeries *m_currentSeries;
44 45 QGridLayout *m_scatterLayout;
45 46 QGridLayout *m_pieLayout;
46 47 };
47 48
48 49 #endif // MAINWIDGET_H
General Comments 0
You need to be logged in to leave comments. Login now