diff --git a/demos/qmlchart/qml/qmlchart/View1.qml b/demos/qmlchart/qml/qmlchart/View1.qml index d509572..4031919 100644 --- a/demos/qmlchart/qml/qmlchart/View1.qml +++ b/demos/qmlchart/qml/qmlchart/View1.qml @@ -23,6 +23,7 @@ import QtCommercial.Chart 1.0 Rectangle { anchors.fill: parent + property int __explodedIndex: -1 ChartView { id: chart @@ -36,9 +37,12 @@ Rectangle { animationOptions: ChartView.SeriesAnimations PieSeries { + id: pieSeries model: PieModel { id: pieModel - PieSlice { label: "Volkswagen"; value: 13.5 } + // TODO: initializing properties does not work at the moment, see DeclarativePieModel::append + // TODO: explode range, color, border color, border thickness, font, .. + PieSlice { exploded: true; label: "Volkswagen"; value: 13.5 } PieSlice { label: "Toyota"; value: 10.9 } PieSlice { label: "Ford"; value: 8.6 } PieSlice { label: "Skoda"; value: 8.2 } @@ -47,6 +51,23 @@ Rectangle { } } + Timer { + repeat: true + interval: 2000 + running: true + onTriggered: { + changeSliceExploded(__explodedIndex); + __explodedIndex = (__explodedIndex + 1) % pieModel.count; + changeSliceExploded(__explodedIndex); + } + } + + function changeSliceExploded(index) { + if (index >= 0 && index < pieModel.count) { + pieSeries.slice(index).exploded = !pieSeries.slice(index).exploded; + } + } + Rectangle { id: button anchors.bottom: parent.bottom @@ -74,6 +95,7 @@ Rectangle { // TODO: this should also be doable by redefining the range inside the model button.state = ""; pieModel.removeRow(pieModel.count - 1); + // TODO: removeAll("label") ? } } } @@ -89,10 +111,15 @@ Rectangle { // // column3 not used by pie series // PieSeries { // model: chartModel -// mappings: [ {"column1":"label"}, {"column2":"value"} ] +// modelMapping: PieMapping { +// labels: 0 // undefined by default +// values: 1 // undefined by default +// first: 0 // 0 by default +// count: 10 // "Undefined" by default +// orientation: PieMapping.Vertical // Vertical by default +// } // } - // TODO: show how to use data from a list model in a chart view // i.e. copy the data into a chart model // ListModel { diff --git a/demos/qmlchart/qml/qmlchart/View3.qml b/demos/qmlchart/qml/qmlchart/View3.qml index b85e6fd..4c31afd 100644 --- a/demos/qmlchart/qml/qmlchart/View3.qml +++ b/demos/qmlchart/qml/qmlchart/View3.qml @@ -49,6 +49,19 @@ Rectangle { } } + // TODO: optional implementation with generic ChartModel +// AreaSeries { +// model: chartModel +// modelMapping: XyMapping { +// xValues: 0 // undefined by default +// yValues: 1 // undefined by default +// first: 0 // 0 by default +// count: 10 // "Undefined" by default +// orientation: XyMapping.Vertical // Vertical by default +// } +// } + + XYModel { id: zerosModel XyPoint { x: 0; y: 0 } diff --git a/demos/qmlchart/qml/qmlchart/View5.qml b/demos/qmlchart/qml/qmlchart/View5.qml index f388093..6eb8b59 100644 --- a/demos/qmlchart/qml/qmlchart/View5.qml +++ b/demos/qmlchart/qml/qmlchart/View5.qml @@ -29,10 +29,50 @@ Rectangle { anchors.fill: parent theme: ChartView.ChartThemeLight legend: ChartView.LegendBottom +// axisXLabels: ["0", "2008", "1", "2009", "2", "2010", "3", "2012"] + axisX.max: 10 BarSeries { barCategories: [ "2008", "2009", "2010", "2011", "2012" ] - // data implementation missing + model: barModel } + + +// // TODO: optional syntax with ChartModel base model API +// BarSeries { +// model: chartModel +// modelMapping: BarSeriesMapping { +// // Giving "undefined" x mapping value means that the indexes are used as x-values +// setIndexes: [BarSeriesMapping.Undefined, 0, +// BarSeriesMapping.Undefined, 1, +// BarSeriesMapping.Undefined, 2] // defaults to [] +//// setValues: [ +//// BarSetMapping {x: BarSetMapping.Undefined; y: 0}, +//// BarSetMapping {x: BarSetMapping.Undefined; y: 1}, +//// BarSetMapping {x: BarSetMapping.Undefined; y: 2} +//// ] +// orientation: BarSeriesMapping.Vertical // defaults to Vertical +// startIndex: 0 // defaults to 0 +// count: BarSeriesMapping.Undefined // defaults to "Undefined" +// } +// } + } + +// ChartModel { +// id: chartModel +// } + + BarModel { + id: barModel + BarSet { name: "Bob"; values: [2, 2, 3, 4, 5, 6] } + BarSet { name: "Bub"; values: [5, 1, 2, 4, 1, 7] } + BarSet { name: "Bib"; values: [3, 5, 8, 13, 5, 8] } } + + // TODO +// Component.onCompleted: { +// bobBars.append(1.2); +// bobBars.append(1.5); +// bobBars.append([1.5, 1.4, 1.9]); +// } } diff --git a/qmlplugin/declarativebarseries.cpp b/qmlplugin/declarativebarseries.cpp index 31ecdd5..cf7d6a4 100644 --- a/qmlplugin/declarativebarseries.cpp +++ b/qmlplugin/declarativebarseries.cpp @@ -20,60 +20,76 @@ #include "declarativebarseries.h" #include "declarativechart.h" -#include "qchart.h" -#include "qbarseries.h" -#include "qbarset.h" +#include QTCOMMERCIALCHART_BEGIN_NAMESPACE -DeclarativeBarSeries::DeclarativeBarSeries(QDeclarativeItem *parent) : - QDeclarativeItem(parent) +DeclarativeBarSet::DeclarativeBarSet(QObject *parent) : + QBarSet("", parent) { - setFlag(QGraphicsItem::ItemHasNoContents, false); } -void DeclarativeBarSeries::componentComplete() +QVariantList DeclarativeBarSet::values() { + QVariantList values; + for (int i(0); i < count(); i++) + values.append(QVariant(at(i))); + return values; } -void DeclarativeBarSeries::setBarCategories(QStringList categories) +void DeclarativeBarSet::setValues(QVariantList values) { - m_categories = categories; + while (count()) + remove(count() - 1); - if (m_series) { - delete m_series; - m_series = 0; + for (int i(0); i < values.count(); i++) { + if (values.at(i).canConvert(QVariant::Double)) + append(values[i].toDouble()); } +} - DeclarativeChart *declarativeChart = qobject_cast(parent()); - if (declarativeChart) { - QChart *chart = qobject_cast(declarativeChart->m_chart); - Q_ASSERT(chart); +DeclarativeBarSeries::DeclarativeBarSeries(QDeclarativeItem *parent) : + QBarSeries(parent) +{ +} -// m_series = new QBarSeries(m_categories); - m_series = new QBarSeries(); - m_series->setCategories(m_categories); +void DeclarativeBarSeries::classBegin() +{ +} - // TODO: use data from model - QBarSet *set0 = new QBarSet("Bub"); - QBarSet *set1 = new QBarSet("Bob"); - QBarSet *set2 = new QBarSet("Guybrush"); +void DeclarativeBarSeries::componentComplete() +{ + if (model()) + setModelMapping(0, 1, 1, Qt::Vertical); +} - *set0 << 1 << 2 << 3 << 4 << 5 << 6; - *set1 << 5 << 1 << 2 << 4 << 1 << 7; - *set2 << 3 << 5 << 8 << 13 << 8 << 5; +bool DeclarativeBarSeries::setDeclarativeModel(DeclarativeBarModel *model) +{ + QAbstractItemModel *m = qobject_cast(model); + bool value(false); + if (m) { + value = setModel(m); + //setModelMapping(int categories, int bottomBoundary, int topBoundary, Qt::Orientation orientation = Qt::Vertical); + setModelMapping(0, 1, 1, Qt::Vertical); + } else { + qWarning("DeclarativeBarSeries: Illegal model"); + } + return value; +} - m_series->appendBarSet(set0); - m_series->appendBarSet(set1); - m_series->appendBarSet(set2); +DeclarativeBarModel *DeclarativeBarSeries::declarativeModel() +{ + return qobject_cast(model()); +} - chart->addSeries(m_series); - } +void DeclarativeBarSeries::setBarCategories(QStringList categories) +{ + setCategories(categories); } QStringList DeclarativeBarSeries::barCategories() { - return m_categories; + return categories(); } #include "moc_declarativebarseries.cpp" diff --git a/qmlplugin/declarativebarseries.h b/qmlplugin/declarativebarseries.h index 4163ea5..4e4120b 100644 --- a/qmlplugin/declarativebarseries.h +++ b/qmlplugin/declarativebarseries.h @@ -22,25 +22,45 @@ #define DECLARATIVEBARSERIES_H #include "qchartglobal.h" +#include "declarativemodel.h" #include +#include +#include QTCOMMERCIALCHART_BEGIN_NAMESPACE class QChart; class QBarSeries; -class DeclarativeBarSeries : public QDeclarativeItem +class DeclarativeBarSet : public QBarSet { Q_OBJECT + Q_PROPERTY(QVariantList values READ values WRITE setValues) + Q_PROPERTY(QString name READ name WRITE setName) + +public: + explicit DeclarativeBarSet(QObject *parent = 0); + QVariantList values(); + void setValues(QVariantList values); +}; + +class DeclarativeBarSeries : public QBarSeries, public QDeclarativeParserStatus +{ + Q_OBJECT + Q_INTERFACES(QDeclarativeParserStatus) + Q_PROPERTY(DeclarativeBarModel *model READ declarativeModel WRITE setDeclarativeModel) Q_PROPERTY(QStringList barCategories READ barCategories WRITE setBarCategories) public: explicit DeclarativeBarSeries(QDeclarativeItem *parent = 0); public: // from QDeclarativeParserStatus + void classBegin(); void componentComplete(); public: + bool setDeclarativeModel(DeclarativeBarModel *model); + DeclarativeBarModel *declarativeModel(); void setBarCategories(QStringList categories); QStringList barCategories(); @@ -49,9 +69,6 @@ Q_SIGNALS: public Q_SLOTS: public: - QChart *m_chart; - QBarSeries *m_series; - QStringList m_categories; }; QTCOMMERCIALCHART_END_NAMESPACE diff --git a/qmlplugin/declarativemodel.cpp b/qmlplugin/declarativemodel.cpp index ab1b285..5362543 100644 --- a/qmlplugin/declarativemodel.cpp +++ b/qmlplugin/declarativemodel.cpp @@ -24,10 +24,54 @@ QTCOMMERCIALCHART_BEGIN_NAMESPACE +////////////// Table model (base) /////////////////// + +DeclarativeTableModel::DeclarativeTableModel(QObject *parent) : + ChartTableModel(parent) +{ +} + +void DeclarativeTableModel::classBegin() +{ +} + +void DeclarativeTableModel::componentComplete() +{ + foreach (QObject *child, children()) + appendToModel(child); +} + +QDeclarativeListProperty DeclarativeTableModel::modelChildren() +{ + return QDeclarativeListProperty(this, 0, &DeclarativeTableModel::appendModelChild); +} + +void DeclarativeTableModel::appendModelChild(QDeclarativeListProperty *list, + QObject *child) +{ + // childs are added in componentComplete instead + Q_UNUSED(list) + Q_UNUSED(child) +} + +void DeclarativeTableModel::appendToModel(QObject *object) +{ + if (qobject_cast(this)) { + DeclarativeBarModel *model = qobject_cast(this); + model->append(qobject_cast(object)); + } else if (qobject_cast(this)) { + DeclarativePieModel *model = qobject_cast(this); + model->append(qobject_cast(object)); + } else if (qobject_cast(this)) { + DeclarativeXyModel *model = qobject_cast(this); + model->append(qobject_cast(object)); + } +} + ////////////// XY model /////////////////////// DeclarativeXyModel::DeclarativeXyModel(QObject *parent) : - ChartTableModel(parent) + DeclarativeTableModel(parent) { } @@ -67,25 +111,10 @@ void DeclarativeXyModel::append(QVariantList points) } } -QDeclarativeListProperty DeclarativeXyModel::points() -{ - return QDeclarativeListProperty(this, 0, &DeclarativeXyModel::appendPoint); -} - -void DeclarativeXyModel::appendPoint(QDeclarativeListProperty *list, - DeclarativeXyPoint *point) -{ - DeclarativeXyModel *model = qobject_cast(list->object); - if (model) - model->append(point); - else - qWarning() << "Illegal point item"; -} - ////////////// Pie model /////////////////////// DeclarativePieModel::DeclarativePieModel(QObject *parent) : - ChartTableModel(parent) + DeclarativeTableModel(parent) { } @@ -109,6 +138,10 @@ void DeclarativePieModel::append(QVariantList slices) if (ok) { QPieSlice *slice = new QPieSlice(value, label); append(slice); + // TODO: how to copy the properties to the newly added slice? + // (DeclarativePieModel::append only copies the label and value to the model) +// QPieSlice *addedSlice = append(slice); +// addedSlice->setExploded(slice->isExploded()); } else { qWarning() << "Illegal slice item"; } @@ -118,19 +151,25 @@ void DeclarativePieModel::append(QVariantList slices) } } -QDeclarativeListProperty DeclarativePieModel::slices() +////////////// Bar model /////////////////////// + +DeclarativeBarModel::DeclarativeBarModel(QObject *parent) : + DeclarativeTableModel(parent) { - return QDeclarativeListProperty(this, 0, &DeclarativePieModel::appendSlice); } -void DeclarativePieModel::appendSlice(QDeclarativeListProperty *list, - QPieSlice *slice) +void DeclarativeBarModel::append(QBarSet* barSet) { - DeclarativePieModel *pieModel = qobject_cast(list->object); - if (pieModel) - pieModel->append(slice); - else - qWarning() << "Illegal slice item"; + insertColumn(columnCount()); + for (int i(0); i < barSet->count(); i++) { + if (rowCount() < (i + 1)) + insertRow(rowCount()); + setData(createIndex(i, columnCount() - 1), barSet->at(i)); +// insertRow(rowCount()); +// setData(createIndex(rowCount() - 1, 0), ); +// setData(createIndex(rowCount() - 1, 1), barSet->at(i)); + } +// TODO: setModelMapping(0, 1, columnCount(), Qt::Vertical); } #include "moc_declarativemodel.cpp" diff --git a/qmlplugin/declarativemodel.h b/qmlplugin/declarativemodel.h index cfb9599..806c52d 100644 --- a/qmlplugin/declarativemodel.h +++ b/qmlplugin/declarativemodel.h @@ -23,46 +23,70 @@ #include "qchartglobal.h" #include "declarativexypoint.h" -#include "qpieslice.h" +#include #include "../src/charttablemodel.h" // TODO +#include #include #include +#include QTCOMMERCIALCHART_BEGIN_NAMESPACE -class DeclarativeXyModel : public ChartTableModel +class DeclarativeTableModel : public ChartTableModel, public QDeclarativeParserStatus +{ + Q_OBJECT + Q_INTERFACES(QDeclarativeParserStatus) + Q_PROPERTY(QDeclarativeListProperty modelChildren READ modelChildren) + Q_CLASSINFO("DefaultProperty", "modelChildren") + +public: + explicit DeclarativeTableModel(QObject *parent = 0); + QDeclarativeListProperty modelChildren(); + +public: // from QDeclarativeParserStatus + void classBegin(); + void componentComplete(); + +public Q_SLOTS: + static void appendModelChild(QDeclarativeListProperty *list, + QObject *element); +private: + void appendToModel(QObject *object); +}; + +class DeclarativeXyModel : public DeclarativeTableModel { Q_OBJECT - Q_PROPERTY(QDeclarativeListProperty points READ points) - Q_CLASSINFO("DefaultProperty", "points") public: explicit DeclarativeXyModel(QObject *parent = 0); - QDeclarativeListProperty points(); public Q_SLOTS: void append(DeclarativeXyPoint* point); void append(QVariantList points); - static void appendPoint(QDeclarativeListProperty *list, - DeclarativeXyPoint *element); }; - -class DeclarativePieModel : public ChartTableModel +class DeclarativePieModel : public DeclarativeTableModel { Q_OBJECT - Q_PROPERTY(QDeclarativeListProperty slices READ slices) - Q_CLASSINFO("DefaultProperty", "slices") public: explicit DeclarativePieModel(QObject *parent = 0); - QDeclarativeListProperty slices(); public Q_SLOTS: void append(QPieSlice* slice); void append(QVariantList slices); - static void appendSlice(QDeclarativeListProperty *list, - QPieSlice *element); +}; + +class DeclarativeBarModel : public DeclarativeTableModel +{ + Q_OBJECT + +public: + explicit DeclarativeBarModel(QObject *parent = 0); + +public Q_SLOTS: + void append(QBarSet* barSet); }; QTCOMMERCIALCHART_END_NAMESPACE diff --git a/qmlplugin/declarativepieseries.cpp b/qmlplugin/declarativepieseries.cpp index 5e1b207..c5c3b91 100644 --- a/qmlplugin/declarativepieseries.cpp +++ b/qmlplugin/declarativepieseries.cpp @@ -30,6 +30,15 @@ DeclarativePieSeries::DeclarativePieSeries(QObject *parent) : { } +QPieSlice *DeclarativePieSeries::slice(int index) +{ + QList sliceList = slices(); + if (index < sliceList.count()) + return sliceList[index]; + + return 0; +} + bool DeclarativePieSeries::setPieModel(DeclarativePieModel *model) { QAbstractItemModel *m = qobject_cast(model); diff --git a/qmlplugin/declarativepieseries.h b/qmlplugin/declarativepieseries.h index ad95fba..d507903 100644 --- a/qmlplugin/declarativepieseries.h +++ b/qmlplugin/declarativepieseries.h @@ -41,6 +41,9 @@ class DeclarativePieSeries : public QPieSeries public: explicit DeclarativePieSeries(QObject *parent = 0); +public: + Q_INVOKABLE QPieSlice *slice(int index); + public Q_SLOTS: public: diff --git a/qmlplugin/declarativexyseries.cpp b/qmlplugin/declarativexyseries.cpp index 3278930..290d2ca 100644 --- a/qmlplugin/declarativexyseries.cpp +++ b/qmlplugin/declarativexyseries.cpp @@ -40,7 +40,7 @@ bool DeclarativeXySeries::setDeclarativeModel(DeclarativeXyModel *model) if (m) { // All the inherited objects must be of type QXYSeries, so it is safe to cast QXYSeries *series = reinterpret_cast(this); - series->setModel(m); + value = series->setModel(m); series->setModelMapping(0, 1, Qt::Vertical); } else { qWarning("DeclarativeXySeries: Illegal model"); diff --git a/qmlplugin/plugin.cpp b/qmlplugin/plugin.cpp index a0cdbe4..927ec5f 100644 --- a/qmlplugin/plugin.cpp +++ b/qmlplugin/plugin.cpp @@ -30,7 +30,6 @@ #include "declarativescatterseries.h" #include "declarativebarseries.h" #include "declarativepieseries.h" -//#include "declarativepiemodel.h" QTCOMMERCIALCHART_BEGIN_NAMESPACE @@ -54,9 +53,10 @@ public: qmlRegisterType(uri, 1, 0, "BarSeries"); qmlRegisterType(uri, 1, 0, "PieSeries"); qmlRegisterType(uri, 1, 0, "PieSlice"); - // TODO: a declarative model for each type qmlRegisterType(uri, 1, 0, "PieModel"); qmlRegisterType(uri, 1, 0, "XYModel"); + qmlRegisterType(uri, 1, 0, "BarModel"); + qmlRegisterType(uri, 1, 0, "BarSet"); } }; diff --git a/src/barchart/qbarset.cpp b/src/barchart/qbarset.cpp index c620605..abf9b2b 100644 --- a/src/barchart/qbarset.cpp +++ b/src/barchart/qbarset.cpp @@ -137,6 +137,9 @@ void QBarSet::replace(const int index, const qreal value) */ qreal QBarSet::at(const int index) const { + if (index < 0 || index >= d_ptr->m_values.count()) + return 0.0; + return d_ptr->m_values.at(index); } diff --git a/src/barchart/qbarset.h b/src/barchart/qbarset.h index 210e071..3f08fae 100644 --- a/src/barchart/qbarset.h +++ b/src/barchart/qbarset.h @@ -32,6 +32,7 @@ class QBarSetPrivate; class QTCOMMERCIALCHART_EXPORT QBarSet : public QObject { Q_OBJECT + Q_PROPERTY(QString name READ name WRITE setName) public: explicit QBarSet(const QString name, QObject *parent = 0); diff --git a/src/charttablemodel.cpp b/src/charttablemodel.cpp index e99d18b..c6f0be8 100644 --- a/src/charttablemodel.cpp +++ b/src/charttablemodel.cpp @@ -64,15 +64,14 @@ QVariant ChartTableModel::headerData (int section, Qt::Orientation orientation, if (role != Qt::DisplayRole) return QVariant(); - if (orientation == Qt::Horizontal) - { - if (section%2 == 0) + if (orientation == Qt::Horizontal) { + if (section % 2 == 0) return "x"; else return "y"; - } - else + } else { return QString("%1").arg(section + 1); + } } QVariant ChartTableModel::data(const QModelIndex &index, int role) const diff --git a/src/piechart/qpieslice.h b/src/piechart/qpieslice.h index b159dc8..9f382c0 100644 --- a/src/piechart/qpieslice.h +++ b/src/piechart/qpieslice.h @@ -33,8 +33,9 @@ class PieSliceData; class QTCOMMERCIALCHART_EXPORT QPieSlice : public QObject { Q_OBJECT - Q_PROPERTY(QString label READ label WRITE setLabel NOTIFY changed) - Q_PROPERTY(qreal value READ value WRITE setValue NOTIFY changed) + Q_PROPERTY(QString label READ label WRITE setLabel) + Q_PROPERTY(qreal value READ value WRITE setValue) + Q_PROPERTY(bool exploded READ isExploded WRITE setExploded) public: explicit QPieSlice(QObject *parent = 0);