From 1666cfa56d96d27c1745c475af5d1c08e563076d 2012-03-01 10:31:21 From: Marek Rosa Date: 2012-03-01 10:31:21 Subject: [PATCH] Spline with problems --- diff --git a/example/splinechart/splinewidget.cpp b/example/splinechart/splinewidget.cpp index abef9c1..7700a01 100644 --- a/example/splinechart/splinewidget.cpp +++ b/example/splinechart/splinewidget.cpp @@ -1,7 +1,7 @@ #include "splinewidget.h" #include "qchartview.h" #include "qsplineseries.h" -#include "qlinechartseries.h" +#include "qlineseries.h" #include QTCOMMERCIALCHART_USE_NAMESPACE @@ -11,23 +11,23 @@ SplineWidget::SplineWidget(QWidget *parent) { //create QSplineSeries QSplineSeries* series = new QSplineSeries(this); - series->addData(QPointF(150, 100)); - series->addData(QPointF(200, 180)); - series->addData(QPointF(240, 130)); - series->addData(QPointF(270, 120)); - series->addData(QPointF(310, 120)); - series->addData(QPointF(420, 160)); - series->addData(QPointF(535, 250)); + series->add(QPointF(150, 100)); + series->add(QPointF(200, 180)); + series->add(QPointF(240, 130)); + series->add(QPointF(270, 120)); + series->add(QPointF(310, 120)); + series->add(QPointF(420, 160)); + series->add(QPointF(535, 250)); series->calculateControlPoints(); - QLineChartSeries* lineSeries = new QLineChartSeries; - for (int i = 0; i < series->count() - 1; i++) - { - lineSeries->add(series->at(i).x(), series->at(i).y()); - lineSeries->add(series->controlPoint(2*i).x(), series->controlPoint(2*i).y()); - lineSeries->add(series->controlPoint(2*i + 1).x(), series->controlPoint(2*i + 1).y()); - } +// QLineSeries* lineSeries = new QLineSeries; +// for (int i = 0; i < series->count() - 1; i++) +// { +// lineSeries->add(series->at(i).x(), series->at(i).y()); +// lineSeries->add(series->controlPoint(2*i).x(), series->controlPoint(2*i).y()); +// lineSeries->add(series->controlPoint(2*i + 1).x(), series->controlPoint(2*i + 1).y()); +// } // QLineChartSeries* lineSeries2 = new QLineChartSeries; // lineSeries2->add(10, 50); diff --git a/src/chartdataset.cpp b/src/chartdataset.cpp index a7755e0..896de3d 100644 --- a/src/chartdataset.cpp +++ b/src/chartdataset.cpp @@ -124,13 +124,13 @@ void ChartDataSet::addSeries(QSeries* series, QChartAxis *axisY) break; } - case QChartSeries::SeriesTypeSpline: { + case QSeries::SeriesTypeSpline: { QSplineSeries* splineSeries = static_cast(series); for (int i = 0; i < splineSeries->count(); i++) { - qreal x = splineSeries->at(i).x(); - qreal y = splineSeries->at(i).y(); + qreal x = splineSeries->x(i); + qreal y = splineSeries->y(i); domain.m_minX = qMin(domain.m_minX,x); domain.m_minY = qMin(domain.m_minY,y); domain.m_maxX = qMax(domain.m_maxX,x); diff --git a/src/chartpresenter.cpp b/src/chartpresenter.cpp index 4289c11..d9ac176 100644 --- a/src/chartpresenter.cpp +++ b/src/chartpresenter.cpp @@ -62,7 +62,7 @@ QRectF ChartPresenter::geometry() const void ChartPresenter::handleGeometryChanged() { m_rect = QRectF(QPoint(0,0),m_chart->size()); - // m_rect.adjust(m_marginSize,m_marginSize, -m_marginSize, -m_marginSize); + m_rect.adjust(m_marginSize,m_marginSize, -m_marginSize, -m_marginSize); Q_ASSERT(m_rect.isValid()); emit geometryChanged(m_rect); } @@ -201,7 +201,7 @@ void ChartPresenter::handleSeriesAdded(QSeries* series) pie->handleGeometryChanged(m_rect); break; } - case QChartSeries::SeriesTypeSpline: { + case QSeries::SeriesTypeSpline: { QSplineSeries* splineSeries = qobject_cast(series); SplinePresenter* splinePresenter = new SplinePresenter(splineSeries, m_chart); QObject::connect(this, SIGNAL(geometryChanged(const QRectF&)), splinePresenter, SLOT(handleGeometryChanged(const QRectF&))); diff --git a/src/charttheme.cpp b/src/charttheme.cpp index 50609bf..ba15e5f 100644 --- a/src/charttheme.cpp +++ b/src/charttheme.cpp @@ -21,7 +21,7 @@ #include "percentbarpresenter_p.h" #include "linechartitem_p.h" #include "scatterpresenter_p.h" -#include "piepresenter.h" +#include "piepresenter_p.h" #include "splinepresenter_p.h" //themes diff --git a/src/linechart/linechartitem_p.h b/src/linechart/linechartitem_p.h index 21d23ff..e751c90 100644 --- a/src/linechart/linechartitem_p.h +++ b/src/linechart/linechartitem_p.h @@ -36,18 +36,18 @@ public slots: public: virtual void updateItem(QVector& oldPoints,QVector& newPoints); virtual void updateItem(QVector& oldPoints,int index,QPointF& newPoint); - void applyGeometry(QVector& points); + virtual void applyGeometry(QVector& points); void createPoints(int count); void clearPoints(int count); QPointF calculateGeometryPoint(int index) const; QVector calculateGeometryPoints() const; -private: - ChartPresenter* m_presenter; +protected: QPainterPath m_path; - QLineSeries* m_series; - QSizeF m_size; QRectF m_rect; + QLineSeries* m_series; + ChartPresenter* m_presenter; + QSizeF m_size; QRectF m_clipRect; Domain m_domain; QGraphicsItemGroup m_items; diff --git a/src/linechart/qlineseries.h b/src/linechart/qlineseries.h index 2018bc6..009cdf9 100644 --- a/src/linechart/qlineseries.h +++ b/src/linechart/qlineseries.h @@ -12,11 +12,11 @@ QTCOMMERCIALCHART_BEGIN_NAMESPACE class QTCOMMERCIALCHART_EXPORT QLineSeries : public QSeries { Q_OBJECT -public: + public: QLineSeries(QObject* parent=0); virtual ~QLineSeries(); -public: // from QChartSeries + public: // from QChartSeries virtual QSeriesType type() const { return QSeries::SeriesTypeLine;} void add(qreal x, qreal y); void add(const QPointF& point); @@ -39,15 +39,17 @@ public: // from QChartSeries QLineSeries& operator << (const QPointF &point); friend QDebug operator<< (QDebug d, const QLineSeries series); -signals: + signals: void pointReplaced(int index); void pointRemoved(int index); void pointAdded(int index); void updated(); -private: + protected: QVector m_x; QVector m_y; + + private: QPen m_pen; bool m_pointsVisible; }; diff --git a/src/splinechart/qsplineseries.cpp b/src/splinechart/qsplineseries.cpp index 2c63fd4..15b1797 100644 --- a/src/splinechart/qsplineseries.cpp +++ b/src/splinechart/qsplineseries.cpp @@ -3,22 +3,22 @@ QTCOMMERCIALCHART_BEGIN_NAMESPACE QSplineSeries::QSplineSeries(QObject *parent) : - QChartSeries(parent) + QLineSeries(parent) { } -QSplineSeries& QSplineSeries::operator << (const QPointF &value) -{ -// d->m_data.append(value); - m_data.append(value); -// emit changed(); - return *this; -} +//QSplineSeries& QSplineSeries::operator << (const QPointF &value) +//{ +//// d->m_data.append(value); +// m_data.append(value); +//// emit changed(); +// return *this; +//} -void QSplineSeries::addData(QPointF value) -{ - m_data.append(value); -} +//void QSplineSeries::addData(QPointF value) +//{ +// m_data.append(value); +//} void QSplineSeries::calculateControlPoints() { @@ -26,15 +26,15 @@ void QSplineSeries::calculateControlPoints() // Based on http://www.codeproject.com/Articles/31859/Draw-a-Smooth-Curve-through-a-Set-of-2D-Points-wit // CPOL Licence - int n = m_data.size() - 1; + int n = m_x.size() - 1; if (n == 1) { // Special case: Bezier curve should be a straight line. // firstControlPoints = new Point[1]; // 3P1 = 2P0 + P3 - m_controlPoints.append(QPointF((2 * m_data[0].x() + m_data[1].x()) / 3, (2 * m_data[0].y() + m_data[1].y()) / 3)); + m_controlPoints.append(QPointF((2 * m_x[0] + m_x[1]) / 3, (2 * m_y[0] + m_y[1]) / 3)); // P2 = 2P1 P0 - m_controlPoints.append(QPointF(2 * m_controlPoints[0].x() - m_data[0].x(), 2 * m_controlPoints[0].y() - m_data[0].y())); + m_controlPoints.append(QPointF(2 * m_controlPoints[0].x() - m_x[0], 2 * m_controlPoints[0].y() - m_y[0])); return; } @@ -52,37 +52,37 @@ void QSplineSeries::calculateControlPoints() // | 0 0 0 0 0 0 0 0 ... 0 2 7 | | P1_n | | 8 * P(n-1) + Pn | // QList rhs; - rhs.append(m_data[0].x() + 2 * m_data[1].x()); + rhs.append(m_x[0] + 2 * m_x[1]); // Set right hand side X values - for (int i = 1; i < m_data.size() - 1; ++i) - rhs.append(4 * m_data[i].x() + 2 * m_data[i + 1].x()); + for (int i = 1; i < m_x.size() - 1; ++i) + rhs.append(4 * m_x[i] + 2 * m_x[i + 1]); - rhs.append((8 * m_data[n - 1].x() + m_data[n].x()) / 2.0); + rhs.append((8 * m_x[n - 1] + m_x[n]) / 2.0); // Get first control points X-values QList x = getFirstControlPoints(rhs); - rhs[0] = m_data[0].y() + 2 * m_data[1].y(); + rhs[0] = m_y[0] + 2 * m_y[1]; // Set right hand side Y values - for (int i = 1; i < m_data.size() - 1; ++i) - rhs[i] = 4 * m_data[i].y() + 2 * m_data[i + 1].y(); + for (int i = 1; i < m_y.size() - 1; ++i) + rhs[i] = 4 * m_y[i] + 2 * m_y[i + 1]; - rhs[n - 1] = (8 * m_data[n - 1].y() + m_data[n].y()) / 2.0; + rhs[n - 1] = (8 * m_y[n - 1] + m_y[n]) / 2.0; // Get first control points Y-values QList y = getFirstControlPoints(rhs); // Fill output arrays. // firstControlPoints = new Point[n]; // secondControlPoints = new Point[n]; - for (int i = 0; i < m_data.size(); ++i) + for (int i = 0; i < m_x.size(); ++i) { // First control point m_controlPoints.append(QPointF(x[i], y[i])); // Second control point if (i < n - 1) - m_controlPoints.append(QPointF(2 * m_data[i + 1].x() - x[i + 1], 2 * m_data[i + 1].y() - y[i + 1])); + m_controlPoints.append(QPointF(2 * m_x[i + 1] - x[i + 1], 2 * m_y[i + 1] - y[i + 1])); else - m_controlPoints.append(QPointF((m_data[n].x() + x[n - 1]) / 2, (m_data[n].y() + y[n - 1]) / 2)); + m_controlPoints.append(QPointF((m_x[n] + x[n - 1]) / 2, (m_y[n] + y[n - 1]) / 2)); } } diff --git a/src/splinechart/qsplineseries.h b/src/splinechart/qsplineseries.h index 0439b21..9a37010 100644 --- a/src/splinechart/qsplineseries.h +++ b/src/splinechart/qsplineseries.h @@ -3,27 +3,27 @@ #include "qchartglobal.h" #include -#include "qchartseries.h" +#include "qlineseries.h" #include #include QTCOMMERCIALCHART_BEGIN_NAMESPACE -class QSplineSeries : public QChartSeries +class QSplineSeries : public QLineSeries { Q_OBJECT public: QSplineSeries(QObject *parent = 0); - QChartSeriesType type() const { return QChartSeries::SeriesTypeSpline; } - void addData(QPointF value); - QSplineSeries& operator << (const QPointF &value); + QSeriesType type() const { return QSeries::SeriesTypeSpline; } +// void addData(QPointF value); +// QSplineSeries& operator << (const QPointF &value); void calculateControlPoints(); QList getFirstControlPoints(QList rhs); - int count() const { return m_data.size(); } + int count() const { return m_x.size(); } - QPointF at(int index) const { return m_data[index]; } +// QPointF at(int index) const { return m_data[index]; } QPointF controlPoint(int index) const { return m_controlPoints[index]; } signals: @@ -31,7 +31,7 @@ class QSplineSeries : public QChartSeries public slots: private: - QList m_data; +// QList m_data; QList m_controlPoints; }; diff --git a/src/splinechart/splinepresenter.cpp b/src/splinechart/splinepresenter.cpp index 0d0fe57..b20ba3c 100644 --- a/src/splinechart/splinepresenter.cpp +++ b/src/splinechart/splinepresenter.cpp @@ -4,7 +4,7 @@ QTCOMMERCIALCHART_BEGIN_NAMESPACE SplinePresenter::SplinePresenter(QSplineSeries* series, QGraphicsObject *parent) : - LineChartItem(this, parent),m_series(series)//,m_boundingRect() + LineChartItem(0, series, parent)//,m_boundingRect() { // if (parent) // m_boundingRect = parent->boundingRect(); @@ -22,22 +22,56 @@ SplinePresenter::SplinePresenter(QSplineSeries* series, QGraphicsObject *parent) // // //} -void SplinePresenter::updateGeometry() +QPointF SplinePresenter::calculateGeometryControlPoint(int index) const { + QSplineSeries* splineSeries = qobject_cast(m_series); + const qreal deltaX = m_size.width()/m_domain.spanX(); + const qreal deltaY = m_size.height()/m_domain.spanY(); + qreal x = (splineSeries->controlPoint(index).x() - m_domain.m_minX)* deltaX; + qreal y = (splineSeries->controlPoint(index).y() - m_domain.m_minY)*-deltaY + m_size.height(); + return QPointF(x,y); +} + +void SplinePresenter::applyGeometry(QVector& points) +{ + if(points.size()==0) return; - if(m_data.size()==0) return; +// QList items = m_items.childItems(); - prepareGeometryChange(); - QPainterPath path; - const QPointF& point = m_data.at(0); - path.moveTo(point); + QPainterPath splinePath; + const QPointF& point = points.at(0); + splinePath.moveTo(point); +// QGraphicsItem* item = items.at(0); +// item->setPos(point.x()-1,point.y()-1); +// if(!m_clipRect.contains(point)) item->setVisible(false); - foreach( const QPointF& point , m_data) { - path.lineTo(point); - } + QSplineSeries* splineSeries = qobject_cast(m_series); + for (int i = 0; i < splineSeries->count() - 1; i++) + { + const QPointF& point = points.at(i + 1); +// painter->setPen(Qt::red); +// splinePath.cubicTo(qobject_cast(m_series)->controlPoint(2 * i), qobject_cast(m_series)->controlPoint(2 * i + 1), QPointF(m_series->x(i + 1), m_series->y(i + 1))); + splinePath.cubicTo(calculateGeometryControlPoint(2 * i), calculateGeometryControlPoint(2 * i + 1), point); +// painter->drawEllipse(m_series->at(i), 4, 4); - m_path = path; - m_rect = path.boundingRect(); +// painter->setPen(Qt::blue); +// painter->drawLine(m_series->at(i), m_series->controlPoint(2 * i)); +// painter->drawLine(m_series->at(i + 1), m_series->controlPoint(2 * i + 1)); +// painter->drawEllipse(m_series->controlPoint(2 * i), 4, 4); +// painter->drawEllipse(m_series->controlPoint(2 * i + 1), 4, 4); + } + +// for(int i=1 ; i< points.size();i++) { +// QGraphicsItem* item = items.at(i); +// const QPointF& point = points.at(i); +// item->setPos(point.x()-1,point.y()-1); +// if(!m_clipRect.contains(point)) item->setVisible(false); +// path.lineTo(point); +// } + + prepareGeometryChange(); + m_path = splinePath; + m_rect = splinePath.boundingRect(); } //void SplinePresenter::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) diff --git a/src/splinechart/splinepresenter_p.h b/src/splinechart/splinepresenter_p.h index 9804633..77799ae 100644 --- a/src/splinechart/splinepresenter_p.h +++ b/src/splinechart/splinepresenter_p.h @@ -16,6 +16,10 @@ public: void updateGeometry(); + void applyGeometry(QVector& points); + + QPointF calculateGeometryControlPoint(int index) const; + // QRectF boundingRect() const { return m_boundingRect; } // void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); @@ -26,7 +30,7 @@ public slots: // void handleGeometryChanged(const QRectF& rect); private: - QSplineSeries* m_series; +// QSplineSeries* m_series; // QRectF m_boundingRect; }; diff --git a/src/src.pro b/src/src.pro index b795d3e..e637ede 100644 --- a/src/src.pro +++ b/src/src.pro @@ -88,9 +88,4 @@ unix:QMAKE_DISTCLEAN += -r \ $$CHART_BUILD_LIB_DIR win32:QMAKE_DISTCLEAN += /Q \ $$CHART_BUILD_HEADER_DIR \ -<<<<<<< HEAD $$CHART_BUILD_LIB_DIR -======= - $$CHART_BUILD_LIB_DIR - ->>>>>>> spline