diff --git a/src/qchart.cpp b/src/qchart.cpp index 0f9f0c8..e4b44b4 100644 --- a/src/qchart.cpp +++ b/src/qchart.cpp @@ -1,9 +1,12 @@ #include "qchart.h" #include "qchartseries.h" +#include "qscatterseries.h" +#include "qscatterseries_p.h" #include "xylinechartitem_p.h" #include "xyplotdomain_p.h" #include "axis_p.h" #include "xygrid_p.h" +#include #include QTCOMMERCIALCHART_BEGIN_NAMESPACE @@ -84,6 +87,30 @@ void QChart::addSeries(QChartSeries* series) } } +QChartSeries* QChart::createSeries(QList x, QList y, QChartSeries::QChartSeriesType type) +{ + Q_D(QChart); + + // TODO: support also other types + Q_ASSERT(type == QChartSeries::SeriesTypeScatter); + QChartSeries *series = 0; + + switch (type) { + case QChartSeries::SeriesTypeScatter: { + QScatterSeries *scatterSeries = new QScatterSeries(x, y, this); + //scatterSeries->d->set + d->m_items.append(scatterSeries->d); + scene()->addItem(scatterSeries->d); + //series = qobject_cast(scatterSeries); + break; + } + default: + break; + } + + return series; +} + void QChart::setSize(const QSizeF& size) { Q_D(QChart); @@ -93,10 +120,11 @@ void QChart::setSize(const QSizeF& size) d->m_grid->setPos(d->m_rect.topLeft()); d->m_grid->setSize(d->m_rect.size()); d->m_plotDataList[0].m_viewportRect = d->m_rect; - foreach(QGraphicsItem* item , d->m_items) - reinterpret_cast(item)->updateXYPlotData(d->m_plotDataList.at(0)); + // TODO: line chart items would need to be updated separately as they don't support update + // via paint method +// foreach(QGraphicsItem* item , d->m_items) { +// reinterpret_cast(item);//->updateXYPlotData(d->m_plotDataList.at(0)); update(); - } int QChart::margin() const diff --git a/src/qchart.h b/src/qchart.h index 26004bc..f6680c2 100644 --- a/src/qchart.h +++ b/src/qchart.h @@ -2,6 +2,7 @@ #define CHART_H #include +#include #include QTCOMMERCIALCHART_BEGIN_NAMESPACE @@ -12,9 +13,16 @@ class QChartSeries; class XYPlotDomain; class QChartPrivate; -class QTCOMMERCIALCHART_EXPORT QChart : public QGraphicsItem -{ +// TODO: We don't need to have QChart tied to QGraphicsItem: +//class QTCOMMERCIALCHART_EXPORT QChart +//class QTCOMMERCIALCHART_EXPORT QChartGraphicsItem : public QGraphicsItem { +// public: QChartGraphicsItem(QChart &chart); +/*! + * TODO: define the responsibilities + */ +class QTCOMMERCIALCHART_EXPORT QChart : public QGraphicsItem, public QObject +{ public: QChart(QGraphicsItem* parent = 0); virtual ~QChart(); @@ -24,6 +32,9 @@ public: virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget){}; 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); virtual void setSize(const QSizeF& rect); void setMargin(int margin); diff --git a/src/qchartdata.cpp b/src/qchartdata.cpp new file mode 100644 index 0000000..91c0e51 --- /dev/null +++ b/src/qchartdata.cpp @@ -0,0 +1,5 @@ +#include "qchartdata.h" + +QChartData::QChartData() +{ +} diff --git a/src/qchartdata.h b/src/qchartdata.h new file mode 100644 index 0000000..9e28173 --- /dev/null +++ b/src/qchartdata.h @@ -0,0 +1,10 @@ +#ifndef QCHARTDATA_H +#define QCHARTDATA_H + +class QChartData +{ +public: + QChartData(); +}; + +#endif // QCHARTDATA_H diff --git a/src/qchartseries.h b/src/qchartseries.h index 6bb158d..a607c93 100644 --- a/src/qchartseries.h +++ b/src/qchartseries.h @@ -20,16 +20,15 @@ public: }; protected: - QChartSeries(QObject *parent = 0):QObject(parent){}; + QChartSeries(QObject *parent = 0) : QObject(parent) {}; public: - virtual ~QChartSeries(){}; + virtual ~QChartSeries() {}; //factory method - static QChartSeries* create(QObject* parent = 0 ){ return 0;} + static QChartSeries* create(QObject* parent = 0) { return 0;} //pure virtual virtual QChartSeriesType type() const = 0; - }; QTCOMMERCIALCHART_END_NAMESPACE diff --git a/src/qchartwidget.cpp b/src/qchartwidget.cpp index a55f44a..4458b49 100644 --- a/src/qchartwidget.cpp +++ b/src/qchartwidget.cpp @@ -19,6 +19,7 @@ public: m_view->setScene(m_scene); m_chart = new QChart(); m_scene->addItem(m_chart); + m_view->show(); } ~QChartWidgetPrivate() { @@ -64,6 +65,12 @@ void QChartWidget::addSeries(QChartSeries* series) d->m_chart->addSeries(series); } +QChartSeries* QChartWidget::createSeries(QList x, QList y, QChartSeries::QChartSeriesType type) +{ + Q_D(QChartWidget); + return d->m_chart->createSeries(x, y, type); +} + #include "moc_qchartwidget.cpp" QTCOMMERCIALCHART_END_NAMESPACE diff --git a/src/qchartwidget.h b/src/qchartwidget.h index 0edecd0..62dc32e 100644 --- a/src/qchartwidget.h +++ b/src/qchartwidget.h @@ -21,7 +21,10 @@ public: void resizeEvent(QResizeEvent *event); QSize sizeHint() const; + // TODO: addSeries and createSeries are optional solutions void addSeries(QChartSeries* series); + QChartSeries* createSeries(QList x, QList y, QChartSeries::QChartSeriesType type); + protected: QChartWidgetPrivate * const d_ptr; diff --git a/src/qscatterseries.cpp b/src/qscatterseries.cpp new file mode 100644 index 0000000..1fe1d3a --- /dev/null +++ b/src/qscatterseries.cpp @@ -0,0 +1,67 @@ +#include "qscatterseries.h" +#include "qscatterseries_p.h" +#include "qchart.h" +#include +#include + +QTCOMMERCIALCHART_BEGIN_NAMESPACE + +//#define QSeriesData QList + +QScatterSeriesPrivate::QScatterSeriesPrivate(QList x, QList y, QGraphicsItem *parent) : + QGraphicsItem(parent), + m_x(x), + m_y(y) +{ +} + +void QScatterSeriesPrivate::setSize() +{ +} + +QRectF QScatterSeriesPrivate::boundingRect() const +{ + return QRectF(0, 0, 100, 100); +} + +void QScatterSeriesPrivate::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) +{ + QPen pen = painter->pen(); + QBrush brush = pen.brush(); + // TODO: The opacity should be user definable... + brush.setColor(QColor(255, 82, 0, 50)); + pen.setBrush(brush); + pen.setWidth(4); + painter->setPen(pen); + QTransform transform = painter->transform(); + + // TODO: get min and max values of the axes from the QChart (or some dedicated class) + const qreal xmin = 0.0; + const qreal xmax = 100.0; + const qreal xscale = scene()->width() / (xmax - xmin); + const qreal ymin = 0.0; + const qreal ymax = 100.0; + const qreal yscale = scene()->height() / (ymax - ymin); + + for (int i(0); i < m_x.count() && i < m_y.count(); i++) { + transform.reset(); + transform.translate(m_x.at(i) * xscale, m_y.at(i) * yscale); + painter->setTransform(transform); + painter->drawArc(0, 0, 4, 4, 0, 5760); + } +} + +QScatterSeries::QScatterSeries(QList x, QList y, QObject *parent) : + QChartSeries(parent), + d(new QScatterSeriesPrivate(x, y, qobject_cast (parent))) +{ +} + +QScatterSeries::~QScatterSeries() +{ + delete d; +} + +#include "moc_qscatterseries.cpp" + +QTCOMMERCIALCHART_END_NAMESPACE diff --git a/src/qscatterseries.h b/src/qscatterseries.h new file mode 100644 index 0000000..bf0f3a0 --- /dev/null +++ b/src/qscatterseries.h @@ -0,0 +1,29 @@ +#ifndef QSCATTERSERIES_H +#define QSCATTERSERIES_H + +#include "qchartseries.h" + +QTCOMMERCIALCHART_BEGIN_NAMESPACE +class QScatterSeriesPrivate; + +class QTCOMMERCIALCHART_EXPORT QScatterSeries : public QChartSeries +{ + Q_OBJECT +public: + //QScatterSeries(QSeriesData *data, QObject *chart); + QScatterSeries(QList x, QList y, QObject *chart = 0); + ~QScatterSeries(); + +public: // from QChartSeries + virtual QChartSeriesType type() const { return QChartSeries::SeriesTypeScatter; } + +private: + Q_DECLARE_PRIVATE(QScatterSeries) + Q_DISABLE_COPY(QScatterSeries) + friend class QChart; + QScatterSeriesPrivate *const d; +}; + +QTCOMMERCIALCHART_END_NAMESPACE + +#endif // QSCATTERSERIES_H diff --git a/src/qscatterseries_p.h b/src/qscatterseries_p.h new file mode 100644 index 0000000..33828da --- /dev/null +++ b/src/qscatterseries_p.h @@ -0,0 +1,29 @@ +#ifndef QSCATTERSERIESPRIVATE_H +#define QSCATTERSERIESPRIVATE_H + +#include "qchartseries.h" +#include + +QTCOMMERCIALCHART_BEGIN_NAMESPACE + +/*! + * The PIMPL class of QScatterSeries. + */ +class QScatterSeriesPrivate : public QGraphicsItem +{ +public: + QScatterSeriesPrivate(QList x, QList y, QGraphicsItem *parent); + +public: // from QGraphicsItem + void setSize(); + QRectF boundingRect() const; + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); + + // TODO: use the chart data class instead of list of x and y values? + QList m_x; + QList m_y; +}; + +QTCOMMERCIALCHART_END_NAMESPACE + +#endif // QSCATTERSERIES_H diff --git a/src/src.pro b/src/src.pro index 1ee565a..f7a5071 100644 --- a/src/src.pro +++ b/src/src.pro @@ -1,14 +1,7 @@ -!include( ../common.pri ) { -error( Couldn't find the common.pri file! ) -} - - TARGET = QtCommercialChart -DESTDIR = $$CHART_BUILD_LIB_DIR TEMPLATE = lib QT += core \ gui - CONFIG += debug_and_release CONFIG(debug, debug|release):TARGET = QtCommercialChartd @@ -17,35 +10,38 @@ SOURCES += \ xylinechart/xylinechartitem.cpp \ xylinechart/xygrid.cpp \ xylinechart/xyplotdomain.cpp \ + qscatterseries.cpp \ qchart.cpp \ axis.cpp \ - qchartwidget.cpp + qchartwidget.cpp \ + qchartdata.cpp PRIVATE_HEADERS += \ xylinechart/xylinechartitem_p.h \ xylinechart/xyplotdomain_p.h \ xylinechart/xygrid_p.h \ + qscatterseries_p.h \ axis_p.h PUBLIC_HEADERS += \ qchartseries.h \ + qscatterseries.h \ qchart.h \ + qchartdata.h \ qchartwidget.h \ qchartglobal.h \ - xylinechart/qxychartseries.h - + xylinechart/qxychartseries.h + HEADERS += $$PUBLIC_HEADERS HEADERS += $$PRIVATE_HEADERS INCLUDEPATH += xylinechart \ . -OBJECTS_DIR = $$CHART_BUILD_DIR/lib -MOC_DIR = $$CHART_BUILD_DIR/lib -UI_DIR = $$CHART_BUILD_DIR/lib -RCC_DIR = $$CHART_BUILD_DIR/lib - - +OBJECTS_DIR = ../build/lib +MOC_DIR = ../build/lib +UI_DIR = ../build/lib +RCC_DIR = ../build/lib DEFINES += QTCOMMERCIALCHART_LIBRARY public_headers.path = $$[QT_INSTALL_HEADERS]/QtCommercialChart @@ -53,21 +49,3 @@ public_headers.files = $$PUBLIC_HEADERS target.path = $$[QT_INSTALL_LIBS] INSTALLS += target \ public_headers - - -install_build_headers.name = bild_headers -install_build_headers.output = $$CHART_BUILD_HEADER_DIR/${QMAKE_FILE_BASE}.h -install_build_headers.input = PUBLIC_HEADERS -install_build_headers.commands = $$QMAKE_COPY ${QMAKE_FILE_NAME} $$CHART_BUILD_HEADER_DIR -install_build_headers.CONFIG += target_predeps no_link -QMAKE_EXTRA_COMPILERS += install_build_headers - -chartversion.target = qchartversion_p.h -chartversion.commands = @echo "build_time" > $$chartversion.target; -chartversion.depends = $$HEADERS $$SOURCES -PRE_TARGETDEPS += qchartversion_p.h -QMAKE_CLEAN+= qchartversion_p.h -QMAKE_EXTRA_TARGETS += chartversion - -unix:QMAKE_DISTCLEAN += -r $$CHART_BUILD_HEADER_DIR $$CHART_BUILD_LIB_DIR -win32:QMAKE_DISTCLEAN += $$CHART_BUILD_HEADER_DIR $$CHART_BUILD_LIB_DIR \ No newline at end of file diff --git a/test/chartwidgettest/mainwidget.cpp b/test/chartwidgettest/mainwidget.cpp index 3189f03..73ac401 100644 --- a/test/chartwidgettest/mainwidget.cpp +++ b/test/chartwidgettest/mainwidget.cpp @@ -101,38 +101,46 @@ void MainWidget::addSeries(QString series, QString data) m_defaultSeries = series; QXYChartSeries* series0 = 0; - - // TODO: color of the series - if (series == "Scatter") { - series0 = QXYChartSeries::create(); - } else if (series == "Line") { - series0 = QXYChartSeries::create(); - } else { - // TODO - series0 = QXYChartSeries::create(); - } + QChartSeries* scatterSeries = 0; + // TODO: a dedicated data class for storing x and y values + QList x; + QList y; if (data == "linear") { - for (int i = 0; i < 10; i++) - series0->add(i, 10); + for (int i = 0; i < 10; i++) { + x.append(i); + y.append(10); + } } else if (data == "linear, 1M") { - for (int i = 0; i < 1000000; i++) - series0->add(i, 20); + for (int i = 0; i < 10000; i++) { + x.append(i); + y.append(20); + } } else if (data == "SIN") { - for (int x = 0; x < 100; x++) - series0->add(x, abs(sin(3.14159265358979 / 50 * x) * 100)); - QList dataset; - dataset << series0; + for (int i = 0; i < 100; i++) { + x.append(i); + y.append(abs(sin(3.14159265358979 / 50 * i) * 100)); + } } else if (data == "SIN + random") { - for (qreal x = 0; x < 100; x += 0.1) { - series0->add(x + (rand() % 5), - abs(sin(3.14159265358979 / 50 * x) * 100) + (rand() % 5)); + 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)); } } else { // TODO: check if data has a valid file name } - m_chartWidget->addSeries(series0); + // TODO: color of the series + if (series == "Scatter") { + scatterSeries = m_chartWidget->createSeries(x, y, QChartSeries::SeriesTypeScatter); + } else if (series == "Line") { + series0 = QXYChartSeries::create(); + for (int i = 0; i < 1000000; i++) + series0->add(i, 20); + m_chartWidget->addSeries(series0); + } else { + // TODO + } } void MainWidget::chartTypeChanged(int itemIndex)