diff --git a/src/qchart.cpp b/src/qchart.cpp index 5c25893..805eb3c 100644 --- a/src/qchart.cpp +++ b/src/qchart.cpp @@ -38,12 +38,11 @@ public: //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -QChart::QChart(QGraphicsItem* parent):QGraphicsItem(parent), -d_ptr(new QChartPrivate(this)) +QChart::QChart(QGraphicsObject* parent) : QGraphicsObject(parent), +d(new QChartPrivate(this)) { // setFlags(QGraphicsItem::ItemClipsChildrenToShape); // set axis - Q_D(QChart); d->m_axisY->rotate(90); } @@ -51,13 +50,12 @@ QChart::~QChart(){} QRectF QChart::boundingRect() const { - Q_D(const QChart); return d->m_rect; } void QChart::addSeries(QChartSeries* series) { - Q_D(QChart); + // TODO: we should check the series not already added d->m_series<(series); + if (scatter) { + scatter->d->setParentItem(this); + scene()->addItem(scatter->d); + } break; } } @@ -96,18 +99,14 @@ void QChart::addSeries(QChartSeries* series) QChartSeries* QChart::createSeries(QList x, QList y, QChartSeries::QChartSeriesType type) { - Q_D(QChart); - - // TODO: support also other types + // TODO: support also other types in addition to scatter Q_ASSERT(type == QChartSeries::SeriesTypeScatter); QChartSeries *series = 0; switch (type) { case QChartSeries::SeriesTypeScatter: { QScatterSeries *scatterSeries = new QScatterSeries(x, y, this); - d->m_items.append(scatterSeries->d); - scene()->addItem(scatterSeries->d); - //series = qobject_cast(scatterSeries); + scatterSeries->d->setParentItem(this); break; } default: @@ -116,21 +115,26 @@ QChartSeries* QChart::createSeries(QList x, QList y, QChartSeries: return series; } + void QChart::setSize(const QSizeF& size) { - Q_D(QChart); d->m_rect = QRect(QPoint(0,0),size.toSize()); - d->m_rect.adjust(margin(),margin(),-margin(),-margin()); + d->m_rect.adjust(margin(),margin(), -margin(), -margin()); d->m_grid->setPos(d->m_rect.topLeft()); d->m_grid->setSize(d->m_rect.size()); - // TODO: line chart items would need to be updated separately as they don't support update - // via paint method - for (int i =0; i< d->m_plotDomainList.size();i++) - { - d->m_plotDomainList[i].m_viewportRect = d->m_rect; - } + // TODO: calculate the scale + // TODO: calculate the origo + // TODO: not sure if emitting a signal here is the best from performance point of view + const qreal xscale = size.width() / 100; + const qreal yscale = size.height() / 100; + emit sizeChanged(QRectF(0, 0, size.width(), size.height()), xscale, yscale); + + for (int i(0); i < d->m_plotDomainList.size(); i++) + d->m_plotDomainList[i].m_viewportRect = d->m_rect; + // TODO: line chart items are updated separately as they don't support update + // via sizeChanged signal foreach(XYLineChartItem* item , d->m_xyLineChartItems) item->updateXYPlotDomain(d->m_plotDomainList.at(d->m_plotDataIndex)); @@ -140,14 +144,15 @@ void QChart::setSize(const QSizeF& size) int QChart::margin() const { - Q_D(const QChart); return d->m_marginSize; } void QChart::setMargin(int margin) { - Q_D(QChart); d->m_marginSize = margin; } +#include "moc_qchart.cpp" + + QTCOMMERCIALCHART_END_NAMESPACE diff --git a/src/qchart.h b/src/qchart.h index 9e06dc8..590b855 100644 --- a/src/qchart.h +++ b/src/qchart.h @@ -3,7 +3,7 @@ #include #include -#include +#include QTCOMMERCIALCHART_BEGIN_NAMESPACE @@ -21,16 +21,16 @@ class QChartPrivate; /*! * TODO: define the responsibilities */ -class QTCOMMERCIALCHART_EXPORT QChart : public QGraphicsItem, public QObject +class QTCOMMERCIALCHART_EXPORT QChart : public QGraphicsObject { - + Q_OBJECT public: - QChart(QGraphicsItem* parent = 0); - virtual ~QChart(); + QChart(QGraphicsObject* parent = 0); + ~QChart(); //from QGraphicsItem - virtual QRectF boundingRect() const; - virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget){}; + QRectF boundingRect() const; + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget){}; void addSeries(QChartSeries* series); //TODO: QChartSeries* createSeries(QSeriesData *data, QChartSeries::QChartSeriesType type); @@ -41,13 +41,13 @@ public: void setMargin(int margin); int margin() const; -protected: - QChartPrivate * const d_ptr; +signals: + void sizeChanged(QRectF rect, qreal xscale, qreal yscale); private: +// Q_DECLARE_PRIVATE(QChart) Q_DISABLE_COPY(QChart) - Q_DECLARE_PRIVATE(QChart) - + QChartPrivate *d; }; QTCOMMERCIALCHART_END_NAMESPACE diff --git a/src/qscatterseries.cpp b/src/qscatterseries.cpp index 1fe1d3a..cfb723e 100644 --- a/src/qscatterseries.cpp +++ b/src/qscatterseries.cpp @@ -3,6 +3,7 @@ #include "qchart.h" #include #include +#include QTCOMMERCIALCHART_BEGIN_NAMESPACE @@ -15,13 +16,21 @@ QScatterSeriesPrivate::QScatterSeriesPrivate(QList x, QList y, QGr { } -void QScatterSeriesPrivate::setSize() +void QScatterSeriesPrivate::resize(QRectF rect, qreal xscale, qreal yscale) { + m_scenex.clear(); + m_sceney.clear(); + + foreach(qreal x, m_x) + m_scenex.append(rect.left() + x * xscale); + + foreach(qreal y, m_y) + m_sceney.append(rect.bottom() - y * yscale); } QRectF QScatterSeriesPrivate::boundingRect() const { - return QRectF(0, 0, 100, 100); + return QRectF(0, 0, 55, 100); } void QScatterSeriesPrivate::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) @@ -33,21 +42,13 @@ void QScatterSeriesPrivate::paint(QPainter *painter, const QStyleOptionGraphicsI 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); + // TODO: m_scenex and m_sceny are left empty during construction -> we would need a resize + // event right after construction or maybe given a size during initialization + for (int i(0); i < m_scenex.count() && i < m_sceney.count(); i++) { + if (scene()->width() > m_scenex.at(i) && scene()->height() > m_sceney.at(i)) + //painter->drawArc(m_scenex.at(i), m_sceney.at(i), 2, 2, 0, 5760); + painter->drawPoint(m_scenex.at(i), m_sceney.at(i)); } } @@ -55,6 +56,15 @@ QScatterSeries::QScatterSeries(QList x, QList y, QObject *parent) QChartSeries(parent), d(new QScatterSeriesPrivate(x, y, qobject_cast (parent))) { + connect(parent, SIGNAL(sizeChanged(QRectF, qreal, qreal)), this, SLOT(chartSizeChanged(QRectF, qreal, qreal))); +} + +void QScatterSeries::chartSizeChanged(QRectF rect, qreal xscale, qreal yscale) +{ + // Recalculate scatter data point locations on the scene +// d->transform().reset(); +// d->transform().translate(); + d->resize(rect, xscale, yscale); } QScatterSeries::~QScatterSeries() diff --git a/src/qscatterseries.h b/src/qscatterseries.h index bf0f3a0..f35d85c 100644 --- a/src/qscatterseries.h +++ b/src/qscatterseries.h @@ -2,6 +2,7 @@ #define QSCATTERSERIES_H #include "qchartseries.h" +#include QTCOMMERCIALCHART_BEGIN_NAMESPACE class QScatterSeriesPrivate; @@ -17,6 +18,9 @@ public: public: // from QChartSeries virtual QChartSeriesType type() const { return QChartSeries::SeriesTypeScatter; } +public Q_SLOTS: + void chartSizeChanged(QRectF rect, qreal xscale, qreal yscale); + private: Q_DECLARE_PRIVATE(QScatterSeries) Q_DISABLE_COPY(QScatterSeries) diff --git a/src/qscatterseries_p.h b/src/qscatterseries_p.h index 33828da..d818c27 100644 --- a/src/qscatterseries_p.h +++ b/src/qscatterseries_p.h @@ -15,13 +15,15 @@ public: QScatterSeriesPrivate(QList x, QList y, QGraphicsItem *parent); public: // from QGraphicsItem - void setSize(); + void resize(QRectF rect, qreal xscale, qreal yscale); 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; + QList m_scenex; + QList m_sceney; }; QTCOMMERCIALCHART_END_NAMESPACE diff --git a/src/src.pro b/src/src.pro index df9fc08..866780c 100644 --- a/src/src.pro +++ b/src/src.pro @@ -2,7 +2,6 @@ error( Couldn't find the common.pri file! ) } - TARGET = QtCommercialChart DESTDIR = $$CHART_BUILD_LIB_DIR TEMPLATE = lib diff --git a/src/xylinechart/xylinechartitem_p.h b/src/xylinechart/xylinechartitem_p.h index 739276b..9f96058 100644 --- a/src/xylinechart/xylinechartitem_p.h +++ b/src/xylinechart/xylinechartitem_p.h @@ -2,7 +2,7 @@ #define XYLINECHARTITEM_H #include "qchartglobal.h" -#include "qchart.h" +#include #include "xyplotdomain_p.h" QTCOMMERCIALCHART_BEGIN_NAMESPACE diff --git a/test/chartwidgettest/chartwidgettest.pro b/test/chartwidgettest/chartwidgettest.pro index ba108cd..d4a0097 100644 --- a/test/chartwidgettest/chartwidgettest.pro +++ b/test/chartwidgettest/chartwidgettest.pro @@ -7,27 +7,27 @@ error( Couldn't find the integrated.pri file! ) } -TARGET = chartwidgettest -TEMPLATE = app - -QT += core gui -contains(QT_MAJOR_VERSION, 5) { - QT += widgets -} - - -OBJECTS_DIR = tmp -MOC_DIR = tmp - -SOURCES += main.cpp \ - mainwidget.cpp \ -# qscatterseries.cpp \ -# qseriespointgraphicsitem.cpp \ - dataseriedialog.cpp - -HEADERS += \ - mainwidget.h \ -# qscatterseries.h \ -# qseriespointgraphicsitem.h \ - dataseriedialog.h +TARGET = chartwidgettest +TEMPLATE = app + +QT += core gui +contains(QT_MAJOR_VERSION, 5) { + QT += widgets +} + + +OBJECTS_DIR = tmp +MOC_DIR = tmp + +SOURCES += main.cpp \ + mainwidget.cpp \ +# qscatterseries.cpp \ +# qseriespointgraphicsitem.cpp \ + dataseriedialog.cpp + +HEADERS += \ + mainwidget.h \ +# qscatterseries.h \ +# qseriespointgraphicsitem.h \ + dataseriedialog.h diff --git a/test/chartwidgettest/mainwidget.cpp b/test/chartwidgettest/mainwidget.cpp index 76c1288..c46f1f5 100644 --- a/test/chartwidgettest/mainwidget.cpp +++ b/test/chartwidgettest/mainwidget.cpp @@ -100,41 +100,49 @@ void MainWidget::addSeries(QString series, QString data) qDebug() << "addSeries: " << series << " data: " << data; m_defaultSeries = series; + QXYChartSeries* series0 = QXYChartSeries::create(); + // 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++) { + for (int i = 0; i < 20; i++) { x.append(i); - y.append(10); + y.append(i); } + for (int i = 0; i < 20; i++) + series0->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++) + series0->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++) + series0->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) + series0->add(i + (rand() % 5), abs(sin(3.14159265358979 / 50 * i) * 100) + (rand() % 5)); } else { // TODO: check if data has a valid file name } // TODO: color of the series if (series == "Scatter") { - /*QChartSeries* scatterSeries = */m_chartWidget->createSeries(x, y, QChartSeries::SeriesTypeScatter); + /*QChartSeries* scatterSeries = */ + m_chartWidget->createSeries(x, y, QChartSeries::SeriesTypeScatter); } else if (series == "Line") { - QXYChartSeries* series0 = QXYChartSeries::create(); - for (int i = 0; i < 1000000; i++) - series0->add(i, 20); m_chartWidget->addSeries(series0); } else { // TODO