@@ -1,7 +1,7 | |||
|
1 | 1 | #include "splinewidget.h" |
|
2 | 2 | #include "qchartview.h" |
|
3 | 3 | #include "qsplineseries.h" |
|
4 |
#include "qline |
|
|
4 | #include "qlineseries.h" | |
|
5 | 5 | #include <QGridLayout> |
|
6 | 6 | |
|
7 | 7 | QTCOMMERCIALCHART_USE_NAMESPACE |
@@ -11,23 +11,23 SplineWidget::SplineWidget(QWidget *parent) | |||
|
11 | 11 | { |
|
12 | 12 | //create QSplineSeries |
|
13 | 13 | QSplineSeries* series = new QSplineSeries(this); |
|
14 |
series->add |
|
|
15 |
series->add |
|
|
16 |
series->add |
|
|
17 |
series->add |
|
|
18 |
series->add |
|
|
19 |
series->add |
|
|
20 |
series->add |
|
|
14 | series->add(QPointF(150, 100)); | |
|
15 | series->add(QPointF(200, 180)); | |
|
16 | series->add(QPointF(240, 130)); | |
|
17 | series->add(QPointF(270, 120)); | |
|
18 | series->add(QPointF(310, 120)); | |
|
19 | series->add(QPointF(420, 160)); | |
|
20 | series->add(QPointF(535, 250)); | |
|
21 | 21 | |
|
22 | 22 | series->calculateControlPoints(); |
|
23 | 23 | |
|
24 |
QLine |
|
|
25 | for (int i = 0; i < series->count() - 1; i++) | |
|
26 | { | |
|
27 | lineSeries->add(series->at(i).x(), series->at(i).y()); | |
|
28 | lineSeries->add(series->controlPoint(2*i).x(), series->controlPoint(2*i).y()); | |
|
29 | lineSeries->add(series->controlPoint(2*i + 1).x(), series->controlPoint(2*i + 1).y()); | |
|
30 | } | |
|
24 | // QLineSeries* lineSeries = new QLineSeries; | |
|
25 | // for (int i = 0; i < series->count() - 1; i++) | |
|
26 | // { | |
|
27 | // lineSeries->add(series->at(i).x(), series->at(i).y()); | |
|
28 | // lineSeries->add(series->controlPoint(2*i).x(), series->controlPoint(2*i).y()); | |
|
29 | // lineSeries->add(series->controlPoint(2*i + 1).x(), series->controlPoint(2*i + 1).y()); | |
|
30 | // } | |
|
31 | 31 | |
|
32 | 32 | // QLineChartSeries* lineSeries2 = new QLineChartSeries; |
|
33 | 33 | // lineSeries2->add(10, 50); |
@@ -124,13 +124,13 void ChartDataSet::addSeries(QSeries* series, QChartAxis *axisY) | |||
|
124 | 124 | break; |
|
125 | 125 | } |
|
126 | 126 | |
|
127 |
case Q |
|
|
127 | case QSeries::SeriesTypeSpline: { | |
|
128 | 128 | QSplineSeries* splineSeries = static_cast<QSplineSeries*>(series); |
|
129 | 129 | |
|
130 | 130 | for (int i = 0; i < splineSeries->count(); i++) |
|
131 | 131 | { |
|
132 |
qreal x = splineSeries-> |
|
|
133 |
qreal y = splineSeries-> |
|
|
132 | qreal x = splineSeries->x(i); | |
|
133 | qreal y = splineSeries->y(i); | |
|
134 | 134 | domain.m_minX = qMin(domain.m_minX,x); |
|
135 | 135 | domain.m_minY = qMin(domain.m_minY,y); |
|
136 | 136 | domain.m_maxX = qMax(domain.m_maxX,x); |
@@ -62,7 +62,7 QRectF ChartPresenter::geometry() const | |||
|
62 | 62 | void ChartPresenter::handleGeometryChanged() |
|
63 | 63 | { |
|
64 | 64 | m_rect = QRectF(QPoint(0,0),m_chart->size()); |
|
65 |
|
|
|
65 | m_rect.adjust(m_marginSize,m_marginSize, -m_marginSize, -m_marginSize); | |
|
66 | 66 | Q_ASSERT(m_rect.isValid()); |
|
67 | 67 | emit geometryChanged(m_rect); |
|
68 | 68 | } |
@@ -201,7 +201,7 void ChartPresenter::handleSeriesAdded(QSeries* series) | |||
|
201 | 201 | pie->handleGeometryChanged(m_rect); |
|
202 | 202 | break; |
|
203 | 203 | } |
|
204 |
case Q |
|
|
204 | case QSeries::SeriesTypeSpline: { | |
|
205 | 205 | QSplineSeries* splineSeries = qobject_cast<QSplineSeries*>(series); |
|
206 | 206 | SplinePresenter* splinePresenter = new SplinePresenter(splineSeries, m_chart); |
|
207 | 207 | QObject::connect(this, SIGNAL(geometryChanged(const QRectF&)), splinePresenter, SLOT(handleGeometryChanged(const QRectF&))); |
@@ -21,7 +21,7 | |||
|
21 | 21 | #include "percentbarpresenter_p.h" |
|
22 | 22 | #include "linechartitem_p.h" |
|
23 | 23 | #include "scatterpresenter_p.h" |
|
24 | #include "piepresenter.h" | |
|
24 | #include "piepresenter_p.h" | |
|
25 | 25 | #include "splinepresenter_p.h" |
|
26 | 26 | |
|
27 | 27 | //themes |
@@ -36,18 +36,18 public slots: | |||
|
36 | 36 | public: |
|
37 | 37 | virtual void updateItem(QVector<QPointF>& oldPoints,QVector<QPointF>& newPoints); |
|
38 | 38 | virtual void updateItem(QVector<QPointF>& oldPoints,int index,QPointF& newPoint); |
|
39 | void applyGeometry(QVector<QPointF>& points); | |
|
39 | virtual void applyGeometry(QVector<QPointF>& points); | |
|
40 | 40 | void createPoints(int count); |
|
41 | 41 | void clearPoints(int count); |
|
42 | 42 | QPointF calculateGeometryPoint(int index) const; |
|
43 | 43 | QVector<QPointF> calculateGeometryPoints() const; |
|
44 | 44 | |
|
45 | private: | |
|
46 | ChartPresenter* m_presenter; | |
|
45 | protected: | |
|
47 | 46 | QPainterPath m_path; |
|
47 | QRectF m_rect; | |
|
48 | 48 | QLineSeries* m_series; |
|
49 | ChartPresenter* m_presenter; | |
|
49 | 50 | QSizeF m_size; |
|
50 | QRectF m_rect; | |
|
51 | 51 |
|
|
52 | 52 | Domain m_domain; |
|
53 | 53 | QGraphicsItemGroup m_items; |
@@ -45,9 +45,11 signals: | |||
|
45 | 45 | void pointAdded(int index); |
|
46 | 46 | void updated(); |
|
47 | 47 | |
|
48 | private: | |
|
48 | protected: | |
|
49 | 49 | QVector<qreal> m_x; |
|
50 | 50 | QVector<qreal> m_y; |
|
51 | ||
|
52 | private: | |
|
51 | 53 | QPen m_pen; |
|
52 | 54 | bool m_pointsVisible; |
|
53 | 55 | }; |
@@ -3,22 +3,22 | |||
|
3 | 3 | QTCOMMERCIALCHART_BEGIN_NAMESPACE |
|
4 | 4 | |
|
5 | 5 | QSplineSeries::QSplineSeries(QObject *parent) : |
|
6 |
Q |
|
|
6 | QLineSeries(parent) | |
|
7 | 7 | { |
|
8 | 8 | } |
|
9 | 9 | |
|
10 | QSplineSeries& QSplineSeries::operator << (const QPointF &value) | |
|
11 | { | |
|
12 | // d->m_data.append(value); | |
|
13 | m_data.append(value); | |
|
14 | // emit changed(); | |
|
15 | return *this; | |
|
16 | } | |
|
10 | //QSplineSeries& QSplineSeries::operator << (const QPointF &value) | |
|
11 | //{ | |
|
12 | //// d->m_data.append(value); | |
|
13 | // m_data.append(value); | |
|
14 | //// emit changed(); | |
|
15 | // return *this; | |
|
16 | //} | |
|
17 | 17 | |
|
18 | void QSplineSeries::addData(QPointF value) | |
|
19 | { | |
|
20 | m_data.append(value); | |
|
21 | } | |
|
18 | //void QSplineSeries::addData(QPointF value) | |
|
19 | //{ | |
|
20 | // m_data.append(value); | |
|
21 | //} | |
|
22 | 22 | |
|
23 | 23 | void QSplineSeries::calculateControlPoints() |
|
24 | 24 | { |
@@ -26,15 +26,15 void QSplineSeries::calculateControlPoints() | |||
|
26 | 26 | // Based on http://www.codeproject.com/Articles/31859/Draw-a-Smooth-Curve-through-a-Set-of-2D-Points-wit |
|
27 | 27 | // CPOL Licence |
|
28 | 28 | |
|
29 |
int n = m_ |
|
|
29 | int n = m_x.size() - 1; | |
|
30 | 30 | if (n == 1) |
|
31 | 31 | { // Special case: Bezier curve should be a straight line. |
|
32 | 32 | // firstControlPoints = new Point[1]; |
|
33 | 33 | // 3P1 = 2P0 + P3 |
|
34 |
m_controlPoints.append(QPointF((2 * m_ |
|
|
34 | m_controlPoints.append(QPointF((2 * m_x[0] + m_x[1]) / 3, (2 * m_y[0] + m_y[1]) / 3)); | |
|
35 | 35 | |
|
36 | 36 | // P2 = 2P1 P0 |
|
37 |
m_controlPoints.append(QPointF(2 * m_controlPoints[0].x() - m_ |
|
|
37 | m_controlPoints.append(QPointF(2 * m_controlPoints[0].x() - m_x[0], 2 * m_controlPoints[0].y() - m_y[0])); | |
|
38 | 38 | return; |
|
39 | 39 | } |
|
40 | 40 | |
@@ -52,37 +52,37 void QSplineSeries::calculateControlPoints() | |||
|
52 | 52 | // | 0 0 0 0 0 0 0 0 ... 0 2 7 | | P1_n | | 8 * P(n-1) + Pn | |
|
53 | 53 | // |
|
54 | 54 | QList<qreal> rhs; |
|
55 |
rhs.append(m_ |
|
|
55 | rhs.append(m_x[0] + 2 * m_x[1]); | |
|
56 | 56 | |
|
57 | 57 | // Set right hand side X values |
|
58 |
for (int i = 1; i < m_ |
|
|
59 |
rhs.append(4 * m_ |
|
|
58 | for (int i = 1; i < m_x.size() - 1; ++i) | |
|
59 | rhs.append(4 * m_x[i] + 2 * m_x[i + 1]); | |
|
60 | 60 | |
|
61 |
rhs.append((8 * m_ |
|
|
61 | rhs.append((8 * m_x[n - 1] + m_x[n]) / 2.0); | |
|
62 | 62 | // Get first control points X-values |
|
63 | 63 | QList<qreal> x = getFirstControlPoints(rhs); |
|
64 |
rhs[0] = m_ |
|
|
64 | rhs[0] = m_y[0] + 2 * m_y[1]; | |
|
65 | 65 | |
|
66 | 66 | // Set right hand side Y values |
|
67 |
for (int i = 1; i < m_ |
|
|
68 |
rhs[i] = 4 * m_ |
|
|
67 | for (int i = 1; i < m_y.size() - 1; ++i) | |
|
68 | rhs[i] = 4 * m_y[i] + 2 * m_y[i + 1]; | |
|
69 | 69 | |
|
70 |
rhs[n - 1] = (8 * m_ |
|
|
70 | rhs[n - 1] = (8 * m_y[n - 1] + m_y[n]) / 2.0; | |
|
71 | 71 | // Get first control points Y-values |
|
72 | 72 | QList<qreal> y = getFirstControlPoints(rhs); |
|
73 | 73 | |
|
74 | 74 | // Fill output arrays. |
|
75 | 75 | // firstControlPoints = new Point[n]; |
|
76 | 76 | // secondControlPoints = new Point[n]; |
|
77 |
for (int i = 0; i < m_ |
|
|
77 | for (int i = 0; i < m_x.size(); ++i) | |
|
78 | 78 | { |
|
79 | 79 | // First control point |
|
80 | 80 | m_controlPoints.append(QPointF(x[i], y[i])); |
|
81 | 81 | // Second control point |
|
82 | 82 | if (i < n - 1) |
|
83 |
m_controlPoints.append(QPointF(2 * m_ |
|
|
83 | m_controlPoints.append(QPointF(2 * m_x[i + 1] - x[i + 1], 2 * m_y[i + 1] - y[i + 1])); | |
|
84 | 84 | else |
|
85 |
m_controlPoints.append(QPointF((m_ |
|
|
85 | m_controlPoints.append(QPointF((m_x[n] + x[n - 1]) / 2, (m_y[n] + y[n - 1]) / 2)); | |
|
86 | 86 | } |
|
87 | 87 | } |
|
88 | 88 |
@@ -3,27 +3,27 | |||
|
3 | 3 | |
|
4 | 4 | #include "qchartglobal.h" |
|
5 | 5 | #include <QtGlobal> |
|
6 |
#include "q |
|
|
6 | #include "qlineseries.h" | |
|
7 | 7 | #include <QList> |
|
8 | 8 | #include <QPointF> |
|
9 | 9 | |
|
10 | 10 | QTCOMMERCIALCHART_BEGIN_NAMESPACE |
|
11 | 11 | |
|
12 |
class QSplineSeries : public Q |
|
|
12 | class QSplineSeries : public QLineSeries | |
|
13 | 13 | { |
|
14 | 14 | Q_OBJECT |
|
15 | 15 | public: |
|
16 | 16 | |
|
17 | 17 | QSplineSeries(QObject *parent = 0); |
|
18 |
Q |
|
|
19 | void addData(QPointF value); | |
|
20 | QSplineSeries& operator << (const QPointF &value); | |
|
18 | QSeriesType type() const { return QSeries::SeriesTypeSpline; } | |
|
19 | // void addData(QPointF value); | |
|
20 | // QSplineSeries& operator << (const QPointF &value); | |
|
21 | 21 | void calculateControlPoints(); |
|
22 | 22 | QList<qreal> getFirstControlPoints(QList<qreal> rhs); |
|
23 | 23 | |
|
24 |
int count() const { return m_ |
|
|
24 | int count() const { return m_x.size(); } | |
|
25 | 25 | |
|
26 | QPointF at(int index) const { return m_data[index]; } | |
|
26 | // QPointF at(int index) const { return m_data[index]; } | |
|
27 | 27 | QPointF controlPoint(int index) const { return m_controlPoints[index]; } |
|
28 | 28 | |
|
29 | 29 | signals: |
@@ -31,7 +31,7 class QSplineSeries : public QChartSeries | |||
|
31 | 31 | public slots: |
|
32 | 32 | |
|
33 | 33 | private: |
|
34 | QList<QPointF> m_data; | |
|
34 | // QList<QPointF> m_data; | |
|
35 | 35 | QList<QPointF> m_controlPoints; |
|
36 | 36 | |
|
37 | 37 | }; |
@@ -4,7 +4,7 | |||
|
4 | 4 | QTCOMMERCIALCHART_BEGIN_NAMESPACE |
|
5 | 5 | |
|
6 | 6 | SplinePresenter::SplinePresenter(QSplineSeries* series, QGraphicsObject *parent) : |
|
7 |
LineChartItem( |
|
|
7 | LineChartItem(0, series, parent)//,m_boundingRect() | |
|
8 | 8 | { |
|
9 | 9 | // if (parent) |
|
10 | 10 | // m_boundingRect = parent->boundingRect(); |
@@ -22,22 +22,56 SplinePresenter::SplinePresenter(QSplineSeries* series, QGraphicsObject *parent) | |||
|
22 | 22 | // // |
|
23 | 23 | //} |
|
24 | 24 | |
|
25 |
|
|
|
25 | QPointF SplinePresenter::calculateGeometryControlPoint(int index) const | |
|
26 | 26 | { |
|
27 | QSplineSeries* splineSeries = qobject_cast<QSplineSeries*>(m_series); | |
|
28 | const qreal deltaX = m_size.width()/m_domain.spanX(); | |
|
29 | const qreal deltaY = m_size.height()/m_domain.spanY(); | |
|
30 | qreal x = (splineSeries->controlPoint(index).x() - m_domain.m_minX)* deltaX; | |
|
31 | qreal y = (splineSeries->controlPoint(index).y() - m_domain.m_minY)*-deltaY + m_size.height(); | |
|
32 | return QPointF(x,y); | |
|
33 | } | |
|
34 | ||
|
35 | void SplinePresenter::applyGeometry(QVector<QPointF>& points) | |
|
36 | { | |
|
37 | if(points.size()==0) return; | |
|
27 | 38 | |
|
28 | if(m_data.size()==0) return; | |
|
39 | // QList<QGraphicsItem*> items = m_items.childItems(); | |
|
29 | 40 | |
|
30 | prepareGeometryChange(); | |
|
31 | QPainterPath path; | |
|
32 | const QPointF& point = m_data.at(0); | |
|
33 | path.moveTo(point); | |
|
41 | QPainterPath splinePath; | |
|
42 | const QPointF& point = points.at(0); | |
|
43 | splinePath.moveTo(point); | |
|
44 | // QGraphicsItem* item = items.at(0); | |
|
45 | // item->setPos(point.x()-1,point.y()-1); | |
|
46 | // if(!m_clipRect.contains(point)) item->setVisible(false); | |
|
47 | ||
|
48 | QSplineSeries* splineSeries = qobject_cast<QSplineSeries*>(m_series); | |
|
49 | for (int i = 0; i < splineSeries->count() - 1; i++) | |
|
50 | { | |
|
51 | const QPointF& point = points.at(i + 1); | |
|
52 | // painter->setPen(Qt::red); | |
|
53 | // splinePath.cubicTo(qobject_cast<QSplineSeries*>(m_series)->controlPoint(2 * i), qobject_cast<QSplineSeries*>(m_series)->controlPoint(2 * i + 1), QPointF(m_series->x(i + 1), m_series->y(i + 1))); | |
|
54 | splinePath.cubicTo(calculateGeometryControlPoint(2 * i), calculateGeometryControlPoint(2 * i + 1), point); | |
|
55 | // painter->drawEllipse(m_series->at(i), 4, 4); | |
|
34 | 56 | |
|
35 | foreach( const QPointF& point , m_data) { | |
|
36 | path.lineTo(point); | |
|
57 | // painter->setPen(Qt::blue); | |
|
58 | // painter->drawLine(m_series->at(i), m_series->controlPoint(2 * i)); | |
|
59 | // painter->drawLine(m_series->at(i + 1), m_series->controlPoint(2 * i + 1)); | |
|
60 | // painter->drawEllipse(m_series->controlPoint(2 * i), 4, 4); | |
|
61 | // painter->drawEllipse(m_series->controlPoint(2 * i + 1), 4, 4); | |
|
37 | 62 | } |
|
38 | 63 | |
|
39 | m_path = path; | |
|
40 | m_rect = path.boundingRect(); | |
|
64 | // for(int i=1 ; i< points.size();i++) { | |
|
65 | // QGraphicsItem* item = items.at(i); | |
|
66 | // const QPointF& point = points.at(i); | |
|
67 | // item->setPos(point.x()-1,point.y()-1); | |
|
68 | // if(!m_clipRect.contains(point)) item->setVisible(false); | |
|
69 | // path.lineTo(point); | |
|
70 | // } | |
|
71 | ||
|
72 | prepareGeometryChange(); | |
|
73 | m_path = splinePath; | |
|
74 | m_rect = splinePath.boundingRect(); | |
|
41 | 75 | } |
|
42 | 76 | |
|
43 | 77 | //void SplinePresenter::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) |
@@ -16,6 +16,10 public: | |||
|
16 | 16 | |
|
17 | 17 | void updateGeometry(); |
|
18 | 18 | |
|
19 | void applyGeometry(QVector<QPointF>& points); | |
|
20 | ||
|
21 | QPointF calculateGeometryControlPoint(int index) const; | |
|
22 | ||
|
19 | 23 | // QRectF boundingRect() const { return m_boundingRect; } |
|
20 | 24 | // void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); |
|
21 | 25 | |
@@ -26,7 +30,7 public slots: | |||
|
26 | 30 | // void handleGeometryChanged(const QRectF& rect); |
|
27 | 31 | |
|
28 | 32 | private: |
|
29 | QSplineSeries* m_series; | |
|
33 | // QSplineSeries* m_series; | |
|
30 | 34 | // QRectF m_boundingRect; |
|
31 | 35 | |
|
32 | 36 | }; |
General Comments 0
You need to be logged in to leave comments.
Login now