From 0385556f52b366ac4d8b472db47f1da4ad73ac94 2012-05-18 10:03:44 From: Tero Ahola Date: 2012-05-18 10:03:44 Subject: [PATCH] QML and static data in pie and xy series --- diff --git a/demos/qmlchart/qml/qmlchart/View1.qml b/demos/qmlchart/qml/qmlchart/View1.qml index 1dd35e7..2dfaf49 100644 --- a/demos/qmlchart/qml/qmlchart/View1.qml +++ b/demos/qmlchart/qml/qmlchart/View1.qml @@ -25,15 +25,6 @@ Rectangle { anchors.fill: parent property int __explodedIndex: -1 - ChartModel { - id: chartModel - ChartModelRow { values: ["Volkswagen", 13.5] } - ChartModelRow { values: ["Toyota", 10.9] } - ChartModelRow { values: ["Ford", 8.6] } - ChartModelRow { values: ["Skoda", 8.2] } - ChartModelRow { values: ["Volvo", 6.8] } - } - ChartView { id: chart title: "Top-5 car brand shares in Finland" @@ -45,22 +36,41 @@ Rectangle { legend: ChartView.LegendBottom animationOptions: ChartView.SeriesAnimations + // If you have static data, you can simply use the PieSlice API PieSeries { id: pieSeries - model: chartModel - modelMapper.mapLabels: 0 - modelMapper.mapValues: 1 - modelMapper.first: 0 - modelMapper.count: -1 // "Undefined" = -1 by default - modelMapper.orientation: PieModelMapper.Vertical - - // TODO: PieSlice to append the data directly into the mapped columns - //PieSlice { label: "Toyota"; value: 10.9 } + PieSlice { label: "Volkswagen"; value: 13.5 } + PieSlice { label: "Toyota"; value: 10.9 } + PieSlice { label: "Ford"; value: 8.6 } + PieSlice { label: "Skoda"; value: 8.2 } + PieSlice { label: "Volvo"; value: 6.8 } } + + // For dynamic data you can use the ChartModel API. +// ChartModel { +// id: chartModel +// ChartModelRow { values: ["Volkswagen", 13.5] } +// ChartModelRow { values: ["Toyota", 10.9] } +// ChartModelRow { values: ["Ford", 8.6] } +// ChartModelRow { values: ["Skoda", 8.2] } +// ChartModelRow { values: ["Volvo", 6.8] } +// } + + // In this case you need to define how the data maps to pie slices with the ModelMapper API of the pie series. +// PieSeries { +// id: pieSeries +// model: chartModel +// modelMapper.mapLabels: 0 +// modelMapper.mapValues: 1 +// modelMapper.first: 0 +// modelMapper.count: -1 // "Undefined" = -1 by default +// modelMapper.orientation: PieModelMapper.Vertical +// } } Component.onCompleted: { - chartModel.append(["Others", 52.0]); + // You can also add data dynamically + pieSeries.model.append(["Others", 52.0]); } Timer { diff --git a/demos/qmlchart/qml/qmlchart/View4.qml b/demos/qmlchart/qml/qmlchart/View4.qml index 3cc8a4e..a2223f5 100644 --- a/demos/qmlchart/qml/qmlchart/View4.qml +++ b/demos/qmlchart/qml/qmlchart/View4.qml @@ -32,26 +32,22 @@ Rectangle { ScatterSeries { id: scatter1 name: "Scatter1" - model: ChartModel { - XyPoint { x: 1.5; y: 1.5 } - XyPoint { x: 1.5; y: 1.6 } - XyPoint { x: 1.57; y: 1.55 } - XyPoint { x: 1.8; y: 1.8 } - XyPoint { x: 1.9; y: 1.6 } - XyPoint { x: 2.1; y: 1.3 } - XyPoint { x: 2.5; y: 2.1 } - } + XyPoint { x: 1.5; y: 1.5 } + XyPoint { x: 1.5; y: 1.6 } + XyPoint { x: 1.57; y: 1.55 } + XyPoint { x: 1.8; y: 1.8 } + XyPoint { x: 1.9; y: 1.6 } + XyPoint { x: 2.1; y: 1.3 } + XyPoint { x: 2.5; y: 2.1 } } ScatterSeries { name: "Scatter2" - model: ChartModel { - XyPoint { x: 2.0; y: 2.0 } - XyPoint { x: 2.0; y: 2.1 } - XyPoint { x: 2.07; y: 2.05 } - XyPoint { x: 2.2; y: 2.9 } - XyPoint { x: 2.4; y: 2.7 } - XyPoint { x: 2.67; y: 2.65 } - } + XyPoint { x: 2.0; y: 2.0 } + XyPoint { x: 2.0; y: 2.1 } + XyPoint { x: 2.07; y: 2.05 } + XyPoint { x: 2.2; y: 2.9 } + XyPoint { x: 2.4; y: 2.7 } + XyPoint { x: 2.67; y: 2.65 } } } } diff --git a/qmlplugin/declarativemodel.cpp b/qmlplugin/declarativemodel.cpp index 58a62cd..8a6aff4 100644 --- a/qmlplugin/declarativemodel.cpp +++ b/qmlplugin/declarativemodel.cpp @@ -55,8 +55,11 @@ void DeclarativeTableModel::classBegin() void DeclarativeTableModel::componentComplete() { - foreach (QObject *child, children()) - appendToModel(child); + foreach (QObject *child, children()) { + if (qobject_cast(child)) { + append(qobject_cast(child)->values()); + } + } } QDeclarativeListProperty DeclarativeTableModel::modelChildren() @@ -94,57 +97,50 @@ void DeclarativeTableModel::append(QVariantList values) dataChanged(beginIndex, endIndex); } -void DeclarativeTableModel::appendToModel(QObject *object) +void DeclarativeTableModel::appendPoint(QXYModelMapper *mapper, DeclarativeXyPoint *point) { - if (qobject_cast(object)) { - DeclarativeBarModel *model = qobject_cast(this); - Q_ASSERT(model); - model->append(qobject_cast(object)); - } else if (qobject_cast(object)) { - // TODO - } else if (qobject_cast(object)) { - // TODO - appendPoint(qobject_cast(object)); - } else if (qobject_cast(this)) { - append(qobject_cast(object)->values()); - } + qDebug() << "DeclarativeTableModel::appendPoint:" << point; + QVariantList values; + values.insert(mapper->mapX(), point->x()); + values.insert(mapper->mapY(), point->y()); + append(values); } -void DeclarativeTableModel::appendPoints(QVariantList points) -{ - qreal x = 0.0; - for (int i(0); i < points.count(); i++) { - if (i % 2) { - bool ok(false); - qreal y = points.at(i).toReal(&ok); - if (ok) { - DeclarativeXyPoint *point= new DeclarativeXyPoint(); - point->setX(x); - point->setY(y); - appendPoint(point); - } else { - qWarning() << "Illegal y value"; - } - } else { - bool ok(false); - x = points.at(i).toReal(&ok); - if (!ok) { - qWarning() << "Illegal x value"; - } - } - } -} - -void DeclarativeTableModel::appendPoint(DeclarativeXyPoint* point) -{ -// qDebug() << "DeclarativeTableModel::append:" << point->x() << " " << point->y(); - insertRow(rowCount()); - QModelIndex xModelIndex = createIndex(rowCount() - 1, 0); - QModelIndex yModelIndex = createIndex(rowCount() - 1, 1); - setData(xModelIndex, point->x()); - setData(yModelIndex, point->y()); - dataChanged(xModelIndex, yModelIndex); -} +//void DeclarativeTableModel::appendPoints(QVariantList points) +//{ +// qreal x = 0.0; +// for (int i(0); i < points.count(); i++) { +// if (i % 2) { +// bool ok(false); +// qreal y = points.at(i).toReal(&ok); +// if (ok) { +// DeclarativeXyPoint *point= new DeclarativeXyPoint(); +// point->setX(x); +// point->setY(y); +// appendPoint(point); +// } else { +// qWarning() << "Illegal y value"; +// } +// } else { +// bool ok(false); +// x = points.at(i).toReal(&ok); +// if (!ok) { +// qWarning() << "Illegal x value"; +// } +// } +// } +//} + +//void DeclarativeTableModel::appendPoint(DeclarativeXyPoint* point) +//{ +//// qDebug() << "DeclarativeTableModel::append:" << point->x() << " " << point->y(); +// insertRow(rowCount()); +// QModelIndex xModelIndex = createIndex(rowCount() - 1, 0); +// QModelIndex yModelIndex = createIndex(rowCount() - 1, 1); +// setData(xModelIndex, point->x()); +// setData(yModelIndex, point->y()); +// dataChanged(xModelIndex, yModelIndex); +//} ////////////// Bar model /////////////////////// diff --git a/qmlplugin/declarativemodel.h b/qmlplugin/declarativemodel.h index fcf3e08..43fc501 100644 --- a/qmlplugin/declarativemodel.h +++ b/qmlplugin/declarativemodel.h @@ -26,6 +26,7 @@ #include #include "../src/charttablemodel.h" // TODO #include +#include #include #include #include @@ -55,6 +56,7 @@ class DeclarativeTableModel : public ChartTableModel, public QDeclarativeParserS public: explicit DeclarativeTableModel(QObject *parent = 0); QDeclarativeListProperty modelChildren(); + void appendPoint(QXYModelMapper *mapper, DeclarativeXyPoint *point); public: // from QDeclarativeParserStatus void classBegin(); @@ -62,12 +64,8 @@ public: // from QDeclarativeParserStatus public Q_SLOTS: void append(QVariantList slices); - void appendPoints(QVariantList points); - void appendPoint(DeclarativeXyPoint* point); static void appendModelChild(QDeclarativeListProperty *list, QObject *element); -private: - void appendToModel(QObject *object); }; class DeclarativeBarModel : public DeclarativeTableModel diff --git a/qmlplugin/declarativepieseries.cpp b/qmlplugin/declarativepieseries.cpp index 19069c6..657005a 100644 --- a/qmlplugin/declarativepieseries.cpp +++ b/qmlplugin/declarativepieseries.cpp @@ -30,7 +30,7 @@ DeclarativePieSeries::DeclarativePieSeries(QObject *parent) : QPieSeries(parent) { // TODO: set default model on init? -// setModel(new DeclarativeTableModel()); + setModel(new DeclarativeTableModel()); // Set default mapper parameters to allow easy to use PieSeries api QPieModelMapper *mapper = new QPieModelMapper(); @@ -42,6 +42,31 @@ DeclarativePieSeries::DeclarativePieSeries(QObject *parent) : setModelMapper(mapper); } +void DeclarativePieSeries::classBegin() +{ +} + +void DeclarativePieSeries::componentComplete() +{ + foreach(QObject *child, children()) { + qDebug() << "pie child: " << child; + if (qobject_cast(child)) { + QPieSlice *slice = qobject_cast(child); + QVariantList values; + values.insert(modelMapper()->mapLabels(), slice->label()); + values.insert(modelMapper()->mapValues(), slice->value()); + DeclarativeTableModel *m = qobject_cast(model()); + Q_ASSERT(m); + m->append(values); + } + } +} + +QDeclarativeListProperty DeclarativePieSeries::initialSlices() +{ + return QDeclarativeListProperty(this, 0, &DeclarativePieSeries::appendInitialSlices); +} + QPieSlice *DeclarativePieSeries::slice(int index) { QList sliceList = slices(); diff --git a/qmlplugin/declarativepieseries.h b/qmlplugin/declarativepieseries.h index a3c9a51..0734d02 100644 --- a/qmlplugin/declarativepieseries.h +++ b/qmlplugin/declarativepieseries.h @@ -22,8 +22,9 @@ #define DECLARATIVEPIESERIES_H #include "qchartglobal.h" -#include "qpieslice.h" -#include "qpieseries.h" +#include +#include +#include #include #include #include @@ -33,20 +34,27 @@ QTCOMMERCIALCHART_BEGIN_NAMESPACE class QChart; -class DeclarativePieSeries : public QPieSeries +class DeclarativePieSeries : public QPieSeries, public QDeclarativeParserStatus { Q_OBJECT + Q_INTERFACES(QDeclarativeParserStatus) Q_PROPERTY(DeclarativeTableModel *model READ pieModel WRITE setPieModel) + Q_PROPERTY(QDeclarativeListProperty initialSlices READ initialSlices) + Q_CLASSINFO("DefaultProperty", "initialSlices") public: explicit DeclarativePieSeries(QObject *parent = 0); - -public: + QDeclarativeListProperty initialSlices(); + DeclarativeTableModel *pieModel(); + void setPieModel(DeclarativeTableModel *model); Q_INVOKABLE QPieSlice *slice(int index); public: - void setPieModel(DeclarativeTableModel *model); - DeclarativeTableModel *pieModel(); + void classBegin(); + void componentComplete(); + +public Q_SLOTS: + static void appendInitialSlices(QDeclarativeListProperty */*list*/, QPieSlice */*element*/) {} }; QTCOMMERCIALCHART_END_NAMESPACE diff --git a/qmlplugin/declarativescatterseries.cpp b/qmlplugin/declarativescatterseries.cpp index cc2ad69..12ff185 100644 --- a/qmlplugin/declarativescatterseries.cpp +++ b/qmlplugin/declarativescatterseries.cpp @@ -30,6 +30,18 @@ DeclarativeScatterSeries::DeclarativeScatterSeries(QObject *parent) : { } +QDeclarativeListProperty DeclarativeScatterSeries::declarativeChildren() +{ + return QDeclarativeListProperty(this, 0, &appendDeclarativeChildren); +} + +void DeclarativeScatterSeries::appendDeclarativeChildren(QDeclarativeListProperty *list, QObject *element) +{ + DeclarativeScatterSeries *series = qobject_cast(list->object); + if (series && qobject_cast(element)) + series->declarativeModel()->appendPoint(series->modelMapper(), qobject_cast(element)); +} + #include "moc_declarativescatterseries.cpp" QTCOMMERCIALCHART_END_NAMESPACE diff --git a/qmlplugin/declarativescatterseries.h b/qmlplugin/declarativescatterseries.h index 0b42721..704bc58 100644 --- a/qmlplugin/declarativescatterseries.h +++ b/qmlplugin/declarativescatterseries.h @@ -24,7 +24,6 @@ #include "qchartglobal.h" #include "qscatterseries.h" #include "declarativexyseries.h" -#include QTCOMMERCIALCHART_BEGIN_NAMESPACE @@ -32,9 +31,15 @@ class DeclarativeScatterSeries : public QScatterSeries, public DeclarativeXySeri { Q_OBJECT Q_PROPERTY(DeclarativeTableModel *model READ declarativeModel WRITE setDeclarativeModel) + Q_PROPERTY(QDeclarativeListProperty declarativeChildren READ declarativeChildren) + Q_CLASSINFO("DefaultProperty", "declarativeChildren") public: explicit DeclarativeScatterSeries(QObject *parent = 0); + QDeclarativeListProperty declarativeChildren(); + +public Q_SLOTS: + static void appendDeclarativeChildren(QDeclarativeListProperty *list, QObject *element); }; QTCOMMERCIALCHART_END_NAMESPACE diff --git a/qmlplugin/declarativexyseries.cpp b/qmlplugin/declarativexyseries.cpp index 6e216eb..a33a6f3 100644 --- a/qmlplugin/declarativexyseries.cpp +++ b/qmlplugin/declarativexyseries.cpp @@ -20,9 +20,10 @@ //#include "DeclarativeXySeries.h" #include "declarativexyseries.h" +#include "declarativechart.h" #include #include -#include "declarativechart.h" +#include QTCOMMERCIALCHART_BEGIN_NAMESPACE @@ -30,6 +31,8 @@ DeclarativeXySeries::DeclarativeXySeries() { // All the inherited objects must be of type QXYSeries, so it is safe to cast QXYSeries *series = reinterpret_cast(this); + // TODO: set default model on init? + series->setModel(new DeclarativeTableModel()); QXYModelMapper *mapper = new QXYModelMapper(series); mapper->setMapX(0); mapper->setMapY(1); @@ -51,10 +54,6 @@ bool DeclarativeXySeries::setDeclarativeModel(DeclarativeTableModel *model) // All the inherited objects must be of type QXYSeries, so it is safe to cast QXYSeries *series = reinterpret_cast(this); series->setModel(m); -// QXYModelMapper *mapper = new QXYModelMapper; -// mapper->setMapX(0); -// mapper->setMapY(1); -// series->setModelMapper(mapper); } else { qWarning("DeclarativeXySeries: Illegal model"); } diff --git a/qmlplugin/declarativexyseries.h b/qmlplugin/declarativexyseries.h index a546e5b..b05d0d5 100644 --- a/qmlplugin/declarativexyseries.h +++ b/qmlplugin/declarativexyseries.h @@ -32,8 +32,6 @@ class QAbstractSeries; class DeclarativeXySeries { - Q_INTERFACES(QDeclarativeParserStatus) - public: explicit DeclarativeXySeries(); ~DeclarativeXySeries();