##// END OF EJS Templates
Clicked, remove and clear to QScatterSeries
Tero Ahola -
r394:9882bdf19567
parent child
Show More
@@ -0,0 +1,11
1 #include <QtGui/QApplication>
2 #include "mainwindow.h"
3
4 int main(int argc, char *argv[])
5 {
6 QApplication a(argc, argv);
7 MainWindow w;
8 w.show();
9
10 return a.exec();
11 }
@@ -0,0 +1,51
1 #include "mainwindow.h"
2 #include <qchartglobal.h>
3 #include <qchartview.h>
4 #include <QDebug>
5
6 QTCOMMERCIALCHART_USE_NAMESPACE
7
8 MainWindow::MainWindow(QWidget *parent)
9 : QMainWindow(parent)
10 {
11 resize(400, 300);
12 setWindowFlags(Qt::FramelessWindowHint);
13
14 QChartView *chartView = new QChartView(this);
15 chartView->setChartTitle("Click to play with points");
16 chartView->setRenderHint(QPainter::Antialiasing);
17 setCentralWidget(chartView);
18
19 m_scatter = new QScatterSeries();
20 for(qreal x(0.5); x <= 5.0; x += 0.5) {
21 for(qreal y(0.5); y <= 5.0; y += 0.5) {
22 *m_scatter << QPointF(x, y);
23 }
24 }
25 chartView->addSeries(m_scatter);
26
27 // Add two more series
28 m_scatter2 = new QScatterSeries();
29 chartView->addSeries(m_scatter2);
30 m_scatter3 = new QScatterSeries();
31 chartView->addSeries(m_scatter3);
32
33 connect(m_scatter, SIGNAL(clicked(QPointF)), this, SLOT(clickPoint(QPointF)));
34 }
35
36 MainWindow::~MainWindow()
37 {
38 }
39
40 void MainWindow::clickPoint(QPointF coordinate)
41 {
42 // Remove the clicked point from the series and add points to the two other series we have
43 int index = m_scatter->closestPoint(coordinate);
44 QPointF point = m_scatter->data().at(index);
45 Q_ASSERT(m_scatter->removeAt(index));
46 point.rx() += 0.25;
47 point.ry() += 0.25;
48 *m_scatter2 << point;
49 point.ry() -= 0.25;
50 *m_scatter3 << point;
51 }
@@ -0,0 +1,27
1 #ifndef MAINWINDOW_H
2 #define MAINWINDOW_H
3
4 #include <QtGui/QMainWindow>
5 #include <qchartglobal.h>
6 #include <qscatterseries.h>
7
8 QTCOMMERCIALCHART_USE_NAMESPACE
9
10 class MainWindow : public QMainWindow
11 {
12 Q_OBJECT
13
14 public:
15 MainWindow(QWidget *parent = 0);
16 ~MainWindow();
17
18 private Q_SLOTS:
19 void clickPoint(QPointF coordinate);
20
21 private:
22 QScatterSeries *m_scatter;
23 QScatterSeries *m_scatter2;
24 QScatterSeries *m_scatter3;
25 };
26
27 #endif // MAINWINDOW_H
@@ -0,0 +1,12
1 !include( ../example.pri ) {
2 error( "Couldn't find the example.pri file!" )
3 }
4 QT += core gui
5
6 TARGET = scatterinteractions
7 TEMPLATE = app
8
9 SOURCES += main.cpp\
10 mainwindow.cpp
11
12 HEADERS += mainwindow.h
@@ -1,15 +1,16
1 TEMPLATE = subdirs
1 TEMPLATE = subdirs
2 SUBDIRS += linechart \
2 SUBDIRS += linechart \
3 zoomlinechart \
3 zoomlinechart \
4 colorlinechart \
4 colorlinechart \
5 barchart \
5 barchart \
6 stackedbarchart \
6 stackedbarchart \
7 percentbarchart \
7 percentbarchart \
8 scatter \
8 scatter \
9 piechart \
9 piechart \
10 dynamiclinechart \
10 dynamiclinechart \
11 axischart \
11 axischart \
12 multichart \
12 multichart \
13 gdpbarchart \
13 gdpbarchart \
14 presenterchart \
14 presenterchart \
15 chartview
15 chartview \
16 scatterinteractions
@@ -1,62 +1,57
1 #include <QtGui/QApplication>
1 #include <QtGui/QApplication>
2 #include <QMainWindow>
2 #include <QMainWindow>
3 #include <qchartglobal.h>
3 #include <qchartglobal.h>
4 #include <qchartview.h>
4 #include <qchartview.h>
5 #include <qscatterseries.h>
5 #include <qscatterseries.h>
6
6
7 QTCOMMERCIALCHART_USE_NAMESPACE
7 QTCOMMERCIALCHART_USE_NAMESPACE
8
8
9 int main(int argc, char *argv[])
9 int main(int argc, char *argv[])
10 {
10 {
11 QApplication a(argc, argv);
11 QApplication a(argc, argv);
12
12
13 //! [1]
13 //! [1]
14 // Create chart view
14 // Create chart view
15 QChartView *chartView = new QChartView();
15 QChartView *chartView = new QChartView();
16 chartView->setChartTheme(QChart::ChartThemeIcy);
16 chartView->setChartTheme(QChart::ChartThemeIcy);
17
18 // Add scatter series with simple test data
17 // Add scatter series with simple test data
19 QScatterSeries *scatter = new QScatterSeries();
18 QScatterSeries *scatter = new QScatterSeries();
20 *scatter << QPointF(0.5, 5.0)
19 *scatter << QPointF(0.5, 5.0) << QPointF(1.0, 4.5) << QPointF(1.0, 5.5) << QPointF(1.5, 5.0);
21 << QPointF(1.0, 4.5)
22 << QPointF(1.0, 5.5)
23 << QPointF(1.5, 5.0)
24 << QPointF(2.0, 4.5)
25 << QPointF(2.5, 5.0);
26 // Chart takes ownership
20 // Chart takes ownership
27 chartView->addSeries(scatter);
21 chartView->addSeries(scatter);
28 //! [1]
22 //! [1]
29
23
30 // And more
24 // And more
31 //! [3]
25 //! [3]
32 *scatter << QPointF(2.0, 5.5) << QPointF(2.2, 5.4);
26 *scatter << QPointF(2.0, 5.5) << QPointF(2.2, 5.4);
33 //! [3]
27 //! [3]
34
28
35 // Add another scatter series (re-use the previous pointer)
29 // Add another scatter series (re-use the previous pointer)
36 // - more data with random component
30 // - more data with random component
37 scatter = new QScatterSeries();
31 scatter = new QScatterSeries();
38 for (qreal i(0.0); i < 20; i += 0.15) {
32 for (qreal i(0.0); i < 20; i += 0.15) {
39 (*scatter) << QPointF(i + (qreal)(rand() % 100) / 100.0,
33 (*scatter) << QPointF(i + (qreal)(rand() % 100) / 100.0,
40 i + (qreal)(rand() % 100) / 100.0);
34 i + (qreal)(rand() % 100) / 100.0);
41 }
35 }
42 //! [4]
36 //! [4]
43 QBrush brush(QColor(255, 0, 0, 100), Qt::SolidPattern);
37 QBrush brush(QColor(255, 0, 0, 100), Qt::SolidPattern);
44 scatter->setBrush(brush);
38 scatter->setBrush(brush);
45 //! [4]
39 //! [4]
46 //! [5]
40 //! [5]
47 QPen pen(QColor(0, 255, 0, 80), 3);
41 QPen pen(QColor(0, 255, 0, 80), 3);
48 scatter->setPen(pen);
42 scatter->setPen(pen);
49 //! [5]
43 //! [5]
50 //! [6]
44 //! [6]
51 scatter->setShape(QScatterSeries::MarkerShapeRectangle);
45 scatter->setShape(QScatterSeries::MarkerShapeRectangle);
52 //! [6]
46 //! [6]
53 chartView->addSeries(scatter);
47 chartView->addSeries(scatter);
54
48
55 // Use the chart widget as the central widget
49 // Use the chart widget as the central widget
56 QMainWindow w;
50 QMainWindow w;
57 w.resize(640, 480);
51 w.resize(400, 300);
58 w.setCentralWidget(chartView);
52 w.setCentralWidget(chartView);
53 w.setWindowFlags(Qt::FramelessWindowHint);
59 w.show();
54 w.show();
60
55
61 return a.exec();
56 return a.exec();
62 }
57 }
@@ -1,8 +1,5
1 !include( ../example.pri ) {
1 !include( ../example.pri ) {
2 error( "Couldn't find the example.pri file!" )
2 error( "Couldn't find the example.pri file!" )
3 }
3 }
4 TARGET = scatter
4 TARGET = scatter
5 SOURCES += main.cpp
5 SOURCES += main.cpp
6
7
8
@@ -1,286 +1,287
1 #include "qchart.h"
1 #include "qchart.h"
2 #include "qchartaxis.h"
2 #include "qchartaxis.h"
3 #include "chartpresenter_p.h"
3 #include "chartpresenter_p.h"
4 #include "chartdataset_p.h"
4 #include "chartdataset_p.h"
5 #include "charttheme_p.h"
5 #include "charttheme_p.h"
6 //series
6 //series
7 #include "qbarseries.h"
7 #include "qbarseries.h"
8 #include "qstackedbarseries.h"
8 #include "qstackedbarseries.h"
9 #include "qpercentbarseries.h"
9 #include "qpercentbarseries.h"
10 #include "qlineseries.h"
10 #include "qlineseries.h"
11 #include "qpieseries.h"
11 #include "qpieseries.h"
12 #include "qscatterseries.h"
12 #include "qscatterseries.h"
13 //items
13 //items
14 #include "axisitem_p.h"
14 #include "axisitem_p.h"
15 #include "axisanimationitem_p.h"
15 #include "axisanimationitem_p.h"
16 #include "barpresenter_p.h"
16 #include "barpresenter_p.h"
17 #include "stackedbarpresenter_p.h"
17 #include "stackedbarpresenter_p.h"
18 #include "percentbarpresenter_p.h"
18 #include "percentbarpresenter_p.h"
19 #include "linechartitem_p.h"
19 #include "linechartitem_p.h"
20 #include "linechartanimationitem_p.h"
20 #include "linechartanimationitem_p.h"
21 #include "piepresenter_p.h"
21 #include "piepresenter_p.h"
22 #include "scatterpresenter_p.h"
22 #include "scatterpresenter_p.h"
23
23
24 QTCOMMERCIALCHART_BEGIN_NAMESPACE
24 QTCOMMERCIALCHART_BEGIN_NAMESPACE
25
25
26 ChartPresenter::ChartPresenter(QChart* chart,ChartDataSet* dataset):QObject(chart),
26 ChartPresenter::ChartPresenter(QChart* chart,ChartDataSet* dataset):QObject(chart),
27 m_chart(chart),
27 m_chart(chart),
28 m_dataset(dataset),
28 m_dataset(dataset),
29 m_chartTheme(0),
29 m_chartTheme(0),
30 m_marginSize(0),
30 m_marginSize(0),
31 m_rect(QRectF(QPoint(0,0),m_chart->size())),
31 m_rect(QRectF(QPoint(0,0),m_chart->size())),
32 m_options(0)
32 m_options(0)
33 {
33 {
34 createConnections();
34 createConnections();
35 setChartTheme(QChart::ChartThemeDefault);
35 setChartTheme(QChart::ChartThemeDefault);
36
36
37 }
37 }
38
38
39 ChartPresenter::~ChartPresenter()
39 ChartPresenter::~ChartPresenter()
40 {
40 {
41 }
41 }
42
42
43 void ChartPresenter::createConnections()
43 void ChartPresenter::createConnections()
44 {
44 {
45 QObject::connect(m_chart,SIGNAL(geometryChanged()),this,SLOT(handleGeometryChanged()));
45 QObject::connect(m_chart,SIGNAL(geometryChanged()),this,SLOT(handleGeometryChanged()));
46 QObject::connect(m_dataset,SIGNAL(seriesAdded(QSeries*)),this,SLOT(handleSeriesAdded(QSeries*)));
46 QObject::connect(m_dataset,SIGNAL(seriesAdded(QSeries*)),this,SLOT(handleSeriesAdded(QSeries*)));
47 QObject::connect(m_dataset,SIGNAL(seriesRemoved(QSeries*)),this,SLOT(handleSeriesRemoved(QSeries*)));
47 QObject::connect(m_dataset,SIGNAL(seriesRemoved(QSeries*)),this,SLOT(handleSeriesRemoved(QSeries*)));
48 QObject::connect(m_dataset,SIGNAL(axisAdded(QChartAxis*)),this,SLOT(handleAxisAdded(QChartAxis*)));
48 QObject::connect(m_dataset,SIGNAL(axisAdded(QChartAxis*)),this,SLOT(handleAxisAdded(QChartAxis*)));
49 QObject::connect(m_dataset,SIGNAL(axisRemoved(QChartAxis*)),this,SLOT(handleAxisRemoved(QChartAxis*)));
49 QObject::connect(m_dataset,SIGNAL(axisRemoved(QChartAxis*)),this,SLOT(handleAxisRemoved(QChartAxis*)));
50 QObject::connect(m_dataset,SIGNAL(seriesDomainChanged(QSeries*,const Domain&)),this,SLOT(handleSeriesDomainChanged(QSeries*,const Domain&)));
50 QObject::connect(m_dataset,SIGNAL(seriesDomainChanged(QSeries*,const Domain&)),this,SLOT(handleSeriesDomainChanged(QSeries*,const Domain&)));
51 QObject::connect(m_dataset,SIGNAL(axisLabelsChanged(QChartAxis*,const QStringList&)),this,SLOT(handleAxisLabelsChanged(QChartAxis*,const QStringList&)));
51 QObject::connect(m_dataset,SIGNAL(axisLabelsChanged(QChartAxis*,const QStringList&)),this,SLOT(handleAxisLabelsChanged(QChartAxis*,const QStringList&)));
52 }
52 }
53
53
54
54
55 QRectF ChartPresenter::geometry() const
55 QRectF ChartPresenter::geometry() const
56 {
56 {
57 return m_rect;
57 return m_rect;
58 }
58 }
59
59
60 void ChartPresenter::handleGeometryChanged()
60 void ChartPresenter::handleGeometryChanged()
61 {
61 {
62 m_rect = QRectF(QPoint(0,0),m_chart->size());
62 m_rect = QRectF(QPoint(0,0),m_chart->size());
63 m_rect.adjust(m_marginSize,m_marginSize, -m_marginSize, -m_marginSize);
63 m_rect.adjust(m_marginSize,m_marginSize, -m_marginSize, -m_marginSize);
64 Q_ASSERT(m_rect.isValid());
64 Q_ASSERT(m_rect.isValid());
65 emit geometryChanged(m_rect);
65 emit geometryChanged(m_rect);
66 }
66 }
67
67
68 int ChartPresenter::margin() const
68 int ChartPresenter::margin() const
69 {
69 {
70 return m_marginSize;
70 return m_marginSize;
71 }
71 }
72
72
73 void ChartPresenter::setMargin(int margin)
73 void ChartPresenter::setMargin(int margin)
74 {
74 {
75 m_marginSize = margin;
75 m_marginSize = margin;
76 }
76 }
77
77
78 void ChartPresenter::handleAxisAdded(QChartAxis* axis)
78 void ChartPresenter::handleAxisAdded(QChartAxis* axis)
79 {
79 {
80
80
81 AxisItem* item ;
81 AxisItem* item ;
82
82
83 if(!m_options.testFlag(QChart::GridAxisAnimations))
83 if(!m_options.testFlag(QChart::GridAxisAnimations))
84 {
84 {
85 item = new AxisItem(axis==m_dataset->axisX()?AxisItem::X_AXIS : AxisItem::Y_AXIS,m_chart);
85 item = new AxisItem(axis==m_dataset->axisX()?AxisItem::X_AXIS : AxisItem::Y_AXIS,m_chart);
86 }else{
86 }else{
87 item = new AxisAnimationItem(axis==m_dataset->axisX()?AxisItem::X_AXIS : AxisItem::Y_AXIS,m_chart);
87 item = new AxisAnimationItem(axis==m_dataset->axisX()?AxisItem::X_AXIS : AxisItem::Y_AXIS,m_chart);
88 }
88 }
89
89
90 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
90 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
91 QObject::connect(axis,SIGNAL(update(QChartAxis*)),item,SLOT(handleAxisUpdate(QChartAxis*)));
91 QObject::connect(axis,SIGNAL(update(QChartAxis*)),item,SLOT(handleAxisUpdate(QChartAxis*)));
92
92
93 item->handleAxisUpdate(axis);
93 item->handleAxisUpdate(axis);
94 item->handleGeometryChanged(m_rect);
94 item->handleGeometryChanged(m_rect);
95 m_chartTheme->decorate(axis,item);
95 m_chartTheme->decorate(axis,item);
96 m_axisItems.insert(axis,item);
96 m_axisItems.insert(axis,item);
97 }
97 }
98
98
99 void ChartPresenter::handleAxisRemoved(QChartAxis* axis)
99 void ChartPresenter::handleAxisRemoved(QChartAxis* axis)
100 {
100 {
101 AxisItem* item = m_axisItems.take(axis);
101 AxisItem* item = m_axisItems.take(axis);
102 Q_ASSERT(item);
102 Q_ASSERT(item);
103 delete item;
103 delete item;
104 }
104 }
105
105
106
106
107 void ChartPresenter::handleSeriesAdded(QSeries* series)
107 void ChartPresenter::handleSeriesAdded(QSeries* series)
108 {
108 {
109 switch(series->type())
109 switch(series->type())
110 {
110 {
111 case QSeries::SeriesTypeLine: {
111 case QSeries::SeriesTypeLine: {
112 QLineSeries* lineSeries = static_cast<QLineSeries*>(series);
112 QLineSeries* lineSeries = static_cast<QLineSeries*>(series);
113 LineChartItem* item;
113 LineChartItem* item;
114 if(m_options.testFlag(QChart::SeriesAnimations)){
114 if(m_options.testFlag(QChart::SeriesAnimations)){
115 item = new LineChartAnimationItem(this,lineSeries,m_chart);
115 item = new LineChartAnimationItem(this,lineSeries,m_chart);
116 }else{
116 }else{
117 item = new LineChartItem(this,lineSeries,m_chart);
117 item = new LineChartItem(this,lineSeries,m_chart);
118 }
118 }
119 m_chartTheme->decorate(item,lineSeries,m_chartItems.count());
119 m_chartTheme->decorate(item,lineSeries,m_chartItems.count());
120 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
120 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
121 QObject::connect(lineSeries,SIGNAL(pointReplaced(int)),item,SLOT(handlePointReplaced(int)));
121 QObject::connect(lineSeries,SIGNAL(pointReplaced(int)),item,SLOT(handlePointReplaced(int)));
122 QObject::connect(lineSeries,SIGNAL(pointAdded(int)),item,SLOT(handlePointAdded(int)));
122 QObject::connect(lineSeries,SIGNAL(pointAdded(int)),item,SLOT(handlePointAdded(int)));
123 QObject::connect(lineSeries,SIGNAL(pointRemoved(int)),item,SLOT(handlePointRemoved(int)));
123 QObject::connect(lineSeries,SIGNAL(pointRemoved(int)),item,SLOT(handlePointRemoved(int)));
124 QObject::connect(lineSeries,SIGNAL(updated()),item,SLOT(handleUpdated()));
124 QObject::connect(lineSeries,SIGNAL(updated()),item,SLOT(handleUpdated()));
125 m_chartItems.insert(series,item);
125 m_chartItems.insert(series,item);
126 if(m_rect.isValid()) item->handleGeometryChanged(m_rect);
126 if(m_rect.isValid()) item->handleGeometryChanged(m_rect);
127 item->handleUpdated();
127 item->handleUpdated();
128 break;
128 break;
129 }
129 }
130
130
131 case QSeries::SeriesTypeBar: {
131 case QSeries::SeriesTypeBar: {
132 QBarSeries* barSeries = static_cast<QBarSeries*>(series);
132 QBarSeries* barSeries = static_cast<QBarSeries*>(series);
133 BarPresenter* item = new BarPresenter(barSeries,m_chart);
133 BarPresenter* item = new BarPresenter(barSeries,m_chart);
134 m_chartTheme->decorate(item,barSeries,m_chartItems.count());
134 m_chartTheme->decorate(item,barSeries,m_chartItems.count());
135 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
135 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
136 QObject::connect(barSeries,SIGNAL(changed(int)),item,SLOT(handleModelChanged(int)));
136 QObject::connect(barSeries,SIGNAL(changed(int)),item,SLOT(handleModelChanged(int)));
137 m_chartItems.insert(series,item);
137 m_chartItems.insert(series,item);
138 // m_axisXItem->setVisible(false);
138 // m_axisXItem->setVisible(false);
139 if(m_rect.isValid()) item->handleGeometryChanged(m_rect);
139 if(m_rect.isValid()) item->handleGeometryChanged(m_rect);
140 break;
140 break;
141 }
141 }
142
142
143 case QSeries::SeriesTypeStackedBar: {
143 case QSeries::SeriesTypeStackedBar: {
144
144
145 QStackedBarSeries* stackedBarSeries = static_cast<QStackedBarSeries*>(series);
145 QStackedBarSeries* stackedBarSeries = static_cast<QStackedBarSeries*>(series);
146 StackedBarPresenter* item = new StackedBarPresenter(stackedBarSeries,m_chart);
146 StackedBarPresenter* item = new StackedBarPresenter(stackedBarSeries,m_chart);
147 m_chartTheme->decorate(item,stackedBarSeries,m_chartItems.count());
147 m_chartTheme->decorate(item,stackedBarSeries,m_chartItems.count());
148 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
148 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
149 QObject::connect(stackedBarSeries,SIGNAL(changed(int)),item,SLOT(handleModelChanged(int)));
149 QObject::connect(stackedBarSeries,SIGNAL(changed(int)),item,SLOT(handleModelChanged(int)));
150 m_chartItems.insert(series,item);
150 m_chartItems.insert(series,item);
151 if(m_rect.isValid()) item->handleGeometryChanged(m_rect);
151 if(m_rect.isValid()) item->handleGeometryChanged(m_rect);
152 break;
152 break;
153 }
153 }
154
154
155 case QSeries::SeriesTypePercentBar: {
155 case QSeries::SeriesTypePercentBar: {
156
156
157 QPercentBarSeries* percentBarSeries = static_cast<QPercentBarSeries*>(series);
157 QPercentBarSeries* percentBarSeries = static_cast<QPercentBarSeries*>(series);
158 PercentBarPresenter* item = new PercentBarPresenter(percentBarSeries,m_chart);
158 PercentBarPresenter* item = new PercentBarPresenter(percentBarSeries,m_chart);
159 m_chartTheme->decorate(item,percentBarSeries ,m_chartItems.count());
159 m_chartTheme->decorate(item,percentBarSeries ,m_chartItems.count());
160 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
160 QObject::connect(this,SIGNAL(geometryChanged(const QRectF&)),item,SLOT(handleGeometryChanged(const QRectF&)));
161 QObject::connect(percentBarSeries,SIGNAL(changed(int)),item,SLOT(handleModelChanged(int)));
161 QObject::connect(percentBarSeries,SIGNAL(changed(int)),item,SLOT(handleModelChanged(int)));
162 m_chartItems.insert(series,item);
162 m_chartItems.insert(series,item);
163 if(m_rect.isValid()) item->handleGeometryChanged(m_rect);
163 if(m_rect.isValid()) item->handleGeometryChanged(m_rect);
164 break;
164 break;
165 }
165 }
166 case QSeries::SeriesTypeScatter: {
166 case QSeries::SeriesTypeScatter: {
167 QScatterSeries *scatterSeries = qobject_cast<QScatterSeries *>(series);
167 QScatterSeries *scatterSeries = qobject_cast<QScatterSeries *>(series);
168 ScatterPresenter *scatterPresenter = new ScatterPresenter(scatterSeries, m_chart);
168 ScatterPresenter *scatterPresenter = new ScatterPresenter(scatterSeries, m_chart);
169 QObject::connect(scatterPresenter, SIGNAL(clicked()), scatterSeries, SIGNAL(clicked()));
169 QObject::connect(scatterPresenter, SIGNAL(clicked(QPointF)),
170 scatterSeries, SIGNAL(clicked(QPointF)));
170 QObject::connect(this, SIGNAL(geometryChanged(const QRectF&)),
171 QObject::connect(this, SIGNAL(geometryChanged(const QRectF&)),
171 scatterPresenter, SLOT(handleGeometryChanged(const QRectF&)));
172 scatterPresenter, SLOT(handleGeometryChanged(const QRectF&)));
172 m_chartTheme->decorate(scatterPresenter, scatterSeries, m_chartItems.count());
173 m_chartTheme->decorate(scatterPresenter, scatterSeries, m_chartItems.count());
173 m_chartItems.insert(scatterSeries, scatterPresenter);
174 m_chartItems.insert(scatterSeries, scatterPresenter);
174 if(m_rect.isValid()) scatterPresenter->handleGeometryChanged(m_rect);
175 if(m_rect.isValid()) scatterPresenter->handleGeometryChanged(m_rect);
175 break;
176 break;
176 }
177 }
177 case QSeries::SeriesTypePie: {
178 case QSeries::SeriesTypePie: {
178 QPieSeries *s = qobject_cast<QPieSeries *>(series);
179 QPieSeries *s = qobject_cast<QPieSeries *>(series);
179 PiePresenter* pie = new PiePresenter(m_chart, s);
180 PiePresenter* pie = new PiePresenter(m_chart, s);
180 m_chartTheme->decorate(pie, s, m_chartItems.count());
181 m_chartTheme->decorate(pie, s, m_chartItems.count());
181 QObject::connect(this, SIGNAL(geometryChanged(const QRectF&)), pie, SLOT(handleGeometryChanged(const QRectF&)));
182 QObject::connect(this, SIGNAL(geometryChanged(const QRectF&)), pie, SLOT(handleGeometryChanged(const QRectF&)));
182
183
183 // Hide all from background when there is only piechart
184 // Hide all from background when there is only piechart
184 // TODO: refactor this ugly code... should be one setting for this
185 // TODO: refactor this ugly code... should be one setting for this
185 if (m_chartItems.count() == 0) {
186 if (m_chartItems.count() == 0) {
186 m_chart->axisX()->setAxisVisible(false);
187 m_chart->axisX()->setAxisVisible(false);
187 m_chart->axisY()->setAxisVisible(false);
188 m_chart->axisY()->setAxisVisible(false);
188 m_chart->axisX()->setGridVisible(false);
189 m_chart->axisX()->setGridVisible(false);
189 m_chart->axisY()->setGridVisible(false);
190 m_chart->axisY()->setGridVisible(false);
190 m_chart->axisX()->setLabelsVisible(false);
191 m_chart->axisX()->setLabelsVisible(false);
191 m_chart->axisY()->setLabelsVisible(false);
192 m_chart->axisY()->setLabelsVisible(false);
192 m_chart->axisX()->setShadesVisible(false);
193 m_chart->axisX()->setShadesVisible(false);
193 m_chart->axisY()->setShadesVisible(false);
194 m_chart->axisY()->setShadesVisible(false);
194 m_chart->setChartBackgroundBrush(Qt::transparent);
195 m_chart->setChartBackgroundBrush(Qt::transparent);
195 }
196 }
196
197
197 m_chartItems.insert(series, pie);
198 m_chartItems.insert(series, pie);
198 pie->handleGeometryChanged(m_rect);
199 pie->handleGeometryChanged(m_rect);
199 break;
200 break;
200 }
201 }
201 default: {
202 default: {
202 qDebug()<< "Series type" << series->type() << "not implemented.";
203 qDebug()<< "Series type" << series->type() << "not implemented.";
203 break;
204 break;
204 }
205 }
205 }
206 }
206 }
207 }
207
208
208 void ChartPresenter::handleSeriesRemoved(QSeries* series)
209 void ChartPresenter::handleSeriesRemoved(QSeries* series)
209 {
210 {
210 ChartItem* item = m_chartItems.take(series);
211 ChartItem* item = m_chartItems.take(series);
211 delete item;
212 delete item;
212 }
213 }
213
214
214 void ChartPresenter::handleSeriesDomainChanged(QSeries* series, const Domain& domain)
215 void ChartPresenter::handleSeriesDomainChanged(QSeries* series, const Domain& domain)
215 {
216 {
216 m_chartItems.value(series)->handleDomainChanged(domain);
217 m_chartItems.value(series)->handleDomainChanged(domain);
217 }
218 }
218
219
219 void ChartPresenter::handleAxisLabelsChanged(QChartAxis* axis,const QStringList& labels)
220 void ChartPresenter::handleAxisLabelsChanged(QChartAxis* axis,const QStringList& labels)
220 {
221 {
221 m_axisItems.value(axis)->handleLabelsChanged(axis,labels);
222 m_axisItems.value(axis)->handleLabelsChanged(axis,labels);
222 }
223 }
223
224
224 void ChartPresenter::setChartTheme(QChart::ChartTheme theme)
225 void ChartPresenter::setChartTheme(QChart::ChartTheme theme)
225 {
226 {
226 delete m_chartTheme;
227 delete m_chartTheme;
227
228
228 m_chartTheme = ChartTheme::createTheme(theme);
229 m_chartTheme = ChartTheme::createTheme(theme);
229
230
230 m_chartTheme->decorate(m_chart);
231 m_chartTheme->decorate(m_chart);
231 QMapIterator<QSeries*,ChartItem*> i(m_chartItems);
232 QMapIterator<QSeries*,ChartItem*> i(m_chartItems);
232
233
233 int index=0;
234 int index=0;
234 while (i.hasNext()) {
235 while (i.hasNext()) {
235 i.next();
236 i.next();
236 m_chartTheme->decorate(i.value(),i.key(),index);
237 m_chartTheme->decorate(i.value(),i.key(),index);
237 index++;
238 index++;
238 }
239 }
239
240
240 QMapIterator<QChartAxis*,AxisItem*> j(m_axisItems);
241 QMapIterator<QChartAxis*,AxisItem*> j(m_axisItems);
241 while (j.hasNext()) {
242 while (j.hasNext()) {
242 j.next();
243 j.next();
243 m_chartTheme->decorate(j.key(),j.value());
244 m_chartTheme->decorate(j.key(),j.value());
244 }
245 }
245 }
246 }
246
247
247 QChart::ChartTheme ChartPresenter::chartTheme()
248 QChart::ChartTheme ChartPresenter::chartTheme()
248 {
249 {
249 return m_chartTheme->id();
250 return m_chartTheme->id();
250 }
251 }
251
252
252 void ChartPresenter::setAnimationOptions(QChart::AnimationOptions options)
253 void ChartPresenter::setAnimationOptions(QChart::AnimationOptions options)
253 {
254 {
254 if(m_options!=options) {
255 if(m_options!=options) {
255
256
256 m_options=options;
257 m_options=options;
257
258
258 //recreate elements
259 //recreate elements
259
260
260 QList<QChartAxis*> axisList = m_axisItems.uniqueKeys();
261 QList<QChartAxis*> axisList = m_axisItems.uniqueKeys();
261 QList<QSeries*> seriesList = m_chartItems.uniqueKeys();
262 QList<QSeries*> seriesList = m_chartItems.uniqueKeys();
262
263
263 foreach(QChartAxis* axis, axisList) {
264 foreach(QChartAxis* axis, axisList) {
264 handleAxisRemoved(axis);
265 handleAxisRemoved(axis);
265 handleAxisAdded(axis);
266 handleAxisAdded(axis);
266 }
267 }
267 foreach(QSeries* series, seriesList) {
268 foreach(QSeries* series, seriesList) {
268 handleSeriesRemoved(series);
269 handleSeriesRemoved(series);
269 handleSeriesAdded(series);
270 handleSeriesAdded(series);
270 }
271 }
271
272
272 //now reintialize view data
273 //now reintialize view data
273 //TODO: make it more nice
274 //TODO: make it more nice
274 m_dataset->setDomain(m_dataset->domainIndex());
275 m_dataset->setDomain(m_dataset->domainIndex());
275 }
276 }
276 }
277 }
277
278
278 QChart::AnimationOptions ChartPresenter::animationOptions() const
279 QChart::AnimationOptions ChartPresenter::animationOptions() const
279 {
280 {
280 return m_options;
281 return m_options;
281 }
282 }
282
283
283
284
284 #include "moc_chartpresenter_p.cpp"
285 #include "moc_chartpresenter_p.cpp"
285
286
286 QTCOMMERCIALCHART_END_NAMESPACE
287 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,222 +1,277
1 #include "qscatterseries.h"
1 #include "qscatterseries.h"
2 #include "scatterseries_p.h"
2 #include "scatterseries_p.h"
3 #include "qchart.h"
3 #include "qchart.h"
4
4
5 /*!
5 /*!
6 \class QScatterSeries
6 \class QScatterSeries
7 \brief QtCommercial Chart series API for showing scatter series.
7 \brief QtCommercial Chart series API for showing scatter series.
8
8
9 \mainclass
9 \mainclass
10
10
11 Example on how to create a chart with scatter series:
11 Example on how to create a chart with scatter series:
12 \snippet ../example/scatter/main.cpp 1
12 \snippet ../example/scatter/main.cpp 1
13
13
14 The example code would result the following:
14 The example code would result the following:
15
15
16 \image scatter_example1.jpg
16 \image scatter_example1.jpg
17 */
17 */
18
18
19 /*!
19 /*!
20 \enum QScatterSeries::MarkerShape
20 \enum QScatterSeries::MarkerShape
21
21
22 This enum describes the shape used when rendering marker items.
22 This enum describes the shape used when rendering marker items.
23
23
24 \value MarkerShapeDefault
24 \value MarkerShapeDefault
25 \value MarkerShapePoint
25 \value MarkerShapePoint
26 \value MarkerShapeX
26 \value MarkerShapeX
27 \value MarkerShapeRectangle
27 \value MarkerShapeRectangle
28 \value MarkerShapeTiltedRectangle
28 \value MarkerShapeTiltedRectangle
29 \value MarkerShapeTriangle
29 \value MarkerShapeTriangle
30 \value MarkerShapeCircle
30 \value MarkerShapeCircle
31 */
31 */
32
32
33 /*!
33 /*!
34 \fn QChartSeriesType QScatterSeries::type() const
34 \fn QChartSeriesType QScatterSeries::type() const
35 \brief Returns QChartSeries::SeriesTypeScatter.
35 \brief Returns QChartSeries::SeriesTypeScatter.
36 */
36 */
37
37
38 /*!
38 /*!
39 \fn void QScatterSeries::clicked()
39 \fn void QScatterSeries::clicked(QPointF coordinate)
40 \brief TODO
40 User clicked the scatter series. Note that the \a coordinate is the chart coordinate that the
41 click occurred on; not necessarily a data point coordinate. To find the corresponding (closest)
42 data point you can use closestPoint().
41 */
43 */
42
44
43 /*!
45 /*!
44 \fn void QScatterSeries::changed()
46 \fn void QScatterSeries::changed()
45 \brief TODO
47 \brief TODO
46 */
48 */
47
49
48 QTCOMMERCIALCHART_BEGIN_NAMESPACE
50 QTCOMMERCIALCHART_BEGIN_NAMESPACE
49
51
50 QScatterSeriesPrivate::QScatterSeriesPrivate() :
52 QScatterSeriesPrivate::QScatterSeriesPrivate() :
51 m_data(QList<QPointF>()),
53 m_data(QList<QPointF>()),
52 m_markerPen(QPen(QColor::Invalid)),
54 m_markerPen(QPen(QColor::Invalid)),
53 m_markerBrush(QBrush(QColor::Invalid)),
55 m_markerBrush(QBrush(QColor::Invalid)),
54 m_markerShape(QScatterSeries::MarkerShapeDefault)
56 m_markerShape(QScatterSeries::MarkerShapeDefault)
55 {
57 {
56 }
58 }
57
59
58 /*!
60 /*!
59 Constructs a series object which is a child of \a parent.
61 Constructs a series object which is a child of \a parent.
60 */
62 */
61 QScatterSeries::QScatterSeries(QObject *parent) :
63 QScatterSeries::QScatterSeries(QObject *parent) :
62 QSeries(parent),
64 QSeries(parent),
63 d(new QScatterSeriesPrivate())
65 d(new QScatterSeriesPrivate())
64 {
66 {
65 }
67 }
66
68
67 /*!
69 /*!
68 Destroys the object. Note that adding series to QChart transfers the ownership to the chart.
70 Destroys the object. Note that adding series to QChart transfers the ownership to the chart.
69 */
71 */
70 QScatterSeries::~QScatterSeries()
72 QScatterSeries::~QScatterSeries()
71 {
73 {
72 delete d;
74 delete d;
73 }
75 }
74
76
75 /*!
77 /*!
76 Add single data point with \a x and \a y coordinates to the series.
78 Add single data point with \a x and \a y coordinates to the series.
77 */
79 */
78 void QScatterSeries::add(qreal x, qreal y)
80 void QScatterSeries::add(qreal x, qreal y)
79 {
81 {
80 d->m_data.append(QPointF(x, y));
82 d->m_data.append(QPointF(x, y));
81 emit changed();
83 emit changed();
82 }
84 }
83
85
84 /*!
86 /*!
85 Add single data point with \a value to the series.
87 Add single data point with \a value to the series.
86 */
88 */
87 void QScatterSeries::add(QPointF value)
89 void QScatterSeries::add(QPointF value)
88 {
90 {
89 d->m_data.append(value);
91 d->m_data.append(value);
90 emit changed();
92 emit changed();
91 }
93 }
92
94
93 /*!
95 /*!
94 Add list of \a points to the series.
96 Add list of \a points to the series.
95 */
97 */
96 void QScatterSeries::add(QList<QPointF> points)
98 void QScatterSeries::add(QList<QPointF> points)
97 {
99 {
98 d->m_data.append(points);
100 d->m_data.append(points);
99 emit changed();
101 emit changed();
100 }
102 }
101
103
102 /*!
104 /*!
103 Stream operator for adding a data point with \a value to the series.
105 Stream operator for adding a data point with \a value to the series.
104 \sa add()
106 \sa add()
105
107
106 For example:
108 For example:
107 \snippet ../example/scatter/main.cpp 3
109 \snippet ../example/scatter/main.cpp 3
108 */
110 */
109 QScatterSeries& QScatterSeries::operator << (const QPointF &value)
111 QScatterSeries& QScatterSeries::operator << (const QPointF &value)
110 {
112 {
111 d->m_data.append(value);
113 d->m_data.append(value);
112 emit changed();
114 emit changed();
113 return *this;
115 return *this;
114 }
116 }
115
117
116 /*!
118 /*!
117 Stream operator for adding a list of points to the series.
119 Stream operator for adding a list of points to the series.
118 \sa add()
120 \sa add()
119 */
121 */
120 QScatterSeries& QScatterSeries::operator << (QList<QPointF> value)
122 QScatterSeries& QScatterSeries::operator << (QList<QPointF> value)
121 {
123 {
122 d->m_data.append(value);
124 d->m_data.append(value);
123 emit changed();
125 emit changed();
124 return *this;
126 return *this;
125 }
127 }
126
128
127 /*!
129 /*!
128 Replaces the data of the series with the given list of data \a points.
130 Replaces the data of the series with the given list of data \a points.
129 */
131 */
130 void QScatterSeries::setData(QList<QPointF> points)
132 void QScatterSeries::setData(QList<QPointF> points)
131 {
133 {
132 d->m_data = points;
134 d->m_data = points;
133 emit changed();
135 emit changed();
134 }
136 }
135
137
136 /*!
138 /*!
137 Returns the current list of data points of the series.
139 Returns the current list of data points of the series.
138 */
140 */
139 QList<QPointF> QScatterSeries::data()
141 QList<QPointF> QScatterSeries::data()
140 {
142 {
141 return d->m_data;
143 return d->m_data;
142 }
144 }
143
145
144 /*!
146 /*!
147 Remove the data point at \a pointIndex. Returns true if a point was removed, false if the point
148 at \a pointIndex does not exist on the series.
149 */
150 bool QScatterSeries::removeAt(int pointIndex)
151 {
152 if (pointIndex >=0 && pointIndex < d->m_data.count()) {
153 d->m_data.removeAt(pointIndex);
154 emit changed();
155 return true;
156 }
157 return false;
158 }
159
160 /*!
161 Remove all occurrences of \a point from the series and returns the number of points removed.
162 */
163 int QScatterSeries::removeAll(QPointF point)
164 {
165 int count = d->m_data.removeAll(point);
166 emit changed();
167 return count;
168 }
169
170 /*!
171 Remove all data points from the series.
172 */
173 void QScatterSeries::clear()
174 {
175 d->m_data.clear();
176 emit changed();
177 }
178
179 /*!
180 Returns the index of the data point that is closest to \a coordinate. If several data points
181 are at the same distance from the \a coordinate, returns the last one. If no points exist,
182 returns -1.
183 */
184 int QScatterSeries::closestPoint(QPointF coordinate)
185 {
186 qreal distance(-1);
187 int pointIndex(-1);
188 for (int i(0); i < d->m_data.count(); i++) {
189 QPointF dataPoint = d->m_data.at(i);
190 QPointF difference = dataPoint - coordinate;
191 if (i == 0 || difference.manhattanLength() <= distance) {
192 distance = difference.manhattanLength();
193 pointIndex = i;
194 }
195 }
196 return pointIndex;
197 }
198
199 /*!
145 Overrides the default pen used for drawing a marker item with a user defined \a pen. The
200 Overrides the default pen used for drawing a marker item with a user defined \a pen. The
146 default pen is defined by chart theme setting.
201 default pen is defined by chart theme setting.
147
202
148 For example:
203 For example:
149 \snippet ../example/scatter/main.cpp 5
204 \snippet ../example/scatter/main.cpp 5
150
205
151 Would present your scatter markers with an opaque, uglyish green outlines instead of the
206 Would present your scatter markers with an opaque, uglyish green outlines instead of the
152 beatiful markers defined by the chart's theme:
207 beatiful markers defined by the chart's theme:
153 \image scatter_example_pen.jpg
208 \image scatter_example_pen.jpg
154
209
155 \sa setBrush()
210 \sa setBrush()
156 \sa QChart::setChartTheme()
211 \sa QChart::setChartTheme()
157 */
212 */
158 void QScatterSeries::setPen(QPen pen)
213 void QScatterSeries::setPen(QPen pen)
159 {
214 {
160 d->m_markerPen = pen;
215 d->m_markerPen = pen;
161 }
216 }
162
217
163 /*!
218 /*!
164 Returns the pen used for drawing markers.
219 Returns the pen used for drawing markers.
165 */
220 */
166 QPen QScatterSeries::pen()
221 QPen QScatterSeries::pen()
167 {
222 {
168 return d->m_markerPen;
223 return d->m_markerPen;
169 }
224 }
170
225
171 /*!
226 /*!
172 Overrides the default brush of the marker items with a user defined \a brush. The default brush
227 Overrides the default brush of the marker items with a user defined \a brush. The default brush
173 is defined by chart theme setting.
228 is defined by chart theme setting.
174
229
175 For example:
230 For example:
176 \snippet ../example/scatter/main.cpp 4
231 \snippet ../example/scatter/main.cpp 4
177
232
178 Would fill your scatter markers with an opaque red color:
233 Would fill your scatter markers with an opaque red color:
179 \image scatter_example_brush.jpg
234 \image scatter_example_brush.jpg
180
235
181 \sa setPen()
236 \sa setPen()
182 \sa QChart::setChartTheme()
237 \sa QChart::setChartTheme()
183 */
238 */
184 void QScatterSeries::setBrush(QBrush brush)
239 void QScatterSeries::setBrush(QBrush brush)
185 {
240 {
186 d->m_markerBrush = brush;
241 d->m_markerBrush = brush;
187 }
242 }
188
243
189 /*!
244 /*!
190 Returns the brush used for drawing markers.
245 Returns the brush used for drawing markers.
191 */
246 */
192 QBrush QScatterSeries::brush()
247 QBrush QScatterSeries::brush()
193 {
248 {
194 return d->m_markerBrush;
249 return d->m_markerBrush;
195 }
250 }
196
251
197 /*!
252 /*!
198 Overrides the default shape of the marker items with a user defined \a shape. The default shape
253 Overrides the default shape of the marker items with a user defined \a shape. The default shape
199 is defined by chart theme setting.
254 is defined by chart theme setting.
200
255
201 For example:
256 For example:
202 \snippet ../example/scatter/main.cpp 6
257 \snippet ../example/scatter/main.cpp 6
203
258
204 Would make your scatter marker items rectangle:
259 Would make your scatter marker items rectangle:
205 \image scatter_example_shape.jpg
260 \image scatter_example_shape.jpg
206 */
261 */
207 void QScatterSeries::setShape(MarkerShape shape)
262 void QScatterSeries::setShape(MarkerShape shape)
208 {
263 {
209 d->m_markerShape = shape;
264 d->m_markerShape = shape;
210 }
265 }
211
266
212 /*!
267 /*!
213 Returns the shape used for drawing markers.
268 Returns the shape used for drawing markers.
214 */
269 */
215 QScatterSeries::MarkerShape QScatterSeries::shape()
270 QScatterSeries::MarkerShape QScatterSeries::shape()
216 {
271 {
217 return (QScatterSeries::MarkerShape) d->m_markerShape;
272 return (QScatterSeries::MarkerShape) d->m_markerShape;
218 }
273 }
219
274
220 #include "moc_qscatterseries.cpp"
275 #include "moc_qscatterseries.cpp"
221
276
222 QTCOMMERCIALCHART_END_NAMESPACE
277 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,68 +1,72
1 #ifndef QSCATTERSERIES_H
1 #ifndef QSCATTERSERIES_H
2 #define QSCATTERSERIES_H
2 #define QSCATTERSERIES_H
3
3
4 #include "qseries.h"
4 #include "qseries.h"
5 #include <QRectF>
5 #include <QRectF>
6 #include <QColor>
6 #include <QColor>
7
7
8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9 class QScatterSeriesPrivate;
9 class QScatterSeriesPrivate;
10
10
11 class QTCOMMERCIALCHART_EXPORT QScatterSeries : public QSeries
11 class QTCOMMERCIALCHART_EXPORT QScatterSeries : public QSeries
12 {
12 {
13 Q_OBJECT
13 Q_OBJECT
14
14
15 public:
15 public:
16 enum MarkerShape {
16 enum MarkerShape {
17 // TODO: to be defined by the graphics design
17 // TODO: to be defined by the graphics design
18 // TODO: marker shapes: "x", star, rectangle, tilted rect, triangle, circle, dot
18 // TODO: marker shapes: "x", star, rectangle, tilted rect, triangle, circle, dot
19 MarkerShapeDefault = 0,
19 MarkerShapeDefault = 0,
20 MarkerShapePoint,
20 MarkerShapePoint,
21 MarkerShapeX,
21 MarkerShapeX,
22 MarkerShapeRectangle,
22 MarkerShapeRectangle,
23 MarkerShapeTiltedRectangle,
23 MarkerShapeTiltedRectangle,
24 MarkerShapeTriangle,
24 MarkerShapeTriangle,
25 MarkerShapeCircle
25 MarkerShapeCircle
26 };
26 };
27
27
28 public:
28 public:
29 QScatterSeries(QObject *parent = 0);
29 QScatterSeries(QObject *parent = 0);
30 ~QScatterSeries();
30 ~QScatterSeries();
31
31
32 public: // from QChartSeries
32 public: // from QChartSeries
33 QSeriesType type() const { return QSeries::SeriesTypeScatter; }
33 QSeriesType type() const { return QSeries::SeriesTypeScatter; }
34
34
35 public:
35 public:
36 void add(qreal x, qreal y);
36 void add(qreal x, qreal y);
37 void add(QPointF value);
37 void add(QPointF value);
38 void add(QList<QPointF> points);
38 void add(QList<QPointF> points);
39 void setData(QList<QPointF> points);
39 void setData(QList<QPointF> points);
40 QScatterSeries& operator << (const QPointF &value);
40 QScatterSeries& operator << (const QPointF &value);
41 QScatterSeries& operator << (QList<QPointF> points);
41 QScatterSeries& operator << (QList<QPointF> points);
42 QList<QPointF> data();
42 QList<QPointF> data();
43 //TODO: insert, replace, remove, clear...?
43 bool removeAt(int pointIndex);
44 int removeAll(QPointF point);
45 void clear();
46 int closestPoint(QPointF coordinate);
47 //TODO: insert, replace...?
44
48
45 QPen pen();
49 QPen pen();
46 void setPen(QPen pen);
50 void setPen(QPen pen);
47 QBrush brush();
51 QBrush brush();
48 void setBrush(QBrush brush);
52 void setBrush(QBrush brush);
49 MarkerShape shape();
53 MarkerShape shape();
50 void setShape(MarkerShape shape);
54 void setShape(MarkerShape shape);
51 // TODO: marker size?
55 // TODO: marker size?
52
56
53 Q_SIGNALS:
57 Q_SIGNALS:
54 void clicked(/* TODO: parameters? */);
58 void clicked(QPointF coordinate);
55 // TODO: move to PIMPL for simplicity or does the user ever need changed signals?
59 // TODO: move to PIMPL for simplicity or does the user ever need changed signals?
56 // TODO: more finegrained signaling for performance reasons
60 // TODO: more finegrained signaling for performance reasons
57 // (check QPieSeries implementation with change sets)
61 // (check QPieSeries implementation with change sets)
58 void changed();
62 void changed();
59
63
60 private:
64 private:
61 Q_DECLARE_PRIVATE(QScatterSeries)
65 Q_DECLARE_PRIVATE(QScatterSeries)
62 Q_DISABLE_COPY(QScatterSeries)
66 Q_DISABLE_COPY(QScatterSeries)
63 QScatterSeriesPrivate *const d;
67 QScatterSeriesPrivate *const d;
64 };
68 };
65
69
66 QTCOMMERCIALCHART_END_NAMESPACE
70 QTCOMMERCIALCHART_END_NAMESPACE
67
71
68 #endif // QSCATTERSERIES_H
72 #endif // QSCATTERSERIES_H
@@ -1,146 +1,153
1 #include "scatterpresenter_p.h"
1 #include "scatterpresenter_p.h"
2 #include "qscatterseries.h"
2 #include "qscatterseries.h"
3 #include "chartpresenter_p.h"
3 #include "chartpresenter_p.h"
4 #include <QPen>
4 #include <QPen>
5 #include <QPainter>
5 #include <QPainter>
6 #include <QGraphicsScene>
6 #include <QGraphicsScene>
7 #include <QGraphicsSceneMouseEvent>
7 #include <QGraphicsSceneMouseEvent>
8 #include <QGraphicsDropShadowEffect>
8 #include <QGraphicsDropShadowEffect>
9 #include <QDebug>
9 #include <QDebug>
10 #include <QTime>
10 #include <QTime>
11
11
12 QTCOMMERCIALCHART_BEGIN_NAMESPACE
12 QTCOMMERCIALCHART_BEGIN_NAMESPACE
13
13
14 ScatterPresenter::ScatterPresenter(QScatterSeries *series, QGraphicsObject *parent) :
14 ScatterPresenter::ScatterPresenter(QScatterSeries *series, QGraphicsObject *parent) :
15 ChartItem(parent),
15 ChartItem(parent),
16 m_series(series),
16 m_series(series),
17 m_boundingRect(),
17 m_boundingRect(),
18 m_visibleChartArea()
18 m_visibleChartArea()
19 {
19 {
20 if (parent)
20 if (parent)
21 m_boundingRect = parent->boundingRect();
21 m_boundingRect = parent->boundingRect();
22
22
23 if (series) {
23 if (series) {
24 connect(series, SIGNAL(changed()), this, SLOT(handleModelChanged()));
24 connect(series, SIGNAL(changed()), this, SLOT(handleModelChanged()));
25 }
25 }
26
26
27 setZValue(ChartPresenter::ScatterSeriesZValue);
27 setZValue(ChartPresenter::ScatterSeriesZValue);
28
28
29 // TODO: how to draw a drop shadow?
29 // TODO: how to draw a drop shadow?
30 // QGraphicsDropShadowEffect *dropShadow = new QGraphicsDropShadowEffect();
30 // QGraphicsDropShadowEffect *dropShadow = new QGraphicsDropShadowEffect();
31 // dropShadow->setOffset(2.0);
31 // dropShadow->setOffset(2.0);
32 // dropShadow->setBlurRadius(2.0);
32 // dropShadow->setBlurRadius(2.0);
33 // setGraphicsEffect(dropShadow);
33 // setGraphicsEffect(dropShadow);
34 }
34 }
35
35
36 void ScatterPresenter::handleDomainChanged(const Domain& domain)
36 void ScatterPresenter::handleDomainChanged(const Domain& domain)
37 {
37 {
38 m_visibleChartArea = domain;
38 m_visibleChartArea = domain;
39 changeGeometry();
39 changeGeometry();
40 }
40 }
41
41
42 void ScatterPresenter::handleGeometryChanged(const QRectF& rect)
42 void ScatterPresenter::handleGeometryChanged(const QRectF& rect)
43 {
43 {
44 m_boundingRect = rect;
44 m_boundingRect = rect.translated(-rect.topLeft());
45 changeGeometry();
45 changeGeometry();
46 setPos(rect.topLeft());
46 }
47 }
47
48
48 void ScatterPresenter::handleModelChanged()
49 void ScatterPresenter::handleModelChanged()
49 {
50 {
50 // TODO: more fine grained modelChanged signaling
51 // TODO: more fine grained modelChanged signaling
51 changeGeometry();
52 changeGeometry();
52 }
53 }
53
54
54 void ScatterPresenter::paint(QPainter *painter, const QStyleOptionGraphicsItem */*option*/, QWidget */*widget*/)
55 void ScatterPresenter::paint(QPainter *painter, const QStyleOptionGraphicsItem */*option*/, QWidget */*widget*/)
55 {
56 {
56 painter->save();
57 painter->save();
57 painter->setClipRect(m_boundingRect);
58 painter->setClipRect(m_boundingRect);
58
59
59 // TODO: how to draw a drop shadow?
60 // TODO: how to draw a drop shadow?
60 // Now using a custom implementation for drop shadow instead of QGraphicsDropShadowEffect.
61 // Now using a custom implementation for drop shadow instead of QGraphicsDropShadowEffect.
61 // It seems QGraphicsDropShadowEffect is quite heavy, at least on windows without open gl.
62 // It seems QGraphicsDropShadowEffect is quite heavy, at least on windows without open gl.
62 QPen dropShadowPen(QColor(0, 0, 0, 70));
63 QPen dropShadowPen(QColor(0, 0, 0, 70));
63 dropShadowPen.setWidth(3);
64 dropShadowPen.setWidth(3);
64 painter->setPen(dropShadowPen);
65 painter->setPen(dropShadowPen);
65 painter->setBrush(dropShadowPen.color());
66 painter->setBrush(dropShadowPen.color());
66 // painter->setRenderHint(QPainter::Antialiasing);
67 // painter->setRenderHint(QPainter::Antialiasing);
67 painter->drawPath(m_path.translated(2, 2));
68 painter->drawPath(m_path.translated(2, 2));
68
69
69 // Paint the shape
70 // Paint the shape
70 // The custom settings in series override those defined by the theme
71 // The custom settings in series override those defined by the theme
71 QPen pen = m_markerPen;
72 QPen pen = m_markerPen;
72 if (m_series->pen().color().isValid())
73 if (m_series->pen().color().isValid())
73 pen = m_series->pen();
74 pen = m_series->pen();
74 painter->setPen(pen);
75 painter->setPen(pen);
75 if (m_series->brush().color().isValid())
76 if (m_series->brush().color().isValid())
76 painter->setBrush(m_series->brush());
77 painter->setBrush(m_series->brush());
77 else
78 else
78 painter->setBrush(m_markerBrush);
79 painter->setBrush(m_markerBrush);
79
80
80 // If either pen or brush is opaque, we need to draw the polygons one-by-one
81 // If either pen or brush is opaque, we need to draw the polygons one-by-one
81 if (painter->pen().color().alpha() < 255 || painter->brush().color().alpha() < 255) {
82 if (painter->pen().color().alpha() < 255 || painter->brush().color().alpha() < 255) {
82 foreach (QPolygonF pol, m_path.toSubpathPolygons())
83 foreach (QPolygonF pol, m_path.toSubpathPolygons())
83 painter->drawPolygon(pol);
84 painter->drawPolygon(pol);
84 } else {
85 } else {
85 painter->drawPath(m_path);
86 painter->drawPath(m_path);
86 }
87 }
87
88
88 painter->restore();
89 painter->restore();
89 }
90 }
90
91
91 void ScatterPresenter::mousePressEvent(QGraphicsSceneMouseEvent *event)
92 void ScatterPresenter::mousePressEvent(QGraphicsSceneMouseEvent *event)
92 {
93 {
93 qDebug() << "ScatterPresenter::mousePressEvent" << event << " cont: "
94 // Empty implementation to grab mouse release events for this item
94 << m_path.contains(event->lastPos());
95 Q_UNUSED(event)
96 }
95
97
96 if (m_path.contains(event->lastPos()))
98 void ScatterPresenter::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
97 emit clicked();
99 {
100 QPointF clickedPoint(
101 m_visibleChartArea.m_minX + (event->lastPos().x() / m_boundingRect.width()) * m_visibleChartArea.spanX(),
102 m_visibleChartArea.m_maxY - (event->lastPos().y() / m_boundingRect.height()) * m_visibleChartArea.spanY());
103 emit clicked(clickedPoint);
98 }
104 }
99
105
100 void ScatterPresenter::changeGeometry()
106 void ScatterPresenter::changeGeometry()
101 {
107 {
102 if (m_boundingRect.isValid()) {
108 if (m_boundingRect.isValid()) {
103 prepareGeometryChange();
109 prepareGeometryChange();
104 qreal scalex = m_boundingRect.width() / m_visibleChartArea.spanX();
110 qreal scalex = m_boundingRect.width() / m_visibleChartArea.spanX();
105 qreal scaley = m_boundingRect.height() / m_visibleChartArea.spanY();
111 qreal scaley = m_boundingRect.height() / m_visibleChartArea.spanY();
106
112
107 int shape = m_series->shape();
113 int shape = m_series->shape();
108 m_path = QPainterPath();
114 m_path = QPainterPath();
109 m_path.setFillRule(Qt::WindingFill);
115 m_path.setFillRule(Qt::WindingFill);
116 const qreal size(9); // TODO: user defined size?
110
117
111 foreach (QPointF point, m_series->data()) {
118 foreach (QPointF point, m_series->data()) {
112 // Convert relative coordinates to absolute pixel coordinates that can be used for drawing
119 // Convert relative coordinates to absolute pixel coordinates that can be used for drawing
113 qreal x = m_boundingRect.left() + point.x() * scalex - m_visibleChartArea.m_minX * scalex;
120 qreal x = point.x() * scalex - m_visibleChartArea.m_minX * scalex - size / 2;
114 qreal y = m_boundingRect.bottom() - point.y() * scaley + m_visibleChartArea.m_minY * scaley;
121 qreal y = m_boundingRect.height() - point.y() * scaley + m_visibleChartArea.m_minY * scaley - size / 2;
115
122
116 if (scene()->width() > x && scene()->height() > y) {
123 if (x < scene()->width() && y < scene()->height()) {
117 switch (shape) {
124 switch (shape) {
118 case QScatterSeries::MarkerShapeDefault:
125 case QScatterSeries::MarkerShapeDefault:
119 // Fallthrough, defaults to circle
126 // Fallthrough, defaults to circle
120 case QScatterSeries::MarkerShapeCircle:
127 case QScatterSeries::MarkerShapeCircle:
121 m_path.addEllipse(x, y, 9, 9);
128 m_path.addEllipse(x, y, size, size);
122 break;
129 break;
123 case QScatterSeries::MarkerShapePoint:
130 case QScatterSeries::MarkerShapePoint:
124 m_path.addEllipse(x, y, 2, 2);
131 m_path.addEllipse(x, y, 2, 2);
125 break;
132 break;
126 case QScatterSeries::MarkerShapeRectangle:
133 case QScatterSeries::MarkerShapeRectangle:
127 m_path.addRect(x, y, 9, 9);
134 m_path.addRect(x, y, size, size);
128 break;
135 break;
129 case QScatterSeries::MarkerShapeTiltedRectangle: {
136 case QScatterSeries::MarkerShapeTiltedRectangle: {
130 // TODO: tilt the rectangle
137 // TODO: tilt the rectangle
131 m_path.addRect(x, y, 9, 9);
138 m_path.addRect(x, y, size, size);
132 break;
139 break;
133 }
140 }
134 default:
141 default:
135 // TODO: implement the rest of the shapes
142 // TODO: implement the rest of the shapes
136 Q_ASSERT(false);
143 Q_ASSERT(false);
137 break;
144 break;
138 }
145 }
139 }
146 }
140 }
147 }
141 }
148 }
142 }
149 }
143
150
144 #include "moc_scatterpresenter_p.cpp"
151 #include "moc_scatterpresenter_p.cpp"
145
152
146 QTCOMMERCIALCHART_END_NAMESPACE
153 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,50 +1,47
1 #ifndef SCATTERPRESENTER_H
1 #ifndef SCATTERPRESENTER_H
2 #define SCATTERPRESENTER_H
2 #define SCATTERPRESENTER_H
3
3
4 #include "qchartglobal.h"
4 #include "qchartglobal.h"
5 #include "chartitem_p.h"
5 #include "chartitem_p.h"
6 #include <QObject>
6 #include <QObject>
7 #include <QPen>
7 #include <QPen>
8
8
9 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9 QTCOMMERCIALCHART_BEGIN_NAMESPACE
10
10
11 class QScatterSeries;
11 class QScatterSeries;
12
12
13 /*!
14 * The "business logic" of scatter series. This is a QObject that does not have a parent QObject.
15 * The QGraphicsItem parent owns the object instead.
16 */
17 class ScatterPresenter : public QObject, public ChartItem
13 class ScatterPresenter : public QObject, public ChartItem
18 {
14 {
19 Q_OBJECT
15 Q_OBJECT
20 public:
16 public:
21 explicit ScatterPresenter(QScatterSeries *series, QGraphicsObject *parent = 0);
17 explicit ScatterPresenter(QScatterSeries *series, QGraphicsObject *parent = 0);
22
18
23 public: // from ChartItem
19 public: // from ChartItem
24 QRectF boundingRect() const { return m_path.boundingRect(); }
20 QRectF boundingRect() const { return m_path.controlPointRect(); }
25 QPainterPath shape() const { return m_path; }
21 QPainterPath shape() const { return m_path; }
26 void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *);
22 void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *);
27 void mousePressEvent (QGraphicsSceneMouseEvent * event);
23 void mousePressEvent (QGraphicsSceneMouseEvent * event);
24 void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
28
25
29 Q_SIGNALS:
26 Q_SIGNALS:
30 void clicked();
27 void clicked(QPointF coordinates);
31
28
32 public Q_SLOTS:
29 public Q_SLOTS:
33 void handleDomainChanged(const Domain& domain);
30 void handleDomainChanged(const Domain& domain);
34 void handleGeometryChanged(const QRectF& rect);
31 void handleGeometryChanged(const QRectF& rect);
35 void handleModelChanged();
32 void handleModelChanged();
36
33
37 public:
34 public:
38 void changeGeometry();
35 void changeGeometry();
39
36
40 QScatterSeries *m_series;
37 QScatterSeries *m_series;
41 QRectF m_boundingRect;
38 QRectF m_boundingRect;
42 Domain m_visibleChartArea;
39 Domain m_visibleChartArea;
43 QPen m_markerPen;
40 QPen m_markerPen;
44 QBrush m_markerBrush;
41 QBrush m_markerBrush;
45 QPainterPath m_path;
42 QPainterPath m_path;
46 };
43 };
47
44
48 QTCOMMERCIALCHART_END_NAMESPACE
45 QTCOMMERCIALCHART_END_NAMESPACE
49
46
50 #endif // SCATTERPRESENTER_H
47 #endif // SCATTERPRESENTER_H
General Comments 0
You need to be logged in to leave comments. Login now