From 5f02a038891db0cfd6a9fa08d7576141485e5d71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomi=20Korpip=C3=A4=C3=A4?= Date: Wed, 9 Oct 2013 08:55:09 +0300 Subject: Renamed examples Task-number: QTRD-2418 Change-Id: Ic0cae9a8caebcbd0f1cf57eb98fb7d543d7d7289 Change-Id: Ic0cae9a8caebcbd0f1cf57eb98fb7d543d7d7289 Reviewed-by: Miikka Heikkinen --- examples/bars/bars.pro | 7 +- examples/bars/doc/images/bars-example-2.png | Bin 198263 -> 0 bytes examples/bars/doc/images/bars-example.png | Bin 135559 -> 322046 bytes examples/bars/doc/src/bars.qdoc | 171 ++++----- examples/bars/graphmodifier.cpp | 229 ++++++++++++ examples/bars/graphmodifier.h | 79 ++++ examples/bars/main.cpp | 406 +++++++++------------ examples/customproxy/customproxy.pro | 24 ++ examples/customproxy/customproxy.qrc | 5 + examples/customproxy/data/raindata.txt | 158 ++++++++ .../customproxy/doc/images/customproxy-example.png | Bin 0 -> 399112 bytes examples/customproxy/doc/src/customproxy.qdoc | 30 ++ examples/customproxy/main.cpp | 37 ++ examples/customproxy/rainfallgraph.cpp | 140 +++++++ examples/customproxy/rainfallgraph.h | 51 +++ examples/customproxy/variantbardatamapping.cpp | 133 +++++++ examples/customproxy/variantbardatamapping.h | 74 ++++ examples/customproxy/variantbardataproxy.cpp | 136 +++++++ examples/customproxy/variantbardataproxy.h | 64 ++++ examples/customproxy/variantdataset.cpp | 63 ++++ examples/customproxy/variantdataset.h | 56 +++ examples/examples.pro | 4 +- .../itemmodel/doc/images/itemmodel-example-2.png | Bin 0 -> 198263 bytes .../itemmodel/doc/images/itemmodel-example.png | Bin 0 -> 135559 bytes examples/itemmodel/doc/src/itemmodel.qdoc | 182 +++++++++ examples/itemmodel/itemmodel.pro | 12 + examples/itemmodel/main.cpp | 287 +++++++++++++++ examples/rainfall/data/raindata.txt | 158 -------- examples/rainfall/doc/images/rainfall-example.png | Bin 294202 -> 0 bytes examples/rainfall/doc/src/rainfall.qdoc | 30 -- examples/rainfall/main.cpp | 37 -- examples/rainfall/rainfall.pro | 25 -- examples/rainfall/rainfall.qrc | 5 - examples/rainfall/rainfallgraph.cpp | 140 ------- examples/rainfall/rainfallgraph.h | 51 --- examples/rainfall/variantbardatamapping.cpp | 133 ------- examples/rainfall/variantbardatamapping.h | 74 ---- examples/rainfall/variantbardataproxy.cpp | 136 ------- examples/rainfall/variantbardataproxy.h | 64 ---- examples/rainfall/variantdataset.cpp | 63 ---- examples/rainfall/variantdataset.h | 56 --- examples/widget/doc/images/widget-example.png | Bin 322046 -> 0 bytes examples/widget/doc/src/widget.qdoc | 159 -------- examples/widget/graphmodifier.cpp | 229 ------------ examples/widget/graphmodifier.h | 79 ---- examples/widget/main.cpp | 211 ----------- examples/widget/widget.pro | 14 - 47 files changed, 2005 insertions(+), 2007 deletions(-) delete mode 100644 examples/bars/doc/images/bars-example-2.png create mode 100644 examples/bars/graphmodifier.cpp create mode 100644 examples/bars/graphmodifier.h create mode 100644 examples/customproxy/customproxy.pro create mode 100644 examples/customproxy/customproxy.qrc create mode 100644 examples/customproxy/data/raindata.txt create mode 100644 examples/customproxy/doc/images/customproxy-example.png create mode 100644 examples/customproxy/doc/src/customproxy.qdoc create mode 100644 examples/customproxy/main.cpp create mode 100644 examples/customproxy/rainfallgraph.cpp create mode 100644 examples/customproxy/rainfallgraph.h create mode 100644 examples/customproxy/variantbardatamapping.cpp create mode 100644 examples/customproxy/variantbardatamapping.h create mode 100644 examples/customproxy/variantbardataproxy.cpp create mode 100644 examples/customproxy/variantbardataproxy.h create mode 100644 examples/customproxy/variantdataset.cpp create mode 100644 examples/customproxy/variantdataset.h create mode 100644 examples/itemmodel/doc/images/itemmodel-example-2.png create mode 100644 examples/itemmodel/doc/images/itemmodel-example.png create mode 100644 examples/itemmodel/doc/src/itemmodel.qdoc create mode 100644 examples/itemmodel/itemmodel.pro create mode 100644 examples/itemmodel/main.cpp delete mode 100644 examples/rainfall/data/raindata.txt delete mode 100644 examples/rainfall/doc/images/rainfall-example.png delete mode 100644 examples/rainfall/doc/src/rainfall.qdoc delete mode 100644 examples/rainfall/main.cpp delete mode 100644 examples/rainfall/rainfall.pro delete mode 100644 examples/rainfall/rainfall.qrc delete mode 100644 examples/rainfall/rainfallgraph.cpp delete mode 100644 examples/rainfall/rainfallgraph.h delete mode 100644 examples/rainfall/variantbardatamapping.cpp delete mode 100644 examples/rainfall/variantbardatamapping.h delete mode 100644 examples/rainfall/variantbardataproxy.cpp delete mode 100644 examples/rainfall/variantbardataproxy.h delete mode 100644 examples/rainfall/variantdataset.cpp delete mode 100644 examples/rainfall/variantdataset.h delete mode 100644 examples/widget/doc/images/widget-example.png delete mode 100644 examples/widget/doc/src/widget.qdoc delete mode 100644 examples/widget/graphmodifier.cpp delete mode 100644 examples/widget/graphmodifier.h delete mode 100644 examples/widget/main.cpp delete mode 100644 examples/widget/widget.pro (limited to 'examples') diff --git a/examples/bars/bars.pro b/examples/bars/bars.pro index f319f690..e4e2c5fa 100644 --- a/examples/bars/bars.pro +++ b/examples/bars/bars.pro @@ -2,11 +2,12 @@ error( "Couldn't find the examples.pri file!" ) } -SOURCES += main.cpp - -INSTALLS += target +SOURCES += main.cpp graphmodifier.cpp +HEADERS += graphmodifier.h QT += widgets +INSTALLS += target + OTHER_FILES += doc/src/* \ doc/images/* diff --git a/examples/bars/doc/images/bars-example-2.png b/examples/bars/doc/images/bars-example-2.png deleted file mode 100644 index 2083a8e0..00000000 Binary files a/examples/bars/doc/images/bars-example-2.png and /dev/null differ diff --git a/examples/bars/doc/images/bars-example.png b/examples/bars/doc/images/bars-example.png index a87f4bdf..c2d4d598 100644 Binary files a/examples/bars/doc/images/bars-example.png and b/examples/bars/doc/images/bars-example.png differ diff --git a/examples/bars/doc/src/bars.qdoc b/examples/bars/doc/src/bars.qdoc index a8de709b..379aa871 100644 --- a/examples/bars/doc/src/bars.qdoc +++ b/examples/bars/doc/src/bars.qdoc @@ -20,22 +20,25 @@ \example bars \title Bars Example \ingroup qtdatavisualization_examples - \brief Using an item model as data source for Q3DBars. + \brief Using Q3DBars in a widget application. - The bars example shows how to make a simple 3D bar graph using Q3DBars and how to modify the - data being drawn at run-time. The example shows how to: + The bars example shows how to make a 3D bar graph using Q3DBars and combining the use of + widgets for adjusting several adjustable qualities. The example shows how to: \list - \li How to create an application with Q3DBars and widgets - \li How to use QItemModelBarDataMapping and QItemModelBarDataProxy to set data to the graph - \li How to use a table widget to modify the data in the graph + \li Create an application with Q3DBars and some widgets + \li Use QBarDataProxy to set data to the graph + \li Adjust some graph properties using widget controls \endlist - \image bars-example-2.png + It also demonstrates how having negative bar values affects the graph. + + \image bars-example.png \section1 Creating the application - First, in main.cpp, we create a QApplication, instantiate Q3DBars and a window container for it: + First, in main.cpp, we create a QApplication, instantiate Q3DBars and a window container + for it: \snippet ../examples/bars/main.cpp 0 @@ -43,140 +46,114 @@ (Q3DBars, Q3DScatter, Q3DSurface) inherit QWindow. Any class inheriting QWindow cannot be used as a widget any other way. - Then we'll create a layout and add the graph and the table widget into it: + Then we'll create horizontal and vertical layouts. We'll add the graph and the vertical + layout into the horizontal one: \snippet ../examples/bars/main.cpp 1 - The table widget is going to be used to display the numerical data being inserted into the - graph, and to modify it (See \l {Adding data to the graph} and \l {Interacting with the data}). - - We need to instantiate QItemModelBarDataMapping and QItemModelBarDataProxy and give them to the - graph: - - \snippet ../examples/bars/main.cpp 2 - - Here we tell the mapping object to directly map model's rows and columns into proxy's rows and - columns instead of defining row and column roles to map for them. Then we give the model from - the table widget and the mapping object to the proxy. Finally we set the proxy as the active - data proxy for the graph. + We're not using the vertical layout for anything yet, but we'll get back to it in + \l {Using widgets to control the graph} Next, let's create another class to handle the data addition and other interaction with the - graph. Let's call it GraphDataGenerator (See \l {Setting up the graph} and - \l {Adding data to the graph} for details) and connect some signals between Q3DBars, - GraphDataGenerator and QTableWidget (See \l {Interacting with the data} for a closer look): + graph. Let's call it GraphModifier (See \l {Setting up the graph} and + \l {Adding data to the graph} for details): - \snippet ../examples/bars/main.cpp 3 + \snippet ../examples/bars/main.cpp 2 The application main is done and we can show the graph and start the event loop: - \snippet ../examples/bars/main.cpp 4 + \snippet ../examples/bars/main.cpp 3 \section1 Setting up the graph - Let's set up the visual attributes for the graph in the constructor of GraphDataGenerator: + Let's set up the graph in the constructor of the GraphModifier class we instantiated in the + application main: - \snippet ../examples/bars/main.cpp 5 - \snippet ../examples/bars/main.cpp 6 - \snippet ../examples/bars/main.cpp 7 - - First we set bar thickness ratio to 1.0, which means bars will be as wide as they are deep. 1.0 - is also the default value, so the line is basically unnecessary. It's left there so you could - easily try how changing it affects the graph. The second line sets bar spacings to 0.2, which - means there will be a gap of 20% of the bar's thickness between the bars in both directions. + \snippet ../examples/bars/graphmodifier.cpp 0 - Then, we set the bar type to flat pyramids, overriding the default bar type. - We want to be able to select rows of data for a closer inspection, so we set the selection mode - to slice row. This means that whenever we select a bar in the graph, the whole row will be - displayed separately. + Let's take a closer look at parts of the code. - Next line sets the font to \c Impact. If your system doesn't have it, it will be replaced by - system default. + First we're creating the axes and the proxy into member variables to support changing them + easily later on, if we want to: - And finally, we set theme to \c Digia and camera position to \c {Preset Front}. Now the initial - graph settings are done. + \snippet ../examples/bars/graphmodifier.cpp 1 - \note You do not need to set any of these in case you're happy with the defaults. You can - easily try them by commenting out the contents of the constructor. + Then we're setting some of the visual qualities for the graph: - \section1 Adding data to the graph + \snippet ../examples/bars/graphmodifier.cpp 2 - We created the data generator in the application main and gave it the graph and the table - widget as parameters: + We're also setting up the axes and adding them to the graph. Notice that we're not setting them + active yet: - \code GraphDataGenerator generator(graph, tableWidget); \endcode + \snippet ../examples/bars/graphmodifier.cpp 3 - We added a separate start method to the generator, so that it wouldn't start doing anything - until everything else is set up. We then called the method when starting the application: + And add the proxy. Note that we're not setting it active yet, but just adding it: - \code generator.start(); \endcode + \snippet ../examples/bars/graphmodifier.cpp 4 - Let's have a look at the contents of the \c start() method: + That concludes setting up the graph. - \snippet ../examples/bars/main.cpp 8 - - The main thing \c start() does is set up the data model. It also activates a timer for getting - the accurate dimensions of the table widget after it's been filled with data. The reason we - do this is that the widget doesn't know its final visual domensions until all the data has been - inserted to it and it has been shown. The whole data timer implementation is not vital for the - application, so we won't take a closer look at it. It's just there to make the table look better. - - In \c setupModel() we first introduce the row and column labels, and the actual data: + \section1 Adding data to the graph - \snippet ../examples/bars/main.cpp 9 + At the end of the constructor there's a call: - Then we set up the axes: + \code resetTemperatureData(); \endcode - \snippet ../examples/bars/main.cpp 10 + The method is used to add data to the proxy: - The other lines there are pretty self-explanatory except for the one with the segment count. - We're setting it to five as we want the value axis (the Y-axis) to show more values than just - the lowest and the highest. + \snippet ../examples/bars/graphmodifier.cpp 5 - Next we will set up the table widget: + Now the data is in the proxy, but not in the graph. We have not set the proxy active yet. - \snippet ../examples/bars/main.cpp 11 + In application main, we called \c {modifier->start()} after constructing all the necessary + objects. This is what is done in it: - After that all that's left is adding the data to the table widget: + \snippet ../examples/bars/graphmodifier.cpp 6 - \snippet ../examples/bars/main.cpp 12 + Finally we set the proxy and the axes active. Now our graph has the data and is ready to be + used. - Now we have a bar graph and a table widget, both displaying the same data. + \section1 Using widgets to control the graph - You're probably wondering how the data can be displayed in the graph, as the only thing we did - was add it to the table widget? That's because of what we did earlier, in the application main: + There isn't much interaction yet, so let's continue by adding some widgets back in the + application main. Let's just focus on two: - \snippet ../examples/bars/main.cpp 2 - - We created QItemModelBarDataMapping and QItemModelBarDataProxy instances, and gave the proxy - the model of the table widget and the model mapping we just created. Then we set the proxy as - the active proxy for the graph. The proxy maps the rows and the columns in the model of the table - widget into rows and columns for itself using the model mapping, and the graph gets the data - to be displayed from its active proxy. + \snippet ../examples/bars/main.cpp 4 - \section1 Interacting with the data + We can use these to rotate the graph using slider widgets instead of just using the mouse or + touch. - We made a couple of signal connections in the application main earlier: + Let's add them to the vertical layout we created earlier: - \snippet ../examples/bars/main.cpp 3 + \snippet ../examples/bars/main.cpp 5 - Now we'll find out what these were for. + Then we'll connect them to methods in GraphModifier: - The first one connects a signal from Q3DBars to the GraphDataGenerator. Signal - Q3DBars::selectedBarPosChanged() is emitted when a bar is selected from the graph. We connect - that to a method in the data generator that selects the same data item in the table widget: + \snippet ../examples/bars/main.cpp 6 - \snippet ../examples/bars/main.cpp 13 + Here are the methods in GraphModifier the signals were connected to: - The second connection does the opposite; it connects a signal from the table widget to a - method in the data generator. The method then selects the corresponding bar in the graph: + \snippet ../examples/bars/graphmodifier.cpp 7 - \snippet ../examples/bars/main.cpp 14 + Now these two sliders can be used to rotate the graph. - You can even select an item in the widget and change the value of it, and the new value is - updated to the graph. This is handled again by the active proxy with mapping between the data - in the table widget and itself. + And so we have an application in which we can control: - \image bars-example.png + \list + \li Graph rotation + \li Label style + \li Camera preset + \li Background visibility + \li Grid visibility + \li Bar shading smoothness + \li Bar style + \li Selection mode + \li Theme + \li Shadow quality + \li Font + \li Font size + \endlist \section1 Example contents + */ diff --git a/examples/bars/graphmodifier.cpp b/examples/bars/graphmodifier.cpp new file mode 100644 index 00000000..0b33bde0 --- /dev/null +++ b/examples/bars/graphmodifier.cpp @@ -0,0 +1,229 @@ +/**************************************************************************** +** +** Copyright (C) 2013 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 "graphmodifier.h" +#include +#include +#include +#include +#include +#include + +QT_DATAVISUALIZATION_USE_NAMESPACE + +const QString celsiusString = QString(QChar(0xB0)) + "C"; + +//! [0] +GraphModifier::GraphModifier(Q3DBars *bargraph) + : m_graph(bargraph), + m_xRotation(0.0), + m_yRotation(0.0), + m_fontSize(30), + m_segments(4), + m_subSegments(3), + m_minval(-20.0), + m_maxval(20.0), + //! [1] + m_temperatureAxis(new Q3DValueAxis), + m_yearAxis(new Q3DCategoryAxis), + m_monthAxis(new Q3DCategoryAxis), + m_temperatureData(new QBarDataProxy), + //! [1] + m_style(QDataVis::MeshStyleBevelBars), + m_smooth(false) +{ + //! [2] + m_graph->setBackgroundVisible(false); + m_graph->setShadowQuality(QDataVis::ShadowQualitySoftMedium); + m_graph->setFont(QFont("Times New Roman", m_fontSize)); + m_graph->setLabelStyle(QDataVis::LabelStyleFromTheme); + //! [2] + + m_months << "January" << "February" << "March" << "April" << "May" << "June" << "July" << "August" << "September" << "October" << "November" << "December"; + m_years << "2006" << "2007" << "2008" << "2009" << "2010" << "2011" << "2012"; + + //! [3] + m_temperatureAxis->setTitle("Average temperature"); + m_temperatureAxis->setSegmentCount(m_segments); + m_temperatureAxis->setSubSegmentCount(m_subSegments); + m_temperatureAxis->setRange(m_minval, m_maxval); + m_temperatureAxis->setLabelFormat(QString(QStringLiteral("%d ") + celsiusString)); + + m_yearAxis->setTitle("Year"); + m_monthAxis->setTitle("Month"); + + m_graph->addAxis(m_temperatureAxis); + m_graph->addAxis(m_yearAxis); + m_graph->addAxis(m_monthAxis); + //! [3] + + m_temperatureData->setItemLabelFormat(QStringLiteral("@valueTitle for @colLabel @rowLabel: @valueLabel")); + + //! [4] + m_graph->addDataProxy(m_temperatureData); + //! [4] + + resetTemperatureData(); +} +//! [0] + +GraphModifier::~GraphModifier() +{ + delete m_graph; +} + +void GraphModifier::start() +{ + //! [6] + m_graph->setActiveDataProxy(m_temperatureData); + + m_graph->setValueAxis(m_temperatureAxis); + m_graph->setRowAxis(m_yearAxis); + m_graph->setColumnAxis(m_monthAxis); + //! [6] +} + +void GraphModifier::resetTemperatureData() +{ + //! [5] + // Set up data + static const qreal temp[7][12] = { + {-6.7, -11.7, -9.7, 3.3, 9.2, 14.0, 16.3, 17.8, 10.2, 2.1, -2.6, -0.3}, // 2006 + {-6.8, -13.3, 0.2, 1.5, 7.9, 13.4, 16.1, 15.5, 8.2, 5.4, -2.6, -0.8}, // 2007 + {-4.2, -4.0, -4.6, 1.9, 7.3, 12.5, 15.0, 12.8, 7.6, 5.1, -0.9, -1.3}, // 2008 + {-7.8, -8.8, -4.2, 0.7, 9.3, 13.2, 15.8, 15.5, 11.2, 0.6, 0.7, -8.4}, // 2009 + {-14.4, -12.1, -7.0, 2.3, 11.0, 12.6, 18.8, 13.8, 9.4, 3.9, -5.6, -13.0}, // 2010 + {-9.0, -15.2, -3.8, 2.6, 8.3, 15.9, 18.6, 14.9, 11.1, 5.3, 1.8, -0.2}, // 2011 + {-8.7, -11.3, -2.3, 0.4, 7.5, 12.2, 16.4, 14.1, 9.2, 3.1, 0.3, -12.1} // 2012 + }; + + // Create data array + QBarDataArray *dataSet = new QBarDataArray; + QBarDataRow *dataRow; + + dataSet->reserve(m_years.size()); + for (int year = 0; year < m_years.size(); year++) { + // Create a data row + dataRow = new QBarDataRow(m_months.size()); + for (int month = 0; month < m_months.size(); month++) { + // Add data to the row + (*dataRow)[month].setValue(temp[year][month]); + } + // Add the row to the set + dataSet->append(dataRow); + } + + // Add data to the graph (the graph assumes ownership of it) + m_temperatureData->resetArray(dataSet, m_years, m_months); + //! [5] +} + +void GraphModifier::changeStyle(int style) +{ + m_style = QDataVis::MeshStyle(style); + m_graph->setBarType(m_style, m_smooth); +} + +void GraphModifier::changePresetCamera() +{ + static int preset = QDataVis::CameraPresetFrontLow; + + m_graph->scene()->activeCamera()->setCameraPreset((QDataVis::CameraPreset)preset); + + if (++preset > QDataVis::CameraPresetDirectlyBelow) + preset = QDataVis::CameraPresetFrontLow; +} + +void GraphModifier::changeTheme(int theme) +{ + m_graph->setTheme((QDataVis::Theme)theme); +} + +void GraphModifier::changeLabelStyle() +{ + static int style = QDataVis::LabelStyleFromTheme; + + m_graph->setLabelStyle((QDataVis::LabelStyle)style); + + if (++style > QDataVis::LabelStyleTransparent) + style = QDataVis::LabelStyleOpaque; +} + +void GraphModifier::changeSelectionMode(int selectionMode) +{ + m_graph->setSelectionMode((QDataVis::SelectionMode)selectionMode); +} + +void GraphModifier::changeFont(const QFont &font) +{ + QFont newFont = font; + newFont.setPointSize(m_fontSize); + m_graph->setFont(newFont); +} + +void GraphModifier::changeFontSize(int fontsize) +{ + m_fontSize = fontsize; + QFont font = m_graph->font(); + font.setPointSize(m_fontSize); + m_graph->setFont(font); +} + +void GraphModifier::shadowQualityUpdatedByVisual(QDataVis::ShadowQuality sq) +{ + int quality = int(sq); + // Updates the UI component to show correct shadow quality + emit shadowQualityChanged(quality); +} + +void GraphModifier::changeShadowQuality(int quality) +{ + QDataVis::ShadowQuality sq = QDataVis::ShadowQuality(quality); + m_graph->setShadowQuality(sq); + emit shadowQualityChanged(quality); +} + +//! [7] +void GraphModifier::rotateX(int rotation) +{ + m_xRotation = rotation; + m_graph->scene()->activeCamera()->setCameraPosition(m_xRotation, m_yRotation); +} + +void GraphModifier::rotateY(int rotation) +{ + m_yRotation = rotation; + m_graph->scene()->activeCamera()->setCameraPosition(m_xRotation, m_yRotation); +} +//! [7] + +void GraphModifier::setBackgroundEnabled(int enabled) +{ + m_graph->setBackgroundVisible((bool)enabled); +} + +void GraphModifier::setGridEnabled(int enabled) +{ + m_graph->setGridVisible((bool)enabled); +} + +void GraphModifier::setSmoothBars(int smooth) +{ + m_smooth = bool(smooth); + m_graph->setBarType(m_style, m_smooth); +} diff --git a/examples/bars/graphmodifier.h b/examples/bars/graphmodifier.h new file mode 100644 index 00000000..2e18ffd2 --- /dev/null +++ b/examples/bars/graphmodifier.h @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** Copyright (C) 2013 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 GRAPHMODIFIER_H +#define GRAPHMODIFIER_H + +#include + +#include +#include +#include +#include + +using namespace QtDataVisualization; + +class GraphModifier : public QObject +{ + Q_OBJECT +public: + explicit GraphModifier(Q3DBars *bargraph); + ~GraphModifier(); + + void resetTemperatureData(); + void changePresetCamera(); + void changeLabelStyle(); + void changeFont(const QFont &font); + void changeFontSize(int fontsize); + void rotateX(int rotation); + void rotateY(int rotation); + void setBackgroundEnabled(int enabled); + void setGridEnabled(int enabled); + void setSmoothBars(int smooth); + void start(); + +public slots: + void changeStyle(int style); + void changeSelectionMode(int selectionMode); + void changeTheme(int theme); + void changeShadowQuality(int quality); + void shadowQualityUpdatedByVisual(QDataVis::ShadowQuality shadowQuality); + +signals: + void shadowQualityChanged(int quality); + +private: + Q3DBars *m_graph; + qreal m_xRotation; + qreal m_yRotation; + int m_fontSize; + int m_segments; + int m_subSegments; + qreal m_minval; + qreal m_maxval; + QStringList m_months; + QStringList m_years; + Q3DValueAxis *m_temperatureAxis; + Q3DCategoryAxis *m_yearAxis; + Q3DCategoryAxis *m_monthAxis; + QBarDataProxy *m_temperatureData; + QDataVis::MeshStyle m_style; + bool m_smooth; +}; + +#endif diff --git a/examples/bars/main.cpp b/examples/bars/main.cpp index 6ab685ed..158244b4 100644 --- a/examples/bars/main.cpp +++ b/examples/bars/main.cpp @@ -16,272 +16,196 @@ ** ****************************************************************************/ -#include -#include -#include -#include -#include -#include +#include "graphmodifier.h" #include +#include +#include #include -#include +#include +#include +#include +#include +#include #include -#include -#include -#include -#include +#include -#define USE_STATIC_DATA - -using namespace QtDataVisualization; - -class GraphDataGenerator : public QObject +int main(int argc, char **argv) { -public: - explicit GraphDataGenerator(Q3DBars *bargraph, QTableWidget *tableWidget); - ~GraphDataGenerator(); - - void setupModel(); - void addRow(); - void changeStyle(); - void changePresetCamera(); - void changeTheme(); - void start(); - void selectFromTable(const QPoint &selection); - void selectedFromTable(int currentRow, int currentColumn, int previousRow, int previousColumn); - void fixTableSize(); + //! [0] + QApplication app(argc, argv); + Q3DBars *widgetgraph = new Q3DBars(); + QWidget *container = QWidget::createWindowContainer(widgetgraph); + //! [0] -private: - Q3DBars *m_graph; - QTimer *m_dataTimer; - QTimer *m_styleTimer; - QTimer *m_presetTimer; - QTimer *m_themeTimer; - int m_columnCount; - int m_rowCount; - QTableWidget *m_tableWidget; // not owned -}; + QSize screenSize = widgetgraph->screen()->size(); + container->setMinimumSize(QSize(screenSize.width() / 2, screenSize.height() / 1.5)); + container->setMaximumSize(screenSize); + container->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + container->setFocusPolicy(Qt::StrongFocus); -GraphDataGenerator::GraphDataGenerator(Q3DBars *bargraph, QTableWidget *tableWidget) - : m_graph(bargraph), - m_dataTimer(0), - m_styleTimer(0), - m_presetTimer(0), - m_themeTimer(0), - m_columnCount(100), - m_rowCount(50), - m_tableWidget(tableWidget) -{ - //! [5] - // Set up bar specifications; make the bars as wide as they are deep, - // and add a small space between them - m_graph->setBarThickness(1.0); - m_graph->setBarSpacing(QSizeF(0.2, 0.2)); + //! [1] + QWidget *widget = new QWidget; + QHBoxLayout *hLayout = new QHBoxLayout(widget); + QVBoxLayout *vLayout = new QVBoxLayout(); + hLayout->addWidget(container, 1); + hLayout->addLayout(vLayout); + //! [1] - // Set bar type to flat pyramids - m_graph->setBarType(QDataVis::MeshStylePyramids, false); + widget->setWindowTitle(QStringLiteral("Average temperatures in Oulu, Finland (2006-2012)")); + + QComboBox *themeList = new QComboBox(widget); + themeList->addItem(QStringLiteral("Qt")); + themeList->addItem(QStringLiteral("Primary Colors")); + themeList->addItem(QStringLiteral("Digia")); + themeList->addItem(QStringLiteral("Stone Moss")); + themeList->addItem(QStringLiteral("Army Blue")); + themeList->addItem(QStringLiteral("Retro")); + themeList->addItem(QStringLiteral("Ebony")); + themeList->addItem(QStringLiteral("Isabelle")); + themeList->setCurrentIndex(0); + + QPushButton *labelButton = new QPushButton(widget); + labelButton->setText(QStringLiteral("Change label style")); + + QCheckBox *smoothCheckBox = new QCheckBox(widget); + smoothCheckBox->setText(QStringLiteral("Smooth bars")); + smoothCheckBox->setChecked(false); + + QComboBox *barStyleList = new QComboBox(widget); + barStyleList->addItem(QStringLiteral("Bars")); + barStyleList->addItem(QStringLiteral("Pyramids")); + barStyleList->addItem(QStringLiteral("Cones")); + barStyleList->addItem(QStringLiteral("Cylinders")); + barStyleList->addItem(QStringLiteral("Beveled Bars")); + barStyleList->setCurrentIndex(4); + + QPushButton *cameraButton = new QPushButton(widget); + cameraButton->setText(QStringLiteral("Change camera preset")); + + QComboBox *selectionModeList = new QComboBox(widget); + selectionModeList->addItem(QStringLiteral("None")); + selectionModeList->addItem(QStringLiteral("Bar")); + selectionModeList->addItem(QStringLiteral("Bar and Row")); + selectionModeList->addItem(QStringLiteral("Bar and Column")); + selectionModeList->addItem(QStringLiteral("Bar, Row and Column")); + selectionModeList->addItem(QStringLiteral("Slice into Row")); + selectionModeList->addItem(QStringLiteral("Slice into Column")); + selectionModeList->setCurrentIndex(1); + + QCheckBox *backgroundCheckBox = new QCheckBox(widget); + backgroundCheckBox->setText(QStringLiteral("Show background")); + backgroundCheckBox->setChecked(false); + + QCheckBox *gridCheckBox = new QCheckBox(widget); + gridCheckBox->setText(QStringLiteral("Show grid")); + gridCheckBox->setChecked(true); - //! [5] + //! [4] + QSlider *rotationSliderX = new QSlider(Qt::Horizontal, widget); + rotationSliderX->setTickInterval(30); + rotationSliderX->setTickPosition(QSlider::TicksBelow); + rotationSliderX->setMinimum(-180); + rotationSliderX->setValue(0); + rotationSliderX->setMaximum(180); + QSlider *rotationSliderY = new QSlider(Qt::Horizontal, widget); + rotationSliderY->setTickInterval(15); + rotationSliderY->setTickPosition(QSlider::TicksAbove); + rotationSliderY->setMinimum(-90); + rotationSliderY->setValue(0); + rotationSliderY->setMaximum(90); + //! [4] -#ifndef USE_STATIC_DATA - // Set up sample space; make it as deep as it's wide - m_graph->setDataWindow(m_rowCount, m_columnCount); - m_tableWidget->setColumnCount(m_columnCount); + QSlider *fontSizeSlider = new QSlider(Qt::Horizontal, widget); + fontSizeSlider->setTickInterval(10); + fontSizeSlider->setTickPosition(QSlider::TicksBelow); + fontSizeSlider->setMinimum(1); + fontSizeSlider->setValue(30); + fontSizeSlider->setMaximum(100); + + QFontComboBox *fontList = new QFontComboBox(widget); + fontList->setCurrentFont(QFont("Times New Roman")); + + QComboBox *shadowQuality = new QComboBox(widget); + shadowQuality->addItem(QStringLiteral("None")); + shadowQuality->addItem(QStringLiteral("Low")); + shadowQuality->addItem(QStringLiteral("Medium")); + shadowQuality->addItem(QStringLiteral("High")); + shadowQuality->addItem(QStringLiteral("Low Soft")); + shadowQuality->addItem(QStringLiteral("Medium Soft")); + shadowQuality->addItem(QStringLiteral("High Soft")); + shadowQuality->setCurrentIndex(5); - // Set selection mode to full - m_graph->setSelectionMode(QDataVis::SelectionModeItemRowAndColumn); + //! [5] + vLayout->addWidget(new QLabel(QStringLiteral("Rotate horizontally"))); + vLayout->addWidget(rotationSliderX, 0, Qt::AlignTop); + vLayout->addWidget(new QLabel(QStringLiteral("Rotate vertically"))); + vLayout->addWidget(rotationSliderY, 0, Qt::AlignTop); + //! [5] + vLayout->addWidget(labelButton, 0, Qt::AlignTop); + vLayout->addWidget(cameraButton, 0, Qt::AlignTop); + vLayout->addWidget(backgroundCheckBox); + vLayout->addWidget(gridCheckBox); + vLayout->addWidget(smoothCheckBox, 0, Qt::AlignTop); + vLayout->addWidget(new QLabel(QStringLiteral("Change bar style"))); + vLayout->addWidget(barStyleList); + vLayout->addWidget(new QLabel(QStringLiteral("Change selection mode"))); + vLayout->addWidget(selectionModeList); + vLayout->addWidget(new QLabel(QStringLiteral("Change theme"))); + vLayout->addWidget(themeList); + vLayout->addWidget(new QLabel(QStringLiteral("Adjust shadow quality"))); + vLayout->addWidget(shadowQuality); + vLayout->addWidget(new QLabel(QStringLiteral("Change font"))); + vLayout->addWidget(fontList); + vLayout->addWidget(new QLabel(QStringLiteral("Adjust font size"))); + vLayout->addWidget(fontSizeSlider, 1, Qt::AlignTop); - // Hide axis labels by explicitly setting one empty string as label list - m_graph->rowAxis()->setCategoryLabels(QStringList(QString())); - m_graph->columnAxis()->setCategoryLabels(QStringList(QString())); + //! [2] + GraphModifier *modifier = new GraphModifier(widgetgraph); + //! [2] - m_graph->activeDataProxy()->setItemLabelFormat(QStringLiteral("@valueLabel")); -#else //! [6] - - // Set selection mode to slice row - m_graph->setSelectionMode(QDataVis::SelectionModeSliceRow); - - // Set font - m_graph->setFont(QFont("Impact", 20)); - + QObject::connect(rotationSliderX, &QSlider::valueChanged, modifier, &GraphModifier::rotateX); + QObject::connect(rotationSliderY, &QSlider::valueChanged, modifier, &GraphModifier::rotateY); //! [6] -#endif - //! [7] + QObject::connect(labelButton, &QPushButton::clicked, modifier, + &GraphModifier::changeLabelStyle); + QObject::connect(cameraButton, &QPushButton::clicked, modifier, + &GraphModifier::changePresetCamera); - // Set theme - m_graph->setTheme(QDataVis::ThemeDigia); + QObject::connect(backgroundCheckBox, &QCheckBox::stateChanged, modifier, + &GraphModifier::setBackgroundEnabled); + QObject::connect(gridCheckBox, &QCheckBox::stateChanged, modifier, + &GraphModifier::setGridEnabled); + QObject::connect(smoothCheckBox, &QCheckBox::stateChanged, modifier, + &GraphModifier::setSmoothBars); - // Set preset camera position - m_graph->scene()->activeCamera()->setCameraPreset(QDataVis::CameraPresetFront); - //! [7] -} + QObject::connect(barStyleList, SIGNAL(currentIndexChanged(int)), modifier, + SLOT(changeStyle(int))); -GraphDataGenerator::~GraphDataGenerator() -{ - if (m_dataTimer) { - m_dataTimer->stop(); - delete m_dataTimer; - } - delete m_graph; -} - -void GraphDataGenerator::start() -{ -#ifndef USE_STATIC_DATA - m_dataTimer = new QTimer(); - m_dataTimer->setTimerType(Qt::CoarseTimer); - QObject::connect(m_dataTimer, &QTimer::timeout, this, &GraphDataGenerator::addRow); - m_dataTimer->start(0); - m_tableWidget->setFixedWidth(m_graph->width()); -#else - //! [8] - setupModel(); - // Table needs to be shown before the size of its headers can be accurately obtained, - // so we postpone it a bit - m_dataTimer = new QTimer(); - m_dataTimer->setSingleShot(true); - QObject::connect(m_dataTimer, &QTimer::timeout, this, &GraphDataGenerator::fixTableSize); - m_dataTimer->start(0); - //! [8] -#endif -} + QObject::connect(selectionModeList, SIGNAL(currentIndexChanged(int)), modifier, + SLOT(changeSelectionMode(int))); -void GraphDataGenerator::setupModel() -{ - //! [9] - // Set up row and column names - QStringList days; - days << "Monday" << "Tuesday" << "Wednesday" << "Thursday" << "Friday" << "Saturday" << "Sunday"; - QStringList weeks; - weeks << "week 1" << "week 2" << "week 3" << "week 4" << "week 5"; - - // Set up data Mon Tue Wed Thu Fri Sat Sun - float hours[5][7] = {{2.0, 1.0, 3.0, 0.2, 1.0, 5.0, 10.0}, // week 1 - {0.5, 1.0, 3.0, 1.0, 2.0, 2.0, 3.0}, // week 2 - {1.0, 1.0, 2.0, 1.0, 4.0, 4.0, 4.0}, // week 3 - {0.0, 1.0, 0.0, 0.0, 2.0, 2.0, 0.3}, // week 4 - {3.0, 3.0, 6.0, 2.0, 2.0, 1.0, 1.0}}; // week 5 - //! [9] + QObject::connect(themeList, SIGNAL(currentIndexChanged(int)), modifier, + SLOT(changeTheme(int))); - // Add labels - //! [10] - m_graph->rowAxis()->setTitle("Week of year"); - m_graph->columnAxis()->setTitle("Day of week"); - m_graph->valueAxis()->setTitle("Hours spent on the Internet"); - m_graph->valueAxis()->setSegmentCount(5); - m_graph->valueAxis()->setLabelFormat("%.1f h"); - //! [10] + QObject::connect(shadowQuality, SIGNAL(currentIndexChanged(int)), modifier, + SLOT(changeShadowQuality(int))); - //! [11] - m_tableWidget->setRowCount(5); - m_tableWidget->setColumnCount(7); - m_tableWidget->setHorizontalHeaderLabels(days); - m_tableWidget->setVerticalHeaderLabels(weeks); - m_tableWidget->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - m_tableWidget->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - m_tableWidget->setCurrentCell(-1, -1); - //! [11] + QObject::connect(modifier, &GraphModifier::shadowQualityChanged, shadowQuality, + &QComboBox::setCurrentIndex); + QObject::connect(widgetgraph, &Q3DBars::shadowQualityChanged, modifier, + &GraphModifier::shadowQualityUpdatedByVisual); - //! [12] - for (int week = 0; week < weeks.size(); week++) { - for (int day = 0; day < days.size(); day++) { - QModelIndex index = m_tableWidget->model()->index(week, day); - m_tableWidget->model()->setData(index, hours[week][day]); - } - } - //! [12] -} + QObject::connect(fontSizeSlider, &QSlider::valueChanged, modifier, + &GraphModifier::changeFontSize); + QObject::connect(fontList, &QFontComboBox::currentFontChanged, modifier, + &GraphModifier::changeFont); -void GraphDataGenerator::addRow() -{ - m_tableWidget->model()->insertRow(0); - if (m_tableWidget->model()->rowCount() > m_rowCount) - m_tableWidget->model()->removeRow(m_rowCount); - for (int i = 0; i < m_columnCount; i++) { - QModelIndex index = m_tableWidget->model()->index(0, i); - m_tableWidget->model()->setData(index, - ((qreal)i / (qreal)m_columnCount) / 2.0 + (qreal)(rand() % 30) / 100.0); - } - m_tableWidget->resizeColumnsToContents(); -} - -//! [13] -void GraphDataGenerator::selectFromTable(const QPoint &selection) -{ - m_tableWidget->setFocus(); - m_tableWidget->setCurrentCell(selection.x(), selection.y()); -} -//! [13] - -//! [14] -void GraphDataGenerator::selectedFromTable(int currentRow, int currentColumn, - int previousRow, int previousColumn) -{ - Q_UNUSED(previousRow) - Q_UNUSED(previousColumn) - m_graph->setSelectedBarPos(QPoint(currentRow, currentColumn)); -} -//! [14] - -void GraphDataGenerator::fixTableSize() -{ - int width = m_tableWidget->horizontalHeader()->length(); - width += m_tableWidget->verticalHeader()->width(); - m_tableWidget->setFixedWidth(width + 2); - int height = m_tableWidget->verticalHeader()->length(); - height += m_tableWidget->horizontalHeader()->height(); - m_tableWidget->setFixedHeight(height + 2); -} - -int main(int argc, char **argv) -{ - //! [0] - QApplication app(argc, argv); - Q3DBars *graph = new Q3DBars(); - QWidget *container = QWidget::createWindowContainer(graph); - //! [0] - - QSize screenSize = graph->screen()->size(); - container->setMinimumSize(QSize(screenSize.width() / 2, screenSize.height() / 2)); - container->setMaximumSize(screenSize); - container->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); - container->setFocusPolicy(Qt::StrongFocus); - - //! [1] - QWidget widget; - QVBoxLayout *layout = new QVBoxLayout(&widget); - QTableWidget *tableWidget = new QTableWidget(&widget); - layout->addWidget(container, 1); - layout->addWidget(tableWidget, 1, Qt::AlignHCenter); - //! [1] - - tableWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); - tableWidget->setAlternatingRowColors(true); - widget.setWindowTitle(QStringLiteral("Hours spent on the Internet")); - - //! [2] - // Since we are dealing with QTableWidget, the model will already have data sorted properly - // in rows and columns, so create a mapping to utilize this. - QItemModelBarDataMapping *mapping = new QItemModelBarDataMapping; - mapping->setUseModelCategories(true); - QItemModelBarDataProxy *proxy = new QItemModelBarDataProxy(tableWidget->model(), mapping); - graph->setActiveDataProxy(proxy); - //! [2] - - //! [3] - GraphDataGenerator generator(graph, tableWidget); - QObject::connect(graph, &Q3DBars::selectedBarPosChanged, &generator, - &GraphDataGenerator::selectFromTable); - QObject::connect(tableWidget, &QTableWidget::currentCellChanged, &generator, - &GraphDataGenerator::selectedFromTable); //! [3] - - //! [4] - widget.show(); - generator.start(); + widget->show(); + modifier->start(); return app.exec(); - //! [4] + //! [3] } diff --git a/examples/customproxy/customproxy.pro b/examples/customproxy/customproxy.pro new file mode 100644 index 00000000..2b764a41 --- /dev/null +++ b/examples/customproxy/customproxy.pro @@ -0,0 +1,24 @@ +!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 + +INSTALLS += target + +RESOURCES += customproxy.qrc + +OTHER_FILES += data/raindata.txt \ + doc/src/* \ + doc/images/* + diff --git a/examples/customproxy/customproxy.qrc b/examples/customproxy/customproxy.qrc new file mode 100644 index 00000000..53cd4915 --- /dev/null +++ b/examples/customproxy/customproxy.qrc @@ -0,0 +1,5 @@ + + + data/raindata.txt + + diff --git a/examples/customproxy/data/raindata.txt b/examples/customproxy/data/raindata.txt new file mode 100644 index 00000000..531d66be --- /dev/null +++ b/examples/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/customproxy/doc/images/customproxy-example.png b/examples/customproxy/doc/images/customproxy-example.png new file mode 100644 index 00000000..6706ea1c Binary files /dev/null and b/examples/customproxy/doc/images/customproxy-example.png differ diff --git a/examples/customproxy/doc/src/customproxy.qdoc b/examples/customproxy/doc/src/customproxy.qdoc new file mode 100644 index 00000000..8bb02105 --- /dev/null +++ b/examples/customproxy/doc/src/customproxy.qdoc @@ -0,0 +1,30 @@ +/**************************************************************************** +** +** Copyright (C) 2013 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 + + TODO +*/ diff --git a/examples/customproxy/main.cpp b/examples/customproxy/main.cpp new file mode 100644 index 00000000..54ea63e9 --- /dev/null +++ b/examples/customproxy/main.cpp @@ -0,0 +1,37 @@ +/**************************************************************************** +** +** Copyright (C) 2013 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 + +using namespace QtDataVisualization; + +int main(int argc, char **argv) +{ + QGuiApplication app(argc, argv); + + Q3DBars *rainfall = new Q3DBars; + rainfall->resize(1280, 800); + rainfall->setPosition(QPoint(10, 30)); + rainfall->show(); + + RainfallGraph rainfallgraph(rainfall); + rainfallgraph.start(); + + return app.exec(); +} diff --git a/examples/customproxy/rainfallgraph.cpp b/examples/customproxy/rainfallgraph.cpp new file mode 100644 index 00000000..41f72464 --- /dev/null +++ b/examples/customproxy/rainfallgraph.cpp @@ -0,0 +1,140 @@ +/**************************************************************************** +** +** Copyright (C) 2013 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 +#include +#include +#include +#include +#include +#include +#include +#include + +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; + m_graph->setActiveDataProxy(m_proxy); + + 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.0); + 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->rowAxis()->setCategoryLabels(m_years); + m_graph->columnAxis()->setCategoryLabels(months); + + // Set bar type to cylinder + m_graph->setBarType(QDataVis::MeshStyleCylinders, false); + + // Set shadows to medium + m_graph->setShadowQuality(QDataVis::ShadowQualityMedium); + + // Set font + m_graph->setFont(QFont("Century Gothic", 30)); + + // Set selection mode to bar and column + m_graph->setSelectionMode(QDataVis::SelectionModeSliceColumn); + + // Set theme + m_graph->setTheme(QDataVis::ThemeArmyBlue); + + // Set preset camera position + m_graph->scene()->activeCamera()->setCameraPreset(QDataVis::CameraPresetIsometricRightHigh); + + // Disable grid + m_graph->setGridVisible(false); + + // 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(); +} + +void RainfallGraph::addDataSet() +{ + m_dataSet = new VariantDataSet; + VariantDataItemList *itemList = new VariantDataItemList; + 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("#")) + continue; + QStringList strList = line.split(",", QString::SkipEmptyParts); + if (strList.size() < 3) { + qWarning() << "Invalid row read from data:" << line; + continue; + } + 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(); + } + + m_dataSet->addItems(itemList); + + m_proxy->setDataSet(m_dataSet); + + m_mapping = new VariantBarDataMapping(0, 1, 2, m_years, m_numericMonths); + m_proxy->setMapping(m_mapping); +} diff --git a/examples/customproxy/rainfallgraph.h b/examples/customproxy/rainfallgraph.h new file mode 100644 index 00000000..6317ab71 --- /dev/null +++ b/examples/customproxy/rainfallgraph.h @@ -0,0 +1,51 @@ +/**************************************************************************** +** +** Copyright (C) 2013 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 + +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/customproxy/variantbardatamapping.cpp b/examples/customproxy/variantbardatamapping.cpp new file mode 100644 index 00000000..0c2f146c --- /dev/null +++ b/examples/customproxy/variantbardatamapping.cpp @@ -0,0 +1,133 @@ +/**************************************************************************** +** +** Copyright (C) 2013 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/customproxy/variantbardatamapping.h b/examples/customproxy/variantbardatamapping.h new file mode 100644 index 00000000..0204ddc8 --- /dev/null +++ b/examples/customproxy/variantbardatamapping.h @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2013 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 "qdatavisualizationenums.h" +#include + +using namespace QtDataVisualization; + +class VariantBarDataMapping : public QObject +{ + Q_OBJECT + 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) +public: + explicit VariantBarDataMapping(); + VariantBarDataMapping(const VariantBarDataMapping &other); + VariantBarDataMapping(int rowIndex, int columnIndex, int valueIndex, + const QStringList &rowCategories, + const QStringList &columnCategories); + 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; + + void remap(int rowIndex, int columnIndex, int valueIndex, + const QStringList &rowCategories, + const QStringList &columnCategories); +signals: + void mappingChanged(); + +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/customproxy/variantbardataproxy.cpp b/examples/customproxy/variantbardataproxy.cpp new file mode 100644 index 00000000..c907a1e3 --- /dev/null +++ b/examples/customproxy/variantbardataproxy.cpp @@ -0,0 +1,136 @@ +/**************************************************************************** +** +** Copyright (C) 2013 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(); // TODO Resolving entire dataset is inefficient +} + +void VariantBarDataProxy::handleDataCleared() +{ + // Data cleared, reset array + resetArray(0); +} + +void VariantBarDataProxy::handleMappingChanged() +{ + resolveDataSet(); +} + +// Resolve entire dataset into QBarDataArray. +void VariantBarDataProxy::resolveDataSet() +{ + 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 ColumnValueMap; + QHash itemValueMap; + foreach (const VariantDataItem *item, itemList) { + itemValueMap[item->at(rowIndex).toString()][item->at(columnIndex).toString()] + = item->at(valueIndex).toReal(); + } + + // Create new data array from itemValueMap + 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); + } + + resetArray(newProxyArray); +} diff --git a/examples/customproxy/variantbardataproxy.h b/examples/customproxy/variantbardataproxy.h new file mode 100644 index 00000000..b931aa5c --- /dev/null +++ b/examples/customproxy/variantbardataproxy.h @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** Copyright (C) 2013 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 +#include +#include + +using namespace QtDataVisualization; + +class VariantBarDataProxy : public QBarDataProxy +{ + Q_OBJECT + +public: + explicit VariantBarDataProxy(); + explicit VariantBarDataProxy(VariantDataSet *newSet, VariantBarDataMapping *mapping); + virtual ~VariantBarDataProxy(); + + // 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(); + +public slots: + void handleItemsAdded(int index, int count); + void handleDataCleared(); + void handleMappingChanged(); + +private: + void resolveDataSet(); + + QPointer m_dataSet; + QPointer m_mapping; + + Q_DISABLE_COPY(VariantBarDataProxy) +}; + +#endif diff --git a/examples/customproxy/variantdataset.cpp b/examples/customproxy/variantdataset.cpp new file mode 100644 index 00000000..f73d83f8 --- /dev/null +++ b/examples/customproxy/variantdataset.cpp @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** Copyright (C) 2013 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/customproxy/variantdataset.h b/examples/customproxy/variantdataset.h new file mode 100644 index 00000000..7906d4f5 --- /dev/null +++ b/examples/customproxy/variantdataset.h @@ -0,0 +1,56 @@ +/**************************************************************************** +** +** Copyright (C) 2013 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 "qdatavisualizationenums.h" +#include +#include + +using namespace QtDataVisualization; + +typedef QVariantList VariantDataItem; +typedef QList VariantDataItemList; + +class VariantDataSet : public QObject +{ + Q_OBJECT + +public: + explicit VariantDataSet(); + ~VariantDataSet(); + + void clear(); + + int addItem(VariantDataItem *item); + int addItems(VariantDataItemList *itemList); + + const VariantDataItemList &itemList() const; + +signals: + void itemsAdded(int index, int count); + void dataCleared(); + +private: + VariantDataItemList m_variantData; + + Q_DISABLE_COPY(VariantDataSet) +}; + +#endif diff --git a/examples/examples.pro b/examples/examples.pro index e5001049..7d9f306a 100644 --- a/examples/examples.pro +++ b/examples/examples.pro @@ -4,8 +4,8 @@ SUBDIRS += qmlbars \ qmlsurface !android: { SUBDIRS += bars \ - rainfall \ - widget \ + customproxy \ + itemmodel \ scatter \ surface } diff --git a/examples/itemmodel/doc/images/itemmodel-example-2.png b/examples/itemmodel/doc/images/itemmodel-example-2.png new file mode 100644 index 00000000..2083a8e0 Binary files /dev/null and b/examples/itemmodel/doc/images/itemmodel-example-2.png differ diff --git a/examples/itemmodel/doc/images/itemmodel-example.png b/examples/itemmodel/doc/images/itemmodel-example.png new file mode 100644 index 00000000..a87f4bdf Binary files /dev/null and b/examples/itemmodel/doc/images/itemmodel-example.png differ diff --git a/examples/itemmodel/doc/src/itemmodel.qdoc b/examples/itemmodel/doc/src/itemmodel.qdoc new file mode 100644 index 00000000..f014bfea --- /dev/null +++ b/examples/itemmodel/doc/src/itemmodel.qdoc @@ -0,0 +1,182 @@ +/**************************************************************************** +** +** Copyright (C) 2013 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 itemmodel + \title Item Model Example + \ingroup qtdatavisualization_examples + \brief Using an item model as data source for Q3DBars. + + The item model example shows how to make a simple 3D bar graph using Q3DBars and how to modify + the data being drawn at run-time. The example shows how to: + + \list + \li How to create an application with Q3DBars and widgets + \li How to use QItemModelBarDataMapping and QItemModelBarDataProxy to set data to the graph + \li How to use a table widget to modify the data in the graph + \endlist + + \image itemmodel-example-2.png + + \section1 Creating the application + + First, in main.cpp, we create a QApplication, instantiate Q3DBars and a window container for it: + + \snippet ../examples/itemmodel/main.cpp 0 + + The call to QWidget::createWindowContainer is required, as all data visualization types + (Q3DBars, Q3DScatter, Q3DSurface) inherit QWindow. Any class inheriting QWindow cannot be used + as a widget any other way. + + Then we'll create a layout and add the graph and the table widget into it: + + \snippet ../examples/itemmodel/main.cpp 1 + + The table widget is going to be used to display the numerical data being inserted into the + graph, and to modify it (See \l {Adding data to the graph} and \l {Interacting with the data}). + + We need to instantiate QItemModelBarDataMapping and QItemModelBarDataProxy and give them to the + graph: + + \snippet ../examples/itemmodel/main.cpp 2 + + Here we tell the mapping object to directly map model's rows and columns into proxy's rows and + columns instead of defining row and column roles to map for them. Then we give the model from + the table widget and the mapping object to the proxy. Finally we set the proxy as the active + data proxy for the graph. + + Next, let's create another class to handle the data addition and other interaction with the + graph. Let's call it GraphDataGenerator (See \l {Setting up the graph} and + \l {Adding data to the graph} for details) and connect some signals between Q3DBars, + GraphDataGenerator and QTableWidget (See \l {Interacting with the data} for a closer look): + + \snippet ../examples/itemmodel/main.cpp 3 + + The application main is done and we can show the graph and start the event loop: + + \snippet ../examples/itemmodel/main.cpp 4 + + \section1 Setting up the graph + + Let's set up the visual attributes for the graph in the constructor of GraphDataGenerator: + + \snippet ../examples/itemmodel/main.cpp 5 + \snippet ../examples/itemmodel/main.cpp 6 + \snippet ../examples/itemmodel/main.cpp 7 + + First we set bar thickness ratio to 1.0, which means bars will be as wide as they are deep. 1.0 + is also the default value, so the line is basically unnecessary. It's left there so you could + easily try how changing it affects the graph. The second line sets bar spacings to 0.2, which + means there will be a gap of 20% of the bar's thickness between the bars in both directions. + + Then, we set the bar type to flat pyramids, overriding the default bar type. + We want to be able to select rows of data for a closer inspection, so we set the selection mode + to slice row. This means that whenever we select a bar in the graph, the whole row will be + displayed separately. + + Next line sets the font to \c Impact. If your system doesn't have it, it will be replaced by + system default. + + And finally, we set theme to \c Digia and camera position to \c {Preset Front}. Now the initial + graph settings are done. + + \note You do not need to set any of these in case you're happy with the defaults. You can + easily try them by commenting out the contents of the constructor. + + \section1 Adding data to the graph + + We created the data generator in the application main and gave it the graph and the table + widget as parameters: + + \code GraphDataGenerator generator(graph, tableWidget); \endcode + + We added a separate start method to the generator, so that it wouldn't start doing anything + until everything else is set up. We then called the method when starting the application: + + \code generator.start(); \endcode + + Let's have a look at the contents of the \c start() method: + + \snippet ../examples/itemmodel/main.cpp 8 + + The main thing \c start() does is set up the data model. It also activates a timer for getting + the accurate dimensions of the table widget after it's been filled with data. The reason we + do this is that the widget doesn't know its final visual domensions until all the data has been + inserted to it and it has been shown. The whole data timer implementation is not vital for the + application, so we won't take a closer look at it. It's just there to make the table look better. + + In \c setupModel() we first introduce the row and column labels, and the actual data: + + \snippet ../examples/itemmodel/main.cpp 9 + + Then we set up the axes: + + \snippet ../examples/itemmodel/main.cpp 10 + + The other lines there are pretty self-explanatory except for the one with the segment count. + We're setting it to five as we want the value axis (the Y-axis) to show more values than just + the lowest and the highest. + + Next we will set up the table widget: + + \snippet ../examples/itemmodel/main.cpp 11 + + After that all that's left is adding the data to the table widget: + + \snippet ../examples/itemmodel/main.cpp 12 + + Now we have a bar graph and a table widget, both displaying the same data. + + You're probably wondering how the data can be displayed in the graph, as the only thing we did + was add it to the table widget? That's because of what we did earlier, in the application main: + + \snippet ../examples/itemmodel/main.cpp 2 + + We created QItemModelBarDataMapping and QItemModelBarDataProxy instances, and gave the proxy + the model of the table widget and the model mapping we just created. Then we set the proxy as + the active proxy for the graph. The proxy maps the rows and the columns in the model of the table + widget into rows and columns for itself using the model mapping, and the graph gets the data + to be displayed from its active proxy. + + \section1 Interacting with the data + + We made a couple of signal connections in the application main earlier: + + \snippet ../examples/itemmodel/main.cpp 3 + + Now we'll find out what these were for. + + The first one connects a signal from Q3DBars to the GraphDataGenerator. Signal + Q3DBars::selectedBarPosChanged() is emitted when a bar is selected from the graph. We connect + that to a method in the data generator that selects the same data item in the table widget: + + \snippet ../examples/itemmodel/main.cpp 13 + + The second connection does the opposite; it connects a signal from the table widget to a + method in the data generator. The method then selects the corresponding bar in the graph: + + \snippet ../examples/itemmodel/main.cpp 14 + + You can even select an item in the widget and change the value of it, and the new value is + updated to the graph. This is handled again by the active proxy with mapping between the data + in the table widget and itself. + + \image itemmodel-example.png + + \section1 Example contents +*/ diff --git a/examples/itemmodel/itemmodel.pro b/examples/itemmodel/itemmodel.pro new file mode 100644 index 00000000..f319f690 --- /dev/null +++ b/examples/itemmodel/itemmodel.pro @@ -0,0 +1,12 @@ +!include( ../examples.pri ) { + error( "Couldn't find the examples.pri file!" ) +} + +SOURCES += main.cpp + +INSTALLS += target + +QT += widgets + +OTHER_FILES += doc/src/* \ + doc/images/* diff --git a/examples/itemmodel/main.cpp b/examples/itemmodel/main.cpp new file mode 100644 index 00000000..6ab685ed --- /dev/null +++ b/examples/itemmodel/main.cpp @@ -0,0 +1,287 @@ +/**************************************************************************** +** +** Copyright (C) 2013 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 +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#define USE_STATIC_DATA + +using namespace QtDataVisualization; + +class GraphDataGenerator : public QObject +{ +public: + explicit GraphDataGenerator(Q3DBars *bargraph, QTableWidget *tableWidget); + ~GraphDataGenerator(); + + void setupModel(); + void addRow(); + void changeStyle(); + void changePresetCamera(); + void changeTheme(); + void start(); + void selectFromTable(const QPoint &selection); + void selectedFromTable(int currentRow, int currentColumn, int previousRow, int previousColumn); + void fixTableSize(); + +private: + Q3DBars *m_graph; + QTimer *m_dataTimer; + QTimer *m_styleTimer; + QTimer *m_presetTimer; + QTimer *m_themeTimer; + int m_columnCount; + int m_rowCount; + QTableWidget *m_tableWidget; // not owned +}; + +GraphDataGenerator::GraphDataGenerator(Q3DBars *bargraph, QTableWidget *tableWidget) + : m_graph(bargraph), + m_dataTimer(0), + m_styleTimer(0), + m_presetTimer(0), + m_themeTimer(0), + m_columnCount(100), + m_rowCount(50), + m_tableWidget(tableWidget) +{ + //! [5] + // Set up bar specifications; make the bars as wide as they are deep, + // and add a small space between them + m_graph->setBarThickness(1.0); + m_graph->setBarSpacing(QSizeF(0.2, 0.2)); + + // Set bar type to flat pyramids + m_graph->setBarType(QDataVis::MeshStylePyramids, false); + + //! [5] + +#ifndef USE_STATIC_DATA + // Set up sample space; make it as deep as it's wide + m_graph->setDataWindow(m_rowCount, m_columnCount); + m_tableWidget->setColumnCount(m_columnCount); + + // Set selection mode to full + m_graph->setSelectionMode(QDataVis::SelectionModeItemRowAndColumn); + + // Hide axis labels by explicitly setting one empty string as label list + m_graph->rowAxis()->setCategoryLabels(QStringList(QString())); + m_graph->columnAxis()->setCategoryLabels(QStringList(QString())); + + m_graph->activeDataProxy()->setItemLabelFormat(QStringLiteral("@valueLabel")); +#else + //! [6] + + // Set selection mode to slice row + m_graph->setSelectionMode(QDataVis::SelectionModeSliceRow); + + // Set font + m_graph->setFont(QFont("Impact", 20)); + + //! [6] +#endif + + //! [7] + + // Set theme + m_graph->setTheme(QDataVis::ThemeDigia); + + // Set preset camera position + m_graph->scene()->activeCamera()->setCameraPreset(QDataVis::CameraPresetFront); + //! [7] +} + +GraphDataGenerator::~GraphDataGenerator() +{ + if (m_dataTimer) { + m_dataTimer->stop(); + delete m_dataTimer; + } + delete m_graph; +} + +void GraphDataGenerator::start() +{ +#ifndef USE_STATIC_DATA + m_dataTimer = new QTimer(); + m_dataTimer->setTimerType(Qt::CoarseTimer); + QObject::connect(m_dataTimer, &QTimer::timeout, this, &GraphDataGenerator::addRow); + m_dataTimer->start(0); + m_tableWidget->setFixedWidth(m_graph->width()); +#else + //! [8] + setupModel(); + // Table needs to be shown before the size of its headers can be accurately obtained, + // so we postpone it a bit + m_dataTimer = new QTimer(); + m_dataTimer->setSingleShot(true); + QObject::connect(m_dataTimer, &QTimer::timeout, this, &GraphDataGenerator::fixTableSize); + m_dataTimer->start(0); + //! [8] +#endif +} + +void GraphDataGenerator::setupModel() +{ + //! [9] + // Set up row and column names + QStringList days; + days << "Monday" << "Tuesday" << "Wednesday" << "Thursday" << "Friday" << "Saturday" << "Sunday"; + QStringList weeks; + weeks << "week 1" << "week 2" << "week 3" << "week 4" << "week 5"; + + // Set up data Mon Tue Wed Thu Fri Sat Sun + float hours[5][7] = {{2.0, 1.0, 3.0, 0.2, 1.0, 5.0, 10.0}, // week 1 + {0.5, 1.0, 3.0, 1.0, 2.0, 2.0, 3.0}, // week 2 + {1.0, 1.0, 2.0, 1.0, 4.0, 4.0, 4.0}, // week 3 + {0.0, 1.0, 0.0, 0.0, 2.0, 2.0, 0.3}, // week 4 + {3.0, 3.0, 6.0, 2.0, 2.0, 1.0, 1.0}}; // week 5 + //! [9] + + // Add labels + //! [10] + m_graph->rowAxis()->setTitle("Week of year"); + m_graph->columnAxis()->setTitle("Day of week"); + m_graph->valueAxis()->setTitle("Hours spent on the Internet"); + m_graph->valueAxis()->setSegmentCount(5); + m_graph->valueAxis()->setLabelFormat("%.1f h"); + //! [10] + + //! [11] + m_tableWidget->setRowCount(5); + m_tableWidget->setColumnCount(7); + m_tableWidget->setHorizontalHeaderLabels(days); + m_tableWidget->setVerticalHeaderLabels(weeks); + m_tableWidget->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + m_tableWidget->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + m_tableWidget->setCurrentCell(-1, -1); + //! [11] + + //! [12] + for (int week = 0; week < weeks.size(); week++) { + for (int day = 0; day < days.size(); day++) { + QModelIndex index = m_tableWidget->model()->index(week, day); + m_tableWidget->model()->setData(index, hours[week][day]); + } + } + //! [12] +} + +void GraphDataGenerator::addRow() +{ + m_tableWidget->model()->insertRow(0); + if (m_tableWidget->model()->rowCount() > m_rowCount) + m_tableWidget->model()->removeRow(m_rowCount); + for (int i = 0; i < m_columnCount; i++) { + QModelIndex index = m_tableWidget->model()->index(0, i); + m_tableWidget->model()->setData(index, + ((qreal)i / (qreal)m_columnCount) / 2.0 + (qreal)(rand() % 30) / 100.0); + } + m_tableWidget->resizeColumnsToContents(); +} + +//! [13] +void GraphDataGenerator::selectFromTable(const QPoint &selection) +{ + m_tableWidget->setFocus(); + m_tableWidget->setCurrentCell(selection.x(), selection.y()); +} +//! [13] + +//! [14] +void GraphDataGenerator::selectedFromTable(int currentRow, int currentColumn, + int previousRow, int previousColumn) +{ + Q_UNUSED(previousRow) + Q_UNUSED(previousColumn) + m_graph->setSelectedBarPos(QPoint(currentRow, currentColumn)); +} +//! [14] + +void GraphDataGenerator::fixTableSize() +{ + int width = m_tableWidget->horizontalHeader()->length(); + width += m_tableWidget->verticalHeader()->width(); + m_tableWidget->setFixedWidth(width + 2); + int height = m_tableWidget->verticalHeader()->length(); + height += m_tableWidget->horizontalHeader()->height(); + m_tableWidget->setFixedHeight(height + 2); +} + +int main(int argc, char **argv) +{ + //! [0] + QApplication app(argc, argv); + Q3DBars *graph = new Q3DBars(); + QWidget *container = QWidget::createWindowContainer(graph); + //! [0] + + QSize screenSize = graph->screen()->size(); + container->setMinimumSize(QSize(screenSize.width() / 2, screenSize.height() / 2)); + container->setMaximumSize(screenSize); + container->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + container->setFocusPolicy(Qt::StrongFocus); + + //! [1] + QWidget widget; + QVBoxLayout *layout = new QVBoxLayout(&widget); + QTableWidget *tableWidget = new QTableWidget(&widget); + layout->addWidget(container, 1); + layout->addWidget(tableWidget, 1, Qt::AlignHCenter); + //! [1] + + tableWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); + tableWidget->setAlternatingRowColors(true); + widget.setWindowTitle(QStringLiteral("Hours spent on the Internet")); + + //! [2] + // Since we are dealing with QTableWidget, the model will already have data sorted properly + // in rows and columns, so create a mapping to utilize this. + QItemModelBarDataMapping *mapping = new QItemModelBarDataMapping; + mapping->setUseModelCategories(true); + QItemModelBarDataProxy *proxy = new QItemModelBarDataProxy(tableWidget->model(), mapping); + graph->setActiveDataProxy(proxy); + //! [2] + + //! [3] + GraphDataGenerator generator(graph, tableWidget); + QObject::connect(graph, &Q3DBars::selectedBarPosChanged, &generator, + &GraphDataGenerator::selectFromTable); + QObject::connect(tableWidget, &QTableWidget::currentCellChanged, &generator, + &GraphDataGenerator::selectedFromTable); + //! [3] + + //! [4] + widget.show(); + generator.start(); + return app.exec(); + //! [4] +} diff --git a/examples/rainfall/data/raindata.txt b/examples/rainfall/data/raindata.txt deleted file mode 100644 index 531d66be..00000000 --- a/examples/rainfall/data/raindata.txt +++ /dev/null @@ -1,158 +0,0 @@ -# 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/rainfall/doc/images/rainfall-example.png b/examples/rainfall/doc/images/rainfall-example.png deleted file mode 100644 index f4087927..00000000 Binary files a/examples/rainfall/doc/images/rainfall-example.png and /dev/null differ diff --git a/examples/rainfall/doc/src/rainfall.qdoc b/examples/rainfall/doc/src/rainfall.qdoc deleted file mode 100644 index cc59b238..00000000 --- a/examples/rainfall/doc/src/rainfall.qdoc +++ /dev/null @@ -1,30 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 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 rainfall - \title Rainfall Example - \ingroup qtdatavisualization_examples - \brief Using Q3DBars with a custom proxy. - - The rainfall example shows how to create a custom proxy to use with Q3DBars. - - \image rainfall-example.png - - TODO -*/ diff --git a/examples/rainfall/main.cpp b/examples/rainfall/main.cpp deleted file mode 100644 index 54ea63e9..00000000 --- a/examples/rainfall/main.cpp +++ /dev/null @@ -1,37 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 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 - -using namespace QtDataVisualization; - -int main(int argc, char **argv) -{ - QGuiApplication app(argc, argv); - - Q3DBars *rainfall = new Q3DBars; - rainfall->resize(1280, 800); - rainfall->setPosition(QPoint(10, 30)); - rainfall->show(); - - RainfallGraph rainfallgraph(rainfall); - rainfallgraph.start(); - - return app.exec(); -} diff --git a/examples/rainfall/rainfall.pro b/examples/rainfall/rainfall.pro deleted file mode 100644 index 0a2e1498..00000000 --- a/examples/rainfall/rainfall.pro +++ /dev/null @@ -1,25 +0,0 @@ -!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 - -INSTALLS += target - -RESOURCES += \ - rainfall.qrc - -OTHER_FILES += data/raindata.txt \ - doc/src/* \ - doc/images/* - diff --git a/examples/rainfall/rainfall.qrc b/examples/rainfall/rainfall.qrc deleted file mode 100644 index 53cd4915..00000000 --- a/examples/rainfall/rainfall.qrc +++ /dev/null @@ -1,5 +0,0 @@ - - - data/raindata.txt - - diff --git a/examples/rainfall/rainfallgraph.cpp b/examples/rainfall/rainfallgraph.cpp deleted file mode 100644 index 41f72464..00000000 --- a/examples/rainfall/rainfallgraph.cpp +++ /dev/null @@ -1,140 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 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 -#include -#include -#include -#include -#include -#include -#include -#include - -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; - m_graph->setActiveDataProxy(m_proxy); - - 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.0); - 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->rowAxis()->setCategoryLabels(m_years); - m_graph->columnAxis()->setCategoryLabels(months); - - // Set bar type to cylinder - m_graph->setBarType(QDataVis::MeshStyleCylinders, false); - - // Set shadows to medium - m_graph->setShadowQuality(QDataVis::ShadowQualityMedium); - - // Set font - m_graph->setFont(QFont("Century Gothic", 30)); - - // Set selection mode to bar and column - m_graph->setSelectionMode(QDataVis::SelectionModeSliceColumn); - - // Set theme - m_graph->setTheme(QDataVis::ThemeArmyBlue); - - // Set preset camera position - m_graph->scene()->activeCamera()->setCameraPreset(QDataVis::CameraPresetIsometricRightHigh); - - // Disable grid - m_graph->setGridVisible(false); - - // 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(); -} - -void RainfallGraph::addDataSet() -{ - m_dataSet = new VariantDataSet; - VariantDataItemList *itemList = new VariantDataItemList; - 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("#")) - continue; - QStringList strList = line.split(",", QString::SkipEmptyParts); - if (strList.size() < 3) { - qWarning() << "Invalid row read from data:" << line; - continue; - } - 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(); - } - - m_dataSet->addItems(itemList); - - m_proxy->setDataSet(m_dataSet); - - m_mapping = new VariantBarDataMapping(0, 1, 2, m_years, m_numericMonths); - m_proxy->setMapping(m_mapping); -} diff --git a/examples/rainfall/rainfallgraph.h b/examples/rainfall/rainfallgraph.h deleted file mode 100644 index 6317ab71..00000000 --- a/examples/rainfall/rainfallgraph.h +++ /dev/null @@ -1,51 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 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 - -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/rainfall/variantbardatamapping.cpp b/examples/rainfall/variantbardatamapping.cpp deleted file mode 100644 index 0c2f146c..00000000 --- a/examples/rainfall/variantbardatamapping.cpp +++ /dev/null @@ -1,133 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 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/rainfall/variantbardatamapping.h b/examples/rainfall/variantbardatamapping.h deleted file mode 100644 index 0204ddc8..00000000 --- a/examples/rainfall/variantbardatamapping.h +++ /dev/null @@ -1,74 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 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 "qdatavisualizationenums.h" -#include - -using namespace QtDataVisualization; - -class VariantBarDataMapping : public QObject -{ - Q_OBJECT - 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) -public: - explicit VariantBarDataMapping(); - VariantBarDataMapping(const VariantBarDataMapping &other); - VariantBarDataMapping(int rowIndex, int columnIndex, int valueIndex, - const QStringList &rowCategories, - const QStringList &columnCategories); - 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; - - void remap(int rowIndex, int columnIndex, int valueIndex, - const QStringList &rowCategories, - const QStringList &columnCategories); -signals: - void mappingChanged(); - -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/rainfall/variantbardataproxy.cpp b/examples/rainfall/variantbardataproxy.cpp deleted file mode 100644 index c907a1e3..00000000 --- a/examples/rainfall/variantbardataproxy.cpp +++ /dev/null @@ -1,136 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 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(); // TODO Resolving entire dataset is inefficient -} - -void VariantBarDataProxy::handleDataCleared() -{ - // Data cleared, reset array - resetArray(0); -} - -void VariantBarDataProxy::handleMappingChanged() -{ - resolveDataSet(); -} - -// Resolve entire dataset into QBarDataArray. -void VariantBarDataProxy::resolveDataSet() -{ - 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 ColumnValueMap; - QHash itemValueMap; - foreach (const VariantDataItem *item, itemList) { - itemValueMap[item->at(rowIndex).toString()][item->at(columnIndex).toString()] - = item->at(valueIndex).toReal(); - } - - // Create new data array from itemValueMap - 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); - } - - resetArray(newProxyArray); -} diff --git a/examples/rainfall/variantbardataproxy.h b/examples/rainfall/variantbardataproxy.h deleted file mode 100644 index b931aa5c..00000000 --- a/examples/rainfall/variantbardataproxy.h +++ /dev/null @@ -1,64 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 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 -#include -#include - -using namespace QtDataVisualization; - -class VariantBarDataProxy : public QBarDataProxy -{ - Q_OBJECT - -public: - explicit VariantBarDataProxy(); - explicit VariantBarDataProxy(VariantDataSet *newSet, VariantBarDataMapping *mapping); - virtual ~VariantBarDataProxy(); - - // 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(); - -public slots: - void handleItemsAdded(int index, int count); - void handleDataCleared(); - void handleMappingChanged(); - -private: - void resolveDataSet(); - - QPointer m_dataSet; - QPointer m_mapping; - - Q_DISABLE_COPY(VariantBarDataProxy) -}; - -#endif diff --git a/examples/rainfall/variantdataset.cpp b/examples/rainfall/variantdataset.cpp deleted file mode 100644 index f73d83f8..00000000 --- a/examples/rainfall/variantdataset.cpp +++ /dev/null @@ -1,63 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 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/rainfall/variantdataset.h b/examples/rainfall/variantdataset.h deleted file mode 100644 index 7906d4f5..00000000 --- a/examples/rainfall/variantdataset.h +++ /dev/null @@ -1,56 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 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 "qdatavisualizationenums.h" -#include -#include - -using namespace QtDataVisualization; - -typedef QVariantList VariantDataItem; -typedef QList VariantDataItemList; - -class VariantDataSet : public QObject -{ - Q_OBJECT - -public: - explicit VariantDataSet(); - ~VariantDataSet(); - - void clear(); - - int addItem(VariantDataItem *item); - int addItems(VariantDataItemList *itemList); - - const VariantDataItemList &itemList() const; - -signals: - void itemsAdded(int index, int count); - void dataCleared(); - -private: - VariantDataItemList m_variantData; - - Q_DISABLE_COPY(VariantDataSet) -}; - -#endif diff --git a/examples/widget/doc/images/widget-example.png b/examples/widget/doc/images/widget-example.png deleted file mode 100644 index c2d4d598..00000000 Binary files a/examples/widget/doc/images/widget-example.png and /dev/null differ diff --git a/examples/widget/doc/src/widget.qdoc b/examples/widget/doc/src/widget.qdoc deleted file mode 100644 index b67386c7..00000000 --- a/examples/widget/doc/src/widget.qdoc +++ /dev/null @@ -1,159 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 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 widget - \title Widget Example - \ingroup qtdatavisualization_examples - \brief Using Q3DBars in a widget application. - - The widget example shows how to make a 3D bar graph using Q3DBars and combining the use of - widgets for adjusting several adjustable qualities. The example shows how to: - - \list - \li Create an application with Q3DBars and some widgets - \li Use QBarDataProxy to set data to the graph - \li Adjust some graph properties using widget controls - \endlist - - It also demonstrates how having negative bar values affects the graph. - - \image widget-example.png - - \section1 Creating the application - - First, in main.cpp, we create a QApplication, instantiate Q3DBars and a window container - for it: - - \snippet ../examples/widget/main.cpp 0 - - The call to QWidget::createWindowContainer is required, as all data visualization types - (Q3DBars, Q3DScatter, Q3DSurface) inherit QWindow. Any class inheriting QWindow cannot be used - as a widget any other way. - - Then we'll create horizontal and vertical layouts. We'll add the graph and the vertical - layout into the horizontal one: - - \snippet ../examples/widget/main.cpp 1 - - We're not using the vertical layout for anything yet, but we'll get back to it in - \l {Using widgets to control the graph} - - Next, let's create another class to handle the data addition and other interaction with the - graph. Let's call it GraphModifier (See \l {Setting up the graph} and - \l {Adding data to the graph} for details): - - \snippet ../examples/widget/main.cpp 2 - - The application main is done and we can show the graph and start the event loop: - - \snippet ../examples/widget/main.cpp 3 - - \section1 Setting up the graph - - Let's set up the graph in the constructor of the GraphModifier class we instantiated in the - application main: - - \snippet ../examples/widget/graphmodifier.cpp 0 - - Let's take a closer look at parts of the code. - - First we're creating the axes and the proxy into member variables to support changing them - easily later on, if we want to: - - \snippet ../examples/widget/graphmodifier.cpp 1 - - Then we're setting some of the visual qualities for the graph: - - \snippet ../examples/widget/graphmodifier.cpp 2 - - We're also setting up the axes and adding them to the graph. Notice that we're not setting them - active yet: - - \snippet ../examples/widget/graphmodifier.cpp 3 - - And add the proxy. Note that we're not setting it active yet, but just adding it: - - \snippet ../examples/widget/graphmodifier.cpp 4 - - That concludes setting up the graph. - - \section1 Adding data to the graph - - At the end of the constructor there's a call: - - \code resetTemperatureData(); \endcode - - The method is used to add data to the proxy: - - \snippet ../examples/widget/graphmodifier.cpp 5 - - Now the data is in the proxy, but not in the graph. We have not set the proxy active yet. - - In application main, we called \c {modifier->start()} after constructing all the necessary - objects. This is what is done in it: - - \snippet ../examples/widget/graphmodifier.cpp 6 - - Finally we set the proxy and the axes active. Now our graph has the data and is ready to be - used. - - \section1 Using widgets to control the graph - - There isn't much interaction yet, so let's continue by adding some widgets back in the - application main. Let's just focus on two: - - \snippet ../examples/widget/main.cpp 4 - - We can use these to rotate the graph using slider widgets instead of just using the mouse or - touch. - - Let's add them to the vertical layout we created earlier: - - \snippet ../examples/widget/main.cpp 5 - - Then we'll connect them to methods in GraphModifier: - - \snippet ../examples/widget/main.cpp 6 - - Here are the methods in GraphModifier the signals were connected to: - - \snippet ../examples/widget/graphmodifier.cpp 7 - - Now these two sliders can be used to rotate the graph. - - And so we have an application in which we can control: - - \list - \li Graph rotation - \li Label style - \li Camera preset - \li Background visibility - \li Grid visibility - \li Bar shading smoothness - \li Bar style - \li Selection mode - \li Theme - \li Shadow quality - \li Font - \li Font size - \endlist - - \section1 Example contents - -*/ diff --git a/examples/widget/graphmodifier.cpp b/examples/widget/graphmodifier.cpp deleted file mode 100644 index 0b33bde0..00000000 --- a/examples/widget/graphmodifier.cpp +++ /dev/null @@ -1,229 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 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 "graphmodifier.h" -#include -#include -#include -#include -#include -#include - -QT_DATAVISUALIZATION_USE_NAMESPACE - -const QString celsiusString = QString(QChar(0xB0)) + "C"; - -//! [0] -GraphModifier::GraphModifier(Q3DBars *bargraph) - : m_graph(bargraph), - m_xRotation(0.0), - m_yRotation(0.0), - m_fontSize(30), - m_segments(4), - m_subSegments(3), - m_minval(-20.0), - m_maxval(20.0), - //! [1] - m_temperatureAxis(new Q3DValueAxis), - m_yearAxis(new Q3DCategoryAxis), - m_monthAxis(new Q3DCategoryAxis), - m_temperatureData(new QBarDataProxy), - //! [1] - m_style(QDataVis::MeshStyleBevelBars), - m_smooth(false) -{ - //! [2] - m_graph->setBackgroundVisible(false); - m_graph->setShadowQuality(QDataVis::ShadowQualitySoftMedium); - m_graph->setFont(QFont("Times New Roman", m_fontSize)); - m_graph->setLabelStyle(QDataVis::LabelStyleFromTheme); - //! [2] - - m_months << "January" << "February" << "March" << "April" << "May" << "June" << "July" << "August" << "September" << "October" << "November" << "December"; - m_years << "2006" << "2007" << "2008" << "2009" << "2010" << "2011" << "2012"; - - //! [3] - m_temperatureAxis->setTitle("Average temperature"); - m_temperatureAxis->setSegmentCount(m_segments); - m_temperatureAxis->setSubSegmentCount(m_subSegments); - m_temperatureAxis->setRange(m_minval, m_maxval); - m_temperatureAxis->setLabelFormat(QString(QStringLiteral("%d ") + celsiusString)); - - m_yearAxis->setTitle("Year"); - m_monthAxis->setTitle("Month"); - - m_graph->addAxis(m_temperatureAxis); - m_graph->addAxis(m_yearAxis); - m_graph->addAxis(m_monthAxis); - //! [3] - - m_temperatureData->setItemLabelFormat(QStringLiteral("@valueTitle for @colLabel @rowLabel: @valueLabel")); - - //! [4] - m_graph->addDataProxy(m_temperatureData); - //! [4] - - resetTemperatureData(); -} -//! [0] - -GraphModifier::~GraphModifier() -{ - delete m_graph; -} - -void GraphModifier::start() -{ - //! [6] - m_graph->setActiveDataProxy(m_temperatureData); - - m_graph->setValueAxis(m_temperatureAxis); - m_graph->setRowAxis(m_yearAxis); - m_graph->setColumnAxis(m_monthAxis); - //! [6] -} - -void GraphModifier::resetTemperatureData() -{ - //! [5] - // Set up data - static const qreal temp[7][12] = { - {-6.7, -11.7, -9.7, 3.3, 9.2, 14.0, 16.3, 17.8, 10.2, 2.1, -2.6, -0.3}, // 2006 - {-6.8, -13.3, 0.2, 1.5, 7.9, 13.4, 16.1, 15.5, 8.2, 5.4, -2.6, -0.8}, // 2007 - {-4.2, -4.0, -4.6, 1.9, 7.3, 12.5, 15.0, 12.8, 7.6, 5.1, -0.9, -1.3}, // 2008 - {-7.8, -8.8, -4.2, 0.7, 9.3, 13.2, 15.8, 15.5, 11.2, 0.6, 0.7, -8.4}, // 2009 - {-14.4, -12.1, -7.0, 2.3, 11.0, 12.6, 18.8, 13.8, 9.4, 3.9, -5.6, -13.0}, // 2010 - {-9.0, -15.2, -3.8, 2.6, 8.3, 15.9, 18.6, 14.9, 11.1, 5.3, 1.8, -0.2}, // 2011 - {-8.7, -11.3, -2.3, 0.4, 7.5, 12.2, 16.4, 14.1, 9.2, 3.1, 0.3, -12.1} // 2012 - }; - - // Create data array - QBarDataArray *dataSet = new QBarDataArray; - QBarDataRow *dataRow; - - dataSet->reserve(m_years.size()); - for (int year = 0; year < m_years.size(); year++) { - // Create a data row - dataRow = new QBarDataRow(m_months.size()); - for (int month = 0; month < m_months.size(); month++) { - // Add data to the row - (*dataRow)[month].setValue(temp[year][month]); - } - // Add the row to the set - dataSet->append(dataRow); - } - - // Add data to the graph (the graph assumes ownership of it) - m_temperatureData->resetArray(dataSet, m_years, m_months); - //! [5] -} - -void GraphModifier::changeStyle(int style) -{ - m_style = QDataVis::MeshStyle(style); - m_graph->setBarType(m_style, m_smooth); -} - -void GraphModifier::changePresetCamera() -{ - static int preset = QDataVis::CameraPresetFrontLow; - - m_graph->scene()->activeCamera()->setCameraPreset((QDataVis::CameraPreset)preset); - - if (++preset > QDataVis::CameraPresetDirectlyBelow) - preset = QDataVis::CameraPresetFrontLow; -} - -void GraphModifier::changeTheme(int theme) -{ - m_graph->setTheme((QDataVis::Theme)theme); -} - -void GraphModifier::changeLabelStyle() -{ - static int style = QDataVis::LabelStyleFromTheme; - - m_graph->setLabelStyle((QDataVis::LabelStyle)style); - - if (++style > QDataVis::LabelStyleTransparent) - style = QDataVis::LabelStyleOpaque; -} - -void GraphModifier::changeSelectionMode(int selectionMode) -{ - m_graph->setSelectionMode((QDataVis::SelectionMode)selectionMode); -} - -void GraphModifier::changeFont(const QFont &font) -{ - QFont newFont = font; - newFont.setPointSize(m_fontSize); - m_graph->setFont(newFont); -} - -void GraphModifier::changeFontSize(int fontsize) -{ - m_fontSize = fontsize; - QFont font = m_graph->font(); - font.setPointSize(m_fontSize); - m_graph->setFont(font); -} - -void GraphModifier::shadowQualityUpdatedByVisual(QDataVis::ShadowQuality sq) -{ - int quality = int(sq); - // Updates the UI component to show correct shadow quality - emit shadowQualityChanged(quality); -} - -void GraphModifier::changeShadowQuality(int quality) -{ - QDataVis::ShadowQuality sq = QDataVis::ShadowQuality(quality); - m_graph->setShadowQuality(sq); - emit shadowQualityChanged(quality); -} - -//! [7] -void GraphModifier::rotateX(int rotation) -{ - m_xRotation = rotation; - m_graph->scene()->activeCamera()->setCameraPosition(m_xRotation, m_yRotation); -} - -void GraphModifier::rotateY(int rotation) -{ - m_yRotation = rotation; - m_graph->scene()->activeCamera()->setCameraPosition(m_xRotation, m_yRotation); -} -//! [7] - -void GraphModifier::setBackgroundEnabled(int enabled) -{ - m_graph->setBackgroundVisible((bool)enabled); -} - -void GraphModifier::setGridEnabled(int enabled) -{ - m_graph->setGridVisible((bool)enabled); -} - -void GraphModifier::setSmoothBars(int smooth) -{ - m_smooth = bool(smooth); - m_graph->setBarType(m_style, m_smooth); -} diff --git a/examples/widget/graphmodifier.h b/examples/widget/graphmodifier.h deleted file mode 100644 index 2e18ffd2..00000000 --- a/examples/widget/graphmodifier.h +++ /dev/null @@ -1,79 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 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 GRAPHMODIFIER_H -#define GRAPHMODIFIER_H - -#include - -#include -#include -#include -#include - -using namespace QtDataVisualization; - -class GraphModifier : public QObject -{ - Q_OBJECT -public: - explicit GraphModifier(Q3DBars *bargraph); - ~GraphModifier(); - - void resetTemperatureData(); - void changePresetCamera(); - void changeLabelStyle(); - void changeFont(const QFont &font); - void changeFontSize(int fontsize); - void rotateX(int rotation); - void rotateY(int rotation); - void setBackgroundEnabled(int enabled); - void setGridEnabled(int enabled); - void setSmoothBars(int smooth); - void start(); - -public slots: - void changeStyle(int style); - void changeSelectionMode(int selectionMode); - void changeTheme(int theme); - void changeShadowQuality(int quality); - void shadowQualityUpdatedByVisual(QDataVis::ShadowQuality shadowQuality); - -signals: - void shadowQualityChanged(int quality); - -private: - Q3DBars *m_graph; - qreal m_xRotation; - qreal m_yRotation; - int m_fontSize; - int m_segments; - int m_subSegments; - qreal m_minval; - qreal m_maxval; - QStringList m_months; - QStringList m_years; - Q3DValueAxis *m_temperatureAxis; - Q3DCategoryAxis *m_yearAxis; - Q3DCategoryAxis *m_monthAxis; - QBarDataProxy *m_temperatureData; - QDataVis::MeshStyle m_style; - bool m_smooth; -}; - -#endif diff --git a/examples/widget/main.cpp b/examples/widget/main.cpp deleted file mode 100644 index 158244b4..00000000 --- a/examples/widget/main.cpp +++ /dev/null @@ -1,211 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 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 "graphmodifier.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -int main(int argc, char **argv) -{ - //! [0] - QApplication app(argc, argv); - Q3DBars *widgetgraph = new Q3DBars(); - QWidget *container = QWidget::createWindowContainer(widgetgraph); - //! [0] - - QSize screenSize = widgetgraph->screen()->size(); - container->setMinimumSize(QSize(screenSize.width() / 2, screenSize.height() / 1.5)); - container->setMaximumSize(screenSize); - container->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); - container->setFocusPolicy(Qt::StrongFocus); - - //! [1] - QWidget *widget = new QWidget; - QHBoxLayout *hLayout = new QHBoxLayout(widget); - QVBoxLayout *vLayout = new QVBoxLayout(); - hLayout->addWidget(container, 1); - hLayout->addLayout(vLayout); - //! [1] - - widget->setWindowTitle(QStringLiteral("Average temperatures in Oulu, Finland (2006-2012)")); - - QComboBox *themeList = new QComboBox(widget); - themeList->addItem(QStringLiteral("Qt")); - themeList->addItem(QStringLiteral("Primary Colors")); - themeList->addItem(QStringLiteral("Digia")); - themeList->addItem(QStringLiteral("Stone Moss")); - themeList->addItem(QStringLiteral("Army Blue")); - themeList->addItem(QStringLiteral("Retro")); - themeList->addItem(QStringLiteral("Ebony")); - themeList->addItem(QStringLiteral("Isabelle")); - themeList->setCurrentIndex(0); - - QPushButton *labelButton = new QPushButton(widget); - labelButton->setText(QStringLiteral("Change label style")); - - QCheckBox *smoothCheckBox = new QCheckBox(widget); - smoothCheckBox->setText(QStringLiteral("Smooth bars")); - smoothCheckBox->setChecked(false); - - QComboBox *barStyleList = new QComboBox(widget); - barStyleList->addItem(QStringLiteral("Bars")); - barStyleList->addItem(QStringLiteral("Pyramids")); - barStyleList->addItem(QStringLiteral("Cones")); - barStyleList->addItem(QStringLiteral("Cylinders")); - barStyleList->addItem(QStringLiteral("Beveled Bars")); - barStyleList->setCurrentIndex(4); - - QPushButton *cameraButton = new QPushButton(widget); - cameraButton->setText(QStringLiteral("Change camera preset")); - - QComboBox *selectionModeList = new QComboBox(widget); - selectionModeList->addItem(QStringLiteral("None")); - selectionModeList->addItem(QStringLiteral("Bar")); - selectionModeList->addItem(QStringLiteral("Bar and Row")); - selectionModeList->addItem(QStringLiteral("Bar and Column")); - selectionModeList->addItem(QStringLiteral("Bar, Row and Column")); - selectionModeList->addItem(QStringLiteral("Slice into Row")); - selectionModeList->addItem(QStringLiteral("Slice into Column")); - selectionModeList->setCurrentIndex(1); - - QCheckBox *backgroundCheckBox = new QCheckBox(widget); - backgroundCheckBox->setText(QStringLiteral("Show background")); - backgroundCheckBox->setChecked(false); - - QCheckBox *gridCheckBox = new QCheckBox(widget); - gridCheckBox->setText(QStringLiteral("Show grid")); - gridCheckBox->setChecked(true); - - //! [4] - QSlider *rotationSliderX = new QSlider(Qt::Horizontal, widget); - rotationSliderX->setTickInterval(30); - rotationSliderX->setTickPosition(QSlider::TicksBelow); - rotationSliderX->setMinimum(-180); - rotationSliderX->setValue(0); - rotationSliderX->setMaximum(180); - QSlider *rotationSliderY = new QSlider(Qt::Horizontal, widget); - rotationSliderY->setTickInterval(15); - rotationSliderY->setTickPosition(QSlider::TicksAbove); - rotationSliderY->setMinimum(-90); - rotationSliderY->setValue(0); - rotationSliderY->setMaximum(90); - //! [4] - - QSlider *fontSizeSlider = new QSlider(Qt::Horizontal, widget); - fontSizeSlider->setTickInterval(10); - fontSizeSlider->setTickPosition(QSlider::TicksBelow); - fontSizeSlider->setMinimum(1); - fontSizeSlider->setValue(30); - fontSizeSlider->setMaximum(100); - - QFontComboBox *fontList = new QFontComboBox(widget); - fontList->setCurrentFont(QFont("Times New Roman")); - - QComboBox *shadowQuality = new QComboBox(widget); - shadowQuality->addItem(QStringLiteral("None")); - shadowQuality->addItem(QStringLiteral("Low")); - shadowQuality->addItem(QStringLiteral("Medium")); - shadowQuality->addItem(QStringLiteral("High")); - shadowQuality->addItem(QStringLiteral("Low Soft")); - shadowQuality->addItem(QStringLiteral("Medium Soft")); - shadowQuality->addItem(QStringLiteral("High Soft")); - shadowQuality->setCurrentIndex(5); - - //! [5] - vLayout->addWidget(new QLabel(QStringLiteral("Rotate horizontally"))); - vLayout->addWidget(rotationSliderX, 0, Qt::AlignTop); - vLayout->addWidget(new QLabel(QStringLiteral("Rotate vertically"))); - vLayout->addWidget(rotationSliderY, 0, Qt::AlignTop); - //! [5] - vLayout->addWidget(labelButton, 0, Qt::AlignTop); - vLayout->addWidget(cameraButton, 0, Qt::AlignTop); - vLayout->addWidget(backgroundCheckBox); - vLayout->addWidget(gridCheckBox); - vLayout->addWidget(smoothCheckBox, 0, Qt::AlignTop); - vLayout->addWidget(new QLabel(QStringLiteral("Change bar style"))); - vLayout->addWidget(barStyleList); - vLayout->addWidget(new QLabel(QStringLiteral("Change selection mode"))); - vLayout->addWidget(selectionModeList); - vLayout->addWidget(new QLabel(QStringLiteral("Change theme"))); - vLayout->addWidget(themeList); - vLayout->addWidget(new QLabel(QStringLiteral("Adjust shadow quality"))); - vLayout->addWidget(shadowQuality); - vLayout->addWidget(new QLabel(QStringLiteral("Change font"))); - vLayout->addWidget(fontList); - vLayout->addWidget(new QLabel(QStringLiteral("Adjust font size"))); - vLayout->addWidget(fontSizeSlider, 1, Qt::AlignTop); - - //! [2] - GraphModifier *modifier = new GraphModifier(widgetgraph); - //! [2] - - //! [6] - QObject::connect(rotationSliderX, &QSlider::valueChanged, modifier, &GraphModifier::rotateX); - QObject::connect(rotationSliderY, &QSlider::valueChanged, modifier, &GraphModifier::rotateY); - //! [6] - - QObject::connect(labelButton, &QPushButton::clicked, modifier, - &GraphModifier::changeLabelStyle); - QObject::connect(cameraButton, &QPushButton::clicked, modifier, - &GraphModifier::changePresetCamera); - - QObject::connect(backgroundCheckBox, &QCheckBox::stateChanged, modifier, - &GraphModifier::setBackgroundEnabled); - QObject::connect(gridCheckBox, &QCheckBox::stateChanged, modifier, - &GraphModifier::setGridEnabled); - QObject::connect(smoothCheckBox, &QCheckBox::stateChanged, modifier, - &GraphModifier::setSmoothBars); - - QObject::connect(barStyleList, SIGNAL(currentIndexChanged(int)), modifier, - SLOT(changeStyle(int))); - - QObject::connect(selectionModeList, SIGNAL(currentIndexChanged(int)), modifier, - SLOT(changeSelectionMode(int))); - - QObject::connect(themeList, SIGNAL(currentIndexChanged(int)), modifier, - SLOT(changeTheme(int))); - - QObject::connect(shadowQuality, SIGNAL(currentIndexChanged(int)), modifier, - SLOT(changeShadowQuality(int))); - - QObject::connect(modifier, &GraphModifier::shadowQualityChanged, shadowQuality, - &QComboBox::setCurrentIndex); - QObject::connect(widgetgraph, &Q3DBars::shadowQualityChanged, modifier, - &GraphModifier::shadowQualityUpdatedByVisual); - - QObject::connect(fontSizeSlider, &QSlider::valueChanged, modifier, - &GraphModifier::changeFontSize); - QObject::connect(fontList, &QFontComboBox::currentFontChanged, modifier, - &GraphModifier::changeFont); - - //! [3] - widget->show(); - modifier->start(); - return app.exec(); - //! [3] -} diff --git a/examples/widget/widget.pro b/examples/widget/widget.pro deleted file mode 100644 index c9feb187..00000000 --- a/examples/widget/widget.pro +++ /dev/null @@ -1,14 +0,0 @@ -!include( ../examples.pri ) { - error( "Couldn't find the examples.pri file!" ) -} - -SOURCES += main.cpp graphmodifier.cpp -HEADERS += graphmodifier.h - -QT += widgets - -INSTALLS += target - -OTHER_FILES += doc/src/* \ - doc/images/* - -- cgit v1.2.3