From 45d3de5e814af983c29ff3851ceef4aebdd39330 2012-01-24 12:31:20 From: Tero Ahola Date: 2012-01-24 12:31:20 Subject: [PATCH] Refactored series creation with QChart --- diff --git a/src/qchart.cpp b/src/qchart.cpp index 1e69918..1179bb9 100644 --- a/src/qchart.cpp +++ b/src/qchart.cpp @@ -93,15 +93,13 @@ void QChart::addSeries(QChartSeries* series) } } -QChartSeries* QChart::createSeries(QList x, QList y, QChartSeries::QChartSeriesType type) +QChartSeries* QChart::createSeries(QChartSeries::QChartSeriesType type) { // TODO: support also other types; not only scatter and pie - Q_ASSERT(type == QChartSeries::SeriesTypeScatter - || type == QChartSeries::SeriesTypePie); switch (type) { case QChartSeries::SeriesTypeScatter: { - QScatterSeries *scatterSeries = new QScatterSeries(x, y, this); + QScatterSeries *scatterSeries = new QScatterSeries(this); connect(this, SIGNAL(sizeChanged(QRectF)), scatterSeries, SLOT(chartSizeChanged(QRectF))); scatterSeries->d->setParentItem(this); @@ -110,12 +108,13 @@ QChartSeries* QChart::createSeries(QList x, QList y, QChartSeries: case QChartSeries::SeriesTypePie: { // TODO: we now have also a list of y values as a parameter, it is ignored // we should use a generic data class instead of list of x and y values - QPieSeries *pieSeries = new QPieSeries(x, this); + QPieSeries *pieSeries = new QPieSeries(this); connect(this, SIGNAL(sizeChanged(QRectF)), pieSeries, SLOT(chartSizeChanged(QRectF))); return pieSeries; } default: + Q_ASSERT(false); break; } diff --git a/src/qchart.h b/src/qchart.h index 975b9d3..e1d0856 100644 --- a/src/qchart.h +++ b/src/qchart.h @@ -36,7 +36,7 @@ public: void addSeries(QChartSeries* series); //TODO: QChartSeries* createSeries(QSeriesData *data, QChartSeries::QChartSeriesType type); // TODO: who owns the series now? maybe owned by chart and returned a reference instead... - QChartSeries* createSeries(QList x, QList y, QChartSeries::QChartSeriesType type); + QChartSeries* createSeries(QChartSeries::QChartSeriesType type); virtual void setSize(const QSizeF& rect); void setMargin(int margin); diff --git a/src/qchartseries.h b/src/qchartseries.h index f16dd45..b7cf198 100644 --- a/src/qchartseries.h +++ b/src/qchartseries.h @@ -25,11 +25,14 @@ protected: public: virtual ~QChartSeries(){}; - //factory method + // Factory method static QChartSeries* create(QObject* parent = 0 ){ return 0;} - //pure virtual + // Pure virtual virtual QChartSeriesType type() const = 0; + virtual bool setData(QList data) { return false; } + virtual bool setData(QList data) { return false; } + virtual bool setData(QList x, QList y){ return false; } }; QTCOMMERCIALCHART_END_NAMESPACE diff --git a/src/qchartview.cpp b/src/qchartview.cpp index bf493c6..f99d881 100644 --- a/src/qchartview.cpp +++ b/src/qchartview.cpp @@ -40,10 +40,10 @@ void QChartView::addSeries(QChartSeries* series) m_chart->addSeries(series); } -QChartSeries* QChartView::createSeries(QList x, QList y, QChartSeries::QChartSeriesType type) +QChartSeries* QChartView::createSeries(QChartSeries::QChartSeriesType type) { - return m_chart->createSeries(x, y, type); + return m_chart->createSeries(type); } void QChartView::mousePressEvent(QMouseEvent *event) diff --git a/src/qchartview.h b/src/qchartview.h index e08daa0..275eaff 100644 --- a/src/qchartview.h +++ b/src/qchartview.h @@ -21,9 +21,9 @@ public: //implement from QWidget void resizeEvent(QResizeEvent *event); - // TODO: addSeries and createSeries are optional solutions void addSeries(QChartSeries* series); - QChartSeries* createSeries(QList x, QList y, QChartSeries::QChartSeriesType type); + // Convenience function + QChartSeries* createSeries(QChartSeries::QChartSeriesType type); protected: void mouseMoveEvent (QMouseEvent *event); diff --git a/src/qchartwidget.cpp b/src/qchartwidget.cpp index 214d765..299e191 100644 --- a/src/qchartwidget.cpp +++ b/src/qchartwidget.cpp @@ -14,7 +14,7 @@ QGraphicsView(parent) setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); setScene(m_scene); - + m_chart = new QChart(); m_scene->addItem(m_chart); show(); @@ -42,9 +42,9 @@ void QChartWidget::addSeries(QChartSeries* series) m_chart->addSeries(series); } -QChartSeries* QChartWidget::createSeries(QList x, QList y, QChartSeries::QChartSeriesType type) +QChartSeries* QChartWidget::createSeries(QChartSeries::QChartSeriesType type) { - return m_chart->createSeries(x, y, type); + return m_chart->createSeries(type); } #include "moc_qchartwidget.cpp" diff --git a/src/qchartwidget.h b/src/qchartwidget.h index f9af9fd..8f5ea76 100644 --- a/src/qchartwidget.h +++ b/src/qchartwidget.h @@ -26,7 +26,7 @@ public: // TODO: addSeries and createSeries are optional solutions // 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)? void addSeries(QChartSeries* series); - QChartSeries* createSeries(QList x, QList y, QChartSeries::QChartSeriesType type); + QChartSeries* createSeries(QChartSeries::QChartSeriesType type); private: Q_DISABLE_COPY(QChartWidget) diff --git a/src/qpieseries.cpp b/src/qpieseries.cpp index a3c57e7..a37c90b 100644 --- a/src/qpieseries.cpp +++ b/src/qpieseries.cpp @@ -5,23 +5,34 @@ QTCOMMERCIALCHART_BEGIN_NAMESPACE -QPieSeries::QPieSeries(QList x, QGraphicsObject *parent) : +QPieSeries::QPieSeries(QGraphicsObject *parent) : QChartSeries(parent), - m_x(x), m_sizeFactor(1.0) { +} + +QPieSeries::~QPieSeries() +{ + while (m_slices.count()) + delete m_slices.takeLast(); +} + +bool QPieSeries::setData(QList data) +{ + m_data = data; + // Create slices qreal fullPie = 360; qreal total = 0; - foreach (qreal value, m_x) + foreach (qreal value, m_data) total += value; - QGraphicsItem *parentItem = qobject_cast(parent); + QGraphicsItem *parentItem = qobject_cast(parent()); Q_ASSERT(parentItem); m_chartSize = parentItem->boundingRect(); qreal angle = 0; // TODO: no need to create new slices in case size changed; we should re-use the existing ones - foreach (qreal value, m_x) { + foreach (qreal value, m_data) { qreal span = value / total * fullPie; PieSlice *slice = new PieSlice(randomColor(), angle, span, parentItem->boundingRect()); slice->setParentItem(parentItem); @@ -30,12 +41,7 @@ QPieSeries::QPieSeries(QList x, QGraphicsObject *parent) : } resizeSlices(m_chartSize); -} - -QPieSeries::~QPieSeries() -{ - while (m_slices.count()) - delete m_slices.takeLast(); + return true; } void QPieSeries::chartSizeChanged(QRectF chartRect) diff --git a/src/qpieseries.h b/src/qpieseries.h index e58da6f..0d9d7d9 100644 --- a/src/qpieseries.h +++ b/src/qpieseries.h @@ -16,7 +16,7 @@ class QTCOMMERCIALCHART_EXPORT QPieSeries : public QChartSeries public: // TODO: use a generic data class instead of x and y - QPieSeries(QList x, QGraphicsObject *parent = 0); + QPieSeries(QGraphicsObject *parent = 0); ~QPieSeries(); QColor randomColor(); void setSizeFactor(qreal sizeFactor); @@ -24,6 +24,7 @@ public: public: // from QChartSeries QChartSeriesType type() const { return QChartSeries::SeriesTypePie; } + bool setData(QList data); public Q_SLOTS: void chartSizeChanged(QRectF rect); @@ -33,7 +34,7 @@ private: //Q_DECLARE_PRIVATE(QPieSeries) Q_DISABLE_COPY(QPieSeries) // TODO: move the followin to internal impl - QList m_x; + QList m_data; QList m_slices; QRectF m_chartSize; qreal m_sizeFactor; diff --git a/src/qscatterseries.cpp b/src/qscatterseries.cpp index 824b695..75b2ea7 100644 --- a/src/qscatterseries.cpp +++ b/src/qscatterseries.cpp @@ -9,14 +9,11 @@ QTCOMMERCIALCHART_BEGIN_NAMESPACE //#define QSeriesData QList -QScatterSeriesPrivate::QScatterSeriesPrivate(QList x, QList y, QGraphicsItem *parent) : +QScatterSeriesPrivate::QScatterSeriesPrivate(QGraphicsItem *parent) : QGraphicsItem(parent), - m_x(x), - m_y(y), m_scalex(100), // TODO: let the use define the scale (or autoscaled) m_scaley(100) { - resize(parent->boundingRect()); } void QScatterSeriesPrivate::resize(QRectF rect) @@ -58,12 +55,23 @@ void QScatterSeriesPrivate::paint(QPainter *painter, const QStyleOptionGraphicsI } } -QScatterSeries::QScatterSeries(QList x, QList y, QObject *parent) : +QScatterSeries::QScatterSeries(QObject *parent) : QChartSeries(parent), - d(new QScatterSeriesPrivate(x, y, qobject_cast (parent))) + d(new QScatterSeriesPrivate(qobject_cast (parent))) { } +bool QScatterSeries::setData(QList x, QList y) +{ + // TODO: validate data + d->m_x = x; + d->m_y = y; + QGraphicsItem *parentItem = qobject_cast(parent()); + Q_ASSERT(parentItem); + d->resize(parentItem->boundingRect()); + return true; +} + void QScatterSeries::chartSizeChanged(QRectF rect) { // Recalculate scatter data point locations on the scene diff --git a/src/qscatterseries.h b/src/qscatterseries.h index 15c1320..83e3a77 100644 --- a/src/qscatterseries.h +++ b/src/qscatterseries.h @@ -12,11 +12,12 @@ class QTCOMMERCIALCHART_EXPORT QScatterSeries : public QChartSeries Q_OBJECT public: //QScatterSeries(QSeriesData *data, QObject *chart); - QScatterSeries(QList x, QList y, QObject *parent = 0); + QScatterSeries(QObject *parent = 0); ~QScatterSeries(); public: // from QChartSeries QChartSeriesType type() const { return QChartSeries::SeriesTypeScatter; } + bool setData(QList x, QList y); public Q_SLOTS: void chartSizeChanged(QRectF rect); diff --git a/src/qscatterseries_p.h b/src/qscatterseries_p.h index e68d2d8..ef8b71e 100644 --- a/src/qscatterseries_p.h +++ b/src/qscatterseries_p.h @@ -12,7 +12,7 @@ QTCOMMERCIALCHART_BEGIN_NAMESPACE class QScatterSeriesPrivate : public QGraphicsItem { public: - QScatterSeriesPrivate(QList x, QList y, QGraphicsItem *parent); + QScatterSeriesPrivate(QGraphicsItem *parent); public: // from QGraphicsItem void resize(QRectF rect); diff --git a/test/chartwidgettest/mainwidget.cpp b/test/chartwidgettest/mainwidget.cpp index 9430082..2b1e48e 100644 --- a/test/chartwidgettest/mainwidget.cpp +++ b/test/chartwidgettest/mainwidget.cpp @@ -120,7 +120,6 @@ void MainWidget::addSeries(QString series, QString data) { qDebug() << "addSeries: " << series << " data: " << data; m_defaultSeriesName = series; - QChartSeries *newSeries = QXYChartSeries::create(); // TODO: a dedicated data class for storing x and y values QList x; @@ -131,40 +130,37 @@ void MainWidget::addSeries(QString series, QString data) x.append(i); y.append(i); } - for (int i = 0; i < 20; i++) - ((QXYChartSeries *)newSeries)->add(i, i); } else if (data == "linear, 1M") { for (int i = 0; i < 10000; i++) { x.append(i); y.append(20); } - for (int i = 0; i < 1000000; i++) - ((QXYChartSeries *)newSeries)->add(i, 10); } else if (data == "SIN") { for (int i = 0; i < 100; i++) { x.append(i); y.append(abs(sin(3.14159265358979 / 50 * i) * 100)); } - for (int i = 0; i < 100; i++) - ((QXYChartSeries *)newSeries)->add(i, abs(sin(3.14159265358979 / 50 * i) * 100)); } else if (data == "SIN + random") { for (qreal i = 0; i < 100; i += 0.1) { x.append(i + (rand() % 5)); y.append(abs(sin(3.14159265358979 / 50 * i) * 100) + (rand() % 5)); } - for (qreal i = 0; i < 100; i += 0.1) - ((QXYChartSeries *)newSeries)->add(i + (rand() % 5), abs(sin(3.14159265358979 / 50 * i) * 100) + (rand() % 5)); } else { // TODO: check if data has a valid file name + Q_ASSERT(false); } // TODO: color of the series + QChartSeries *newSeries = 0; if (series == "Scatter") { - newSeries = m_chartWidget->createSeries(x, y, QChartSeries::SeriesTypeScatter); + newSeries = m_chartWidget->createSeries(QChartSeries::SeriesTypeScatter); + Q_ASSERT(newSeries->setData(x, y)); } else if (series == "Pie") { - newSeries = m_chartWidget->createSeries(x, y, QChartSeries::SeriesTypePie); + newSeries = m_chartWidget->createSeries(QChartSeries::SeriesTypePie); + Q_ASSERT(newSeries->setData(y)); } else if (series == "Line") { - m_chartWidget->addSeries(newSeries); + newSeries = m_chartWidget->createSeries(QChartSeries::SeriesTypePie); + Q_ASSERT(newSeries->setData(x, y)); } else { // TODO }