Bars Example▲
Sélectionnez
/**
**************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Data Visualization module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:GPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 or (at your option) any later version
** approved by the KDE Free Qt Foundation. The licenses are as published by
** the Free Software Foundation and appearing in the file LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
***************************************************************************
*/
#include
"graphmodifier.h"
#include <QtDataVisualization/qcategory3daxis.h>
#include <QtDataVisualization/qvalue3daxis.h>
#include <QtDataVisualization/qbardataproxy.h>
#include <QtDataVisualization/q3dscene.h>
#include <QtDataVisualization/q3dcamera.h>
#include <QtDataVisualization/qbar3dseries.h>
#include <QtDataVisualization/q3dtheme.h>
#include <QtCore/QTime>
#include <QtWidgets/QComboBox>
#include <QtCore/qmath.h>
using
namespace
QtDataVisualization;
const
QString celsiusString =
QString(QChar(0xB0
)) +
"C"
;
GraphModifier::
GraphModifier(Q3DBars *
bargraph)
:
m_graph(bargraph),
m_xRotation(0.0
f),
m_yRotation(0.0
f),
m_fontSize(30
),
m_segments(4
),
m_subSegments(3
),
m_minval(-
20.0
f),
m_maxval(20.0
f),
m_temperatureAxis(new
QValue3DAxis),
m_yearAxis(new
QCategory3DAxis),
m_monthAxis(new
QCategory3DAxis),
m_primarySeries(new
QBar3DSeries),
m_secondarySeries(new
QBar3DSeries),
m_barMesh(QAbstract3DSeries::
MeshBevelBar),
m_smooth(false
)
{
m_graph-&
gt;setShadowQuality(QAbstract3DGraph::
ShadowQualitySoftMedium);
m_graph-&
gt;activeTheme()-&
gt;setBackgroundEnabled(false
);
m_graph-&
gt;activeTheme()-&
gt;setFont(QFont("Times New Roman"
, m_fontSize));
m_graph-&
gt;activeTheme()-&
gt;setLabelBackgroundEnabled(true
);
m_graph-&
gt;setMultiSeriesUniform(true
);
m_months &
lt;&
lt; "January"
&
lt;&
lt; "February"
&
lt;&
lt; "March"
&
lt;&
lt; "April"
&
lt;&
lt; "May"
&
lt;&
lt; "June"
&
lt;&
lt; "July"
&
lt;&
lt; "August"
&
lt;&
lt; "September"
&
lt;&
lt; "October"
&
lt;&
lt; "November"
&
lt;&
lt; "December"
;
m_years &
lt;&
lt; "2006"
&
lt;&
lt; "2007"
&
lt;&
lt; "2008"
&
lt;&
lt; "2009"
&
lt;&
lt; "2010"
&
lt;&
lt; "2011"
&
lt;&
lt; "2012"
&
lt;&
lt; "2013"
;
m_temperatureAxis-&
gt;setTitle("Average temperature"
);
m_temperatureAxis-&
gt;setSegmentCount(m_segments);
m_temperatureAxis-&
gt;setSubSegmentCount(m_subSegments);
m_temperatureAxis-&
gt;setRange(m_minval, m_maxval);
m_temperatureAxis-&
gt;setLabelFormat(QString(QStringLiteral("%.1f "
) +
celsiusString));
m_temperatureAxis-&
gt;setLabelAutoRotation(30.0
f);
m_temperatureAxis-&
gt;setTitleVisible(true
);
m_yearAxis-&
gt;setTitle("Year"
);
m_yearAxis-&
gt;setLabelAutoRotation(30.0
f);
m_yearAxis-&
gt;setTitleVisible(true
);
m_monthAxis-&
gt;setTitle("Month"
);
m_monthAxis-&
gt;setLabelAutoRotation(30.0
f);
m_monthAxis-&
gt;setTitleVisible(true
);
m_graph-&
gt;setValueAxis(m_temperatureAxis);
m_graph-&
gt;setRowAxis(m_yearAxis);
m_graph-&
gt;setColumnAxis(m_monthAxis);
m_primarySeries-&
gt;setItemLabelFormat(QStringLiteral("Oulu - @colLabel @rowLabel: @valueLabel"
));
m_primarySeries-&
gt;setMesh(QAbstract3DSeries::
MeshBevelBar);
m_primarySeries-&
gt;setMeshSmooth(false
);
m_secondarySeries-&
gt;setItemLabelFormat(QStringLiteral("Helsinki - @colLabel @rowLabel: @valueLabel"
));
m_secondarySeries-&
gt;setMesh(QAbstract3DSeries::
MeshBevelBar);
m_secondarySeries-&
gt;setMeshSmooth(false
);
m_secondarySeries-&
gt;setVisible(false
);
m_graph-&
gt;addSeries(m_primarySeries);
m_graph-&
gt;addSeries(m_secondarySeries);
changePresetCamera();
resetTemperatureData();
// Set up property animations for zooming to the selected bar
Q3DCamera *
camera =
m_graph-&
gt;scene()-&
gt;activeCamera();
m_defaultAngleX =
camera-&
gt;xRotation();
m_defaultAngleY =
camera-&
gt;yRotation();
m_defaultZoom =
camera-&
gt;zoomLevel();
m_defaultTarget =
camera-&
gt;target();
m_animationCameraX.setTargetObject(camera);
m_animationCameraY.setTargetObject(camera);
m_animationCameraZoom.setTargetObject(camera);
m_animationCameraTarget.setTargetObject(camera);
m_animationCameraX.setPropertyName("xRotation"
);
m_animationCameraY.setPropertyName("yRotation"
);
m_animationCameraZoom.setPropertyName("zoomLevel"
);
m_animationCameraTarget.setPropertyName("target"
);
int
duration =
1700
;
m_animationCameraX.setDuration(duration);
m_animationCameraY.setDuration(duration);
m_animationCameraZoom.setDuration(duration);
m_animationCameraTarget.setDuration(duration);
// The zoom always first zooms out above the graph and then zooms in
qreal zoomOutFraction =
0.3
;
m_animationCameraX.setKeyValueAt(zoomOutFraction, QVariant::
fromValue(0.0
f));
m_animationCameraY.setKeyValueAt(zoomOutFraction, QVariant::
fromValue(90.0
f));
m_animationCameraZoom.setKeyValueAt(zoomOutFraction, QVariant::
fromValue(50.0
f));
m_animationCameraTarget.setKeyValueAt(zoomOutFraction,
QVariant::
fromValue(QVector3D(0.0
f, 0.0
f, 0.0
f)));
}
GraphModifier::
~
GraphModifier()
{
delete
m_graph;
}
void
GraphModifier::
resetTemperatureData()
{
// Set up data
static
const
float
tempOulu[8
][12
] =
{
{-
6.7
f, -
11.7
f, -
9.7
f, 3.3
f, 9.2
f, 14.0
f, 16.3
f, 17.8
f, 10.2
f, 2.1
f, -
2.6
f, -
0.3
f}
, // 2006
{-
6.8
f, -
13.3
f, 0.2
f, 1.5
f, 7.9
f, 13.4
f, 16.1
f, 15.5
f, 8.2
f, 5.4
f, -
2.6
f, -
0.8
f}
, // 2007
{-
4.2
f, -
4.0
f, -
4.6
f, 1.9
f, 7.3
f, 12.5
f, 15.0
f, 12.8
f, 7.6
f, 5.1
f, -
0.9
f, -
1.3
f}
, // 2008
{-
7.8
f, -
8.8
f, -
4.2
f, 0.7
f, 9.3
f, 13.2
f, 15.8
f, 15.5
f, 11.2
f, 0.6
f, 0.7
f, -
8.4
f}
, // 2009
{-
14.4
f, -
12.1
f, -
7.0
f, 2.3
f, 11.0
f, 12.6
f, 18.8
f, 13.8
f, 9.4
f, 3.9
f, -
5.6
f, -
13.0
f}
, // 2010
{-
9.0
f, -
15.2
f, -
3.8
f, 2.6
f, 8.3
f, 15.9
f, 18.6
f, 14.9
f, 11.1
f, 5.3
f, 1.8
f, -
0.2
f}
, // 2011
{-
8.7
f, -
11.3
f, -
2.3
f, 0.4
f, 7.5
f, 12.2
f, 16.4
f, 14.1
f, 9.2
f, 3.1
f, 0.3
f, -
12.1
f}
, // 2012
{-
7.9
f, -
5.3
f, -
9.1
f, 0.8
f, 11.6
f, 16.6
f, 15.9
f, 15.5
f, 11.2
f, 4.0
f, 0.1
f, -
1.9
f}
// 2013
}
;
static
const
float
tempHelsinki[8
][12
] =
{
{-
3.7
f, -
7.8
f, -
5.4
f, 3.4
f, 10.7
f, 15.4
f, 18.6
f, 18.7
f, 14.3
f, 8.5
f, 2.9
f, 4.1
f}
, // 2006
{-
1.2
f, -
7.5
f, 3.1
f, 5.5
f, 10.3
f, 15.9
f, 17.4
f, 17.9
f, 11.2
f, 7.3
f, 1.1
f, 0.5
f}
, // 2007
{-
0.6
f, 1.2
f, 0.2
f, 6.3
f, 10.2
f, 13.8
f, 18.1
f, 15.1
f, 10.1
f, 9.4
f, 2.5
f, 0.4
f}
, // 2008
{-
2.9
f, -
3.5
f, -
0.9
f, 4.7
f, 10.9
f, 14.0
f, 17.4
f, 16.8
f, 13.2
f, 4.1
f, 2.6
f, -
2.3
f}
, // 2009
{-
10.2
f, -
8.0
f, -
1.9
f, 6.6
f, 11.3
f, 14.5
f, 21.0
f, 18.8
f, 12.6
f, 6.1
f, -
0.5
f, -
7.3
f}
, // 2010
{-
4.4
f, -
9.1
f, -
2.0
f, 5.5
f, 9.9
f, 15.6
f, 20.8
f, 17.8
f, 13.4
f, 8.9
f, 3.6
f, 1.5
f}
, // 2011
{-
3.5
f, -
3.2
f, -
0.7
f, 4.0
f, 11.1
f, 13.4
f, 17.3
f, 15.8
f, 13.1
f, 6.4
f, 4.1
f, -
5.1
f}
, // 2012
{-
4.8
f, -
1.8
f, -
5.0
f, 2.9
f, 12.8
f, 17.2
f, 18.0
f, 17.1
f, 12.5
f, 7.5
f, 4.5
f, 2.3
f}
// 2013
}
;
// Create data arrays
QBarDataArray *
dataSet =
new
QBarDataArray;
QBarDataArray *
dataSet2 =
new
QBarDataArray;
QBarDataRow *
dataRow;
QBarDataRow *
dataRow2;
dataSet-&
gt;reserve(m_years.size());
for
(int
year =
0
; year &
lt; m_years.size(); year++
) {
// Create a data row
dataRow =
new
QBarDataRow(m_months.size());
dataRow2 =
new
QBarDataRow(m_months.size());
for
(int
month =
0
; month &
lt; m_months.size(); month++
) {
// Add data to the row
(*
dataRow)[month].setValue(tempOulu[year][month]);
(*
dataRow2)[month].setValue(tempHelsinki[year][month]);
}
// Add the row to the set
dataSet-&
gt;append(dataRow);
dataSet2-&
gt;append(dataRow2);
}
// Add data to the data proxy (the data proxy assumes ownership of it)
m_primarySeries-&
gt;dataProxy()-&
gt;resetArray(dataSet, m_years, m_months);
m_secondarySeries-&
gt;dataProxy()-&
gt;resetArray(dataSet2, m_years, m_months);
}
void
GraphModifier::
changeRange(int
range)
{
if
(range &
gt;=
m_years.count())
m_yearAxis-&
gt;setRange(0
, m_years.count() -
1
);
else
m_yearAxis-&
gt;setRange(range, range);
}
void
GraphModifier::
changeStyle(int
style)
{
QComboBox *
comboBox =
qobject_cast&
lt;QComboBox *&
gt;(sender());
if
(comboBox) {
m_barMesh =
QAbstract3DSeries::
Mesh(comboBox-&
gt;itemData(style).toInt());
m_primarySeries-&
gt;setMesh(m_barMesh);
m_secondarySeries-&
gt;setMesh(m_barMesh);
}
}
void
GraphModifier::
changePresetCamera()
{
m_animationCameraX.stop();
m_animationCameraY.stop();
m_animationCameraZoom.stop();
m_animationCameraTarget.stop();
// Restore camera target in case animation has changed it
m_graph-&
gt;scene()-&
gt;activeCamera()-&
gt;setTarget(QVector3D(0.0
f, 0.0
f, 0.0
f));
static
int
preset =
Q3DCamera::
CameraPresetFront;
m_graph-&
gt;scene()-&
gt;activeCamera()-&
gt;setCameraPreset((Q3DCamera::
CameraPreset)preset);
if
(++
preset &
gt; Q3DCamera::
CameraPresetDirectlyBelow)
preset =
Q3DCamera::
CameraPresetFrontLow;
}
void
GraphModifier::
changeTheme(int
theme)
{
Q3DTheme *
currentTheme =
m_graph-&
gt;activeTheme();
currentTheme-&
gt;setType(Q3DTheme::
Theme(theme));
emit backgroundEnabledChanged(currentTheme-&
gt;isBackgroundEnabled());
emit gridEnabledChanged(currentTheme-&
gt;isGridEnabled());
emit fontChanged(currentTheme-&
gt;font());
emit fontSizeChanged(currentTheme-&
gt;font().pointSize());
}
void
GraphModifier::
changeLabelBackground()
{
m_graph-&
gt;activeTheme()-&
gt;setLabelBackgroundEnabled(!
m_graph-&
gt;activeTheme()-&
gt;isLabelBackgroundEnabled());
}
void
GraphModifier::
changeSelectionMode(int
selectionMode)
{
QComboBox *
comboBox =
qobject_cast&
lt;QComboBox *&
gt;(sender());
if
(comboBox) {
int
flags =
comboBox-&
gt;itemData(selectionMode).toInt();
m_graph-&
gt;setSelectionMode(QAbstract3DGraph::
SelectionFlags(flags));
}
}
void
GraphModifier::
changeFont(const
QFont &
amp;font)
{
QFont newFont =
font;
m_graph-&
gt;activeTheme()-&
gt;setFont(newFont);
}
void
GraphModifier::
changeFontSize(int
fontsize)
{
m_fontSize =
fontsize;
QFont font =
m_graph-&
gt;activeTheme()-&
gt;font();
font.setPointSize(m_fontSize);
m_graph-&
gt;activeTheme()-&
gt;setFont(font);
}
void
GraphModifier::
shadowQualityUpdatedByVisual(QAbstract3DGraph::
ShadowQuality sq)
{
int
quality =
int
(sq);
// Updates the UI component to show correct shadow quality
emit shadowQualityChanged(quality);
}
void
GraphModifier::
changeLabelRotation(int
rotation)
{
m_temperatureAxis-&
gt;setLabelAutoRotation(float
(rotation));
m_monthAxis-&
gt;setLabelAutoRotation(float
(rotation));
m_yearAxis-&
gt;setLabelAutoRotation(float
(rotation));
}
void
GraphModifier::
setAxisTitleVisibility(bool
enabled)
{
m_temperatureAxis-&
gt;setTitleVisible(enabled);
m_monthAxis-&
gt;setTitleVisible(enabled);
m_yearAxis-&
gt;setTitleVisible(enabled);
}
void
GraphModifier::
setAxisTitleFixed(bool
enabled)
{
m_temperatureAxis-&
gt;setTitleFixed(enabled);
m_monthAxis-&
gt;setTitleFixed(enabled);
m_yearAxis-&
gt;setTitleFixed(enabled);
}
void
GraphModifier::
zoomToSelectedBar()
{
m_animationCameraX.stop();
m_animationCameraY.stop();
m_animationCameraZoom.stop();
m_animationCameraTarget.stop();
Q3DCamera *
camera =
m_graph-&
gt;scene()-&
gt;activeCamera();
float
currentX =
camera-&
gt;xRotation();
float
currentY =
camera-&
gt;yRotation();
float
currentZoom =
camera-&
gt;zoomLevel();
QVector3D currentTarget =
camera-&
gt;target();
m_animationCameraX.setStartValue(QVariant::
fromValue(currentX));
m_animationCameraY.setStartValue(QVariant::
fromValue(currentY));
m_animationCameraZoom.setStartValue(QVariant::
fromValue(currentZoom));
m_animationCameraTarget.setStartValue(QVariant::
fromValue(currentTarget));
QPoint selectedBar =
m_graph-&
gt;selectedSeries()
? m_graph-&
gt;selectedSeries()-&
gt;selectedBar()
:
QBar3DSeries::
invalidSelectionPosition();
if
(selectedBar !=
QBar3DSeries::
invalidSelectionPosition()) {
// Normalize selected bar position within axis range to determine target coordinates
QVector3D endTarget;
float
xMin =
m_graph-&
gt;columnAxis()-&
gt;min();
float
xRange =
m_graph-&
gt;columnAxis()-&
gt;max() -
xMin;
float
zMin =
m_graph-&
gt;rowAxis()-&
gt;min();
float
zRange =
m_graph-&
gt;rowAxis()-&
gt;max() -
zMin;
endTarget.setX((selectedBar.y() -
xMin) /
xRange *
2.0
f -
1.0
f);
endTarget.setZ((selectedBar.x() -
zMin) /
zRange *
2.0
f -
1.0
f);
// Rotate the camera so that it always points approximately to the graph center
qreal endAngleX =
90.0
-
qRadiansToDegrees(qAtan(qreal(endTarget.z() /
endTarget.x())));
if
(endTarget.x() &
gt; 0.0
f)
endAngleX -=
180.0
f;
float
barValue =
m_graph-&
gt;selectedSeries()-&
gt;dataProxy()-&
gt;itemAt(selectedBar.x(),
selectedBar.y())-&
gt;value();
float
endAngleY =
barValue &
gt;=
0.0
f ? 30.0
f : -
30.0
f;
if
(m_graph-&
gt;valueAxis()-&
gt;reversed())
endAngleY *=
-
1.0
f;
m_animationCameraX.setEndValue(QVariant::
fromValue(float
(endAngleX)));
m_animationCameraY.setEndValue(QVariant::
fromValue(endAngleY));
m_animationCameraZoom.setEndValue(QVariant::
fromValue(250
));
m_animationCameraTarget.setEndValue(QVariant::
fromValue(endTarget));
}
else
{
// No selected bar, so return to the default view
m_animationCameraX.setEndValue(QVariant::
fromValue(m_defaultAngleX));
m_animationCameraY.setEndValue(QVariant::
fromValue(m_defaultAngleY));
m_animationCameraZoom.setEndValue(QVariant::
fromValue(m_defaultZoom));
m_animationCameraTarget.setEndValue(QVariant::
fromValue(m_defaultTarget));
}
m_animationCameraX.start();
m_animationCameraY.start();
m_animationCameraZoom.start();
m_animationCameraTarget.start();
}
void
GraphModifier::
changeShadowQuality(int
quality)
{
QAbstract3DGraph::
ShadowQuality sq =
QAbstract3DGraph::
ShadowQuality(quality);
m_graph-&
gt;setShadowQuality(sq);
emit shadowQualityChanged(quality);
}
void
GraphModifier::
rotateX(int
rotation)
{
m_xRotation =
rotation;
m_graph-&
gt;scene()-&
gt;activeCamera()-&
gt;setCameraPosition(m_xRotation, m_yRotation);
}
void
GraphModifier::
rotateY(int
rotation)
{
m_yRotation =
rotation;
m_graph-&
gt;scene()-&
gt;activeCamera()-&
gt;setCameraPosition(m_xRotation, m_yRotation);
}
void
GraphModifier::
setBackgroundEnabled(int
enabled)
{
m_graph-&
gt;activeTheme()-&
gt;setBackgroundEnabled(bool
(enabled));
}
void
GraphModifier::
setGridEnabled(int
enabled)
{
m_graph-&
gt;activeTheme()-&
gt;setGridEnabled(bool
(enabled));
}
void
GraphModifier::
setSmoothBars(int
smooth)
{
m_smooth =
bool
(smooth);
m_primarySeries-&
gt;setMeshSmooth(m_smooth);
m_secondarySeries-&
gt;setMeshSmooth(m_smooth);
}
void
GraphModifier::
setSeriesVisibility(int
enabled)
{
m_secondarySeries-&
gt;setVisible(bool
(enabled));
}
void
GraphModifier::
setReverseValueAxis(int
enabled)
{
m_graph-&
gt;valueAxis()-&
gt;setReversed(enabled);
}
void
GraphModifier::
setReflection(bool
enabled)
{
m_graph-&
gt;setReflection(enabled);
}