##// END OF EJS Templates
Integrated scatter again. Missing functionality....
Tero Ahola -
r158:dd283485728c
parent child
Show More
@@ -0,0 +1,93
1 #include "scatterpresenter.h"
2 #include "qscatterseries.h"
3 #include <QPen>
4 #include <QPainter>
5 #include <QGraphicsScene>
6 #include <QDebug>
7
8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9
10 ScatterPresenter::ScatterPresenter(QScatterSeries *series, QGraphicsObject *parent) :
11 ChartItem(parent),
12 m_series(series),
13 m_boundingRect(),
14 //m_markerColor(QColor()),
15 m_markerColor(QColor(255, 0, 0)),
16 m_visibleChartArea()
17 {
18 if (parent)
19 m_boundingRect = parent->boundingRect();
20
21 if (series) {
22 connect(series, SIGNAL(changed()), this, SLOT(handleModelChanged()));
23 }
24 }
25
26 void ScatterPresenter::handleDomainChanged(const Domain& domain)
27 {
28 m_visibleChartArea = domain;
29 changeGeometry();
30 }
31
32 void ScatterPresenter::handleGeometryChanged(const QRectF& rect)
33 {
34 m_boundingRect = rect;
35 changeGeometry();
36 }
37
38 void ScatterPresenter::handleModelChanged()
39 {
40 // TODO: more fine grained modelChanged signaling
41 changeGeometry();
42 }
43
44 void ScatterPresenter::paint(QPainter *painter, const QStyleOptionGraphicsItem */*option*/, QWidget */*widget*/)
45 {
46 // TODO: The opacity should be user definable?
47 //brush.setColor(QColor(255, 82, 0, 100));
48 if (m_markerColor.isValid()) {
49 QPen pen = painter->pen();
50 QBrush brush = pen.brush();
51 brush.setColor(m_markerColor);
52 pen.setBrush(brush);
53 pen.setWidth(4);
54 painter->setPen(pen);
55 }
56 else {
57 //painter->setPen(m_theme.markerPen);
58 // brush.setColor(m_theme..lineColor);
59 }
60
61 // TODO: m_scenex and m_sceny are left empty during construction -> we would need a resize
62 // event right after construction or maybe given a size during initialization
63 qDebug() << "scene w: "<< scene()->width() << " h: " << scene()->height();
64 for (int i(0); i < m_scenex.count() && i < m_sceney.count(); i++) {
65 qDebug() << "scene w: "<< scene()->width() << " h: " << scene()->height();
66 qDebug() << "x: "<< m_scenex.at(i) << " y: " << m_sceney.at(i);
67 if (scene()->width() > m_scenex.at(i) && scene()->height() > m_sceney.at(i))
68 //painter->drawArc(m_scenex.at(i), m_sceney.at(i), 2, 2, 0, 5760);
69 painter->drawPoint(m_scenex.at(i), m_sceney.at(i));
70 }
71 }
72
73 void ScatterPresenter::changeGeometry()
74 {
75 if (m_boundingRect.isValid()) {
76
77 prepareGeometryChange();
78 qreal scalex = m_boundingRect.width() / m_visibleChartArea.spanX();
79 qreal scaley = m_boundingRect.height() / m_visibleChartArea.spanY();
80 m_scenex.clear();
81 m_sceney.clear();
82
83 // Convert relative coordinates to absolute pixel coordinates that can be used for drawing
84 foreach (QPointF point, m_series->data()) {
85 m_scenex.append(m_boundingRect.left() + point.x() * scalex - m_visibleChartArea.m_minX * scalex);
86 m_sceney.append(m_boundingRect.bottom() - point.y() * scaley + m_visibleChartArea.m_minY * scaley);
87 }
88 }
89 }
90
91 #include "moc_scatterpresenter.cpp"
92
93 QTCOMMERCIALCHART_END_NAMESPACE
@@ -0,0 +1,46
1 #ifndef SCATTERPRESENTER_H
2 #define SCATTERPRESENTER_H
3
4 #include "qchartglobal.h"
5 #include "chartitem_p.h"
6 #include <QObject>
7
8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9
10 class QScatterSeries;
11
12 /*!
13 * The "business logic" of scatter series. This is a QObject that does not have a parent QObject.
14 * The QGraphicsItem parent owns the object instead.
15 */
16 class ScatterPresenter : public QObject, public ChartItem
17 {
18 Q_OBJECT
19 public:
20 explicit ScatterPresenter(QScatterSeries *series, QGraphicsObject *parent = 0);
21
22 public: // from ChartItem
23 QRectF boundingRect() const { return m_boundingRect; }
24 void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *);
25
26 signals:
27
28 public Q_SLOTS:
29 void handleDomainChanged(const Domain& domain);
30 void handleGeometryChanged(const QRectF& rect);
31 void handleModelChanged();
32
33 public:
34 void changeGeometry();
35
36 QScatterSeries *m_series;
37 QRectF m_boundingRect;
38 QList<qreal> m_scenex;
39 QList<qreal> m_sceney;
40 QColor m_markerColor;
41 Domain m_visibleChartArea;
42 };
43
44 QTCOMMERCIALCHART_END_NAMESPACE
45
46 #endif // SCATTERPRESENTER_H
@@ -44,7 +44,7 void DeclarativeSeries::initSeries()
44 44
45 45 switch (m_seriesType) {
46 46 case SeriesTypeLine: {
47 m_series = QLineChartSeries::create(this);
47 m_series = new QLineChartSeries(this);
48 48 for (qreal i(0.0); i < 100.0; i += 1.0)
49 49 ((QLineChartSeries *)m_series)->add(i, i);
50 50 chart->addSeries(m_series);
@@ -5,6 +5,7
5 5 #include "stackedbarchartseries.h"
6 6 #include "percentbarchartseries.h"
7 7 #include "qpieseries.h"
8 #include "qscatterseries.h"
8 9
9 10 QTCOMMERCIALCHART_BEGIN_NAMESPACE
10 11
@@ -89,6 +90,18 void ChartDataSet::addSeries(QChartSeries* series)
89 90 break;
90 91 }
91 92
93 case QChartSeries::SeriesTypeScatter: {
94 QScatterSeries *scatterSeries = qobject_cast<QScatterSeries *>(series);
95 Q_ASSERT(scatterSeries);
96 foreach (QPointF point, scatterSeries->data()) {
97 domain.m_minX = qMin(domain.m_minX, point.x());
98 domain.m_maxX = qMax(domain.m_maxX, point.x());
99 domain.m_minY = qMin(domain.m_minY, point.y());
100 domain.m_maxY = qMax(domain.m_maxY, point.y());
101 }
102 break;
103 }
104
92 105 default: {
93 106 qDebug()<<__FUNCTION__<<"type" << series->type()<<"not supported";
94 107 return;
@@ -9,6 +9,7
9 9 #include "percentbarchartseries.h"
10 10 #include "qlinechartseries.h"
11 11 #include "qpieseries.h"
12 #include "qscatterseries.h"
12 13 //items
13 14 #include "axisitem_p.h"
14 15 #include "bargroup.h"
@@ -17,6 +18,7
17 18 #include "percentbargroup.h"
18 19 #include "linechartanimationitem_p.h"
19 20 #include "piepresenter.h"
21 #include "scatterpresenter.h"
20 22
21 23 QTCOMMERCIALCHART_BEGIN_NAMESPACE
22 24
@@ -122,28 +124,19 void ChartPresenter::handleSeriesAdded(QChartSeries* series)
122 124 m_chartItems.insert(series,item);
123 125 break;
124 126 }
125 /*
126 127 case QChartSeries::SeriesTypeScatter: {
127 128 QScatterSeries *scatterSeries = qobject_cast<QScatterSeries *>(series);
128 scatterSeries->d->m_theme = m_chartTheme->themeForSeries();
129 scatterSeries->d->setParentItem(this);
130 scatterSeries->d->m_boundingRect = m_rect.adjusted(margin(),margin(), -margin(), -margin());
131 m_chartItems << scatterSeries->d;
132 m_chartTheme->addObserver(scatterSeries->d);
133
134 foreach (qreal x, scatterSeries->d->m_x) {
135 domain.m_minX = qMin(domain.m_minX, x);
136 domain.m_maxX = qMax(domain.m_maxX, x);
137 }
138 foreach (qreal y, scatterSeries->d->m_y) {
139 domain.m_minY = qMin(domain.m_minY, y);
140 domain.m_maxY = qMax(domain.m_maxY, y);
141 }
142
129 ScatterPresenter *scatterPresenter = new ScatterPresenter(scatterSeries, m_chart);
130 QObject::connect(this, SIGNAL(geometryChanged(const QRectF&)),
131 scatterPresenter, SLOT(handleGeometryChanged(const QRectF&)));
132 QObject::connect(m_dataset, SIGNAL(domainChanged(const Domain&)),
133 scatterPresenter, SLOT(handleDomainChanged(const Domain&)));
134 // scatterSeries->d->m_theme = m_chartTheme->themeForSeries();
135 // scatterSeries->d->setParentItem(this);
136 // scatterSeries->d->m_boundingRect = m_rect.adjusted(margin(),margin(), -margin(), -margin());
137 m_chartItems.insert(scatterSeries, scatterPresenter);
143 138 break;
144 139 }
145 */
146
147 140 case QChartSeries::SeriesTypePie: {
148 141 QPieSeries *pieSeries = qobject_cast<QPieSeries *>(series);
149 142 PiePresenter* pie = new PiePresenter(m_chart, pieSeries);
@@ -153,7 +146,6 void ChartPresenter::handleSeriesAdded(QChartSeries* series)
153 146 m_chartItems.insert(series, pie);
154 147 break;
155 148 }
156
157 149 default: {
158 150 qDebug()<< "Series type" << series->type() << "not implemented.";
159 151 break;
@@ -36,8 +36,6 void QChart::addSeries(QChartSeries* series)
36 36 //TODO on review, is it really needed ??
37 37 QChartSeries* QChart::createSeries(QChartSeries::QChartSeriesType type)
38 38 {
39 // TODO: support also other types; not only scatter and pie
40
41 39 QChartSeries *series(0);
42 40
43 41 switch (type) {
@@ -1,138 +1,68
1 1 #include "qscatterseries.h"
2 2 #include "qscatterseries_p.h"
3 3 #include "qchart.h"
4 #include <QPainter>
5 #include <QGraphicsScene>
6 #include <QDebug>
7 4
8 5 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9 6
10 //#define QSeriesData QList<qreal>
11
12 QScatterSeriesPrivate::QScatterSeriesPrivate(QGraphicsItem *parent) :
13 ChartItem(parent),
14 m_boundingRect(),
15 m_markerColor(QColor()),
16 m_visibleChartArea()
17 {
18 if (parent)
19 m_boundingRect = parent->boundingRect();
20 }
21
22 void QScatterSeriesPrivate::changeGeometry()
23 {
24 if (m_boundingRect.isValid()) {
25 prepareGeometryChange();
26 qreal scalex = m_boundingRect.width() / m_visibleChartArea.spanX();
27 qreal scaley = m_boundingRect.height() / m_visibleChartArea.spanY();
28 m_scenex.clear();
29 m_sceney.clear();
30
31 // Convert relative coordinates to absolute pixel coordinates that can be used for drawing
32 foreach(qreal x, m_x)
33 m_scenex.append(m_boundingRect.left() + x * scalex - m_visibleChartArea.m_minX * scalex);
34
35 foreach(qreal y, m_y)
36 m_sceney.append(m_boundingRect.bottom() - y * scaley + m_visibleChartArea.m_minY * scaley);
37 }
38 }
39
40 void QScatterSeriesPrivate::setSize(const QSizeF &size)
7 QScatterSeriesPrivate::QScatterSeriesPrivate() :
8 m_data(QList<QPointF>())
41 9 {
42 // m_boundingRect = QRectF(pos().x(), pos().y(), size.width(), size.height());
43 m_boundingRect = QRectF(0, 0, size.width(), size.height());
44 changeGeometry();
45 10 }
46 11
47 void QScatterSeriesPrivate::themeChanged(ChartTheme *theme)
48 {
49 //m_theme = theme->themeForSeries();
50 }
51
52 void QScatterSeriesPrivate::setPlotDomain(const Domain& plotDomain)
53 {
54 //m_visibleChartArea = plotDomain;
55 changeGeometry();
56 }
57
58 QRectF QScatterSeriesPrivate::boundingRect() const
59 {
60 return m_boundingRect;
61 }
62
63 void QScatterSeriesPrivate::paint(QPainter *painter, const QStyleOptionGraphicsItem */*option*/, QWidget */*widget*/)
12 QScatterSeries::QScatterSeries(QObject *parent) :
13 QChartSeries(parent),
14 d(new QScatterSeriesPrivate())
64 15 {
65 // TODO: The opacity should be user definable?
66 //brush.setColor(QColor(255, 82, 0, 100));
67 if (m_markerColor.isValid()) {
68 QPen pen = painter->pen();
69 QBrush brush = pen.brush();
70 brush.setColor(m_markerColor);
71 pen.setBrush(brush);
72 pen.setWidth(4);
73 painter->setPen(pen);
74 }
75 else
76 //painter->setPen(m_theme.markerPen);
77 // brush.setColor(m_theme..lineColor);
78
79 // TODO: m_scenex and m_sceny are left empty during construction -> we would need a resize
80 // event right after construction or maybe given a size during initialization
81 for (int i(0); i < m_scenex.count() && i < m_sceney.count(); i++) {
82 if (scene()->width() > m_scenex.at(i) && scene()->height() > m_sceney.at(i))
83 //painter->drawArc(m_scenex.at(i), m_sceney.at(i), 2, 2, 0, 5760);
84 painter->drawPoint(m_scenex.at(i), m_sceney.at(i));
85 }
86 16 }
87 17
88 QScatterSeries::QScatterSeries(QObject *parent) :
89 QChartSeries(parent),
90 d(new QScatterSeriesPrivate(qobject_cast<QGraphicsItem *> (parent)))
18 QScatterSeries::~QScatterSeries()
91 19 {
20 delete d;
92 21 }
93 22
23 // TODO: change to list of QPointFs?
94 24 bool QScatterSeries::setData(QList<qreal> xlist, QList<qreal> ylist)
95 25 {
26 d->m_data.clear();
96 27 // TODO: validate data
97 d->m_x = xlist;
98 d->m_y = ylist;
28 for (int i(0); i < xlist.count() && i < ylist.count(); i++) {
29 d->m_data.append(QPointF(xlist[i], ylist[i]));
30 }
31
99 32
100 33 // TODO: the following updates the visible chart area setting of the series, we would instead
101 34 // need to update the _chart's_ visible area... this would require a callback or
102 35 // similar to the parenting QChart object...
103 foreach (qreal x, d->m_x) {
104 d->m_visibleChartArea.m_minX = qMin(d->m_visibleChartArea.m_minX, x);
105 d->m_visibleChartArea.m_maxX = qMax(d->m_visibleChartArea.m_maxX, x);
106 }
107 foreach (qreal y, d->m_y) {
108 d->m_visibleChartArea.m_minY = qMin(d->m_visibleChartArea.m_minY, y);
109 d->m_visibleChartArea.m_maxY = qMax(d->m_visibleChartArea.m_maxY, y);
110 }
111
112 d->changeGeometry();
36 // foreach (qreal x, d->m_x) {
37 // d->m_visibleChartArea.m_minX = qMin(d->m_visibleChartArea.m_minX, x);
38 // d->m_visibleChartArea.m_maxX = qMax(d->m_visibleChartArea.m_maxX, x);
39 // }
40 // foreach (qreal y, d->m_y) {
41 // d->m_visibleChartArea.m_minY = qMin(d->m_visibleChartArea.m_minY, y);
42 // d->m_visibleChartArea.m_maxY = qMax(d->m_visibleChartArea.m_maxY, y);
43 // }
44 // d->changeGeometry();
113 45
46 emit changed();
114 47 return true;
115 48 }
116 49
117 void QScatterSeries::setMarkerColor(QColor color)
50 QList<QPointF> QScatterSeries::data()
118 51 {
119 d->m_markerColor = color;
52 return d->m_data;
120 53 }
121 54
122 QColor QScatterSeries::markerColor()
55 void QScatterSeries::setMarkerColor(QColor color)
123 56 {
124 return d->m_markerColor;
125 }
126
127 57 // TODO:
128 //void QScatterSeries::chartScaleChanged(qreal xscale, qreal yscale)
129 //{
130 // d->rescale(xscale, yscale);
131 //}
58 // d->m_markerColor = color;
59 }
132 60
133 QScatterSeries::~QScatterSeries()
61 QColor QScatterSeries::markerColor()
134 62 {
135 delete d;
63 // TODO:
64 // return d->m_markerColor;
65 return QColor();
136 66 }
137 67
138 68 #include "moc_qscatterseries.cpp"
@@ -20,17 +20,22 public: // from QChartSeries
20 20 QChartSeriesType type() const { return QChartSeries::SeriesTypeScatter; }
21 21 bool setData(QList<qreal> x, QList<qreal> y);
22 22
23 public:
24 QList<QPointF> data();
25 Q_SIGNALS:
26 // TODO: move to PIMPL?
27 // TODO: more finegrained signaling
28 void changed();
29
23 30 public Q_SLOTS:
24 31 // TODO: also affects opacity of the marker...? To be documented
25 32 void setMarkerColor(QColor color);
26 33 QColor markerColor();
27 34 // TODO: marker shapes: "x", star, rectangle, tilted rect, triangle, circle, dot
28 35 //void setMarkerShape(QChartSeries::MarkerShape/QScatterSeries::MarkerShape shape);
29
30 36 private:
31 37 Q_DECLARE_PRIVATE(QScatterSeries)
32 38 Q_DISABLE_COPY(QScatterSeries)
33 friend class QChart;
34 39 QScatterSeriesPrivate *const d;
35 40 };
36 41
@@ -1,45 +1,23
1 1 #ifndef QSCATTERSERIESPRIVATE_H
2 2 #define QSCATTERSERIESPRIVATE_H
3 3
4 #include "qchartglobal.h"
4 5 #include "qchartseries.h"
5 #include "charttheme_p.h"
6 #include "chartitem_p.h"
7 #include "domain_p.h"
8 #include <QGraphicsItem>
9 6
10 7 QTCOMMERCIALCHART_BEGIN_NAMESPACE
11 8
12 9 /*!
13 10 * The PIMPL class of QScatterSeries.
14 11 */
15 class QScatterSeriesPrivate : public ChartItem
12 class QScatterSeriesPrivate
16 13 {
17 14 public:
18 QScatterSeriesPrivate(QGraphicsItem *parent);
19
20 public: // from ChartObjectInterface
21 void setSize(const QSizeF &size);
22 void setPlotDomain(const Domain& data);
23
24 public: // from ChartThemeObserver
25 void themeChanged(ChartTheme *theme);
26
27 public: // from QGraphicsItem
28 QRectF boundingRect() const;
29 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
15 QScatterSeriesPrivate();
30 16
31 17 public:
32 void changeGeometry();
33 18
34 QRectF m_boundingRect;
35 19 // TODO: use the chart data class instead of list of x and y values?
36 QList<qreal> m_x;
37 QList<qreal> m_y;
38 QList<qreal> m_scenex;
39 QList<qreal> m_sceney;
40 QColor m_markerColor;
41 //SeriesTheme m_theme;
42 Domain m_visibleChartArea;
20 QList<QPointF> m_data;
43 21 };
44 22
45 23 QTCOMMERCIALCHART_END_NAMESPACE
@@ -21,6 +21,7 SOURCES += barchart/barchartseries.cpp \
21 21 barchart/bargroupbase.cpp \
22 22 barchart/barchartseriesbase.cpp \
23 23 qscatterseries.cpp \
24 #scatterpresentation.cpp \
24 25 qchart.cpp \
25 26 axisitem.cpp \
26 27 qchartview.cpp \
@@ -29,13 +30,15 SOURCES += barchart/barchartseries.cpp \
29 30 charttheme.cpp \
30 31 chartdataset.cpp \
31 32 chartpresenter.cpp \
32 domain.cpp
33 domain.cpp \
34 scatterpresenter.cpp
33 35 PRIVATE_HEADERS += linechart/linechartitem_p.h \
34 36 linechart/linechartanimationitem_p.h \
35 37 barchart/barlabel_p.h \
36 38 barchart/bar_p.h \
37 39 barchart/separator_p.h \
38 40 qscatterseries_p.h \
41 #scatterpresentation.h \
39 42 axisitem_p.h \
40 43 chartitem_p.h \
41 44 charttheme_p.h \
@@ -64,7 +67,8 THEMES += themes/chartthemeicy_p.h \
64 67 themes/chartthemegrayscale_p.h \
65 68 themes/chartthemescientific_p.h \
66 69 themes/chartthemevanilla_p.h
67 HEADERS += $$PUBLIC_HEADERS
70 HEADERS += $$PUBLIC_HEADERS \
71 scatterpresenter.h
68 72 HEADERS += $$PRIVATE_HEADERS
69 73 HEADERS += $$THEMES
70 74 INCLUDEPATH += linechart \
@@ -13,9 +13,25 Rectangle {
13 13 anchors.fill: parent
14 14 theme: Chart.ThemeIcy
15 15
16 Series {
17 seriesType: Series.SeriesTypePie
16 // PieSeries {
17 // labels: ["point1", "point2", "point3", "point4", "point5"]
18 // datax: [2, 1.5, 3, 3, 3]
19 // }
20 PieSeries {
21 name: "raspberry pie"
22 seriesLabels: ["point1", "point2", "point3", "point4", "point5"]
23 seriesData: [2, 1.5, 3, 3, 3]
24 }
25 ScatterSeries {
26 name: "scatter1"
27 datax: [2, 1.5, 3, 3, 3]
28 datay: [2, 1.5, 3, 3, 3]
18 29 }
30 // Series {
31 // labels: ["point1", "point2", "point3", "point4", "point5"]
32 // datax: [2, 1.5, 3, 3, 3]
33 // seriesType: Series.SeriesTypePie
34 // }
19 35 Series {
20 36 seriesType: Series.SeriesTypeScatter
21 37 }
General Comments 0
You need to be logged in to leave comments. Login now