diff options
Diffstat (limited to 'examples/datavisualization/customproxy')
14 files changed, 1080 insertions, 0 deletions
diff --git a/examples/datavisualization/customproxy/customproxy.pro b/examples/datavisualization/customproxy/customproxy.pro new file mode 100644 index 00000000..7a347d78 --- /dev/null +++ b/examples/datavisualization/customproxy/customproxy.pro @@ -0,0 +1,20 @@ +!include( ../examples.pri ) { + error( "Couldn't find the examples.pri file!" ) +} + +SOURCES += main.cpp \ + rainfallgraph.cpp \ + variantdataset.cpp \ + variantbardataproxy.cpp \ + variantbardatamapping.cpp \ + +HEADERS += \ + rainfallgraph.h \ + variantdataset.h \ + variantbardataproxy.h \ + variantbardatamapping.h + +RESOURCES += customproxy.qrc + +OTHER_FILES += data/raindata.txt + diff --git a/examples/datavisualization/customproxy/customproxy.qrc b/examples/datavisualization/customproxy/customproxy.qrc new file mode 100644 index 00000000..53cd4915 --- /dev/null +++ b/examples/datavisualization/customproxy/customproxy.qrc @@ -0,0 +1,5 @@ +<RCC> + <qresource prefix="/"> + <file>data/raindata.txt</file> + </qresource> +</RCC> diff --git a/examples/datavisualization/customproxy/data/raindata.txt b/examples/datavisualization/customproxy/data/raindata.txt new file mode 100644 index 00000000..531d66be --- /dev/null +++ b/examples/datavisualization/customproxy/data/raindata.txt @@ -0,0 +1,158 @@ +# Rainfall per month from 2000 to 2012 in Northern Finland (Sodankylä, Utsjoki, Kuusamo) +# Format: year, month, rainfall +2000,1, 72, +2000,2, 47, +2000,3, 37, +2000,4, 79, +2000,5, 42, +2000,6, 73, +2000,7, 94, +2000,8, 37, +2000,9, 17, +2000,10,69, +2000,11,42, +2000,12,42, +2001,1, 25, +2001,2, 47, +2001,3, 20, +2001,4, 70, +2001,5, 27, +2001,6, 40, +2001,7, 123, +2001,8, 39, +2001,9, 66, +2001,10,55, +2001,11,29, +2001,12,12, +2002,1, 24, +2002,2, 45, +2002,3, 27, +2002,4, 30, +2002,5, 16, +2002,6, 98, +2002,7, 122, +2002,8, 20, +2002,9, 50, +2002,10,24, +2002,11,22, +2002,12,12, +2003,1, 43, +2003,2, 17, +2003,3, 26, +2003,4, 22, +2003,5, 60, +2003,6, 14, +2003,7, 86, +2003,8, 77, +2003,9, 69, +2003,10,49, +2003,11,23, +2003,12,44, +2004,1, 15, +2004,2, 19, +2004,3, 10, +2004,4, 11, +2004,5, 41, +2004,6, 29, +2004,7, 49, +2004,8, 72, +2004,9, 50, +2004,10,18, +2004,11,19, +2004,12,40, +2005,1, 60, +2005,2, 24, +2005,3, 12, +2005,4, 50, +2005,5, 88, +2005,6, 32, +2005,7, 76, +2005,8, 55, +2005,9, 92, +2005,10,35, +2005,11,105, +2005,12,59, +2006,1, 27, +2006,2, 18, +2006,3, 17, +2006,4, 26, +2006,5, 24, +2006,6, 18, +2006,7, 35, +2006,8, 28, +2006,9, 80, +2006,10,52, +2006,11,43, +2006,12,44, +2007,1, 41, +2007,2, 21, +2007,3, 30, +2007,4, 20, +2007,5, 53, +2007,6, 29, +2007,7, 139, +2007,8, 52, +2007,9, 51, +2007,10,24, +2007,11,47, +2007,12,33, +2008,1, 67, +2008,2, 19, +2008,3, 30, +2008,4, 31, +2008,5, 29, +2008,6, 79, +2008,7, 75, +2008,8, 99, +2008,9, 34, +2008,10,52, +2008,11,60, +2008,12,20, +2009,1, 9, +2009,2, 22, +2009,3, 11, +2009,4, 10, +2009,5, 69, +2009,6, 30, +2009,7, 78, +2009,8, 93, +2009,9, 70, +2009,10,32, +2009,11,56, +2009,12,23, +2010,1, 12, +2010,2, 28, +2010,3, 55, +2010,4, 20, +2010,5, 65, +2010,6, 26, +2010,7, 134, +2010,8, 57, +2010,9, 51, +2010,10,53, +2010,11,8, +2010,12,9, +2011,1, 34, +2011,2, 20, +2011,3, 30, +2011,4, 31, +2011,5, 42, +2011,6, 78, +2011,7, 85, +2011,8, 33, +2011,9, 42, +2011,10,87, +2011,11,41, +2011,12,72, +2012,1, 32, +2012,2, 42, +2012,3, 30, +2012,4, 50, +2012,5, 30, +2012,6, 70, +2012,7, 52, +2012,8, 20, +2012,9, 99, +2012,10,70, +2012,11,69, +2012,12,49 diff --git a/examples/datavisualization/customproxy/doc/images/customproxy-example.png b/examples/datavisualization/customproxy/doc/images/customproxy-example.png Binary files differnew file mode 100644 index 00000000..753b8951 --- /dev/null +++ b/examples/datavisualization/customproxy/doc/images/customproxy-example.png diff --git a/examples/datavisualization/customproxy/doc/src/customproxy.qdoc b/examples/datavisualization/customproxy/doc/src/customproxy.qdoc new file mode 100644 index 00000000..e666c709 --- /dev/null +++ b/examples/datavisualization/customproxy/doc/src/customproxy.qdoc @@ -0,0 +1,113 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the QtDataVisualization module. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.digia.com +** +****************************************************************************/ + +/*! + \example customproxy + \title Custom Proxy Example + \ingroup qtdatavisualization_examples + \brief Using Q3DBars with a custom proxy. + + The custom proxy example shows how to create a custom proxy to use with Q3DBars. + + \image customproxy-example.png + + The interesting thing about custom proxy example is the custom dataset and the corresponding + proxy usage, so we concentrate on that and skip explaining the basic Q3DBars functionality + - for that see \l{Bars Example}. + + This example defines a simple flexible data set \c VariantDataSet where each data item is a + a variant list. Each item can have multiple different values, identified by their index in + the list. In this example, the data set is storing monthly rainfall data, where the value in + index zero is the year, the value in index one is the month, and the value in index two is + the amount of rainfall in that month. + + The custom proxy we provide here is similar to item model based proxies provided by Qt + Data Visualization in that it requires a mapping to interpret the data. + + Let's take a closer look at the custom classes: + + \section1 VariantDataSet + + \c VariantDataSet class provides a simple API: + + \snippet ../examples/customproxy/variantdataset.h 1 + \dots 0 + \codeline + \snippet ../examples/customproxy/variantdataset.h 0 + + As you can see, the data items are simply QVariantList objects, and the data can be added either + singly or in lists. The only additional functionality provided is clearing the data set and querying + for a reference to the data contained in the set. Signals are emitted when data is added or the set + is cleared. + + \section1 VariantBarDataProxy + + \c VariantBarDataProxy is a subclass of QBarDataProxy and provides a simple API of just getters + and setters for the data set and the mapping: + + \snippet ../examples/customproxy/variantbardataproxy.h 0 + \dots 0 + \codeline + \snippet ../examples/customproxy/variantbardataproxy.h 1 + + On the implementation side, the proxy listens for the changes in the data set and the mapping, + and resolves the data set if any changes are detected. It is not particularly efficient + implementation in that any change will cause re-resolving of the entire data set, but that is not + an issue for this example. The interesting part is the \c resolveDataSet() method: + + \snippet ../examples/customproxy/variantbardataproxy.cpp 0 + + In \c resolveDataSet() method we sort the variant data values into rows and columns based on the + mapping. This is very similar to how QItemModelBarDataProxy handles mapping, except we use + list indexes instead of item model roles here. Once the values are sorted, we generate \c QBarDataArray + out of them, and call \c resetArray() method on the parent class. + + \section1 VariantBarDataMapping + + \c VariantBarDataMapping stores the mapping information between \c VariantDataSet data item indexes + and rows, columns, and values of \c QBarDataArray. It also contains the lists of rows and columns to + be included in the resolved data: + + \snippet ../examples/customproxy/variantbardatamapping.h 0 + \dots 0 + \codeline + \snippet ../examples/customproxy/variantbardatamapping.h 1 + \dots 0 + \codeline + \snippet ../examples/customproxy/variantbardatamapping.h 2 + \dots 0 + \codeline + \snippet ../examples/customproxy/variantbardatamapping.h 3 + + The primary way to use a \c VariantBarDataMapping object is to give the mappings already at the + constructor, though they can be set later individually or all together with the \c remap() method. + A signal is emitted if mapping changes. It is basically a simplified version of the mapping + functionality of QItemModelBarDataProxy adapted to work with variant lists instead of item models. + + \section1 RainfallGraph + + \c RainfallGraph class handles the setup of the graph. The interesting part is the \c addDataSet() + method: + + \snippet ../examples/customproxy/rainfallgraph.cpp 0 + + The bulk of that method is used for populating the variant data set. Once the set is populated, + visualizing the data is trivial with the help of our custom proxy: + + \snippet ../examples/customproxy/rainfallgraph.cpp 1 +*/ diff --git a/examples/datavisualization/customproxy/main.cpp b/examples/datavisualization/customproxy/main.cpp new file mode 100644 index 00000000..dd74721e --- /dev/null +++ b/examples/datavisualization/customproxy/main.cpp @@ -0,0 +1,38 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the QtDataVisualization module. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.digia.com +** +****************************************************************************/ + +#include "rainfallgraph.h" +#include <QGuiApplication> + +using namespace QtDataVisualization; + +int main(int argc, char **argv) +{ + QGuiApplication app(argc, argv); + + Q3DBars *rainfall = new Q3DBars; + rainfall->setFlags(rainfall->flags() ^ Qt::FramelessWindowHint); + rainfall->resize(1280, 800); + rainfall->setPosition(QPoint(10, 30)); + rainfall->show(); + + RainfallGraph rainfallgraph(rainfall); + rainfallgraph.start(); + + return app.exec(); +} diff --git a/examples/datavisualization/customproxy/rainfallgraph.cpp b/examples/datavisualization/customproxy/rainfallgraph.cpp new file mode 100644 index 00000000..e2f04923 --- /dev/null +++ b/examples/datavisualization/customproxy/rainfallgraph.cpp @@ -0,0 +1,155 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the QtDataVisualization module. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.digia.com +** +****************************************************************************/ + +#include "rainfallgraph.h" +#include <QtDataVisualization/qcategory3daxis.h> +#include <QtDataVisualization/qvalue3daxis.h> +#include <QtDataVisualization/q3dscene.h> +#include <QtDataVisualization/q3dcamera.h> +#include <QtDataVisualization/qbar3dseries.h> +#include <QtDataVisualization/q3dtheme.h> +#include <QGuiApplication> +#include <QFont> +#include <QDebug> +#include <QTextStream> +#include <QFile> + +using namespace QtDataVisualization; + +RainfallGraph::RainfallGraph(Q3DBars *rainfall) + : m_graph(rainfall) +{ + // In data file the months are in numeric format, so create custom list + for (int i = 1; i <= 12; i++) + m_numericMonths << QString::number(i); + + m_columnCount = m_numericMonths.size(); + + m_proxy = new VariantBarDataProxy; + QBar3DSeries *series = new QBar3DSeries(m_proxy); + m_graph->addSeries(series); + + updateYearsList(2000, 2012); + + // Set up bar specifications; make the bars as wide as they are deep, + // and add a small space between the bars + m_graph->setBarThickness(1.0f); + m_graph->setBarSpacing(QSizeF(0.2, 0.2)); + + // Set axis labels and titles + QStringList months; + months << "January" << "February" << "March" << "April" << "May" << "June" << "July" << "August" << "September" << "October" << "November" << "December"; + m_graph->rowAxis()->setTitle("Year"); + m_graph->columnAxis()->setTitle("Month"); + m_graph->valueAxis()->setTitle("rainfall"); + m_graph->valueAxis()->setLabelFormat("%d mm"); + m_graph->valueAxis()->setSegmentCount(5); + m_graph->rowAxis()->setLabels(m_years); + m_graph->columnAxis()->setLabels(months); + + // Set bar type to cylinder + series->setMesh(QAbstract3DSeries::MeshCylinder); + + // Set shadows to medium + m_graph->setShadowQuality(QAbstract3DGraph::ShadowQualityMedium); + + // Set selection mode to bar and column + m_graph->setSelectionMode(QAbstract3DGraph::SelectionItemAndColumn | QAbstract3DGraph::SelectionSlice); + + // Set theme + m_graph->activeTheme()->setType(Q3DTheme::ThemeArmyBlue); + + // Override font in theme + m_graph->activeTheme()->setFont(QFont("Century Gothic", 30)); + + // Override label background for theme + m_graph->activeTheme()->setLabelBackgroundEnabled(false); + + // Set camera position and zoom + m_graph->scene()->activeCamera()->setCameraPreset(Q3DCamera::CameraPresetIsometricRightHigh); + + // Set window title + m_graph->setTitle(QStringLiteral("Monthly rainfall in Northern Finland")); +} + +RainfallGraph::~RainfallGraph() +{ + delete m_mapping; + delete m_dataSet; + delete m_graph; +} + +void RainfallGraph::start() +{ + addDataSet(); +} + +void RainfallGraph::updateYearsList(int start, int end) +{ + m_years.clear(); + for (int i = start; i <= end; i++) + m_years << QString::number(i); + + m_rowCount = m_years.size(); +} + +//! [0] +void RainfallGraph::addDataSet() +{ + // Create a new variant data set and data item list + m_dataSet = new VariantDataSet; + VariantDataItemList *itemList = new VariantDataItemList; + + // Read data from a data file into the data item list + QTextStream stream; + QFile dataFile(":/data/raindata.txt"); + if (dataFile.open(QIODevice::ReadOnly | QIODevice::Text)) { + stream.setDevice(&dataFile); + while (!stream.atEnd()) { + QString line = stream.readLine(); + if (line.startsWith("#")) // Ignore comments + continue; + QStringList strList = line.split(",", QString::SkipEmptyParts); + // Each line has three data items: Year, month, and rainfall value + if (strList.size() < 3) { + qWarning() << "Invalid row read from data:" << line; + continue; + } + // Store year and month as strings, and rainfall value as double + // into a variant data item and add the item to the item list. + VariantDataItem *newItem = new VariantDataItem; + for (int i = 0; i < 2; i++) + newItem->append(strList.at(i).trimmed()); + newItem->append(strList.at(2).trimmed().toDouble()); + itemList->append(newItem); + } + } else { + qWarning() << "Unable to open data file:" << dataFile.fileName(); + } + + //! [1] + // Add items to the data set and set it to the proxy + m_dataSet->addItems(itemList); + m_proxy->setDataSet(m_dataSet); + + // Create new mapping for the data and set it to the proxy + m_mapping = new VariantBarDataMapping(0, 1, 2, m_years, m_numericMonths); + m_proxy->setMapping(m_mapping); + //! [1] +} +//! [0] diff --git a/examples/datavisualization/customproxy/rainfallgraph.h b/examples/datavisualization/customproxy/rainfallgraph.h new file mode 100644 index 00000000..6116eb9b --- /dev/null +++ b/examples/datavisualization/customproxy/rainfallgraph.h @@ -0,0 +1,51 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the QtDataVisualization module. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.digia.com +** +****************************************************************************/ + +#ifndef RAINFALLGRAPH_H +#define RAINFALLGRAPH_H + +#include "variantbardataproxy.h" +#include <QtDataVisualization/q3dbars.h> + +using namespace QtDataVisualization; + +class RainfallGraph : public QObject +{ + Q_OBJECT +public: + explicit RainfallGraph(Q3DBars *rainfall); + ~RainfallGraph(); + + void addDataSet(); + void start(); + +private: + + void updateYearsList(int start, int end); + Q3DBars *m_graph; + int m_columnCount; + int m_rowCount; + QStringList m_years; + QStringList m_numericMonths; + VariantBarDataProxy *m_proxy; + VariantBarDataMapping *m_mapping; + VariantDataSet *m_dataSet; +}; + + +#endif diff --git a/examples/datavisualization/customproxy/variantbardatamapping.cpp b/examples/datavisualization/customproxy/variantbardatamapping.cpp new file mode 100644 index 00000000..c8369b6e --- /dev/null +++ b/examples/datavisualization/customproxy/variantbardatamapping.cpp @@ -0,0 +1,133 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the QtDataVisualization module. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.digia.com +** +****************************************************************************/ + +#include "variantbardatamapping.h" + +VariantBarDataMapping::VariantBarDataMapping() + : QObject(0), + m_rowIndex(0), + m_columnIndex(1), + m_valueIndex(2) +{ +} + +VariantBarDataMapping::VariantBarDataMapping(const VariantBarDataMapping &other) + : QObject(0), + m_rowIndex(0), + m_columnIndex(1), + m_valueIndex(2) +{ + operator=(other); +} + +VariantBarDataMapping::VariantBarDataMapping(int rowIndex, int columnIndex, int valueIndex, + const QStringList &rowCategories, + const QStringList &columnCategories) + : QObject(0), + m_rowIndex(0), + m_columnIndex(1), + m_valueIndex(2) +{ + m_rowIndex = rowIndex; + m_columnIndex = columnIndex; + m_valueIndex = valueIndex; + m_rowCategories = rowCategories; + m_columnCategories = columnCategories; +} + +VariantBarDataMapping::~VariantBarDataMapping() +{ +} + +VariantBarDataMapping &VariantBarDataMapping::operator=(const VariantBarDataMapping &other) +{ + m_rowIndex = other.m_rowIndex; + m_columnIndex = other.m_columnIndex; + m_valueIndex = other.m_valueIndex; + m_rowCategories = other.m_rowCategories; + m_columnCategories = other.m_columnCategories; + + return *this; +} + +void VariantBarDataMapping::setRowIndex(int index) +{ + m_rowIndex = index; + emit mappingChanged(); +} + +int VariantBarDataMapping::rowIndex() const +{ + return m_rowIndex; +} + +void VariantBarDataMapping::setColumnIndex(int index) +{ + m_columnIndex = index; + emit mappingChanged(); +} + +int VariantBarDataMapping::columnIndex() const +{ + return m_columnIndex; +} + +void VariantBarDataMapping::setValueIndex(int index) +{ + m_valueIndex = index; + emit mappingChanged(); +} + +int VariantBarDataMapping::valueIndex() const +{ + return m_valueIndex; +} + +void VariantBarDataMapping::setRowCategories(const QStringList &categories) +{ + m_rowCategories = categories; + emit mappingChanged(); +} + +const QStringList &VariantBarDataMapping::rowCategories() const +{ + return m_rowCategories; +} + +void VariantBarDataMapping::setColumnCategories(const QStringList &categories) +{ + m_columnCategories = categories; + emit mappingChanged(); +} + +const QStringList &VariantBarDataMapping::columnCategories() const +{ + return m_columnCategories; +} + +void VariantBarDataMapping::remap(int rowIndex, int columnIndex, int valueIndex, + const QStringList &rowCategories, + const QStringList &columnCategories) +{ + m_rowIndex = rowIndex; + m_columnIndex = columnIndex; + m_valueIndex = valueIndex; + m_rowCategories = rowCategories; + m_columnCategories = columnCategories; + emit mappingChanged(); +} diff --git a/examples/datavisualization/customproxy/variantbardatamapping.h b/examples/datavisualization/customproxy/variantbardatamapping.h new file mode 100644 index 00000000..3a145d9a --- /dev/null +++ b/examples/datavisualization/customproxy/variantbardatamapping.h @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the QtDataVisualization module. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.digia.com +** +****************************************************************************/ + +#ifndef VARIANTBARDATAMAPPING_H +#define VARIANTBARDATAMAPPING_H + +#include <QStringList> + +class VariantBarDataMapping : public QObject +{ + Q_OBJECT + //! [0] + Q_PROPERTY(int rowIndex READ rowIndex WRITE setRowIndex) + Q_PROPERTY(int columnIndex READ columnIndex WRITE setColumnIndex) + Q_PROPERTY(int valueIndex READ valueIndex WRITE setValueIndex) + Q_PROPERTY(QStringList rowCategories READ rowCategories WRITE setRowCategories) + Q_PROPERTY(QStringList columnCategories READ columnCategories WRITE setColumnCategories) + //! [0] +public: + explicit VariantBarDataMapping(); + VariantBarDataMapping(const VariantBarDataMapping &other); + //! [1] + VariantBarDataMapping(int rowIndex, int columnIndex, int valueIndex, + const QStringList &rowCategories, + const QStringList &columnCategories); + //! [1] + virtual ~VariantBarDataMapping(); + + VariantBarDataMapping &operator=(const VariantBarDataMapping &other); + + void setRowIndex(int index); + int rowIndex() const; + void setColumnIndex(int index); + int columnIndex() const; + void setValueIndex(int index); + int valueIndex() const; + + void setRowCategories(const QStringList &categories); + const QStringList &rowCategories() const; + void setColumnCategories(const QStringList &categories); + const QStringList &columnCategories() const; + + //! [2] + void remap(int rowIndex, int columnIndex, int valueIndex, + const QStringList &rowCategories, + const QStringList &columnCategories); + //! [2] +signals: + //! [3] + void mappingChanged(); + //! [3] + +private: + // Indexes of the mapped items in the VariantDataItem + int m_rowIndex; + int m_columnIndex; + int m_valueIndex; + + // For row/column items, sort items into these categories. Other categories are ignored. + QStringList m_rowCategories; + QStringList m_columnCategories; +}; + +#endif diff --git a/examples/datavisualization/customproxy/variantbardataproxy.cpp b/examples/datavisualization/customproxy/variantbardataproxy.cpp new file mode 100644 index 00000000..cf1e1f90 --- /dev/null +++ b/examples/datavisualization/customproxy/variantbardataproxy.cpp @@ -0,0 +1,140 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the QtDataVisualization module. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.digia.com +** +****************************************************************************/ + +#include "variantbardataproxy.h" + +using namespace QtDataVisualization; + +VariantBarDataProxy::VariantBarDataProxy() : + QBarDataProxy() +{ +} + +VariantBarDataProxy::VariantBarDataProxy(VariantDataSet *newSet, + VariantBarDataMapping *mapping) : + QBarDataProxy() +{ + setDataSet(newSet); + setMapping(mapping); +} + +VariantBarDataProxy::~VariantBarDataProxy() +{ + delete m_dataSet; +} + +void VariantBarDataProxy::setDataSet(VariantDataSet *newSet) +{ + if (!m_dataSet.isNull()) + QObject::disconnect(m_dataSet.data(), 0, this, 0); + + m_dataSet = newSet; + + if (!m_dataSet.isNull()) { + QObject::connect(m_dataSet.data(), &VariantDataSet::itemsAdded, this, + &VariantBarDataProxy::handleItemsAdded); + QObject::connect(m_dataSet.data(), &VariantDataSet::dataCleared, this, + &VariantBarDataProxy::handleDataCleared); + } + resolveDataSet(); +} + +VariantDataSet *VariantBarDataProxy::dataSet() +{ + return m_dataSet.data(); +} + +void VariantBarDataProxy::setMapping(VariantBarDataMapping *mapping) +{ + if (!m_mapping.isNull()) + QObject::disconnect(m_mapping.data(), &VariantBarDataMapping::mappingChanged, this, + &VariantBarDataProxy::handleMappingChanged); + + m_mapping = mapping; + + if (!m_mapping.isNull()) + QObject::connect(m_mapping.data(), &VariantBarDataMapping::mappingChanged, this, + &VariantBarDataProxy::handleMappingChanged); + + resolveDataSet(); +} + +VariantBarDataMapping *VariantBarDataProxy::mapping() +{ + return m_mapping.data(); +} + +void VariantBarDataProxy::handleItemsAdded(int index, int count) +{ + Q_UNUSED(index) + Q_UNUSED(count) + + // Resolve new items + resolveDataSet(); +} + +void VariantBarDataProxy::handleDataCleared() +{ + // Data cleared, reset array + resetArray(0); +} + +void VariantBarDataProxy::handleMappingChanged() +{ + resolveDataSet(); +} + +// Resolve entire dataset into QBarDataArray. +//! [0] +void VariantBarDataProxy::resolveDataSet() +{ + // If we have no data or mapping, or the categories are not defined, simply clear the array + if (m_dataSet.isNull() || m_mapping.isNull() || !m_mapping->rowCategories().size() + || !m_mapping->columnCategories().size()) { + resetArray(0); + return; + } + const VariantDataItemList &itemList = m_dataSet->itemList(); + + int rowIndex = m_mapping->rowIndex(); + int columnIndex = m_mapping->columnIndex(); + int valueIndex = m_mapping->valueIndex(); + const QStringList &rowList = m_mapping->rowCategories(); + const QStringList &columnList = m_mapping->columnCategories(); + + // Sort values into rows and columns + typedef QHash<QString, float> ColumnValueMap; + QHash <QString, ColumnValueMap> itemValueMap; + foreach (const VariantDataItem *item, itemList) { + itemValueMap[item->at(rowIndex).toString()][item->at(columnIndex).toString()] + = item->at(valueIndex).toReal(); + } + + // Create a new data array in format the parent class understands + QBarDataArray *newProxyArray = new QBarDataArray; + foreach (QString rowKey, rowList) { + QBarDataRow *newProxyRow = new QBarDataRow(columnList.size()); + for (int i = 0; i < columnList.size(); i++) + (*newProxyRow)[i].setValue(itemValueMap[rowKey][columnList.at(i)]); + newProxyArray->append(newProxyRow); + } + + // Finally, reset the data array in the parent class + resetArray(newProxyArray); +} +//! [0] diff --git a/examples/datavisualization/customproxy/variantbardataproxy.h b/examples/datavisualization/customproxy/variantbardataproxy.h new file mode 100644 index 00000000..b83f8a71 --- /dev/null +++ b/examples/datavisualization/customproxy/variantbardataproxy.h @@ -0,0 +1,68 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the QtDataVisualization module. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.digia.com +** +****************************************************************************/ + +#ifndef VARIANTBARDATAPROXY_H +#define VARIANTBARDATAPROXY_H + +#include "qbardataproxy.h" +#include "variantdataset.h" +#include "variantbardatamapping.h" +#include <QStringList> +#include <QMap> +#include <QPointer> + +using namespace QtDataVisualization; + +//! [0] +class VariantBarDataProxy : public QBarDataProxy +//! [0] +{ + Q_OBJECT + +public: + explicit VariantBarDataProxy(); + explicit VariantBarDataProxy(VariantDataSet *newSet, VariantBarDataMapping *mapping); + virtual ~VariantBarDataProxy(); + + //! [1] + // Doesn't gain ownership of the dataset, but does connect to it to listen for data changes. + void setDataSet(VariantDataSet *newSet); + VariantDataSet *dataSet(); + + // Map key (row, column, value) to value index in data item (VariantItem). + // Doesn't gain ownership of mapping, but does connect to it to listen for mapping changes. + // Modifying mapping that is set to proxy will trigger dataset re-resolving. + void setMapping(VariantBarDataMapping *mapping); + VariantBarDataMapping *mapping(); + //! [1] + +public slots: + void handleItemsAdded(int index, int count); + void handleDataCleared(); + void handleMappingChanged(); + +private: + void resolveDataSet(); + + QPointer<VariantDataSet> m_dataSet; + QPointer<VariantBarDataMapping> m_mapping; + + Q_DISABLE_COPY(VariantBarDataProxy) +}; + +#endif diff --git a/examples/datavisualization/customproxy/variantdataset.cpp b/examples/datavisualization/customproxy/variantdataset.cpp new file mode 100644 index 00000000..3576aaab --- /dev/null +++ b/examples/datavisualization/customproxy/variantdataset.cpp @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the QtDataVisualization module. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.digia.com +** +****************************************************************************/ + +#include "variantdataset.h" + +VariantDataSet::VariantDataSet() + : QObject(0) +{ +} + +VariantDataSet::~VariantDataSet() +{ + clear(); +} + +void VariantDataSet::clear() +{ + foreach (VariantDataItem *item, m_variantData) { + item->clear(); + delete item; + } + m_variantData.clear(); + emit dataCleared(); +} + +int VariantDataSet::addItem(VariantDataItem *item) +{ + m_variantData.append(item); + int addIndex = m_variantData.size(); + + emit itemsAdded(addIndex, 1); + return addIndex; +} + +int VariantDataSet::addItems(VariantDataItemList *itemList) +{ + int newCount = itemList->size(); + int addIndex = m_variantData.size(); + m_variantData.append(*itemList); + delete itemList; + emit itemsAdded(addIndex, newCount); + return addIndex; +} + +const VariantDataItemList &VariantDataSet::itemList() const +{ + return m_variantData; +} diff --git a/examples/datavisualization/customproxy/variantdataset.h b/examples/datavisualization/customproxy/variantdataset.h new file mode 100644 index 00000000..f5eb5863 --- /dev/null +++ b/examples/datavisualization/customproxy/variantdataset.h @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the QtDataVisualization module. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.digia.com +** +****************************************************************************/ + +#ifndef VARIANTDATASET_H +#define VARIANTDATASET_H + +#include <QScopedPointer> +#include <QVariantList> + +//! [1] +typedef QVariantList VariantDataItem; +typedef QList<VariantDataItem *> VariantDataItemList; +//! [1] + +class VariantDataSet : public QObject +{ + Q_OBJECT + +public: + explicit VariantDataSet(); + ~VariantDataSet(); + + //! [0] + void clear(); + + int addItem(VariantDataItem *item); + int addItems(VariantDataItemList *itemList); + + const VariantDataItemList &itemList() const; + +signals: + void itemsAdded(int index, int count); + void dataCleared(); + //! [0] + +private: + VariantDataItemList m_variantData; + + Q_DISABLE_COPY(VariantDataSet) +}; + +#endif |