##// END OF EJS Templates
QSplineSeries calculateControlPoints moved to splinechartitem. This way we don't need to deal with controlPoints on logaritmic scale
Marek Rosa -
r2372:d6a999e30ac3
parent child
Show More
@@ -1,135 +1,134
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "chartlogvalueaxisx_p.h"
21 #include "chartlogvalueaxisx_p.h"
22 #include "chartpresenter_p.h"
22 #include "chartpresenter_p.h"
23 #include "qlogvalueaxis.h"
23 #include "qlogvalueaxis.h"
24 #include "chartlayout_p.h"
24 #include "chartlayout_p.h"
25 #include <QGraphicsLayout>
25 #include <QGraphicsLayout>
26 #include <QFontMetrics>
26 #include <QFontMetrics>
27 #include <qmath.h>
27 #include <qmath.h>
28 #include <QDebug>
28 #include <QDebug>
29
29
30 QTCOMMERCIALCHART_BEGIN_NAMESPACE
30 QTCOMMERCIALCHART_BEGIN_NAMESPACE
31
31
32 ChartLogValueAxisX::ChartLogValueAxisX(QLogValueAxis *axis, QGraphicsItem* item)
32 ChartLogValueAxisX::ChartLogValueAxisX(QLogValueAxis *axis, QGraphicsItem* item)
33 : HorizontalAxis(axis, item),
33 : HorizontalAxis(axis, item),
34 m_axis(axis)
34 m_axis(axis)
35 {
35 {
36 QObject::connect(m_axis,SIGNAL(baseChanged(qreal)),this, SLOT(handleBaseChanged(qreal)));
36 QObject::connect(m_axis,SIGNAL(baseChanged(qreal)),this, SLOT(handleBaseChanged(qreal)));
37 QObject::connect(m_axis,SIGNAL(labelFormatChanged(QString)),this, SLOT(handleLabelFormatChanged(QString)));
37 QObject::connect(m_axis,SIGNAL(labelFormatChanged(QString)),this, SLOT(handleLabelFormatChanged(QString)));
38 }
38 }
39
39
40 ChartLogValueAxisX::~ChartLogValueAxisX()
40 ChartLogValueAxisX::~ChartLogValueAxisX()
41 {
41 {
42 }
42 }
43
43
44 QVector<qreal> ChartLogValueAxisX::calculateLayout() const
44 QVector<qreal> ChartLogValueAxisX::calculateLayout() const
45 {
45 {
46 QVector<qreal> points;
46 QVector<qreal> points;
47
47
48 qreal logMax = log10(m_axis->max()) / log10(m_axis->base());
48 qreal logMax = log10(m_axis->max()) / log10(m_axis->base());
49 qreal logMin = log10(m_axis->min()) / log10(m_axis->base());
49 qreal logMin = log10(m_axis->min()) / log10(m_axis->base());
50 qreal leftEdge = logMin < logMax ? logMin : logMax;
50 qreal leftEdge = logMin < logMax ? logMin : logMax;
51 qreal ceilEdge = ceil(leftEdge);
51 qreal ceilEdge = ceil(leftEdge);
52 int tickCount = qAbs(qRound(logMax - logMin));
52 int tickCount = qAbs(ceil(logMax) - ceil(logMin));
53 tickCount++;
54
53
55 points.resize(tickCount);
54 points.resize(tickCount);
56 const QRectF &gridRect = gridGeometry();
55 const QRectF &gridRect = gridGeometry();
57 const qreal deltaX = gridRect.width() / qAbs(logMax - logMin);
56 const qreal deltaX = gridRect.width() / qAbs(logMax - logMin);
58 for (int i = 0; i < tickCount; ++i)
57 for (int i = 0; i < tickCount; ++i)
59 points[i] = (ceilEdge + i) * deltaX - leftEdge * deltaX + gridRect.left();
58 points[i] = (ceilEdge + i) * deltaX - leftEdge * deltaX + gridRect.left();
60
59
61 return points;
60 return points;
62 }
61 }
63
62
64 void ChartLogValueAxisX::updateGeometry()
63 void ChartLogValueAxisX::updateGeometry()
65 {
64 {
66 const QVector<qreal>& layout = ChartAxis::layout();
65 const QVector<qreal>& layout = ChartAxis::layout();
67 if (layout.isEmpty())
66 if (layout.isEmpty())
68 return;
67 return;
69 setLabels(createLogValueLabels(m_axis->min(), m_axis->max(), m_axis->base(), layout.size(), m_axis->labelFormat()));
68 setLabels(createLogValueLabels(m_axis->min(), m_axis->max(), m_axis->base(), layout.size(), m_axis->labelFormat()));
70 HorizontalAxis::updateGeometry();
69 HorizontalAxis::updateGeometry();
71 }
70 }
72
71
73 void ChartLogValueAxisX::handleBaseChanged(qreal base)
72 void ChartLogValueAxisX::handleBaseChanged(qreal base)
74 {
73 {
75 Q_UNUSED(base);
74 Q_UNUSED(base);
76 QGraphicsLayoutItem::updateGeometry();
75 QGraphicsLayoutItem::updateGeometry();
77 if(presenter()) presenter()->layout()->invalidate();
76 if(presenter()) presenter()->layout()->invalidate();
78 }
77 }
79
78
80 void ChartLogValueAxisX::handleLabelFormatChanged(const QString &format)
79 void ChartLogValueAxisX::handleLabelFormatChanged(const QString &format)
81 {
80 {
82 Q_UNUSED(format);
81 Q_UNUSED(format);
83 QGraphicsLayoutItem::updateGeometry();
82 QGraphicsLayoutItem::updateGeometry();
84 if(presenter()) presenter()->layout()->invalidate();
83 if(presenter()) presenter()->layout()->invalidate();
85 }
84 }
86
85
87 QSizeF ChartLogValueAxisX::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
86 QSizeF ChartLogValueAxisX::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
88 {
87 {
89 Q_UNUSED(constraint)
88 Q_UNUSED(constraint)
90
89
91 QFontMetrics fn(font());
90 QFontMetrics fn(font());
92 QSizeF sh;
91 QSizeF sh;
93
92
94 QSizeF base = HorizontalAxis::sizeHint(which, constraint);
93 QSizeF base = HorizontalAxis::sizeHint(which, constraint);
95 QStringList ticksList;
94 QStringList ticksList;
96 qreal logMax = log10(m_axis->max()) / log10(m_axis->base());
95 qreal logMax = log10(m_axis->max()) / log10(m_axis->base());
97 qreal logMin = log10(m_axis->min()) / log10(m_axis->base());
96 qreal logMin = log10(m_axis->min()) / log10(m_axis->base());
98 int tickCount = qAbs(ceil(logMax) - ceil(logMin));
97 int tickCount = qAbs(ceil(logMax) - ceil(logMin));
99 if (m_axis->max() > m_axis->min() && tickCount > 1)
98 if (m_axis->max() > m_axis->min() && tickCount > 1)
100 ticksList = createLogValueLabels(m_axis->min(), m_axis->max(), m_axis->base(), tickCount, m_axis->labelFormat());
99 ticksList = createLogValueLabels(m_axis->min(), m_axis->max(), m_axis->base(), tickCount, m_axis->labelFormat());
101 else
100 else
102 ticksList.append(QString(" "));
101 ticksList.append(QString(" "));
103 qreal width = 0;
102 qreal width = 0;
104 qreal height = 0;
103 qreal height = 0;
105
104
106
105
107 switch (which) {
106 switch (which) {
108 case Qt::MinimumSize:{
107 case Qt::MinimumSize:{
109 int count = qMax(ticksList.last().count(),ticksList.first().count());
108 int count = qMax(ticksList.last().count(),ticksList.first().count());
110 width = fn.averageCharWidth() * count;
109 width = fn.averageCharWidth() * count;
111 height = fn.height() + labelPadding();
110 height = fn.height() + labelPadding();
112 width = qMax(width,base.width());
111 width = qMax(width,base.width());
113 height += base.height();
112 height += base.height();
114 sh = QSizeF(width,height);
113 sh = QSizeF(width,height);
115 break;
114 break;
116 }
115 }
117 case Qt::PreferredSize: {
116 case Qt::PreferredSize: {
118 int count = qMax(ticksList.last().count(),ticksList.first().count());
117 int count = qMax(ticksList.last().count(),ticksList.first().count());
119 width=fn.averageCharWidth() * count;
118 width=fn.averageCharWidth() * count;
120 height=fn.height()+labelPadding();
119 height=fn.height()+labelPadding();
121 width=qMax(width,base.width());
120 width=qMax(width,base.width());
122 height+=base.height();
121 height+=base.height();
123 sh = QSizeF(width,height);
122 sh = QSizeF(width,height);
124 break;
123 break;
125 }
124 }
126 default:
125 default:
127 break;
126 break;
128 }
127 }
129
128
130 return sh;
129 return sh;
131 }
130 }
132
131
133 #include "moc_chartlogvalueaxisx_p.cpp"
132 #include "moc_chartlogvalueaxisx_p.cpp"
134
133
135 QTCOMMERCIALCHART_END_NAMESPACE
134 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,135 +1,132
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "chartlogvalueaxisy_p.h"
21 #include "chartlogvalueaxisy_p.h"
22 #include "chartpresenter_p.h"
22 #include "chartpresenter_p.h"
23 #include "qlogvalueaxis.h"
23 #include "qlogvalueaxis.h"
24 #include "chartlayout_p.h"
24 #include "chartlayout_p.h"
25 #include <QGraphicsLayout>
25 #include <QGraphicsLayout>
26 #include <QFontMetrics>
26 #include <QFontMetrics>
27 #include <qmath.h>
27 #include <qmath.h>
28 #include <QDebug>
28 #include <QDebug>
29
29
30 QTCOMMERCIALCHART_BEGIN_NAMESPACE
30 QTCOMMERCIALCHART_BEGIN_NAMESPACE
31
31
32 ChartLogValueAxisY::ChartLogValueAxisY(QLogValueAxis *axis, QGraphicsItem* item)
32 ChartLogValueAxisY::ChartLogValueAxisY(QLogValueAxis *axis, QGraphicsItem* item)
33 : VerticalAxis(axis, item),
33 : VerticalAxis(axis, item),
34 m_axis(axis)
34 m_axis(axis)
35 {
35 {
36 QObject::connect(m_axis, SIGNAL(baseChanged(qreal)),this, SLOT(handleBaseChanged(qreal)));
36 QObject::connect(m_axis, SIGNAL(baseChanged(qreal)),this, SLOT(handleBaseChanged(qreal)));
37 QObject::connect(m_axis,SIGNAL(labelFormatChanged(QString)),this, SLOT(handleLabelFormatChanged(QString)));
37 QObject::connect(m_axis,SIGNAL(labelFormatChanged(QString)),this, SLOT(handleLabelFormatChanged(QString)));
38 }
38 }
39
39
40 ChartLogValueAxisY::~ChartLogValueAxisY()
40 ChartLogValueAxisY::~ChartLogValueAxisY()
41 {
41 {
42 }
42 }
43
43
44 QVector<qreal> ChartLogValueAxisY::calculateLayout() const
44 QVector<qreal> ChartLogValueAxisY::calculateLayout() const
45 {
45 {
46 QVector<qreal> points;
46 QVector<qreal> points;
47 qreal logMax = log10(m_axis->max()) / log10(m_axis->base());
47 qreal logMax = log10(m_axis->max()) / log10(m_axis->base());
48 qreal logMin = log10(m_axis->min()) / log10(m_axis->base());
48 qreal logMin = log10(m_axis->min()) / log10(m_axis->base());
49 qreal leftEdge = logMin < logMax ? logMin : logMax;
49 qreal leftEdge = logMin < logMax ? logMin : logMax;
50 qreal ceilEdge = ceil(leftEdge);
50 qreal ceilEdge = ceil(leftEdge);
51 int tickCount = qAbs(qRound(logMax - logMin));
51 int tickCount = qAbs(ceil(logMax) - ceil(logMin));
52 tickCount++;
53
52
54 points.resize(tickCount);
53 points.resize(tickCount);
55 const QRectF &gridRect = gridGeometry();
54 const QRectF &gridRect = gridGeometry();
56 const qreal deltaY = gridRect.height() / qAbs(logMax - logMin);
55 const qreal deltaY = gridRect.height() / qAbs(logMax - logMin);
57 for (int i = 0; i < tickCount; ++i)
56 for (int i = 0; i < tickCount; ++i)
58 points[i] = (ceilEdge + i) * -deltaY - leftEdge * -deltaY + gridRect.bottom();
57 points[i] = (ceilEdge + i) * -deltaY - leftEdge * -deltaY + gridRect.bottom();
59
58
60 return points;
59 return points;
61 }
60 }
62
61
63
62
64 void ChartLogValueAxisY::updateGeometry()
63 void ChartLogValueAxisY::updateGeometry()
65 {
64 {
66 const QVector<qreal> &layout = ChartAxis::layout();
65 const QVector<qreal> &layout = ChartAxis::layout();
67 if (layout.isEmpty())
66 if (layout.isEmpty())
68 return;
67 return;
69 setLabels(createLogValueLabels(m_axis->min(), m_axis->max(), m_axis->base(), layout.size(), m_axis->labelFormat()));
68 setLabels(createLogValueLabels(m_axis->min(), m_axis->max(), m_axis->base(), layout.size(), m_axis->labelFormat()));
70 VerticalAxis::updateGeometry();
69 VerticalAxis::updateGeometry();
71 }
70 }
72
71
73 void ChartLogValueAxisY::handleBaseChanged(qreal base)
72 void ChartLogValueAxisY::handleBaseChanged(qreal base)
74 {
73 {
75 Q_UNUSED(base);
74 Q_UNUSED(base);
76 QGraphicsLayoutItem::updateGeometry();
75 QGraphicsLayoutItem::updateGeometry();
77 if(presenter()) presenter()->layout()->invalidate();
76 if(presenter()) presenter()->layout()->invalidate();
78 }
77 }
79
78
80 void ChartLogValueAxisY::handleLabelFormatChanged(const QString &format)
79 void ChartLogValueAxisY::handleLabelFormatChanged(const QString &format)
81 {
80 {
82 Q_UNUSED(format);
81 Q_UNUSED(format);
83 QGraphicsLayoutItem::updateGeometry();
82 QGraphicsLayoutItem::updateGeometry();
84 if(presenter()) presenter()->layout()->invalidate();
83 if(presenter()) presenter()->layout()->invalidate();
85 }
84 }
86
85
87 QSizeF ChartLogValueAxisY::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
86 QSizeF ChartLogValueAxisY::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
88 {
87 {
89 Q_UNUSED(constraint)
88 Q_UNUSED(constraint)
90
89
91 QFontMetrics fn(font());
90 QFontMetrics fn(font());
92 QSizeF sh;
91 QSizeF sh;
93
92
94 QSizeF base = VerticalAxis::sizeHint(which, constraint);
93 QSizeF base = VerticalAxis::sizeHint(which, constraint);
95 QStringList ticksList;
94 QStringList ticksList;
96 qreal logMax = log10(m_axis->max()) / log10(m_axis->base());
95 qreal logMax = log10(m_axis->max()) / log10(m_axis->base());
97 qreal logMin = log10(m_axis->min()) / log10(m_axis->base());
96 qreal logMin = log10(m_axis->min()) / log10(m_axis->base());
98 int tickCount = qAbs(ceil(logMax) - ceil(logMin));
97 int tickCount = qAbs(ceil(logMax) - ceil(logMin));
99 if (m_axis->max() > m_axis->min() && tickCount > 1)
98 if (m_axis->max() > m_axis->min() && tickCount > 1)
100 ticksList = createLogValueLabels(m_axis->min(), m_axis->max(), m_axis->base(), tickCount, m_axis->labelFormat());
99 ticksList = createLogValueLabels(m_axis->min(), m_axis->max(), m_axis->base(), tickCount, m_axis->labelFormat());
101 else
100 else
102 ticksList.append(QString(" "));
101 ticksList.append(QString(" "));
103 qDebug() << ticksList;
104 qDebug() << tickCount;
105 qreal width = 0;
102 qreal width = 0;
106 qreal height = 0;
103 qreal height = 0;
107
104
108 switch (which) {
105 switch (which) {
109 case Qt::MinimumSize: {
106 case Qt::MinimumSize: {
110 width = fn.boundingRect("...").width() + labelPadding();
107 width = fn.boundingRect("...").width() + labelPadding();
111 width += base.width();
108 width += base.width();
112 height = fn.height();
109 height = fn.height();
113 height = qMax(height,base.height());
110 height = qMax(height,base.height());
114 sh = QSizeF(width,height);
111 sh = QSizeF(width,height);
115 break;
112 break;
116 }
113 }
117 case Qt::PreferredSize: {
114 case Qt::PreferredSize: {
118 int count = qMax(ticksList.first().count(), ticksList.last().count());
115 int count = qMax(ticksList.first().count(), ticksList.last().count());
119 width = count*fn.averageCharWidth() + labelPadding() + 2; //two pixels of tolerance
116 width = count*fn.averageCharWidth() + labelPadding() + 2; //two pixels of tolerance
120 width += base.width();
117 width += base.width();
121 height = fn.height() * ticksList.count();
118 height = fn.height() * ticksList.count();
122 height = qMax(height,base.height());
119 height = qMax(height,base.height());
123 sh = QSizeF(width,height);
120 sh = QSizeF(width,height);
124 break;
121 break;
125 }
122 }
126 default:
123 default:
127 break;
124 break;
128 }
125 }
129
126
130 return sh;
127 return sh;
131 }
128 }
132
129
133 #include "moc_chartlogvalueaxisy_p.cpp"
130 #include "moc_chartlogvalueaxisy_p.cpp"
134
131
135 QTCOMMERCIALCHART_END_NAMESPACE
132 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,272 +1,152
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "qsplineseries.h"
21 #include "qsplineseries.h"
22 #include "qsplineseries_p.h"
22 #include "qsplineseries_p.h"
23 #include "splinechartitem_p.h"
23 #include "splinechartitem_p.h"
24 #include "chartdataset_p.h"
24 #include "chartdataset_p.h"
25 #include "charttheme_p.h"
25 #include "charttheme_p.h"
26 #include "splineanimation_p.h"
26 #include "splineanimation_p.h"
27
27
28 /*!
28 /*!
29 \class QSplineSeries
29 \class QSplineSeries
30 \brief Series type used to store data needed to draw a spline.
30 \brief Series type used to store data needed to draw a spline.
31
31
32 QSplineSeries stores the data points along with the segment control points needed by QPainterPath to draw spline
32 QSplineSeries stores the data points along with the segment control points needed by QPainterPath to draw spline
33 Control points are automatically calculated when data changes. The algorithm computes the points so that the normal spline can be drawn.
33 Control points are automatically calculated when data changes. The algorithm computes the points so that the normal spline can be drawn.
34
34
35 \image examples_splinechart.png
35 \image examples_splinechart.png
36
36
37 Creating basic spline chart is simple:
37 Creating basic spline chart is simple:
38 \code
38 \code
39 QSplineSeries* series = new QSplineSeries();
39 QSplineSeries* series = new QSplineSeries();
40 series->append(0, 6);
40 series->append(0, 6);
41 series->append(2, 4);
41 series->append(2, 4);
42 ...
42 ...
43 chart->addSeries(series);
43 chart->addSeries(series);
44 \endcode
44 \endcode
45 */
45 */
46
46
47 /*!
47 /*!
48 \qmlclass SplineSeries QSplineSeries
48 \qmlclass SplineSeries QSplineSeries
49 \inherits XYSeries
49 \inherits XYSeries
50
50
51 The following QML shows how to create a simple spline chart:
51 The following QML shows how to create a simple spline chart:
52 \snippet ../demos/qmlchart/qml/qmlchart/View3.qml 1
52 \snippet ../demos/qmlchart/qml/qmlchart/View3.qml 1
53 \beginfloatleft
53 \beginfloatleft
54 \image demos_qmlchart3.png
54 \image demos_qmlchart3.png
55 \endfloat
55 \endfloat
56 \clearfloat
56 \clearfloat
57 */
57 */
58
58
59 /*!
59 /*!
60 \fn QSeriesType QSplineSeries::type() const
60 \fn QSeriesType QSplineSeries::type() const
61 Returns the type of the series
61 Returns the type of the series
62 */
62 */
63
63
64 /*!
64 /*!
65 \qmlproperty real SplineSeries::width
65 \qmlproperty real SplineSeries::width
66 The width of the line. By default the width is 2.0.
66 The width of the line. By default the width is 2.0.
67 */
67 */
68
68
69 /*!
69 /*!
70 \qmlproperty Qt::PenStyle SplineSeries::style
70 \qmlproperty Qt::PenStyle SplineSeries::style
71 Controls the style of the line. Set to one of Qt.NoPen, Qt.SolidLine, Qt.DashLine, Qt.DotLine,
71 Controls the style of the line. Set to one of Qt.NoPen, Qt.SolidLine, Qt.DashLine, Qt.DotLine,
72 Qt.DashDotLine or Qt.DashDotDotLine. Using Qt.CustomDashLine is not supported in the QML API.
72 Qt.DashDotLine or Qt.DashDotDotLine. Using Qt.CustomDashLine is not supported in the QML API.
73 By default the style is Qt.SolidLine.
73 By default the style is Qt.SolidLine.
74 */
74 */
75
75
76 /*!
76 /*!
77 \qmlproperty Qt::PenCapStyle SplineSeries::capStyle
77 \qmlproperty Qt::PenCapStyle SplineSeries::capStyle
78 Controls the cap style of the line. Set to one of Qt.FlatCap, Qt.SquareCap or Qt.RoundCap. By
78 Controls the cap style of the line. Set to one of Qt.FlatCap, Qt.SquareCap or Qt.RoundCap. By
79 default the cap style is Qt.SquareCap.
79 default the cap style is Qt.SquareCap.
80 */
80 */
81
81
82 QTCOMMERCIALCHART_BEGIN_NAMESPACE
82 QTCOMMERCIALCHART_BEGIN_NAMESPACE
83
83
84 /*!
84 /*!
85 Constructs empty series object which is a child of \a parent.
85 Constructs empty series object which is a child of \a parent.
86 When series object is added to QChartView or QChart instance then the ownerships is transferred.
86 When series object is added to QChartView or QChart instance then the ownerships is transferred.
87 */
87 */
88
88
89 QSplineSeries::QSplineSeries(QObject *parent)
89 QSplineSeries::QSplineSeries(QObject *parent)
90 : QLineSeries(*new QSplineSeriesPrivate(this), parent)
90 : QLineSeries(*new QSplineSeriesPrivate(this), parent)
91 {
91 {
92 Q_D(QSplineSeries);
93 QObject::connect(this, SIGNAL(pointAdded(int)), d, SLOT(updateControlPoints()));
94 QObject::connect(this, SIGNAL(pointRemoved(int)), d, SLOT(updateControlPoints()));
95 QObject::connect(this, SIGNAL(pointReplaced(int)), d, SLOT(updateControlPoints()));
96 QObject::connect(this, SIGNAL(pointsReplaced()), d, SLOT(updateControlPoints()));
97 }
92 }
98
93
99 /*!
94 /*!
100 Destroys the object.
95 Destroys the object.
101 */
96 */
102 QSplineSeries::~QSplineSeries()
97 QSplineSeries::~QSplineSeries()
103 {
98 {
104 Q_D(QSplineSeries);
99 Q_D(QSplineSeries);
105 if (d->m_chart)
100 if (d->m_chart)
106 d->m_chart->removeSeries(this);
101 d->m_chart->removeSeries(this);
107 }
102 }
108
103
109 QAbstractSeries::SeriesType QSplineSeries::type() const
104 QAbstractSeries::SeriesType QSplineSeries::type() const
110 {
105 {
111 return QAbstractSeries::SeriesTypeSpline;
106 return QAbstractSeries::SeriesTypeSpline;
112 }
107 }
113
108
114 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
109 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
115
110
116 QSplineSeriesPrivate::QSplineSeriesPrivate(QSplineSeries *q)
111 QSplineSeriesPrivate::QSplineSeriesPrivate(QSplineSeries *q)
117 : QLineSeriesPrivate(q)
112 : QLineSeriesPrivate(q)
118 {
113 {
119 }
114 }
120
115
121 /*!
122 Calculates control points which are needed by QPainterPath.cubicTo function to draw the cubic Bezier cureve between two points.
123 */
124 void QSplineSeriesPrivate::calculateControlPoints()
125 {
126 Q_Q(QSplineSeries);
127
128 const QList<QPointF>& points = q->points();
129
130 int n = points.count() - 1;
131
132 if (n == 1) {
133 //for n==1
134 m_controlPoints[0].setX((2 * points[0].x() + points[1].x()) / 3);
135 m_controlPoints[0].setY((2 * points[0].y() + points[1].y()) / 3);
136 m_controlPoints[1].setX(2 * m_controlPoints[0].x() - points[0].x());
137 m_controlPoints[1].setY(2 * m_controlPoints[0].y() - points[0].y());
138 return;
139 }
140
141 // Calculate first Bezier control points
142 // Set of equations for P0 to Pn points.
143 //
144 // | 2 1 0 0 ... 0 0 0 ... 0 0 0 | | P1_1 | | P0 + 2 * P1 |
145 // | 1 4 1 0 ... 0 0 0 ... 0 0 0 | | P1_2 | | 4 * P1 + 2 * P2 |
146 // | 0 1 4 1 ... 0 0 0 ... 0 0 0 | | P1_3 | | 4 * P2 + 2 * P3 |
147 // | . . . . . . . . . . . . | | ... | | ... |
148 // | 0 0 0 0 ... 1 4 1 ... 0 0 0 | * | P1_i | = | 4 * P(i-1) + 2 * Pi |
149 // | . . . . . . . . . . . . | | ... | | ... |
150 // | 0 0 0 0 0 0 0 0 ... 1 4 1 | | P1_(n-1)| | 4 * P(n-2) + 2 * P(n-1) |
151 // | 0 0 0 0 0 0 0 0 ... 0 2 7 | | P1_n | | 8 * P(n-1) + Pn |
152 //
153 QVector<qreal> vector;
154 vector.resize(n);
155
156 vector[0] = points[0].x() + 2 * points[1].x();
157
158
159 for (int i = 1; i < n - 1; ++i)
160 vector[i] = 4 * points[i].x() + 2 * points[i + 1].x();
161
162 vector[n - 1] = (8 * points[n - 1].x() + points[n].x()) / 2.0;
163
164 QVector<qreal> xControl = firstControlPoints(vector);
165
166 vector[0] = points[0].y() + 2 * points[1].y();
167
168 for (int i = 1; i < n - 1; ++i)
169 vector[i] = 4 * points[i].y() + 2 * points[i + 1].y();
170
171 vector[n - 1] = (8 * points[n - 1].y() + points[n].y()) / 2.0;
172
173 QVector<qreal> yControl = firstControlPoints(vector);
174
175 for (int i = 0, j = 0; i < n; ++i, ++j) {
176
177 m_controlPoints[j].setX(xControl[i]);
178 m_controlPoints[j].setY(yControl[i]);
179
180 j++;
181
182 if (i < n - 1) {
183 m_controlPoints[j].setX(2 * points[i + 1].x() - xControl[i + 1]);
184 m_controlPoints[j].setY(2 * points[i + 1].y() - yControl[i + 1]);
185 } else {
186 m_controlPoints[j].setX((points[n].x() + xControl[n - 1]) / 2);
187 m_controlPoints[j].setY((points[n].y() + yControl[n - 1]) / 2);
188 }
189 }
190 }
191
192 QVector<qreal> QSplineSeriesPrivate::firstControlPoints(const QVector<qreal>& vector)
193 {
194 QVector<qreal> result;
195
196 int count = vector.count();
197 result.resize(count);
198 result[0] = vector[0] / 2.0;
199
200 QVector<qreal> temp;
201 temp.resize(count);
202 temp[0] = 0;
203
204 qreal b = 2.0;
205
206 for (int i = 1; i < count; i++) {
207 temp[i] = 1 / b;
208 b = (i < count - 1 ? 4.0 : 3.5) - temp[i];
209 result[i] = (vector[i] - result[i - 1]) / b;
210 }
211
212 for (int i = 1; i < count; i++)
213 result[count - i - 1] -= temp[count - i] * result[count - i];
214
215 return result;
216 }
217
218 QPointF QSplineSeriesPrivate::controlPoint(int index) const
219 {
220 return m_controlPoints[index];
221 }
222
223 /*!
224 Updates the control points, besed on currently avaiable knots.
225 */
226 void QSplineSeriesPrivate::updateControlPoints()
227 {
228 Q_Q(QSplineSeries);
229 if (q->count() > 1) {
230 m_controlPoints.resize(2 * q->count() - 2);
231 calculateControlPoints();
232 }
233 }
234
235 void QSplineSeriesPrivate::initializeGraphics(QGraphicsItem* parent)
116 void QSplineSeriesPrivate::initializeGraphics(QGraphicsItem* parent)
236 {
117 {
237 Q_Q(QSplineSeries);
118 Q_Q(QSplineSeries);
238 SplineChartItem *spline = new SplineChartItem(q,parent);
119 SplineChartItem *spline = new SplineChartItem(q,parent);
239 m_item.reset(spline);
120 m_item.reset(spline);
240 QAbstractSeriesPrivate::initializeGraphics(parent);
121 QAbstractSeriesPrivate::initializeGraphics(parent);
241 }
122 }
242
123
243 void QSplineSeriesPrivate::initializeTheme(int index, ChartTheme* theme, bool forced)
124 void QSplineSeriesPrivate::initializeTheme(int index, ChartTheme* theme, bool forced)
244 {
125 {
245 Q_Q(QSplineSeries);
126 Q_Q(QSplineSeries);
246 const QList<QColor> colors = theme->seriesColors();
127 const QList<QColor> colors = theme->seriesColors();
247
128
248 QPen pen;
129 QPen pen;
249 if (forced || pen == m_pen) {
130 if (forced || pen == m_pen) {
250 pen.setColor(colors.at(index % colors.size()));
131 pen.setColor(colors.at(index % colors.size()));
251 pen.setWidthF(2);
132 pen.setWidthF(2);
252 q->setPen(pen);
133 q->setPen(pen);
253 }
134 }
254 }
135 }
255
136
256
257 void QSplineSeriesPrivate::initializeAnimations(QtCommercialChart::QChart::AnimationOptions options)
137 void QSplineSeriesPrivate::initializeAnimations(QtCommercialChart::QChart::AnimationOptions options)
258 {
138 {
259 SplineChartItem *item = static_cast<SplineChartItem *>(m_item.data());
139 SplineChartItem *item = static_cast<SplineChartItem *>(m_item.data());
260 Q_ASSERT(item);
140 Q_ASSERT(item);
261 if (options.testFlag(QChart::SeriesAnimations)) {
141 if (options.testFlag(QChart::SeriesAnimations)) {
262 item->setAnimation(new SplineAnimation(item));
142 item->setAnimation(new SplineAnimation(item));
263 }else{
143 }else{
264 item->setAnimation(0);
144 item->setAnimation(0);
265 }
145 }
266 QAbstractSeriesPrivate::initializeAnimations(options);
146 QAbstractSeriesPrivate::initializeAnimations(options);
267 }
147 }
268
148
269 #include "moc_qsplineseries.cpp"
149 #include "moc_qsplineseries.cpp"
270 #include "moc_qsplineseries_p.cpp"
150 #include "moc_qsplineseries_p.cpp"
271
151
272 QTCOMMERCIALCHART_END_NAMESPACE
152 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,65 +1,54
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 // W A R N I N G
21 // W A R N I N G
22 // -------------
22 // -------------
23 //
23 //
24 // This file is not part of the QtCommercial Chart API. It exists purely as an
24 // This file is not part of the QtCommercial Chart API. It exists purely as an
25 // implementation detail. This header file may change from version to
25 // implementation detail. This header file may change from version to
26 // version without notice, or even be removed.
26 // version without notice, or even be removed.
27 //
27 //
28 // We mean it.
28 // We mean it.
29
29
30 #ifndef QSPLINESERIES_P_H
30 #ifndef QSPLINESERIES_P_H
31 #define QSPLINESERIES_P_H
31 #define QSPLINESERIES_P_H
32
32
33 #include "qlineseries_p.h"
33 #include "qlineseries_p.h"
34
34
35 QTCOMMERCIALCHART_BEGIN_NAMESPACE
35 QTCOMMERCIALCHART_BEGIN_NAMESPACE
36
36
37
37
38 class QSplineSeriesPrivate: public QLineSeriesPrivate
38 class QSplineSeriesPrivate: public QLineSeriesPrivate
39 {
39 {
40 Q_OBJECT
40 Q_OBJECT
41 public:
41 public:
42 QSplineSeriesPrivate(QSplineSeries *q);
42 QSplineSeriesPrivate(QSplineSeries *q);
43
43
44 void initializeTheme(int index, ChartTheme* theme, bool forced = false);
44 void initializeTheme(int index, ChartTheme* theme, bool forced = false);
45 void initializeGraphics(QGraphicsItem* parent);
45 void initializeGraphics(QGraphicsItem* parent);
46 void initializeAnimations(QtCommercialChart::QChart::AnimationOptions options);
46 void initializeAnimations(QtCommercialChart::QChart::AnimationOptions options);
47
47
48 QPointF controlPoint(int index) const;
49
50 public Q_SLOTS:
51 void updateControlPoints();
52
53 private:
54 void calculateControlPoints();
55 QVector<qreal> firstControlPoints(const QVector<qreal>& vector);
56
57 public:
58 QVector<QPointF> m_controlPoints;
59 private:
48 private:
60 Q_DECLARE_PUBLIC(QSplineSeries)
49 Q_DECLARE_PUBLIC(QSplineSeries)
61 };
50 };
62
51
63 QTCOMMERCIALCHART_END_NAMESPACE
52 QTCOMMERCIALCHART_END_NAMESPACE
64
53
65 #endif
54 #endif
@@ -1,191 +1,276
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "splinechartitem_p.h"
21 #include "splinechartitem_p.h"
22 #include "qsplineseries_p.h"
22 #include "qsplineseries_p.h"
23 #include "chartpresenter_p.h"
23 #include "chartpresenter_p.h"
24 #include "splineanimation_p.h"
24 #include "splineanimation_p.h"
25 #include "abstractdomain_p.h"
25 #include "abstractdomain_p.h"
26 #include <QPainter>
26 #include <QPainter>
27 #include <QGraphicsSceneMouseEvent>
27 #include <QGraphicsSceneMouseEvent>
28
28
29 QTCOMMERCIALCHART_BEGIN_NAMESPACE
29 QTCOMMERCIALCHART_BEGIN_NAMESPACE
30
30
31 SplineChartItem::SplineChartItem(QSplineSeries *series, QGraphicsItem* item)
31 SplineChartItem::SplineChartItem(QSplineSeries *series, QGraphicsItem* item)
32 : XYChart(series,item),
32 : XYChart(series,item),
33 m_series(series),
33 m_series(series),
34 m_pointsVisible(false),
34 m_pointsVisible(false),
35 m_animation(0)
35 m_animation(0)
36 {
36 {
37 setAcceptHoverEvents(true);
37 setAcceptHoverEvents(true);
38 setZValue(ChartPresenter::SplineChartZValue);
38 setZValue(ChartPresenter::SplineChartZValue);
39 QObject::connect(m_series->d_func(), SIGNAL(updated()), this, SLOT(handleUpdated()));
39 QObject::connect(m_series->d_func(), SIGNAL(updated()), this, SLOT(handleUpdated()));
40 QObject::connect(series, SIGNAL(visibleChanged()), this, SLOT(handleUpdated()));
40 QObject::connect(series, SIGNAL(visibleChanged()), this, SLOT(handleUpdated()));
41 QObject::connect(series, SIGNAL(opacityChanged()), this, SLOT(handleUpdated()));
41 QObject::connect(series, SIGNAL(opacityChanged()), this, SLOT(handleUpdated()));
42 handleUpdated();
42 handleUpdated();
43 }
43 }
44
44
45 QRectF SplineChartItem::boundingRect() const
45 QRectF SplineChartItem::boundingRect() const
46 {
46 {
47 return m_rect;
47 return m_rect;
48 }
48 }
49
49
50 QPainterPath SplineChartItem::shape() const
50 QPainterPath SplineChartItem::shape() const
51 {
51 {
52 QPainterPathStroker stroker;
52 QPainterPathStroker stroker;
53 return stroker.createStroke(m_path);
53 return stroker.createStroke(m_path);
54 }
54 }
55
55
56 void SplineChartItem::setAnimation(SplineAnimation *animation)
56 void SplineChartItem::setAnimation(SplineAnimation *animation)
57 {
57 {
58 m_animation = animation;
58 m_animation = animation;
59 XYChart::setAnimation(animation);
59 XYChart::setAnimation(animation);
60 }
60 }
61
61
62 ChartAnimation *SplineChartItem::animation() const
62 ChartAnimation *SplineChartItem::animation() const
63 {
63 {
64 return m_animation;
64 return m_animation;
65 }
65 }
66
66
67 void SplineChartItem::setControlGeometryPoints(QVector<QPointF>& points)
67 void SplineChartItem::setControlGeometryPoints(QVector<QPointF>& points)
68 {
68 {
69 m_controlPoints = points;
69 m_controlPoints = points;
70 }
70 }
71
71
72 QVector<QPointF> SplineChartItem::controlGeometryPoints() const
72 QVector<QPointF> SplineChartItem::controlGeometryPoints() const
73 {
73 {
74 return m_controlPoints;
74 return m_controlPoints;
75 }
75 }
76
76
77 void SplineChartItem::updateChart(QVector<QPointF> &oldPoints, QVector<QPointF> &newPoints, int index)
77 void SplineChartItem::updateChart(QVector<QPointF> &oldPoints, QVector<QPointF> &newPoints, int index)
78 {
78 {
79 QVector<QPointF> controlPoints;
79 QVector<QPointF> controlPoints;
80
81 if (newPoints.count() >= 2)
80 if (newPoints.count() >= 2)
82 controlPoints.resize(newPoints.count() * 2 - 2);
81 controlPoints = calculateControlPoints(newPoints);
83
84 for (int i = 0; i < newPoints.size() - 1; i++) {
85 controlPoints[2 * i] = calculateGeometryControlPoint(2 * i);
86 controlPoints[2 * i + 1] = calculateGeometryControlPoint(2 * i + 1);
87 }
88
82
89 if (m_animation)
83 if (m_animation)
90 m_animation->setup(oldPoints, newPoints, m_controlPoints, controlPoints, index);
84 m_animation->setup(oldPoints, newPoints, m_controlPoints, controlPoints, index);
91
85
92 m_points = newPoints;
86 m_points = newPoints;
93 m_controlPoints = controlPoints;
87 m_controlPoints = controlPoints;
94 setDirty(false);
88 setDirty(false);
95
89
96 if (m_animation)
90 if (m_animation)
97 presenter()->startAnimation(m_animation);
91 presenter()->startAnimation(m_animation);
98 else
92 else
99 updateGeometry();
93 updateGeometry();
100 }
94 }
101
95
102 QPointF SplineChartItem::calculateGeometryControlPoint(int index) const
103 {
104 bool ok;
105 return domain()->calculateGeometryPoint(m_series->d_func()->controlPoint(index), ok);
106 }
107
108 void SplineChartItem::updateGeometry()
96 void SplineChartItem::updateGeometry()
109 {
97 {
110 const QVector<QPointF> &points = m_points;
98 const QVector<QPointF> &points = m_points;
111 const QVector<QPointF> &controlPoints = m_controlPoints;
99 const QVector<QPointF> &controlPoints = m_controlPoints;
112
100
113 if ((points.size() < 2) || (controlPoints.size() < 2)) {
101 if ((points.size() < 2) || (controlPoints.size() < 2)) {
114 prepareGeometryChange();
102 prepareGeometryChange();
115 m_path = QPainterPath();
103 m_path = QPainterPath();
116 m_rect = QRect();
104 m_rect = QRect();
117 return;
105 return;
118 }
106 }
119
107
120 Q_ASSERT(points.count() * 2 - 2 == controlPoints.count());
108 Q_ASSERT(points.count() * 2 - 2 == controlPoints.count());
121
109
122 QPainterPath splinePath(points.at(0));
110 QPainterPath splinePath(points.at(0));
123
111
124 for (int i = 0; i < points.size() - 1; i++) {
112 for (int i = 0; i < points.size() - 1; i++) {
125 const QPointF &point = points.at(i + 1);
113 const QPointF &point = points.at(i + 1);
126 splinePath.cubicTo(controlPoints[2 * i], controlPoints[2 * i + 1], point);
114 splinePath.cubicTo(controlPoints[2 * i], controlPoints[2 * i + 1], point);
127 }
115 }
128
116
129 prepareGeometryChange();
117 prepareGeometryChange();
130 // QPainterPathStroker stroker;
118 // QPainterPathStroker stroker;
131 // stroker.setWidth(m_linePen.width() / 2.0);
119 // stroker.setWidth(m_linePen.width() / 2.0);
132 // m_path = stroker.createStroke(splinePath);
120 // m_path = stroker.createStroke(splinePath);
133 m_path = splinePath;
121 m_path = splinePath;
134 m_rect = splinePath.boundingRect();
122 m_rect = splinePath.boundingRect();
135
123
136 }
124 }
137
125
126 /*!
127 Calculates control points which are needed by QPainterPath.cubicTo function to draw the cubic Bezier cureve between two points.
128 */
129 QVector<QPointF> SplineChartItem::calculateControlPoints(const QVector<QPointF> &points)
130 {
131 QVector<QPointF> controlPoints;
132 controlPoints.resize(points.count() * 2 - 2);
133
134 int n = points.count() - 1;
135
136 if (n == 1) {
137 //for n==1
138 controlPoints[0].setX((2 * points[0].x() + points[1].x()) / 3);
139 controlPoints[0].setY((2 * points[0].y() + points[1].y()) / 3);
140 controlPoints[1].setX(2 * controlPoints[0].x() - points[0].x());
141 controlPoints[1].setY(2 * controlPoints[0].y() - points[0].y());
142 return controlPoints;
143 }
144
145 // Calculate first Bezier control points
146 // Set of equations for P0 to Pn points.
147 //
148 // | 2 1 0 0 ... 0 0 0 ... 0 0 0 | | P1_1 | | P0 + 2 * P1 |
149 // | 1 4 1 0 ... 0 0 0 ... 0 0 0 | | P1_2 | | 4 * P1 + 2 * P2 |
150 // | 0 1 4 1 ... 0 0 0 ... 0 0 0 | | P1_3 | | 4 * P2 + 2 * P3 |
151 // | . . . . . . . . . . . . | | ... | | ... |
152 // | 0 0 0 0 ... 1 4 1 ... 0 0 0 | * | P1_i | = | 4 * P(i-1) + 2 * Pi |
153 // | . . . . . . . . . . . . | | ... | | ... |
154 // | 0 0 0 0 0 0 0 0 ... 1 4 1 | | P1_(n-1)| | 4 * P(n-2) + 2 * P(n-1) |
155 // | 0 0 0 0 0 0 0 0 ... 0 2 7 | | P1_n | | 8 * P(n-1) + Pn |
156 //
157 QVector<qreal> vector;
158 vector.resize(n);
159
160 vector[0] = points[0].x() + 2 * points[1].x();
161
162
163 for (int i = 1; i < n - 1; ++i)
164 vector[i] = 4 * points[i].x() + 2 * points[i + 1].x();
165
166 vector[n - 1] = (8 * points[n - 1].x() + points[n].x()) / 2.0;
167
168 QVector<qreal> xControl = firstControlPoints(vector);
169
170 vector[0] = points[0].y() + 2 * points[1].y();
171
172 for (int i = 1; i < n - 1; ++i)
173 vector[i] = 4 * points[i].y() + 2 * points[i + 1].y();
174
175 vector[n - 1] = (8 * points[n - 1].y() + points[n].y()) / 2.0;
176
177 QVector<qreal> yControl = firstControlPoints(vector);
178
179 for (int i = 0, j = 0; i < n; ++i, ++j) {
180
181 controlPoints[j].setX(xControl[i]);
182 controlPoints[j].setY(yControl[i]);
183
184 j++;
185
186 if (i < n - 1) {
187 controlPoints[j].setX(2 * points[i + 1].x() - xControl[i + 1]);
188 controlPoints[j].setY(2 * points[i + 1].y() - yControl[i + 1]);
189 } else {
190 controlPoints[j].setX((points[n].x() + xControl[n - 1]) / 2);
191 controlPoints[j].setY((points[n].y() + yControl[n - 1]) / 2);
192 }
193 }
194 return controlPoints;
195 }
196
197 QVector<qreal> SplineChartItem::firstControlPoints(const QVector<qreal>& vector)
198 {
199 QVector<qreal> result;
200
201 int count = vector.count();
202 result.resize(count);
203 result[0] = vector[0] / 2.0;
204
205 QVector<qreal> temp;
206 temp.resize(count);
207 temp[0] = 0;
208
209 qreal b = 2.0;
210
211 for (int i = 1; i < count; i++) {
212 temp[i] = 1 / b;
213 b = (i < count - 1 ? 4.0 : 3.5) - temp[i];
214 result[i] = (vector[i] - result[i - 1]) / b;
215 }
216
217 for (int i = 1; i < count; i++)
218 result[count - i - 1] -= temp[count - i] * result[count - i];
219
220 return result;
221 }
222
138 //handlers
223 //handlers
139
224
140 void SplineChartItem::handleUpdated()
225 void SplineChartItem::handleUpdated()
141 {
226 {
142 setVisible(m_series->isVisible());
227 setVisible(m_series->isVisible());
143 setOpacity(m_series->opacity());
228 setOpacity(m_series->opacity());
144 m_pointsVisible = m_series->pointsVisible();
229 m_pointsVisible = m_series->pointsVisible();
145 m_linePen = m_series->pen();
230 m_linePen = m_series->pen();
146 m_pointPen = m_series->pen();
231 m_pointPen = m_series->pen();
147 m_pointPen.setWidthF(2 * m_pointPen.width());
232 m_pointPen.setWidthF(2 * m_pointPen.width());
148 update();
233 update();
149 }
234 }
150
235
151 //painter
236 //painter
152
237
153 void SplineChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
238 void SplineChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
154 {
239 {
155 Q_UNUSED(widget)
240 Q_UNUSED(widget)
156 Q_UNUSED(option)
241 Q_UNUSED(option)
157
242
158 painter->save();
243 painter->save();
159 painter->setClipRect(QRectF(QPointF(0,0),domain()->size()));
244 painter->setClipRect(QRectF(QPointF(0,0),domain()->size()));
160 painter->setPen(m_linePen);
245 painter->setPen(m_linePen);
161 // painter->setBrush(m_linePen.color());
246 // painter->setBrush(m_linePen.color());
162
247
163 painter->drawPath(m_path);
248 painter->drawPath(m_path);
164 if (m_pointsVisible) {
249 if (m_pointsVisible) {
165 painter->setPen(m_pointPen);
250 painter->setPen(m_pointPen);
166 painter->drawPoints(geometryPoints());
251 painter->drawPoints(geometryPoints());
167 }
252 }
168 painter->restore();
253 painter->restore();
169 }
254 }
170
255
171 void SplineChartItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
256 void SplineChartItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
172 {
257 {
173 emit XYChart::clicked(domain()->calculateDomainPoint(event->pos()));
258 emit XYChart::clicked(domain()->calculateDomainPoint(event->pos()));
174 QGraphicsItem::mousePressEvent(event);
259 QGraphicsItem::mousePressEvent(event);
175 }
260 }
176
261
177 void SplineChartItem::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
262 void SplineChartItem::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
178 {
263 {
179 emit XYChart::hovered(domain()->calculateDomainPoint(event->pos()), true);
264 emit XYChart::hovered(domain()->calculateDomainPoint(event->pos()), true);
180 QGraphicsItem::hoverEnterEvent(event);
265 QGraphicsItem::hoverEnterEvent(event);
181 }
266 }
182
267
183 void SplineChartItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
268 void SplineChartItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
184 {
269 {
185 emit XYChart::hovered(domain()->calculateDomainPoint(event->pos()), false);
270 emit XYChart::hovered(domain()->calculateDomainPoint(event->pos()), false);
186 QGraphicsItem::hoverLeaveEvent(event);
271 QGraphicsItem::hoverLeaveEvent(event);
187 }
272 }
188
273
189 #include "moc_splinechartitem_p.cpp"
274 #include "moc_splinechartitem_p.cpp"
190
275
191 QTCOMMERCIALCHART_END_NAMESPACE
276 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,86 +1,85
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 // W A R N I N G
21 // W A R N I N G
22 // -------------
22 // -------------
23 //
23 //
24 // This file is not part of the QtCommercial Chart API. It exists purely as an
24 // This file is not part of the QtCommercial Chart API. It exists purely as an
25 // implementation detail. This header file may change from version to
25 // implementation detail. This header file may change from version to
26 // version without notice, or even be removed.
26 // version without notice, or even be removed.
27 //
27 //
28 // We mean it.
28 // We mean it.
29
29
30 #ifndef SPLINECHARTITEM_P_H
30 #ifndef SPLINECHARTITEM_P_H
31 #define SPLINECHARTITEM_P_H
31 #define SPLINECHARTITEM_P_H
32
32
33 #include "qsplineseries.h"
33 #include "qsplineseries.h"
34 #include "xychart_p.h"
34 #include "xychart_p.h"
35
35
36 QTCOMMERCIALCHART_BEGIN_NAMESPACE
36 QTCOMMERCIALCHART_BEGIN_NAMESPACE
37
37
38 class SplineAnimation;
38 class SplineAnimation;
39
39
40 class SplineChartItem : public XYChart
40 class SplineChartItem : public XYChart
41 {
41 {
42 Q_OBJECT
42 Q_OBJECT
43 Q_INTERFACES(QGraphicsItem)
43 Q_INTERFACES(QGraphicsItem)
44 public:
44 public:
45 SplineChartItem(QSplineSeries *series, QGraphicsItem* item = 0);
45 SplineChartItem(QSplineSeries *series, QGraphicsItem* item = 0);
46
46
47 //from QGraphicsItem
47 //from QGraphicsItem
48 QRectF boundingRect() const;
48 QRectF boundingRect() const;
49 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
49 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
50 QPainterPath shape() const;
50 QPainterPath shape() const;
51
51
52 void setControlGeometryPoints(QVector<QPointF>& points);
52 void setControlGeometryPoints(QVector<QPointF>& points);
53 QVector<QPointF> controlGeometryPoints() const;
53 QVector<QPointF> controlGeometryPoints() const;
54
54
55 void setAnimation(SplineAnimation *animation);
55 void setAnimation(SplineAnimation *animation);
56 ChartAnimation *animation() const;
56 ChartAnimation *animation() const;
57
57
58 public Q_SLOTS:
58 public Q_SLOTS:
59 void handleUpdated();
59 void handleUpdated();
60
60
61 protected:
61 protected:
62 void updateGeometry();
62 void updateGeometry();
63 QVector<QPointF> calculateControlPoints(const QVector<QPointF> &points);
64 QVector<qreal> firstControlPoints(const QVector<qreal>& vector);
63 void updateChart(QVector<QPointF> &oldPoints, QVector<QPointF> &newPoints, int index);
65 void updateChart(QVector<QPointF> &oldPoints, QVector<QPointF> &newPoints, int index);
64 void mousePressEvent(QGraphicsSceneMouseEvent *event);
66 void mousePressEvent(QGraphicsSceneMouseEvent *event);
65 void hoverEnterEvent(QGraphicsSceneHoverEvent *event);
67 void hoverEnterEvent(QGraphicsSceneHoverEvent *event);
66 void hoverLeaveEvent(QGraphicsSceneHoverEvent *event);
68 void hoverLeaveEvent(QGraphicsSceneHoverEvent *event);
67
69
68 private:
70 private:
69 QPointF calculateGeometryControlPoint(int index) const;
70
71 private:
72 QSplineSeries *m_series;
71 QSplineSeries *m_series;
73 QPainterPath m_path;
72 QPainterPath m_path;
74 QRectF m_rect;
73 QRectF m_rect;
75 QPen m_linePen;
74 QPen m_linePen;
76 QPen m_pointPen;
75 QPen m_pointPen;
77 bool m_pointsVisible;
76 bool m_pointsVisible;
78 QVector<QPointF> m_controlPoints;
77 QVector<QPointF> m_controlPoints;
79 SplineAnimation *m_animation;
78 SplineAnimation *m_animation;
80
79
81 friend class SplineAnimation;
80 friend class SplineAnimation;
82 };
81 };
83
82
84 QTCOMMERCIALCHART_END_NAMESPACE
83 QTCOMMERCIALCHART_END_NAMESPACE
85
84
86 #endif // SPLINECHARTITEM_P_H
85 #endif // SPLINECHARTITEM_P_H
General Comments 0
You need to be logged in to leave comments. Login now