##// END OF EJS Templates
Declarative series classed now derived from QSeries childs
Tero Ahola -
r789:a31eb092569c
parent child
Show More
@@ -0,0 +1,41
1 #include "declarativesplineseries.h"
2 #include "declarativechart.h"
3 #include "qchart.h"
4
5 QTCOMMERCIALCHART_BEGIN_NAMESPACE
6
7 DeclarativeSplineSeries::DeclarativeSplineSeries(QObject *parent) :
8 QSplineSeries(parent)
9 {
10 }
11
12 void DeclarativeSplineSeries::seriesComplete()
13 {
14 DeclarativeChart *declarativeChart = qobject_cast<DeclarativeChart *>(parent());
15
16 if (declarativeChart) {
17 QChart *chart = qobject_cast<QChart *>(declarativeChart->m_chart);
18 Q_ASSERT(chart);
19 chart->addSeries(this);
20 }
21 }
22
23 QObject *DeclarativeSplineSeries::seriesObject()
24 {
25 return this;
26 }
27
28 QDeclarativeListProperty<DeclarativeXyPoint> DeclarativeSplineSeries::points()
29 {
30 return DeclarativeXySeries::points();
31 }
32
33 void DeclarativeSplineSeries::appendPoints(QDeclarativeListProperty<DeclarativeXyPoint> *list,
34 DeclarativeXyPoint *element)
35 {
36 DeclarativeXySeries::appendPoints(list, element);
37 }
38
39 #include "moc_declarativesplineseries.cpp"
40
41 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,15 +1,42
1 #include "declarativelineseries.h"
1 #include "declarativelineseries.h"
2 #include "declarativechart.h"
2 #include "declarativechart.h"
3 #include "qchart.h"
3 #include "qchart.h"
4 #include "qlineseries.h"
4 #include "qlineseries.h"
5
5
6 QTCOMMERCIALCHART_BEGIN_NAMESPACE
6 QTCOMMERCIALCHART_BEGIN_NAMESPACE
7
7
8 DeclarativeLineSeries::DeclarativeLineSeries(QDeclarativeItem *parent) :
8 DeclarativeLineSeries::DeclarativeLineSeries(QObject *parent) :
9 DeclarativeXySeries(QSeries::SeriesTypeLine, parent)
9 QLineSeries(parent)
10 {
10 {
11 }
11 }
12
12
13 void DeclarativeLineSeries::seriesComplete()
14 {
15 DeclarativeChart *declarativeChart = qobject_cast<DeclarativeChart *>(parent());
16
17 if (declarativeChart) {
18 QChart *chart = qobject_cast<QChart *>(declarativeChart->m_chart);
19 Q_ASSERT(chart);
20 chart->addSeries(this);
21 }
22 }
23
24 QObject *DeclarativeLineSeries::seriesObject()
25 {
26 return this;
27 }
28
29 QDeclarativeListProperty<DeclarativeXyPoint> DeclarativeLineSeries::points()
30 {
31 return DeclarativeXySeries::points();
32 }
33
34 void DeclarativeLineSeries::appendPoints(QDeclarativeListProperty<DeclarativeXyPoint> *list,
35 DeclarativeXyPoint *element)
36 {
37 DeclarativeXySeries::appendPoints(list, element);
38 }
39
13 #include "moc_declarativelineseries.cpp"
40 #include "moc_declarativelineseries.cpp"
14
41
15 QTCOMMERCIALCHART_END_NAMESPACE
42 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,20 +1,33
1 #ifndef DECLARATIVELINESERIES_H
1 #ifndef DECLARATIVELINESERIES_H
2 #define DECLARATIVELINESERIES_H
2 #define DECLARATIVELINESERIES_H
3
3
4 #include "qchartglobal.h"
4 #include "qchartglobal.h"
5 #include "qlineseries.h"
5 #include "declarativexyseries.h"
6 #include "declarativexyseries.h"
6 #include <QDeclarativeItem>
7 #include <QDeclarativeParserStatus>
7
8
8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9
10
10 class DeclarativeLineSeries : public DeclarativeXySeries
11 class DeclarativeLineSeries : public QLineSeries, public DeclarativeXySeries
11 {
12 {
12 Q_OBJECT
13 Q_OBJECT
14 Q_PROPERTY(QDeclarativeListProperty<DeclarativeXyPoint> points READ points)
13
15
14 public:
16 public:
15 explicit DeclarativeLineSeries(QDeclarativeItem *parent = 0);
17 explicit DeclarativeLineSeries(QObject *parent = 0);
18
19 public:
20 void seriesComplete();
21 QObject *seriesObject();
22
23 public:
24 QDeclarativeListProperty<DeclarativeXyPoint> points();
25
26 public slots:
27 static void appendPoints(QDeclarativeListProperty<DeclarativeXyPoint> *list,
28 DeclarativeXyPoint *element);
16 };
29 };
17
30
18 QTCOMMERCIALCHART_END_NAMESPACE
31 QTCOMMERCIALCHART_END_NAMESPACE
19
32
20 #endif // DECLARATIVELINESERIES_H
33 #endif // DECLARATIVELINESERIES_H
@@ -1,58 +1,43
1 #include "declarativepieseries.h"
1 #include "declarativepieseries.h"
2 #include "declarativechart.h"
2 #include "declarativechart.h"
3 #include "qchart.h"
3 #include "qchart.h"
4 #include "qpieseries.h"
5
4
6 QTCOMMERCIALCHART_BEGIN_NAMESPACE
5 QTCOMMERCIALCHART_BEGIN_NAMESPACE
7
6
8 DeclarativePieSeries::DeclarativePieSeries(QDeclarativeItem *parent) :
7 DeclarativePieSeries::DeclarativePieSeries(QObject *parent) :
9 QDeclarativeItem(parent),
8 QPieSeries(parent),
10 m_chart(0),
9 m_chart(0)
11 m_series(0)
12 {
10 {
13 setFlag(QGraphicsItem::ItemHasNoContents, false);
14 connect(this, SIGNAL(parentChanged()),
15 this, SLOT(setParentForSeries()));
16 }
11 }
17
12
18 void DeclarativePieSeries::setParentForSeries()
13 void DeclarativePieSeries::classBegin()
19 {
14 {
20 if (!m_series) {
15 }
21 DeclarativeChart *declarativeChart = qobject_cast<DeclarativeChart *>(parent());
16
22 if (declarativeChart) {
17 void DeclarativePieSeries::componentComplete()
23 QChart *chart = qobject_cast<QChart *>(declarativeChart->m_chart);
18 {
24 qDebug() << "creating pie series for chart: " << chart;
19 DeclarativeChart *declarativeChart = qobject_cast<DeclarativeChart *>(parent());
25 Q_ASSERT(chart);
20 if (declarativeChart) {
26
21 QChart *chart = qobject_cast<QChart *>(declarativeChart->m_chart);
27 m_series = new QPieSeries();
22 Q_ASSERT(chart);
28 Q_ASSERT(m_series);
23 qDebug() << "parent for pie:" << chart;
29 foreach (QPieSlice* slice, m_data) {
24 chart->addSeries(this);
30 // Have to duplicate the data
31 m_series->add(slice->value(), slice->label());
32 }
33 chart->addSeries(m_series);
34 //chart->axisY();
35 }
36 }
25 }
37 }
26 }
38
27
39 QDeclarativeListProperty<QPieSlice> DeclarativePieSeries::data()
28 QDeclarativeListProperty<QPieSlice> DeclarativePieSeries::slices()
40 {
29 {
41 return QDeclarativeListProperty<QPieSlice>(this, 0, &DeclarativePieSeries::appendData);
30 return QDeclarativeListProperty<QPieSlice>(this, 0, &DeclarativePieSeries::appendSlice);
42 }
31 }
43
32
44 void DeclarativePieSeries::appendData(QDeclarativeListProperty<QPieSlice> *list,
33 void DeclarativePieSeries::appendSlice(QDeclarativeListProperty<QPieSlice> *list,
45 QPieSlice *slice)
34 QPieSlice *slice)
46 {
35 {
47 DeclarativePieSeries *series = qobject_cast<DeclarativePieSeries *>(list->object);
36 DeclarativePieSeries *series = qobject_cast<DeclarativePieSeries *>(list->object);
48 if (series) {
37 if (series)
49 series->m_data.append(slice);
38 series->add(slice->value(), slice->label());
50 // Have to duplicate the data
51 if (series->m_series)
52 series->m_series->add(slice->value(), slice->label());
53 }
54 }
39 }
55
40
56 #include "moc_declarativepieseries.cpp"
41 #include "moc_declarativepieseries.cpp"
57
42
58 QTCOMMERCIALCHART_END_NAMESPACE
43 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,39 +1,37
1 #ifndef DECLARATIVEPIESERIES_H
1 #ifndef DECLARATIVEPIESERIES_H
2 #define DECLARATIVEPIESERIES_H
2 #define DECLARATIVEPIESERIES_H
3
3
4 #include "qchartglobal.h"
4 #include "qchartglobal.h"
5 #include "qpieslice.h"
5 #include "qpieslice.h"
6 #include "qpieseries.h"
6 #include <QDeclarativeItem>
7 #include <QDeclarativeItem>
7
8
8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9
10
10 class QPieSeries;
11 class QChart;
11 class QChart;
12
12
13 class DeclarativePieSeries : public QDeclarativeItem
13 class DeclarativePieSeries : public QPieSeries, public QDeclarativeParserStatus
14 {
14 {
15 Q_OBJECT
15 Q_OBJECT
16 Q_PROPERTY(QDeclarativeListProperty<QPieSlice> data READ data)
16 Q_INTERFACES(QDeclarativeParserStatus)
17 Q_PROPERTY(QDeclarativeListProperty<QPieSlice> slices READ slices)
17
18
18 public:
19 public:
19 explicit DeclarativePieSeries(QDeclarativeItem *parent = 0);
20 explicit DeclarativePieSeries(QObject *parent = 0);
20 QDeclarativeListProperty<QPieSlice> data();
21 QDeclarativeListProperty<QPieSlice> slices();
21
22
22 Q_SIGNALS:
23 public: // from QDeclarativeParserStatus
24 void classBegin();
25 void componentComplete();
23
26
24 public Q_SLOTS:
27 public Q_SLOTS:
25 static void appendData(QDeclarativeListProperty<QPieSlice> *list,
28 static void appendSlice(QDeclarativeListProperty<QPieSlice> *list,
26 QPieSlice *element);
29 QPieSlice *element);
27
28 private Q_SLOTS:
29 void setParentForSeries();
30
30
31 private:
31 private:
32 QChart *m_chart;
32 QChart *m_chart;
33 QPieSeries *m_series;
34 QList<QPieSlice *> m_data;
35 };
33 };
36
34
37 QTCOMMERCIALCHART_END_NAMESPACE
35 QTCOMMERCIALCHART_END_NAMESPACE
38
36
39 #endif // DECLARATIVEPIESERIES_H
37 #endif // DECLARATIVEPIESERIES_H
@@ -1,16 +1,43
1 #include "declarativescatterseries.h"
1 #include "declarativescatterseries.h"
2 #include "declarativechart.h"
2 #include "declarativechart.h"
3 #include "qchart.h"
3 #include "qchart.h"
4 #include "qscatterseries.h"
4 #include "qscatterseries.h"
5
5
6 QTCOMMERCIALCHART_BEGIN_NAMESPACE
6 QTCOMMERCIALCHART_BEGIN_NAMESPACE
7
7
8 DeclarativeScatterSeries::DeclarativeScatterSeries(QDeclarativeItem *parent) :
8 DeclarativeScatterSeries::DeclarativeScatterSeries(QObject *parent) :
9 DeclarativeXySeries(QSeries::SeriesTypeScatter, parent)
9 QScatterSeries(parent)
10 {
10 {
11 setFlag(QGraphicsItem::ItemHasNoContents, false);
11 }
12
13 void DeclarativeScatterSeries::seriesComplete()
14 {
15 DeclarativeChart *declarativeChart = qobject_cast<DeclarativeChart *>(parent());
16
17 if (declarativeChart) {
18 QChart *chart = qobject_cast<QChart *>(declarativeChart->m_chart);
19 Q_ASSERT(chart);
20 qDebug() << "chart:" << chart;
21 chart->addSeries(this);
22 }
23 }
24
25 QObject *DeclarativeScatterSeries::seriesObject()
26 {
27 return this;
28 }
29
30 QDeclarativeListProperty<DeclarativeXyPoint> DeclarativeScatterSeries::points()
31 {
32 return DeclarativeXySeries::points();
33 }
34
35 void DeclarativeScatterSeries::appendPoints(QDeclarativeListProperty<DeclarativeXyPoint> *list,
36 DeclarativeXyPoint *element)
37 {
38 DeclarativeXySeries::appendPoints(list, element);
12 }
39 }
13
40
14 #include "moc_declarativescatterseries.cpp"
41 #include "moc_declarativescatterseries.cpp"
15
42
16 QTCOMMERCIALCHART_END_NAMESPACE
43 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,20 +1,33
1 #ifndef DECLARATIVESCATTERSERIES_H
1 #ifndef DECLARATIVESCATTERSERIES_H
2 #define DECLARATIVESCATTERSERIES_H
2 #define DECLARATIVESCATTERSERIES_H
3
3
4 #include "qchartglobal.h"
4 #include "qchartglobal.h"
5 #include "qscatterseries.h"
5 #include "declarativexyseries.h"
6 #include "declarativexyseries.h"
6 #include <QDeclarativeItem>
7 #include <QDeclarativeParserStatus>
7
8
8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9
10
10 class DeclarativeScatterSeries : public DeclarativeXySeries
11 class DeclarativeScatterSeries : public QScatterSeries, public DeclarativeXySeries
11 {
12 {
12 Q_OBJECT
13 Q_OBJECT
14 Q_PROPERTY(QDeclarativeListProperty<DeclarativeXyPoint> points READ points)
13
15
14 public:
16 public:
15 explicit DeclarativeScatterSeries(QDeclarativeItem *parent = 0);
17 explicit DeclarativeScatterSeries(QObject *parent = 0);
18
19 public:
20 void seriesComplete();
21 QObject *seriesObject();
22
23 public:
24 QDeclarativeListProperty<DeclarativeXyPoint> points();
25
26 public slots:
27 static void appendPoints(QDeclarativeListProperty<DeclarativeXyPoint> *list,
28 DeclarativeXyPoint *element);
16 };
29 };
17
30
18 QTCOMMERCIALCHART_END_NAMESPACE
31 QTCOMMERCIALCHART_END_NAMESPACE
19
32
20 #endif // DECLARATIVESCATTERSERIES_H
33 #endif // DECLARATIVESCATTERSERIES_H
@@ -1,23 +1,33
1 #ifndef DECLARATIVESPLINESERIES_H
1 #ifndef DECLARATIVESPLINESERIES_H
2 #define DECLARATIVESPLINESERIES_H
2 #define DECLARATIVESPLINESERIES_H
3
3
4 #include "qchartglobal.h"
4 #include "qchartglobal.h"
5 #include "qsplineseries.h"
5 #include "declarativexyseries.h"
6 #include "declarativexyseries.h"
6 #include <QDeclarativeItem>
7 #include <QDeclarativeParserStatus>
7
8
8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9
10
10 class DeclarativeSplineSeries : public DeclarativeXySeries
11 class DeclarativeSplineSeries : public QSplineSeries, public DeclarativeXySeries
11 {
12 {
12 Q_OBJECT
13 Q_OBJECT
14 Q_PROPERTY(QDeclarativeListProperty<DeclarativeXyPoint> points READ points)
13
15
14 public:
16 public:
15 explicit DeclarativeSplineSeries(QDeclarativeItem *parent = 0) :
17 explicit DeclarativeSplineSeries(QObject *parent = 0);
16 DeclarativeXySeries(QSeries::SeriesTypeSpline, parent) {}
18
17 };
19 public:
20 void seriesComplete();
21 QObject *seriesObject();
18
22
19 #include "moc_declarativesplineseries.cpp"
23 public:
24 QDeclarativeListProperty<DeclarativeXyPoint> points();
25
26 public slots:
27 static void appendPoints(QDeclarativeListProperty<DeclarativeXyPoint> *list,
28 DeclarativeXyPoint *element);
29 };
20
30
21 QTCOMMERCIALCHART_END_NAMESPACE
31 QTCOMMERCIALCHART_END_NAMESPACE
22
32
23 #endif // DECLARATIVESPLINESERIES_H
33 #endif // DECLARATIVESPLINESERIES_H
@@ -1,12 +1,14
1 #include "declarativexypoint.h"
1 #include "declarativexypoint.h"
2
2
3 QTCOMMERCIALCHART_BEGIN_NAMESPACE
3 QTCOMMERCIALCHART_BEGIN_NAMESPACE
4
4
5 DeclarativeXyPoint::DeclarativeXyPoint(QObject *parent) :
5 DeclarativeXyPoint::DeclarativeXyPoint(QObject *parent) :
6 QObject(parent)
6 QObject(parent)
7 {
7 {
8 setX(0.0);
9 setY(0.0);
8 }
10 }
9
11
10 #include "moc_declarativexypoint.cpp"
12 #include "moc_declarativexypoint.cpp"
11
13
12 QTCOMMERCIALCHART_END_NAMESPACE
14 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,30 +1,22
1 #ifndef DECLARATIVE_XY_POINT_H
1 #ifndef DECLARATIVE_XY_POINT_H
2 #define DECLARATIVE_XY_POINT_H
2 #define DECLARATIVE_XY_POINT_H
3
3
4 #include "qchartglobal.h"
4 #include "qchartglobal.h"
5 #include <QObject>
5 #include <QObject>
6 #include <QPointF>
6
7
7 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8 QTCOMMERCIALCHART_BEGIN_NAMESPACE
8
9
9 class DeclarativeXyPoint : public QObject
10 class DeclarativeXyPoint : public QObject, public QPointF
10 {
11 {
11 Q_OBJECT
12 Q_OBJECT
12 Q_PROPERTY(qreal x READ x WRITE setX /*NOTIFY dataXChanged*/)
13 Q_PROPERTY(qreal x READ x WRITE setX /*NOTIFY dataXChanged*/)
13 Q_PROPERTY(qreal y READ y WRITE setY /*NOTIFY dataYChanged*/)
14 Q_PROPERTY(qreal y READ y WRITE setY /*NOTIFY dataYChanged*/)
14
15
15 public:
16 public:
16 explicit DeclarativeXyPoint(QObject *parent = 0);
17 explicit DeclarativeXyPoint(QObject *parent = 0);
17
18 void setX(qreal x) {m_x = x;}
19 qreal x() {return m_x;}
20 void setY(qreal y) {m_y = y;}
21 qreal y() {return m_y;}
22
23 public:
24 qreal m_x;
25 qreal m_y;
26 };
18 };
27
19
28 QTCOMMERCIALCHART_END_NAMESPACE
20 QTCOMMERCIALCHART_END_NAMESPACE
29
21
30 #endif // DECLARATIVE_XY_POINT_H
22 #endif // DECLARATIVE_XY_POINT_H
@@ -1,86 +1,37
1 //#include "DeclarativeXySeries.h"
1 //#include "DeclarativeXySeries.h"
2 #include "declarativexyseries.h"
2 #include "declarativexyseries.h"
3 #include "declarativechart.h"
4 #include "qchart.h"
5 #include "qxyseries.h"
3 #include "qxyseries.h"
6 #include "qareaseries.h"
7 #include "qsplineseries.h"
8 #include "qscatterseries.h"
9
4
10 QTCOMMERCIALCHART_BEGIN_NAMESPACE
5 QTCOMMERCIALCHART_BEGIN_NAMESPACE
11
6
12 DeclarativeXySeries::DeclarativeXySeries(QSeries::QSeriesType type, QDeclarativeItem *parent) :
7 DeclarativeXySeries::DeclarativeXySeries()
13 QDeclarativeItem(parent),
14 m_seriesType(type),
15 m_chart(0),
16 m_series(0)
17 {
8 {
18 setFlag(QGraphicsItem::ItemHasNoContents, false);
19 }
9 }
20
10
21 DeclarativeXySeries::~DeclarativeXySeries()
11 DeclarativeXySeries::~DeclarativeXySeries()
22 {
12 {
23 }
13 }
24
14
25 void DeclarativeXySeries::componentComplete()
15 void DeclarativeXySeries::classBegin()
26 {
16 {
27 Q_ASSERT(!m_series);
17 }
28 DeclarativeChart *declarativeChart = qobject_cast<DeclarativeChart *>(parent());
29
30 if (declarativeChart) {
31 m_chart = qobject_cast<QChart *>(declarativeChart->m_chart);
32 Q_ASSERT(m_chart);
33
34 switch (m_seriesType) {
35 case QSeries::SeriesTypeLine:
36 qDebug() << "creating line series for chart: " << m_chart;
37 m_series = new QLineSeries();
38 break;
39 case QSeries::SeriesTypeArea:
40 qDebug() << "TODO: creating area series for chart: " << m_chart;
41 // m_series = new QAreaSeries();
42 break;
43 case QSeries::SeriesTypeSpline:
44 qDebug() << "creating spline series for chart: " << m_chart;
45 m_series = new QSplineSeries();
46 break;
47 case QSeries::SeriesTypeScatter:
48 qDebug() << "creating scatter series for chart: " << m_chart;
49 m_series = new QScatterSeries();
50 break;
51 default:
52 Q_ASSERT(false);
53 }
54
18
55 for (int i(0); i < m_points.count(); i++) {
19 void DeclarativeXySeries::componentComplete()
56 DeclarativeXyPoint *element = m_points.at(i);
20 {
57 m_series->add(element->x(), element->y());
21 seriesComplete();
58 }
59 m_chart->addSeries(m_series);
60 }
61 }
22 }
62
23
63 QDeclarativeListProperty<DeclarativeXyPoint> DeclarativeXySeries::points()
24 QDeclarativeListProperty<DeclarativeXyPoint> DeclarativeXySeries::points()
64 {
25 {
65 return QDeclarativeListProperty<DeclarativeXyPoint>(this, 0, &DeclarativeXySeries::appendPoints);
26 return QDeclarativeListProperty<DeclarativeXyPoint>(seriesObject(), 0, &DeclarativeXySeries::appendPoints);
66 }
27 }
67
28
68 void DeclarativeXySeries::appendPoints(QDeclarativeListProperty<DeclarativeXyPoint> *list,
29 void DeclarativeXySeries::appendPoints(QDeclarativeListProperty<DeclarativeXyPoint> *list,
69 DeclarativeXyPoint *element)
30 DeclarativeXyPoint *element)
70 {
31 {
71 DeclarativeXySeries *series = qobject_cast<DeclarativeXySeries *>(list->object);
32 QXYSeries *series = qobject_cast<QXYSeries *>(list->object);
72 qDebug() << "appendPoints: " << series;
33 if (series)
73 qDebug() << "appendPoints: " << element;
34 series->add(QPointF(element->x(), element->y()));
74 qDebug() << "appendPoints: " << element->x();
75 qDebug() << "appendPoints: " << element->y();
76 qDebug() << "appendPoints: " << series->m_series;
77 if (series) {
78 series->m_points.append(element);
79 if (series->m_series)
80 series->m_series->add(element->x(), element->y());
81 }
82 }
35 }
83
36
84 #include "moc_declarativexyseries.cpp"
85
86 QTCOMMERCIALCHART_END_NAMESPACE
37 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,45 +1,39
1 #ifndef DECLARATIVE_XY_SERIES_H
1 #ifndef DECLARATIVE_XY_SERIES_H
2 #define DECLARATIVE_XY_SERIES_H
2 #define DECLARATIVE_XY_SERIES_H
3
3
4 #include "qchartglobal.h"
4 #include "qchartglobal.h"
5 #include "declarativexypoint.h"
5 #include "declarativexypoint.h"
6 #include "qxyseries.h"
6 #include <QDeclarativeParserStatus>
7 #include <QDeclarativeItem>
7 #include <QDeclarativeListProperty>
8
8
9 QTCOMMERCIALCHART_BEGIN_NAMESPACE
9 QTCOMMERCIALCHART_BEGIN_NAMESPACE
10
10
11 class QChart;
11 class QChart;
12
12
13 class DeclarativeXySeries : public QDeclarativeItem
13 class DeclarativeXySeries : public QDeclarativeParserStatus
14 {
14 {
15 Q_OBJECT
15 Q_INTERFACES(QDeclarativeParserStatus)
16 Q_PROPERTY(QDeclarativeListProperty<DeclarativeXyPoint> points READ points)
17
16
18 public:
17 public:
19 explicit DeclarativeXySeries(QSeries::QSeriesType type, QDeclarativeItem *parent = 0);
18 explicit DeclarativeXySeries();
20 ~DeclarativeXySeries();
19 ~DeclarativeXySeries();
21
20
22 public: // from QDeclarativeParserStatus
21 public: // from QDeclarativeParserStatus
22 void classBegin();
23 void componentComplete();
23 void componentComplete();
24
24
25 public:
25 public:
26 QDeclarativeListProperty<DeclarativeXyPoint> points();
26 QDeclarativeListProperty<DeclarativeXyPoint> points();
27
27
28 Q_SIGNALS:
29
30 public Q_SLOTS:
28 public Q_SLOTS:
31 static void appendPoints(QDeclarativeListProperty<DeclarativeXyPoint> *list,
29 static void appendPoints(QDeclarativeListProperty<DeclarativeXyPoint> *list,
32 DeclarativeXyPoint *element);
30 DeclarativeXyPoint *element);
33
34 private Q_SLOTS:
35
31
36 public:
32 protected:
37 QSeries::QSeriesType m_seriesType;
33 virtual void seriesComplete() = 0;
38 QChart *m_chart;
34 virtual QObject *seriesObject() = 0;
39 QXYSeries *m_series;
40 QList<DeclarativeXyPoint *> m_points;
41 };
35 };
42
36
43 QTCOMMERCIALCHART_END_NAMESPACE
37 QTCOMMERCIALCHART_END_NAMESPACE
44
38
45 #endif // DECLARATIVE_XY_SERIES_H
39 #endif // DECLARATIVE_XY_SERIES_H
@@ -1,48 +1,49
1 TEMPLATE = lib
1 TEMPLATE = lib
2 TARGET = qtcommercialchartqml
2 TARGET = qtcommercialchartqml
3 CONFIG += qt plugin
3 CONFIG += qt plugin
4 QT += declarative
4 QT += declarative
5
5
6 !include( ../common.pri ) {
6 !include( ../common.pri ) {
7 error( "Couldn't find the common.pri file!" )
7 error( "Couldn't find the common.pri file!" )
8 }
8 }
9 !include( ../integrated.pri ) {
9 !include( ../integrated.pri ) {
10 error( "Couldn't find the integrated.pri file !")
10 error( "Couldn't find the integrated.pri file !")
11 }
11 }
12
12
13 DESTDIR = $$CHART_BUILD_PLUGIN_DIR
13 DESTDIR = $$CHART_BUILD_PLUGIN_DIR
14 contains(QT_MAJOR_VERSION, 5) {
14 contains(QT_MAJOR_VERSION, 5) {
15 # TODO: QtQuick2 not supported by the implementation currently
15 # TODO: QtQuick2 not supported by the implementation currently
16 DEFINES += QTQUICK2
16 DEFINES += QTQUICK2
17 }
17 }
18
18
19 OBJECTS_DIR = $$CHART_BUILD_DIR/plugin
19 OBJECTS_DIR = $$CHART_BUILD_DIR/plugin
20 MOC_DIR = $$CHART_BUILD_DIR/plugin
20 MOC_DIR = $$CHART_BUILD_DIR/plugin
21 UI_DIR = $$CHART_BUILD_DIR/plugin
21 UI_DIR = $$CHART_BUILD_DIR/plugin
22 RCC_DIR = $$CHART_BUILD_DIR/plugin
22 RCC_DIR = $$CHART_BUILD_DIR/plugin
23
23
24 SOURCES += \
24 SOURCES += \
25 plugin.cpp \
25 plugin.cpp \
26 declarativechart.cpp \
26 declarativechart.cpp \
27 declarativexypoint.cpp \
28 declarativexyseries.cpp \
27 declarativexyseries.cpp \
28 declarativexypoint.cpp \
29 declarativelineseries.cpp \
29 declarativelineseries.cpp \
30 declarativesplineseries.cpp \
30 declarativescatterseries.cpp \
31 declarativescatterseries.cpp \
31 declarativepieseries.cpp \
32 declarativepieseries.cpp \
32 declarativebarseries.cpp
33 declarativebarseries.cpp
33 HEADERS += \
34 HEADERS += \
34 declarativechart.h \
35 declarativechart.h \
35 declarativexypoint.h \
36 declarativexyseries.h \
36 declarativexyseries.h \
37 declarativexypoint.h \
37 declarativelineseries.h \
38 declarativelineseries.h \
38 declarativesplineseries.h \
39 declarativesplineseries.h \
39 declarativescatterseries.h \
40 declarativescatterseries.h \
40 declarativepieseries.h \
41 declarativepieseries.h \
41 declarativebarseries.h
42 declarativebarseries.h
42
43
43 TARGETPATH = QtCommercial/Chart
44 TARGETPATH = QtCommercial/Chart
44 target.path = $$[QT_INSTALL_IMPORTS]/$$TARGETPATH
45 target.path = $$[QT_INSTALL_IMPORTS]/$$TARGETPATH
45 qmldir.files += $$PWD/qmldir
46 qmldir.files += $$PWD/qmldir
46 qmldir.path += $$[QT_INSTALL_IMPORTS]/$$TARGETPATH
47 qmldir.path += $$[QT_INSTALL_IMPORTS]/$$TARGETPATH
47
48
48 INSTALLS += target qmldir
49 INSTALLS += target qmldir
@@ -1,185 +1,184
1 #include "piesliceitem_p.h"
1 #include "piesliceitem_p.h"
2 #include "piechartitem_p.h"
2 #include "piechartitem_p.h"
3 #include "qpieseries.h"
3 #include "qpieseries.h"
4 #include "qpieslice.h"
4 #include "qpieslice.h"
5 #include "chartpresenter_p.h"
5 #include "chartpresenter_p.h"
6 #include <QPainter>
6 #include <QPainter>
7 #include <QDebug>
7 #include <QDebug>
8 #include <qmath.h>
8 #include <qmath.h>
9 #include <QGraphicsSceneEvent>
9 #include <QGraphicsSceneEvent>
10 #include <QTime>
10 #include <QTime>
11
11
12 QTCOMMERCIALCHART_BEGIN_NAMESPACE
12 QTCOMMERCIALCHART_BEGIN_NAMESPACE
13
13
14 #define PI 3.14159265 // TODO: is this defined in some header?
14 #define PI 3.14159265 // TODO: is this defined in some header?
15
15
16 QPointF offset(qreal angle, qreal length)
16 QPointF offset(qreal angle, qreal length)
17 {
17 {
18 qreal dx = qSin(angle*(PI/180)) * length;
18 qreal dx = qSin(angle*(PI/180)) * length;
19 qreal dy = qCos(angle*(PI/180)) * length;
19 qreal dy = qCos(angle*(PI/180)) * length;
20 return QPointF(dx, -dy);
20 return QPointF(dx, -dy);
21 }
21 }
22
22
23 PieSliceItem::PieSliceItem(QGraphicsItem* parent)
23 PieSliceItem::PieSliceItem(QGraphicsItem* parent)
24 :QGraphicsObject(parent)
24 :QGraphicsObject(parent)
25 {
25 {
26 setAcceptHoverEvents(true);
26 setAcceptHoverEvents(true);
27 setAcceptedMouseButtons(Qt::MouseButtonMask);
27 setAcceptedMouseButtons(Qt::MouseButtonMask);
28 setZValue(ChartPresenter::PieSeriesZValue);
28 setZValue(ChartPresenter::PieSeriesZValue);
29 }
29 }
30
30
31 PieSliceItem::~PieSliceItem()
31 PieSliceItem::~PieSliceItem()
32 {
32 {
33
33
34 }
34 }
35
35
36 QRectF PieSliceItem::boundingRect() const
36 QRectF PieSliceItem::boundingRect() const
37 {
37 {
38 return m_boundingRect;
38 return m_boundingRect;
39 }
39 }
40
40
41 QPainterPath PieSliceItem::shape() const
41 QPainterPath PieSliceItem::shape() const
42 {
42 {
43 // Don't include the label and label arm.
43 // Don't include the label and label arm.
44 // This is used to detect a mouse clicks. We do not want clicks from label.
44 // This is used to detect a mouse clicks. We do not want clicks from label.
45 return m_slicePath;
45 return m_slicePath;
46 }
46 }
47
47
48 void PieSliceItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* /*option*/, QWidget* /*widget*/)
48 void PieSliceItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* /*option*/, QWidget* /*widget*/)
49 {
49 {
50 painter->setClipRect(parentItem()->boundingRect());
51
52 painter->save();
50 painter->save();
51 painter->setClipRect(parentItem()->boundingRect());
53 painter->setPen(m_data.m_slicePen);
52 painter->setPen(m_data.m_slicePen);
54 painter->setBrush(m_data.m_sliceBrush);
53 painter->setBrush(m_data.m_sliceBrush);
55 painter->drawPath(m_slicePath);
54 painter->drawPath(m_slicePath);
56 painter->restore();
55 painter->restore();
57
56
58 if (m_data.m_isLabelVisible) {
57 if (m_data.m_isLabelVisible) {
59 painter->setPen(m_data.m_labelPen);
58 painter->setPen(m_data.m_labelPen);
60 painter->drawPath(m_labelArmPath);
59 painter->drawPath(m_labelArmPath);
61 // the pen color will affect the font color as well
60 // the pen color will affect the font color as well
62 painter->setFont(m_data.m_labelFont);
61 painter->setFont(m_data.m_labelFont);
63 painter->drawText(m_labelTextRect.bottomLeft(), m_data.m_labelText);
62 painter->drawText(m_labelTextRect.bottomLeft(), m_data.m_labelText);
64 }
63 }
65 }
64 }
66
65
67 void PieSliceItem::hoverEnterEvent(QGraphicsSceneHoverEvent* /*event*/)
66 void PieSliceItem::hoverEnterEvent(QGraphicsSceneHoverEvent* /*event*/)
68 {
67 {
69 emit hoverEnter();
68 emit hoverEnter();
70 }
69 }
71
70
72 void PieSliceItem::hoverLeaveEvent(QGraphicsSceneHoverEvent* /*event*/)
71 void PieSliceItem::hoverLeaveEvent(QGraphicsSceneHoverEvent* /*event*/)
73 {
72 {
74 emit hoverLeave();
73 emit hoverLeave();
75 }
74 }
76
75
77 void PieSliceItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
76 void PieSliceItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
78 {
77 {
79 emit clicked(event->buttons());
78 emit clicked(event->buttons());
80 }
79 }
81
80
82 void PieSliceItem::setSliceData(PieSliceData sliceData)
81 void PieSliceItem::setSliceData(PieSliceData sliceData)
83 {
82 {
84 m_data = sliceData;
83 m_data = sliceData;
85 }
84 }
86
85
87 void PieSliceItem::updateGeometry()
86 void PieSliceItem::updateGeometry()
88 {
87 {
89 if (m_data.m_radius <= 0)
88 if (m_data.m_radius <= 0)
90 return;
89 return;
91
90
92 prepareGeometryChange();
91 prepareGeometryChange();
93
92
94 // update slice path
93 // update slice path
95 qreal centerAngle;
94 qreal centerAngle;
96 QPointF armStart;
95 QPointF armStart;
97 m_slicePath = slicePath(m_data.m_center, m_data.m_radius, m_data.m_startAngle, m_data.m_angleSpan, &centerAngle, &armStart);
96 m_slicePath = slicePath(m_data.m_center, m_data.m_radius, m_data.m_startAngle, m_data.m_angleSpan, &centerAngle, &armStart);
98
97
99 // update text rect
98 // update text rect
100 m_labelTextRect = labelTextRect(m_data.m_labelFont, m_data.m_labelText);
99 m_labelTextRect = labelTextRect(m_data.m_labelFont, m_data.m_labelText);
101
100
102 // update label arm path
101 // update label arm path
103 QPointF labelTextStart;
102 QPointF labelTextStart;
104 m_labelArmPath = labelArmPath(armStart, centerAngle, m_data.m_radius * m_data.m_labelArmLengthFactor, m_labelTextRect.width(), &labelTextStart);
103 m_labelArmPath = labelArmPath(armStart, centerAngle, m_data.m_radius * m_data.m_labelArmLengthFactor, m_labelTextRect.width(), &labelTextStart);
105
104
106 // update text position
105 // update text position
107 m_labelTextRect.moveBottomLeft(labelTextStart);
106 m_labelTextRect.moveBottomLeft(labelTextStart);
108
107
109 // update bounding rect
108 // update bounding rect
110 if (m_data.m_isLabelVisible)
109 if (m_data.m_isLabelVisible)
111 m_boundingRect = m_slicePath.boundingRect().united(m_labelArmPath.boundingRect()).united(m_labelTextRect);
110 m_boundingRect = m_slicePath.boundingRect().united(m_labelArmPath.boundingRect()).united(m_labelTextRect);
112 else
111 else
113 m_boundingRect = m_slicePath.boundingRect();
112 m_boundingRect = m_slicePath.boundingRect();
114 }
113 }
115
114
116 QPointF PieSliceItem::sliceCenter(QPointF point, qreal radius, QPieSlice *slice)
115 QPointF PieSliceItem::sliceCenter(QPointF point, qreal radius, QPieSlice *slice)
117 {
116 {
118 if (slice->isExploded()) {
117 if (slice->isExploded()) {
119 qreal centerAngle = slice->startAngle() + ((slice->endAngle() - slice->startAngle())/2);
118 qreal centerAngle = slice->startAngle() + ((slice->endAngle() - slice->startAngle())/2);
120 qreal len = radius * slice->explodeDistanceFactor();
119 qreal len = radius * slice->explodeDistanceFactor();
121 qreal dx = qSin(centerAngle*(PI/180)) * len;
120 qreal dx = qSin(centerAngle*(PI/180)) * len;
122 qreal dy = -qCos(centerAngle*(PI/180)) * len;
121 qreal dy = -qCos(centerAngle*(PI/180)) * len;
123 point += QPointF(dx, dy);
122 point += QPointF(dx, dy);
124 }
123 }
125 return point;
124 return point;
126 }
125 }
127
126
128 QPainterPath PieSliceItem::slicePath(QPointF center, qreal radius, qreal startAngle, qreal angleSpan, qreal* centerAngle, QPointF* armStart)
127 QPainterPath PieSliceItem::slicePath(QPointF center, qreal radius, qreal startAngle, qreal angleSpan, qreal* centerAngle, QPointF* armStart)
129 {
128 {
130 // calculate center angle
129 // calculate center angle
131 *centerAngle = startAngle + (angleSpan/2);
130 *centerAngle = startAngle + (angleSpan/2);
132
131
133 // calculate slice rectangle
132 // calculate slice rectangle
134 QRectF rect(center.x()-radius, center.y()-radius, radius*2, radius*2);
133 QRectF rect(center.x()-radius, center.y()-radius, radius*2, radius*2);
135
134
136 // slice path
135 // slice path
137 // TODO: draw the shape so that it might have a hole in the center
136 // TODO: draw the shape so that it might have a hole in the center
138 QPainterPath path;
137 QPainterPath path;
139 path.moveTo(rect.center());
138 path.moveTo(rect.center());
140 path.arcTo(rect, -startAngle + 90, -angleSpan);
139 path.arcTo(rect, -startAngle + 90, -angleSpan);
141 path.closeSubpath();
140 path.closeSubpath();
142
141
143 // calculate label arm start point
142 // calculate label arm start point
144 *armStart = center;
143 *armStart = center;
145 *armStart += offset(*centerAngle, radius + PIESLICE_LABEL_GAP);
144 *armStart += offset(*centerAngle, radius + PIESLICE_LABEL_GAP);
146
145
147 return path;
146 return path;
148 }
147 }
149
148
150 QPainterPath PieSliceItem::labelArmPath(QPointF start, qreal angle, qreal length, qreal textWidth, QPointF* textStart)
149 QPainterPath PieSliceItem::labelArmPath(QPointF start, qreal angle, qreal length, qreal textWidth, QPointF* textStart)
151 {
150 {
152 qreal dx = qSin(angle*(PI/180)) * length;
151 qreal dx = qSin(angle*(PI/180)) * length;
153 qreal dy = -qCos(angle*(PI/180)) * length;
152 qreal dy = -qCos(angle*(PI/180)) * length;
154 QPointF parm1 = start + QPointF(dx, dy);
153 QPointF parm1 = start + QPointF(dx, dy);
155
154
156 QPointF parm2 = parm1;
155 QPointF parm2 = parm1;
157 if (angle < 180) { // arm swings the other way on the left side
156 if (angle < 180) { // arm swings the other way on the left side
158 parm2 += QPointF(textWidth, 0);
157 parm2 += QPointF(textWidth, 0);
159 *textStart = parm1;
158 *textStart = parm1;
160 }
159 }
161 else {
160 else {
162 parm2 += QPointF(-textWidth,0);
161 parm2 += QPointF(-textWidth,0);
163 *textStart = parm2;
162 *textStart = parm2;
164 }
163 }
165
164
166 // elevate the text position a bit so that it does not hit the line
165 // elevate the text position a bit so that it does not hit the line
167 *textStart += QPointF(0, -5);
166 *textStart += QPointF(0, -5);
168
167
169 QPainterPath path;
168 QPainterPath path;
170 path.moveTo(start);
169 path.moveTo(start);
171 path.lineTo(parm1);
170 path.lineTo(parm1);
172 path.lineTo(parm2);
171 path.lineTo(parm2);
173
172
174 return path;
173 return path;
175 }
174 }
176
175
177 QRectF PieSliceItem::labelTextRect(QFont font, QString text)
176 QRectF PieSliceItem::labelTextRect(QFont font, QString text)
178 {
177 {
179 QFontMetricsF fm(font);
178 QFontMetricsF fm(font);
180 return fm.boundingRect(text);
179 return fm.boundingRect(text);
181 }
180 }
182
181
183 #include "moc_piesliceitem_p.cpp"
182 #include "moc_piesliceitem_p.cpp"
184
183
185 QTCOMMERCIALCHART_END_NAMESPACE
184 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,104 +1,103
1 import QtQuick 1.0
1 import QtQuick 1.0
2 import QtCommercial.Chart 1.0
2 import QtCommercial.Chart 1.0
3
3
4 Rectangle {
4 Rectangle {
5 width: parent.width
5 width: parent.width
6 height: parent.height
6 height: parent.height
7
7
8 // Another option for QML data api:
8 // Another option for QML data api:
9 // ListModel {
9 // ListModel {
10 // id: listModelForPie
10 // id: listModelForPie
11 // // PieDataElement
11 // // PieDataElement
12 // ListElement {
12 // ListElement {
13 // label: "Apple"
13 // label: "Apple"
14 // value: 4.3
14 // value: 4.3
15 // }
15 // }
16 // ListElement {
16 // ListElement {
17 // label: "Blackberry"
17 // label: "Blackberry"
18 // value: 15.1
18 // value: 15.1
19 // }
19 // }
20 // }
20 // }
21
21
22 Component.onCompleted: {
22 Component.onCompleted: {
23 // console.log("model:" + myModel.item(0));
23 // console.log("model:" + myModel.item(0));
24 // myModel.insert(1, {"time":1.4; "speed":41.1 });
24 // myModel.insert(1, {"time":1.4; "speed":41.1 });
25 // scatter.appendData();
25 // scatter.appendData();
26 // chart1.theme = Chart.ThemeHighContrast;
27 // chart2.theme = Chart.ThemeHighContrast;
26 }
28 }
27
29
28
30
29 Chart {
31 Chart {
30 id: chart1
32 id: chart1
31 anchors.top: parent.top
33 anchors.top: parent.top
32 anchors.left: parent.left
34 anchors.left: parent.left
33 anchors.right: parent.right
35 anchors.right: parent.right
34 height: parent.height / 2
36 height: parent.height / 2
35 theme: Chart.ThemeBlueCerulean
37 theme: Chart.ThemeBlueCerulean
36
38
37 BarSeries {
39 BarSeries {
38 barCategories: [ "2008", "2009", "2010", "2011", "2012" ]
40 barCategories: [ "2008", "2009", "2010", "2011", "2012" ]
39 // data: [
40 // BarSet { }
41 // ]
42 }
41 }
43
42
44 // PieSeries {
43 PieSeries {
45 // data: [
44 slices: [
46 // PieSlice { label: "Volkswagen"; value: 13.5 },
45 PieSlice { label: "Volkswagen"; value: 13.5 },
47 // PieSlice { label: "Toyota"; value: 10.9 },
46 PieSlice { label: "Toyota"; value: 10.9 },
48 // PieSlice { label: "Ford"; value: 8.6 },
47 PieSlice { label: "Ford"; value: 8.6 },
49 // PieSlice { label: "Skoda"; value: 8.2 },
48 PieSlice { label: "Skoda"; value: 8.2 },
50 // PieSlice { label: "Volvo"; value: 6.8 },
49 PieSlice { label: "Volvo"; value: 6.8 },
51 // PieSlice { label: "Others"; value: 52.0 }
50 PieSlice { label: "Others"; value: 52.0 }
52 // ]
51 ]
53 // }
52 }
54 }
53 }
55
54
56
55
57 Chart {
56 Chart {
58 id: chart2
57 id: chart2
59 anchors.top: chart1.bottom
58 anchors.top: chart1.bottom
60 anchors.bottom: parent.bottom
59 anchors.bottom: parent.bottom
61 anchors.left: parent.left
60 anchors.left: parent.left
62 anchors.right: parent.right
61 anchors.right: parent.right
63 theme: Chart.ThemeBrownSand
62 theme: Chart.ThemeBrownSand
64
63
65 LineSeries {
64 LineSeries {
66 points: [
65 points: [
67 XyPoint { x: 0.0; y: 0.0 },
66 XyPoint { x: 0.0; y: 0.0 },
68 XyPoint { x: 1.1; y: 2.1 },
67 XyPoint { x: 1.1; y: 2.1 },
69 XyPoint { x: 2.9; y: 4.9 },
68 XyPoint { x: 2.9; y: 4.9 },
70 XyPoint { x: 3.2; y: 3.0 }
69 XyPoint { x: 3.2; y: 3.0 }
71 ]
70 ]
72 }
71 }
73
72
74 SplineSeries {
73 SplineSeries {
75 id: scatter
76 points: [
74 points: [
77 XyPoint { x: 0.0; y: 0.3 },
75 XyPoint { x: 0.0; y: 0.3 },
78 XyPoint { x: 1.1; y: 3.2 },
76 XyPoint { x: 1.1; y: 3.2 },
79 XyPoint { x: 4.17; y: 3.15 }
77 XyPoint { x: 4.17; y: 3.15 }
80 ]
78 ]
81 }
79 }
80
82 ScatterSeries {
81 ScatterSeries {
83 points: [
82 points: [
84 XyPoint { x: 1.5; y: 1.5 },
83 XyPoint { x: 1.5; y: 1.5 },
85 XyPoint { x: 1.5; y: 1.6 },
84 XyPoint { x: 1.5; y: 1.6 },
86 XyPoint { x: 1.57; y: 1.55 }
85 XyPoint { x: 1.57; y: 1.55 }
87 ]
86 ]
88 }
87 }
89 ScatterSeries {
88 ScatterSeries {
90 points: [
89 points: [
91 XyPoint { x: 2.0; y: 2.0 },
90 XyPoint { x: 2.0; y: 2.0 },
92 XyPoint { x: 2.0; y: 2.1 },
91 XyPoint { x: 2.0; y: 2.1 },
93 XyPoint { x: 2.07; y: 2.05 }
92 XyPoint { x: 2.07; y: 2.05 }
94 ]
93 ]
95 }
94 }
96 ScatterSeries {
95 ScatterSeries {
97 points: [
96 points: [
98 XyPoint { x: 2.6; y: 2.6 },
97 XyPoint { x: 2.6; y: 2.6 },
99 XyPoint { x: 2.6; y: 2.7 },
98 XyPoint { x: 2.6; y: 2.7 },
100 XyPoint { x: 2.67; y: 2.65 }
99 XyPoint { x: 2.67; y: 2.65 }
101 ]
100 ]
102 }
101 }
103 }
102 }
104 }
103 }
General Comments 0
You need to be logged in to leave comments. Login now