summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--examples/barchart/main.cpp6
-rw-r--r--examples/mapdata/mapdata.cpp12
-rw-r--r--examples/qmlbarchart/qml/qmlbarchart/main.qml2
-rw-r--r--examples/rainfall/rainfallchart.cpp4
-rw-r--r--examples/spectrum/spectrumapp/main.cpp6
-rw-r--r--examples/widget/chart.cpp27
-rw-r--r--examples/widget/chart.h5
-rw-r--r--examples/widget/main.cpp23
-rw-r--r--src/datavis3d/doc/images/q3dbars-minimal.pngbin7688 -> 8611 bytes
-rw-r--r--src/datavis3d/doc/snippets/doc_src_q3dbars_construction.cpp12
-rw-r--r--src/datavis3d/engine/bars3dcontroller.cpp25
-rw-r--r--src/datavis3d/engine/bars3dcontroller_p.h10
-rw-r--r--src/datavis3d/engine/bars3drenderer.cpp13
-rw-r--r--src/datavis3d/engine/bars3drenderer_p.h2
-rw-r--r--src/datavis3d/engine/q3dbars.cpp187
-rw-r--r--src/datavis3d/engine/q3dbars.h34
-rw-r--r--src/datavis3d/engine/q3dwindow.cpp8
-rw-r--r--src/datavis3dqml2/declarativebars.cpp18
-rw-r--r--src/datavis3dqml2/declarativebars_p.h8
19 files changed, 178 insertions, 224 deletions
diff --git a/examples/barchart/main.cpp b/examples/barchart/main.cpp
index d5d138e4..040c92eb 100644
--- a/examples/barchart/main.cpp
+++ b/examples/barchart/main.cpp
@@ -72,11 +72,11 @@ ChartDataGenerator::ChartDataGenerator(Q3DBars *barchart, QTableWidget *tableWid
{
// Set up bar specifications; make the bars as wide as they are deep,
// and add a small space between the bars
- m_chart->setBarSpecs(QSizeF(1.0f, 1.0f), QSizeF(0.2f, 0.2f), true);
+ m_chart->setBarSpecs(1.0, QSizeF(0.2f, 0.2f));
#ifndef USE_STATIC_DATA
// Set up sample space; make it as deep as it's wide
- m_chart->setupSampleSpace(m_rowCount, m_columnCount);
+ m_chart->setDataWindow(m_rowCount, m_columnCount);
m_tableWidget->setColumnCount(m_columnCount);
#endif
@@ -204,7 +204,7 @@ void ChartDataGenerator::setupModel()
}
// Set up sample space based on prepared data
- m_chart->setupSampleSpace(weeks.size(), days.size());
+ m_chart->setDataWindow(weeks.size(), days.size());
}
void ChartDataGenerator::addRow()
diff --git a/examples/mapdata/mapdata.cpp b/examples/mapdata/mapdata.cpp
index 6f0157da..cf94c5da 100644
--- a/examples/mapdata/mapdata.cpp
+++ b/examples/mapdata/mapdata.cpp
@@ -354,15 +354,3 @@ void MapsModifier::changeShadowQuality(int quality)
// m_yRotation = rotation;
// m_chart->setCameraPosition(m_xRotation, m_yRotation);
//}
-
-//void MapsModifier::setSpecsX(int barwidth)
-//{
-// m_barWidth = (float)barwidth / 100.0f;
-// m_chart->setBarSpecs(QSizeF(m_barWidth, m_barDepth), QSizeF(m_barSpacingX, m_barSpacingZ));
-//}
-
-//void MapsModifier::setSpecsZ(int bardepth)
-//{
-// m_barDepth = (float)bardepth / 100.0f;
-// m_chart->setBarSpecs(QSizeF(m_barWidth, m_barDepth), QSizeF(m_barSpacingX, m_barSpacingZ));
-//}
diff --git a/examples/qmlbarchart/qml/qmlbarchart/main.qml b/examples/qmlbarchart/qml/qmlbarchart/main.qml
index d23113db..67d9aad0 100644
--- a/examples/qmlbarchart/qml/qmlbarchart/main.qml
+++ b/examples/qmlbarchart/qml/qmlbarchart/main.qml
@@ -117,7 +117,7 @@ Item {
rows: 5
columns: 12
mapping: valueMapping
- barThickness: Qt.size(0.5, 1.0)
+ barThickness: 0.5
barSpacing: Qt.size(0.5, 0.5)
barSpacingRelative: false
barType: Bars3D.BevelBars
diff --git a/examples/rainfall/rainfallchart.cpp b/examples/rainfall/rainfallchart.cpp
index 8d7e0157..cf517da6 100644
--- a/examples/rainfall/rainfallchart.cpp
+++ b/examples/rainfall/rainfallchart.cpp
@@ -47,7 +47,7 @@ RainfallChart::RainfallChart(Q3DBars *rainfall)
// Set up bar specifications; make the bars as wide as they are deep,
// and add a small space between the bars
- m_chart->setBarSpecs(QSizeF(1.0f, 1.0f), QSizeF(0.2f, 0.2f), true);
+ m_chart->setBarSpecs(1.0, QSizeF(0.2f, 0.2f), true);
// Set axis labels and titles
QStringList months;
@@ -120,7 +120,7 @@ void RainfallChart::updateYearsList(int start, int end)
m_rowCount = m_years.size();
// Set up sample space; make it match actual resolved data size
- m_chart->setupSampleSpace(m_rowCount, m_columnCount);
+ m_chart->setDataWindow(m_rowCount, m_columnCount);
}
void RainfallChart::addDataSet()
diff --git a/examples/spectrum/spectrumapp/main.cpp b/examples/spectrum/spectrumapp/main.cpp
index d0333e75..2e65180b 100644
--- a/examples/spectrum/spectrumapp/main.cpp
+++ b/examples/spectrum/spectrumapp/main.cpp
@@ -66,7 +66,7 @@ MainApp::MainApp(Q3DBars *window)
m_lowFreq(SpectrumLowFreq),
m_highFreq(SpectrumHighFreq)
{
- m_chart->setupSampleSpace(SpectrumNumBands * 2, SpectrumNumBands);
+ m_chart->setDataWindow(SpectrumNumBands * 2, SpectrumNumBands);
// Disable grid
m_chart->setGridVisible(false);
// Disable auto-scaling of height by defining explicit range
@@ -78,7 +78,7 @@ MainApp::MainApp(Q3DBars *window)
#if USE_CONES
// Set bar specifications; make them a bit wider than deep and make them be drawn 75%
// inside each other
- m_chart->setBarSpecs(QSizeF(1.0f, 0.75f), QSizeF(0.2f, -0.75f));
+ m_chart->setBarSpecs(1.25), QSizeF(0.2f, -0.75f));
// Set bar type, smooth cones
m_chart->setBarType(QDataVis::Cones, true);
// Adjust zoom manually; automatic zoom level calculation does not work well with negative
@@ -86,7 +86,7 @@ MainApp::MainApp(Q3DBars *window)
m_chart->setCameraPosition(10.0f, 5.0f, 70);
#else
// Set bar specifications; make them twice as wide as they're deep
- m_chart->setBarSpecs(QSizeF(1.0f, 0.5f), QSizeF(0.0f, 0.0f));
+ m_chart->setBarSpecs(2.0, QSizeF(0.0f, 0.0f));
// Set bar type, flat bars
m_chart->setBarType(QDataVis::Bars, false);
// Adjust camera position
diff --git a/examples/widget/chart.cpp b/examples/widget/chart.cpp
index 637c140e..558ea755 100644
--- a/examples/widget/chart.cpp
+++ b/examples/widget/chart.cpp
@@ -33,8 +33,7 @@ ChartModifier::ChartModifier(Q3DBars *barchart)
m_xRotation(0.0f),
m_yRotation(0.0f),
m_static(true),
- m_barWidth(1.0f),
- m_barDepth(1.0f),
+ m_barThicknessRatio(1.0),
m_barSpacingX(0.1f),
m_barSpacingZ(0.1f),
m_fontSize(20),
@@ -82,7 +81,7 @@ void ChartModifier::restart(bool dynamicData)
} else {
m_chart->dataProxy()->resetArray(0);
// Set up sample space
- m_chart->setupSampleSpace(m_rowCount, m_columnCount);
+ m_chart->setDataWindow(m_rowCount, m_columnCount);
// Set selection mode to full
m_chart->setSelectionMode(QDataVis::ModeItemRowAndColumn);
m_chart->valueAxis()->setSegmentCount(m_segments * 2);
@@ -157,7 +156,7 @@ void ChartModifier::addDataSet()
}
// Set up sample space based on prepared data
- m_chart->setupSampleSpace(years.size(), months.size());
+ m_chart->setDataWindow(years.size(), months.size());
// Add data to chart (chart assumes ownership)
proxy->resetArray(dataSet);
@@ -401,34 +400,28 @@ void ChartModifier::rotateY(int rotation)
m_chart->setCameraPosition(m_xRotation, m_yRotation);
}
-void ChartModifier::setSpecsX(int barwidth)
+void ChartModifier::setSpecsRatio(int barwidth)
{
- m_barWidth = (float)barwidth / 100.0f;
- m_chart->setBarSpecs(QSizeF(m_barWidth, m_barDepth), QSizeF(m_barSpacingX, m_barSpacingZ));
-}
-
-void ChartModifier::setSpecsZ(int bardepth)
-{
- m_barDepth = (float)bardepth / 100.0f;
- m_chart->setBarSpecs(QSizeF(m_barWidth, m_barDepth), QSizeF(m_barSpacingX, m_barSpacingZ));
+ m_barThicknessRatio = (float)barwidth / 30.0f;
+ m_chart->setBarSpecs(m_barThicknessRatio, QSizeF(m_barSpacingX, m_barSpacingZ));
}
void ChartModifier::setSpacingSpecsX(int spacing)
{
m_barSpacingX = (float)spacing / 100.0f;
- m_chart->setBarSpecs(QSizeF(m_barWidth, m_barDepth), QSizeF(m_barSpacingX, m_barSpacingZ));
+ m_chart->setBarSpecs(m_barThicknessRatio, QSizeF(m_barSpacingX, m_barSpacingZ));
}
void ChartModifier::setSpacingSpecsZ(int spacing)
{
m_barSpacingZ = (float)spacing / 100.0f;
- m_chart->setBarSpecs(QSizeF(m_barWidth, m_barDepth), QSizeF(m_barSpacingX, m_barSpacingZ));
+ m_chart->setBarSpecs(m_barThicknessRatio, QSizeF(m_barSpacingX, m_barSpacingZ));
}
void ChartModifier::setSampleCountX(int samples)
{
m_columnCount = samples;
- m_chart->setupSampleSpace(m_rowCount, m_columnCount);
+ m_chart->setDataWindow(m_rowCount, m_columnCount);
if (m_chart->columnAxis()->labels().size() < m_columnCount)
m_chart->columnAxis()->setCategoryLabels(m_genericColumnLabels.mid(0, m_columnCount));
}
@@ -436,7 +429,7 @@ void ChartModifier::setSampleCountX(int samples)
void ChartModifier::setSampleCountZ(int samples)
{
m_rowCount = samples;
- m_chart->setupSampleSpace(m_rowCount, m_columnCount);
+ m_chart->setDataWindow(m_rowCount, m_columnCount);
if (m_chart->rowAxis()->labels().size() < m_rowCount)
m_chart->rowAxis()->setCategoryLabels(m_genericRowLabels.mid(0, m_rowCount));
}
diff --git a/examples/widget/chart.h b/examples/widget/chart.h
index 67280e13..85fa36ea 100644
--- a/examples/widget/chart.h
+++ b/examples/widget/chart.h
@@ -53,7 +53,7 @@ public:
void rotateY(int rotation);
void setBackgroundEnabled(int enabled);
void setGridEnabled(int enabled);
- void setSpecsX(int barwidth);
+ void setSpecsRatio(int barwidth);
void setSpecsZ(int bardepth);
void setSpacingSpecsX(int spacing);
void setSpacingSpecsZ(int spacing);
@@ -76,8 +76,7 @@ private:
float m_xRotation;
float m_yRotation;
bool m_static;
- float m_barWidth;
- float m_barDepth;
+ qreal m_barThicknessRatio;
float m_barSpacingX;
float m_barSpacingZ;
int m_fontSize;
diff --git a/examples/widget/main.cpp b/examples/widget/main.cpp
index 47892484..4fa4f9ba 100644
--- a/examples/widget/main.cpp
+++ b/examples/widget/main.cpp
@@ -123,16 +123,11 @@ int main(int argc, char **argv)
rotationSliderY->setMaximum(90);
rotationSliderY->setEnabled(false);
- QSlider *sizeSliderX = new QSlider(Qt::Horizontal, widget);
- sizeSliderX->setTickInterval(1);
- sizeSliderX->setMinimum(1);
- sizeSliderX->setValue(100);
- sizeSliderX->setMaximum(100);
- QSlider *sizeSliderZ = new QSlider(Qt::Horizontal, widget);
- sizeSliderZ->setTickInterval(1);
- sizeSliderZ->setMinimum(1);
- sizeSliderZ->setValue(100);
- sizeSliderZ->setMaximum(100);
+ QSlider *ratioSlider = new QSlider(Qt::Horizontal, widget);
+ ratioSlider->setTickInterval(1);
+ ratioSlider->setMinimum(10);
+ ratioSlider->setValue(30);
+ ratioSlider->setMaximum(100);
QSlider *spacingSliderX = new QSlider(Qt::Horizontal, widget);
spacingSliderX->setTickInterval(1);
@@ -171,15 +166,14 @@ int main(int argc, char **argv)
shadowQuality->addItem(QStringLiteral("Low"));
shadowQuality->addItem(QStringLiteral("Medium"));
shadowQuality->addItem(QStringLiteral("High"));
- shadowQuality->setCurrentIndex(1);
+ shadowQuality->setCurrentIndex(2);
vLayout->addWidget(staticCheckBox, 0, Qt::AlignTop);
vLayout->addWidget(rotationCheckBox, 0, Qt::AlignTop);
vLayout->addWidget(rotationSliderX, 0, Qt::AlignTop);
vLayout->addWidget(rotationSliderY, 0, Qt::AlignTop);
vLayout->addWidget(new QLabel(QStringLiteral("Adjust relative bar size")));
- vLayout->addWidget(sizeSliderX, 0, Qt::AlignTop);
- vLayout->addWidget(sizeSliderZ, 0, Qt::AlignTop);
+ vLayout->addWidget(ratioSlider, 0, Qt::AlignTop);
vLayout->addWidget(new QLabel(QStringLiteral("Adjust relative bar spacing")));
vLayout->addWidget(spacingSliderX, 0, Qt::AlignTop);
vLayout->addWidget(spacingSliderZ, 0, Qt::AlignTop);
@@ -215,8 +209,7 @@ int main(int argc, char **argv)
QObject::connect(rotationSliderX, &QSlider::valueChanged, modifier, &ChartModifier::rotateX);
QObject::connect(rotationSliderY, &QSlider::valueChanged, modifier, &ChartModifier::rotateY);
- QObject::connect(sizeSliderX, &QSlider::valueChanged, modifier, &ChartModifier::setSpecsX);
- QObject::connect(sizeSliderZ, &QSlider::valueChanged, modifier, &ChartModifier::setSpecsZ);
+ QObject::connect(ratioSlider, &QSlider::valueChanged, modifier, &ChartModifier::setSpecsRatio);
QObject::connect(spacingSliderX, &QSlider::valueChanged, modifier,
&ChartModifier::setSpacingSpecsX);
diff --git a/src/datavis3d/doc/images/q3dbars-minimal.png b/src/datavis3d/doc/images/q3dbars-minimal.png
index 63b77998..fff8d415 100644
--- a/src/datavis3d/doc/images/q3dbars-minimal.png
+++ b/src/datavis3d/doc/images/q3dbars-minimal.png
Binary files differ
diff --git a/src/datavis3d/doc/snippets/doc_src_q3dbars_construction.cpp b/src/datavis3d/doc/snippets/doc_src_q3dbars_construction.cpp
index 09979d8c..4372fada 100644
--- a/src/datavis3d/doc/snippets/doc_src_q3dbars_construction.cpp
+++ b/src/datavis3d/doc/snippets/doc_src_q3dbars_construction.cpp
@@ -24,16 +24,16 @@ int main(int argc, char **argv)
QGuiApplication app(argc, argv);
//! [0]
- Q3DBars bars;
- bars.setupSampleSpace(5, 5);
+ Q3DBars *bars = new Q3DBars();
+ bars->setDataWindow(5, 5);
//! [0]
//! [1]
- QVector<float> data;
- data << 1.0f << 3.0f << 7.5f << 5.0f << 2.2f;
- bars.addDataRow(data);
+ QBarDataRow data;
+ data << 1.0 << 3.0 << 7.5 << 5.0 << 2.2;
+ bars->dataProxy()->addRow(&data);
//! [1]
//! [2]
- bars.show();
+ bars->show();
//! [2]
return app.exec();
diff --git a/src/datavis3d/engine/bars3dcontroller.cpp b/src/datavis3d/engine/bars3dcontroller.cpp
index aca9a344..0d8428cb 100644
--- a/src/datavis3d/engine/bars3dcontroller.cpp
+++ b/src/datavis3d/engine/bars3dcontroller.cpp
@@ -32,14 +32,14 @@ QT_DATAVIS3D_BEGIN_NAMESPACE
Bars3dController::Bars3dController(QRect boundRect)
: Abstract3DController(boundRect),
- m_rowCount(0),
- m_columnCount(0),
+ m_rowCount(10),
+ m_columnCount(10),
m_mouseState(MouseNone),
m_mousePos(QPoint(0, 0)),
m_isSlicingActivated(false),
m_isBarSpecRelative(true),
- m_barThickness(QSizeF(0.75f, 0.75f)),
- m_barSpacing(m_barThickness * 3.0f),
+ m_barThicknessRatio(1.0f),
+ m_barSpacing(QSizeF(1.0f, 1.0f)),
m_renderer(0),
m_data(0)
{
@@ -89,7 +89,7 @@ void Bars3dController::synchDataToRenderer()
}
if (m_changeTracker.barSpecsChanged) {
- m_renderer->updateBarSpecs(m_barThickness, m_barSpacing, m_isBarSpecRelative);
+ m_renderer->updateBarSpecs(m_barThicknessRatio, m_barSpacing, m_isBarSpecRelative);
m_changeTracker.barSpecsChanged = false;
}
@@ -336,26 +336,27 @@ void Bars3dController::handleItemChanged(int rowIndex, int columnIndex)
m_isDataDirty = true;
}
-void Bars3dController::handleAxisAutoAdjustRangeChangedInOrientation(QAbstractAxis::AxisOrientation orientation, bool autoAdjust)
+void Bars3dController::handleAxisAutoAdjustRangeChangedInOrientation(
+ QAbstractAxis::AxisOrientation orientation, bool autoAdjust)
{
Q_UNUSED(orientation)
Q_UNUSED(autoAdjust)
adjustValueAxisRange();
}
-void Bars3dController::setBarSpecs(QSizeF thickness, QSizeF spacing, bool relative)
+void Bars3dController::setBarSpecs(GLfloat thicknessRatio, QSizeF spacing, bool relative)
{
- m_barThickness = thickness;
+ m_barThicknessRatio = thicknessRatio;
m_barSpacing = spacing;
m_isBarSpecRelative = relative;
m_changeTracker.barSpecsChanged = true;
- emit barSpecsChanged(thickness, spacing, relative);
+ emit barSpecsChanged(thicknessRatio, spacing, relative);
}
-QSizeF Bars3dController::barThickness()
+GLfloat Bars3dController::barThickness()
{
- return m_barThickness;
+ return m_barThicknessRatio;
}
QSizeF Bars3dController::barSpacing()
@@ -389,7 +390,7 @@ void Bars3dController::setBarType(QDataVis::MeshStyle style, bool smooth)
}
// TODO: This sets data window. Needs more parameters, now assumes window always starts at 0,0.
-void Bars3dController::setupSampleSpace(int rowCount, int columnCount)
+void Bars3dController::setDataWindow(int rowCount, int columnCount)
{
// Disable zoom mode if we're in it (causes crash if not, as zoom selection is deleted)
setSlicingActive(false);
diff --git a/src/datavis3d/engine/bars3dcontroller_p.h b/src/datavis3d/engine/bars3dcontroller_p.h
index 9811eb0d..97a84eb0 100644
--- a/src/datavis3d/engine/bars3dcontroller_p.h
+++ b/src/datavis3d/engine/bars3dcontroller_p.h
@@ -72,7 +72,7 @@ private:
// Look'n'feel
bool m_isBarSpecRelative;
- QSizeF m_barThickness;
+ GLfloat m_barThicknessRatio;
QSizeF m_barSpacing;
// Rendering
@@ -100,10 +100,10 @@ public:
// bar thickness, spacing between bars, and is spacing relative to thickness or absolute
// y -component sets the thickness/spacing of z -direction
// With relative 0.0f means side-to-side, 1.0f = one thickness in between
- void setBarSpecs(QSizeF thickness = QSizeF(1.0f, 1.0f),
+ void setBarSpecs(GLfloat thicknessRatio = 1.0f,
QSizeF spacing = QSizeF(1.0f, 1.0f),
bool relative = true);
- QSizeF barThickness();
+ GLfloat barThickness();
QSizeF barSpacing();
bool isBarSpecRelative();
@@ -111,7 +111,7 @@ public:
void setBarType(QDataVis::MeshStyle style, bool smooth = false);
// how many samples per row and column, and names for axes
- void setupSampleSpace(int samplesRow, int samplesColumn);
+ void setDataWindow(int samplesRow, int samplesColumn);
// Change selection mode; single bar, bar and row, bar and column, or all
void setSelectionMode(QDataVis::SelectionMode mode);
@@ -142,7 +142,7 @@ public slots:
signals:
void slicingActiveChanged(bool isSlicing);
void sampleSpaceChanged(int samplesRow, int samplesColumn);
- void barSpecsChanged(QSizeF thickness, QSizeF spacing, bool relative);
+ void barSpecsChanged(GLfloat thicknessRatio, QSizeF spacing, bool relative);
private:
void adjustValueAxisRange();
diff --git a/src/datavis3d/engine/bars3drenderer.cpp b/src/datavis3d/engine/bars3drenderer.cpp
index f7fd875e..4cf65ca4 100644
--- a/src/datavis3d/engine/bars3drenderer.cpp
+++ b/src/datavis3d/engine/bars3drenderer.cpp
@@ -1429,14 +1429,17 @@ void Bars3dRenderer::handleResize()
Abstract3DRenderer::handleResize();
}
-void Bars3dRenderer::updateBarSpecs(QSizeF thickness, QSizeF spacing, bool relative)
+void Bars3dRenderer::updateBarSpecs(GLfloat thicknessRatio, QSizeF spacing, bool relative)
{
- m_cachedBarThickness = thickness;
+ // Convert ratio to QSizeF, as we need it in that format for autoscaling calculations
+ m_cachedBarThickness.setWidth(1.0f);
+ m_cachedBarThickness.setHeight(1.0f / thicknessRatio);
+
if (relative) {
- m_cachedBarSpacing.setWidth((thickness.width() * 2) * (spacing.width() + 1.0f));
- m_cachedBarSpacing.setHeight((thickness.height() * 2) * (spacing.height() + 1.0f));
+ m_cachedBarSpacing.setWidth((m_cachedBarThickness.width() * 2) * (spacing.width() + 1.0f));
+ m_cachedBarSpacing.setHeight((m_cachedBarThickness.height() * 2) * (spacing.height() + 1.0f));
} else {
- m_cachedBarSpacing = thickness * 2 + spacing * 2;
+ m_cachedBarSpacing = m_cachedBarThickness * 2 + spacing * 2;
}
// Calculate here and at setting sample space
diff --git a/src/datavis3d/engine/bars3drenderer_p.h b/src/datavis3d/engine/bars3drenderer_p.h
index 95df8428..5ba98d56 100644
--- a/src/datavis3d/engine/bars3drenderer_p.h
+++ b/src/datavis3d/engine/bars3drenderer_p.h
@@ -142,7 +142,7 @@ protected:
virtual void loadMeshFile();
public slots:
- void updateBarSpecs(QSizeF thickness = QSizeF(1.0f, 1.0f),
+ void updateBarSpecs(GLfloat thicknessRatio = 1.0f,
QSizeF spacing = QSizeF(1.0f, 1.0f),
bool relative = true);
void updateSelectionMode(QDataVis::SelectionMode newMode);
diff --git a/src/datavis3d/engine/q3dbars.cpp b/src/datavis3d/engine/q3dbars.cpp
index bd9f9f09..8acf3690 100644
--- a/src/datavis3d/engine/q3dbars.cpp
+++ b/src/datavis3d/engine/q3dbars.cpp
@@ -44,12 +44,13 @@ QT_DATAVIS3D_BEGIN_NAMESPACE
*
* \section1 How to construct a minimal Q3DBars chart
*
- * After constructing Q3DBars, you need to set up sample space using setupSampleSpace(). Let's
- * set the sample space to 5 rows and 5 columns:
+ * After constructing Q3DBars, you should set data window using setDataWindow(). It is not
+ * mandatory, as data window has default value of 10 x 10. For the example, let's set the data
+ * window to 5 rows and 5 columns:
*
* \snippet doc_src_q3dbars_construction.cpp 0
*
- * Now Q3DBars is ready to receive data to be rendered. Add one row of 5 floats into the data
+ * Now Q3DBars is ready to receive data to be rendered. Add one row of 5 qreals into the data
* set:
*
* \snippet doc_src_q3dbars_construction.cpp 1
@@ -69,11 +70,12 @@ QT_DATAVIS3D_BEGIN_NAMESPACE
*
* \image q3dbars-minimal.png
*
- * The scene can be rotated and zoomed into, but no other interaction is included in this minimal
- * code example. You can learn more by familiarizing yourself with the examples provided, like
- * the \l{Rainfall Example} or the \l{Widget Example}.
+ * The scene can be rotated, zoomed into, and a bar can be selected to view it's value,
+ * but no other interaction is included in this minimal code example. You can learn more by
+ * familiarizing yourself with the examples provided, like the \l{Rainfall Example} or
+ * the \l{Widget Example}.
*
- * \sa Q3DMaps, {Qt Data Visualization 3D C++ Classes}
+ * \sa Q3DScatter, Q3DSurface and {Qt Data Visualization 3D C++ Classes}
*/
/*!
@@ -103,6 +105,9 @@ void Q3DBars::render()
d_ptr->m_shared->render();
}
+/*!
+ * \internal
+ */
void Q3DBars::handleShadowQualityUpdate(QDataVis::ShadowQuality quality)
{
emit shadowQualityChanged(quality);
@@ -167,14 +172,18 @@ void Q3DBars::resizeEvent(QResizeEvent *event)
d_ptr->m_shared->setSize(width(), height());
}
-// TODO: Document
-// Size
+/*!
+ * Sets window \a width.
+ */
void Q3DBars::setWidth(const int width)
{
d_ptr->m_shared->setWidth(width);
QWindow::setWidth(width);
}
+/*!
+ * Sets window \a height.
+ */
void Q3DBars::setHeight(const int height)
{
d_ptr->m_shared->setHeight(height);
@@ -182,29 +191,22 @@ void Q3DBars::setHeight(const int height)
}
/*!
- * \a thickness Thickness of a bar in x and z axes.
- *
- * \a spacing Spacing between bars in x and z axes. If relative -flag is true, value of 0.0f
- * means the bars are side-to-side and for example 1.0f means there is one thickness in between the
- * bars.
- *
- * \a relative A flag to indicate if spacing is meant to be absolute or relative. \c true by
- * default.
- *
- * Sets bar specifications. Bar thickness is relative, as scene is automatically scaled to fit into
- * the view.
+ * Sets bar specifications. Bar \a thicknessRatio specifies the ratio of a bar thickness between x
+ * and z axes. For example, setting the ratio to 2.0 means bars are twice as wide in x dimension
+ * as they are in z dimension. Bar \a spacing sets the spacing between bars in x and z axes.
+ * \a relative -flag is used to indicate if spacing is meant to be absolute or relative to bar
+ * thickness. If it is true, value of 0.0 means the bars are side-to-side and for example 1.0 means
+ * there is one thickness in between the bars. It is \c true by default.
*/
-void Q3DBars::setBarSpecs(QSizeF thickness, QSizeF spacing, bool relative)
+void Q3DBars::setBarSpecs(qreal thicknessRatio, QSizeF spacing, bool relative)
{
- d_ptr->m_shared->setBarSpecs(thickness, spacing, relative);
+ d_ptr->m_shared->setBarSpecs(GLfloat(thicknessRatio), spacing, relative);
}
/*!
- * \a style One of the values in \c MeshStyle. \c Bars by default.
- *
- * \a smooth A flag to set shading to smooth. \c false by default.
- *
- * Sets the bar type to one of the supplied ones.
+ * Sets the bar \a style to one of the values in \c QDataVis::MeshStyle. It is preset to
+ * \c QDataVis::Bars by default. A \a smooth flag can be used to set shading to smooth.
+ * It is \c false by default.
*
* \sa setMeshFileName()
*/
@@ -214,29 +216,24 @@ void Q3DBars::setBarType(QDataVis::MeshStyle style, bool smooth)
}
/*!
- * \a samplesRow How many rows of data there will be.
- *
- * \a samplesColumn How many items there are per row.
- *
- * Set up sample space. This must be called to initialize the sample space before adding data to the
- * Q3DBars.
- *
- * \sa addDataRow(), addDataSet()
+ * Set up data window to \a samplesRow rows and \a samplesColumn columns. Both are preset to \c 10
+ * by default.
*/
-void Q3DBars::setupSampleSpace(int samplesRow, int samplesColumn)
+void Q3DBars::setDataWindow(int samplesRow, int samplesColumn)
{
- d_ptr->m_shared->setupSampleSpace(samplesRow, samplesColumn);
+ d_ptr->m_shared->setDataWindow(samplesRow, samplesColumn);
}
-QSize Q3DBars::sampleSpace() const
+/*!
+ * \return size of the sample space in QSize.
+ */
+QSize Q3DBars::dataWindow() const
{
return QSize(d_ptr->m_shared->rowCount(), d_ptr->m_shared->columnCount());
}
/*!
- * \a preset Move camera to a predefined position from \c QDataVis::CameraPreset.
- *
- * Moves camera to a predefined position.
+ * Moves camera to a \a preset position. The position can be one of \c QDataVis::CameraPreset.
*/
void Q3DBars::setCameraPreset(QDataVis::CameraPreset preset)
{
@@ -244,16 +241,10 @@ void Q3DBars::setCameraPreset(QDataVis::CameraPreset preset)
}
/*!
- * \a horizontal Horizontal angle for camera.
- *
- * \a vertical Vertical angle for camera.
- *
- * \a distance Distance from the center. \c 100 by default.
- *
- * Move camera to a wanted position based on horizontal and veritcal angles. Angles are limited
+ * Move camera to a wanted position based on \a horizontal and \a vertical angles. Angles are limited
* to -180...180 in horizontal direction and either -90...90 or 0...90 in vertical, depending
* on data values. Negative vertical angles are allowed only if there are negative bar values.
- * Distance is adjustable between 10 and 500.
+ * \a distance is adjustable between 10 and 500, being \c 100 by default.
*/
void Q3DBars::setCameraPosition(qreal horizontal, qreal vertical, int distance)
{
@@ -261,10 +252,11 @@ void Q3DBars::setCameraPosition(qreal horizontal, qreal vertical, int distance)
}
/*!
- * \a theme Apply a predefined theme from \c QDataVis::ColorTheme.
+ * Sets a predefined \a theme from \c QDataVis::ColorTheme. It is preset to \c QDataVis::ThemeSystem by
+ * default. Theme affects bar colors, label colors, text color, background color, window color and
+ * grid color. Lighting is also adjusted by themes.
*
- * Sets a predefined theme. Theme affects bar colors, label colors, text color, background color,
- * window color and grid color. Lighting is also adjusted by themes.
+ * \sa setBarColor()
*/
void Q3DBars::setTheme(QDataVis::ColorTheme theme)
{
@@ -272,19 +264,20 @@ void Q3DBars::setTheme(QDataVis::ColorTheme theme)
}
/*!
- * \a baseColor The base color of a bar. If all other colors are black, this sets the final color of
- * the bar.
+ * Set bar color using your own colors. \a baseColor sets the base color of a bar. If all other
+ * colors are black, this sets the final color of the bar if uniform is set to false.
+ * \a heightColor is added to the bar based on its height. The higher the bar, the more prominent
+ * this color becomes. Setting this black keeps the color unchanged regardless of height.
+ * \a depthColor becomes more prominent the further away from the first row the bar is.
+ * Setting this black keeps bars the same color regardless of "depth" in the set. \a uniform -flag
+ * is used to define if color needs to be uniform throughout bar's length, or will the colors be
+ * applied by height. It is \c true by default.
*
- * \a heightColor This color is added to the bar based on its height. The higher the bar, the more
- * prominent this color becomes. Setting this black keeps the color unchanged regardless of height.
+ * Calling this method overrides colors from theme.
*
- * \a depthColor This color becomes more prominent the further away from the first row the bar is.
- * Setting this black keeps bars the same color regardless of "depth" in the set.
+ * \sa setTheme()
*
- * \a uniform A flag to define if color needs to be uniform throughout bar's length, or will the
- * colors be applied by height. \c true by default.
- *
- * Set bar color using your own colors. This overrides colors from theme.
+ * \warning This method is subject to change.
*/
void Q3DBars::setBarColor(QColor baseColor, QColor heightColor, QColor depthColor, bool uniform)
{
@@ -294,9 +287,8 @@ void Q3DBars::setBarColor(QColor baseColor, QColor heightColor, QColor depthColo
/*!
* \property Q3DBars::selectionMode
*
- * \a mode Set bar selection mode from \c QDataVis::SelectionMode. \c ModeItem by default.
- *
- * Sets bar selection mode to be used.
+ * Sets bar selection \a mode to one of \c QDataVis::SelectionMode. It is preset to
+ * \c QDataVis::ModeItem by default.
*/
void Q3DBars::setSelectionMode(QDataVis::SelectionMode mode)
{
@@ -311,9 +303,7 @@ QDataVis::SelectionMode Q3DBars::selectionMode() const
/*!
* \property Q3DBars::windowTitle
*
- * \a title QString label to be used as window title.
- *
- * Sets the window title. The default is application executable name.
+ * Sets the window \a title. The default is application executable name.
*/
void Q3DBars::setWindowTitle(const QString &title)
{
@@ -326,10 +316,11 @@ QString Q3DBars::windowTitle() const
}
/*!
- * \a objFileName File name of a mesh object. Object needs to be in Wavefront obj format
- * and include vertices, normals and UVs. It also needs to be in triangles.
+ * Override bar type with a mesh object located in \a objFileName.
+ * \note Object needs to be in Wavefront obj format and include vertices, normals and UVs.
+ * It also needs to be in triangles.
*
- * Override bar type with an object mesh. \sa setBarType()
+ * \sa setBarType()
*/
void Q3DBars::setMeshFileName(const QString &objFileName)
{
@@ -339,9 +330,7 @@ void Q3DBars::setMeshFileName(const QString &objFileName)
/*!
* \property Q3DBars::fontSize
*
- * \a fontsize Size of the font.
- *
- * Sets font size.
+ * Sets font size to \a fontsize.
*/
void Q3DBars::setFontSize(float fontsize)
{
@@ -356,9 +345,7 @@ float Q3DBars::fontSize()
/*!
* \property Q3DBars::font
*
- * \a font QFont to be used for labels. \c Arial by default.
- *
- * Sets the font for labels.
+ * Sets the \a font for labels. It is preset to \c Arial by default.
*/
void Q3DBars::setFont(const QFont &font)
{
@@ -373,10 +360,8 @@ QFont Q3DBars::font() const
/*!
* \property Q3DBars::labelTransparency
*
- * \a transparency Transparency level of labels from \c QDataVis::LabelTransparency.
- * \c TransparencyFromTheme by default.
- *
- * Sets label transparency.
+ * Sets label \a transparency to one of \c QDataVis::LabelTransparency. It is preset to
+ * \c QDataVis::TransparencyFromTheme by default.
*/
void Q3DBars::setLabelTransparency(QDataVis::LabelTransparency transparency)
{
@@ -391,9 +376,7 @@ QDataVis::LabelTransparency Q3DBars::labelTransparency() const
/*!
* \property Q3DBars::gridVisible
*
- * \a visible Flag to enable or disable grid. \c true by default.
- *
- * Sets grid drawing on or off.
+ * Sets grid visibility to \a visible. It is preset to \c true by default.
*/
void Q3DBars::setGridVisible(bool visible)
{
@@ -408,9 +391,7 @@ bool Q3DBars::isGridVisible() const
/*!
* \property Q3DBars::backgroundVisible
*
- * \a visible Flag to enable or disable background. \c true by default.
- *
- * Sets backround rendering on or off.
+ * Sets background visibility to \a visible. It is preset to \c true by default.
*/
void Q3DBars::setBackgroundVisible(bool visible)
{
@@ -425,10 +406,12 @@ bool Q3DBars::isBackgroundVisible() const
/*!
* \property Q3DBars::shadowQuality
*
- * \a quality Shadow quality from \c QDataVis::ShadowQuality. \c ShadowLow by default.
+ * Sets shadow \a quality to one of \c QDataVis::ShadowQuality. It is preset to
+ * \c QDataVis::ShadowMedium by default.
*
- * Sets shadow quality. If setting QDataVis::ShadowQuality of a certain level fails, a level is lowered
- * until it is successful and shadowQualityChanged signal is emitted for each time the change is done.
+ * \note If setting QDataVis::ShadowQuality of a certain level fails, a level is lowered
+ * until it is successful and shadowQualityChanged signal is emitted for each time the change is
+ * done.
*/
void Q3DBars::setShadowQuality(QDataVis::ShadowQuality quality)
{
@@ -440,16 +423,25 @@ QDataVis::ShadowQuality Q3DBars::shadowQuality() const
return d_ptr->m_shared->shadowQuality();
}
+/*!
+ * \return category axis for rows.
+ */
QCategoryAxis *Q3DBars::rowAxis()
{
return reinterpret_cast<QCategoryAxis *>(d_ptr->m_shared->axisX());
}
+/*!
+ * \return category axis for columns.
+ */
QCategoryAxis *Q3DBars::columnAxis()
{
return reinterpret_cast<QCategoryAxis *>(d_ptr->m_shared->axisZ());
}
+/*!
+ * Sets a user-defined value \a axis (Y-axis). Ownership of the axis is transferred to Q3DBars.
+ */
void Q3DBars::setValueAxis(QValueAxis *axis)
{
Q_ASSERT(axis);
@@ -457,21 +449,36 @@ void Q3DBars::setValueAxis(QValueAxis *axis)
return d_ptr->m_shared->setAxisY(axis);
}
+/*!
+ * \return used value axis (Y-axis).
+ */
QValueAxis *Q3DBars::valueAxis()
{
return static_cast<QValueAxis *>(d_ptr->m_shared->axisY());
}
+/*!
+ * Sets a user-defined data \a proxy. Ownership of the proxy is transferred to Q3DBars.
+ */
void Q3DBars::setDataProxy(QBarDataProxy *proxy)
{
d_ptr->m_shared->setDataProxy(proxy);
}
+/*!
+ * \return used data proxy.
+ */
QBarDataProxy *Q3DBars::dataProxy()
{
return d_ptr->m_shared->dataProxy();
}
+/*!
+ * \fn void Q3DBars::shadowQualityChanged(QDataVis::ShadowQuality quality)
+ *
+ * This signal is emitted when shadow quality changes.
+ */
+
Q3DBarsPrivate::Q3DBarsPrivate(Q3DBars *q, QRect rect)
: q_ptr(q),
m_shared(new Bars3dController(rect))
diff --git a/src/datavis3d/engine/q3dbars.h b/src/datavis3d/engine/q3dbars.h
index a0eb9cb5..21e3c46d 100644
--- a/src/datavis3d/engine/q3dbars.h
+++ b/src/datavis3d/engine/q3dbars.h
@@ -49,86 +49,59 @@ public:
explicit Q3DBars();
~Q3DBars();
- // bar thickness, spacing between bars, and is spacing relative to thickness or absolute
- // y -component sets the thickness/spacing of z -direction
- // With relative 0.0f means side-to-side, 1.0f = one thickness in between
- void setBarSpecs(QSizeF thickness = QSizeF(1.0f, 1.0f),
+ void setBarSpecs(qreal thicknessRatio = 1.0,
QSizeF spacing = QSizeF(1.0f, 1.0f),
bool relative = true);
- // bar type; bars (=cubes), pyramids, cones, cylinders, etc.
void setBarType(QDataVis::MeshStyle style, bool smooth = false);
- // how many samples per row and column, and names for axes
// TODO: This defines the data window, needs additional parameters startRow, startColumn
- void setupSampleSpace(int samplesRow, int samplesColumn);
- QSize sampleSpace() const; // TODO: Return QRect once data window properly implemented?
+ void setDataWindow(int samplesRow, int samplesColumn);
+ QSize dataWindow() const; // TODO: Return QRect once data window properly implemented?
- // Select preset camera placement
void setCameraPreset(QDataVis::CameraPreset preset);
- // Set camera rotation if you don't want to use the presets (in horizontal (-180...180) and
- // vertical (0...90) (or (-90...90) if there are negative values) angles and distance in
- // percentage (10...500))
void setCameraPosition(qreal horizontal, qreal vertical, int distance = 100);
- // Set theme (bar colors, shaders, window color, background colors, light intensity and text
- // colors are affected)
void setTheme(QDataVis::ColorTheme theme);
- // Set color if you don't want to use themes. Set uniform to false if you want the (height)
- // color to change from bottom to top
void setBarColor(QColor baseColor, QColor heightColor, QColor depthColor,
bool uniform = true);
- // override bar type with own mesh
void setMeshFileName(const QString &objFileName);
- // TODO: light placement API
- // Change selection mode; single bar, bar and row, bar and column, or all
void setSelectionMode(QDataVis::SelectionMode mode);
QDataVis::SelectionMode selectionMode() const;
- // Set window title
void setWindowTitle(const QString &title);
QString windowTitle() const;
- // Font size adjustment
void setFontSize(float fontsize);
float fontSize();
- // Set font
void setFont(const QFont &font);
QFont font() const;
- // Label transparency adjustment
void setLabelTransparency(QDataVis::LabelTransparency transparency);
QDataVis::LabelTransparency labelTransparency() const;
- // Enable or disable background grid
void setGridVisible(bool visible);
bool isGridVisible() const;
- // Size
void setWidth(const int width);
void setHeight(const int height);
- // Enable or disable background mesh
void setBackgroundVisible(bool visible);
bool isBackgroundVisible() const;
- // Adjust shadow quality
void setShadowQuality(QDataVis::ShadowQuality quality);
QDataVis::ShadowQuality shadowQuality() const;
- // Axes - row & column axes are fixed to category axes, value axis can be
- // customized.
QCategoryAxis *rowAxis();
QCategoryAxis *columnAxis();
void setValueAxis(QValueAxis *axis);
QValueAxis *valueAxis();
- // Sets the data proxy. Assumes ownership of the data proxy. Deletes old proxy.
void setDataProxy(QBarDataProxy *proxy);
QBarDataProxy *dataProxy();
@@ -137,7 +110,6 @@ public slots:
void handleShadowQualityUpdate(QDataVis::ShadowQuality quality);
signals:
- // Signals shadow quality changes.
void shadowQualityChanged(QDataVis::ShadowQuality quality);
protected:
diff --git a/src/datavis3d/engine/q3dwindow.cpp b/src/datavis3d/engine/q3dwindow.cpp
index 5b2b70ab..56c2b9dd 100644
--- a/src/datavis3d/engine/q3dwindow.cpp
+++ b/src/datavis3d/engine/q3dwindow.cpp
@@ -38,14 +38,12 @@ QT_DATAVIS3D_BEGIN_NAMESPACE
* This class creates a QWindow and provides render loop for visualization types inheriting it.
* \warning This class is not intended to be used directly by developers.
*
- * \sa Q3DBars, Q3DMaps, {Qt Data Visualization 3D C++ Classes}
+ * \sa Q3DBars, Q3DScatter, Q3DSurface and {Qt Data Visualization 3D C++ Classes}
*/
/*!
- * \a parent A QWindow parent.
- *
- * Constructs Q3DWindow. It creates a QWindow and an OpenGL context. It also sets surface
- * format and initializes OpenGL functions for use.
+ * Constructs Q3DWindow with \a parent. It creates a QWindow and an OpenGL context. It also sets
+ * surface format and initializes OpenGL functions for use.
*/
Q3DWindow::Q3DWindow(QWindow *parent)
: QWindow(parent),
diff --git a/src/datavis3dqml2/declarativebars.cpp b/src/datavis3dqml2/declarativebars.cpp
index 2e4dbf04..2adcd870 100644
--- a/src/datavis3dqml2/declarativebars.cpp
+++ b/src/datavis3dqml2/declarativebars.cpp
@@ -90,9 +90,9 @@ QSGNode *DeclarativeBars::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData
return node;
}
-void DeclarativeBars::setupSampleSpace(int rowCount, int columnCount)
+void DeclarativeBars::setDataWindow(int rowCount, int columnCount)
{
- m_shared->setupSampleSpace(rowCount, columnCount);
+ m_shared->setDataWindow(rowCount, columnCount);
}
void DeclarativeBars::setBarColor(QColor baseColor, QColor heightColor, QColor depthColor,
@@ -156,19 +156,19 @@ QItemModelBarDataMapping *DeclarativeBars::mapping() const
return static_cast<QItemModelBarDataProxy *>(m_shared->dataProxy())->mapping();
}
-void DeclarativeBars::setBarThickness(QSizeF thickness)
+void DeclarativeBars::setBarThickness(qreal thicknessRatio)
{
- m_shared->setBarSpecs(thickness, barSpacing(), isBarSpacingRelative());
+ m_shared->setBarSpecs(GLfloat(thicknessRatio), barSpacing(), isBarSpacingRelative());
}
-QSizeF DeclarativeBars::barThickness()
+qreal DeclarativeBars::barThickness()
{
return m_shared->barThickness();
}
void DeclarativeBars::setBarSpacing(QSizeF spacing)
{
- m_shared->setBarSpecs(barThickness(), spacing, isBarSpacingRelative());
+ m_shared->setBarSpecs(GLfloat(barThickness()), spacing, isBarSpacingRelative());
}
QSizeF DeclarativeBars::barSpacing()
@@ -178,7 +178,7 @@ QSizeF DeclarativeBars::barSpacing()
void DeclarativeBars::setBarSpacingRelative(bool relative)
{
- m_shared->setBarSpecs(barThickness(), barSpacing(), relative);
+ m_shared->setBarSpecs(GLfloat(barThickness()), barSpacing(), relative);
}
bool DeclarativeBars::isBarSpacingRelative()
@@ -338,7 +338,7 @@ int DeclarativeBars::rows() const
void DeclarativeBars::setRows(int rows)
{
- setupSampleSpace(rows, columns());
+ setDataWindow(rows, columns());
}
int DeclarativeBars::columns() const
@@ -348,7 +348,7 @@ int DeclarativeBars::columns() const
void DeclarativeBars::setColumns(int columns)
{
- setupSampleSpace(rows(), columns);
+ setDataWindow(rows(), columns);
}
void DeclarativeBars::mousePressEvent(QMouseEvent *event)
diff --git a/src/datavis3dqml2/declarativebars_p.h b/src/datavis3dqml2/declarativebars_p.h
index 07dc21d4..0256b5e5 100644
--- a/src/datavis3dqml2/declarativebars_p.h
+++ b/src/datavis3dqml2/declarativebars_p.h
@@ -57,7 +57,7 @@ class DeclarativeBars : public QQuickItem
Q_PROPERTY(QtDataVis3D::QDataVis::MeshStyle barType READ barType WRITE setBarType)
Q_PROPERTY(QtDataVis3D::QDataVis::CameraPreset cameraPreset READ cameraPreset WRITE setCameraPreset)
Q_PROPERTY(QtDataVis3D::QDataVis::ColorTheme theme READ theme WRITE setTheme)
- Q_PROPERTY(QSizeF barThickness READ barThickness WRITE setBarThickness)
+ Q_PROPERTY(qreal barThickness READ barThickness WRITE setBarThickness)
Q_PROPERTY(QSizeF barSpacing READ barSpacing WRITE setBarSpacing)
Q_PROPERTY(bool barSpacingRelative READ isBarSpacingRelative WRITE setBarSpacingRelative)
Q_PROPERTY(bool barSmooth READ barSmooth WRITE setBarSmooth)
@@ -83,7 +83,7 @@ public:
void componentComplete();
// how many samples per row and column
- Q_INVOKABLE void setupSampleSpace(int rowCount, int columnCount);
+ Q_INVOKABLE void setDataWindow(int rowCount, int columnCount);
// Set color if you don't want to use themes. Set uniform to false if you want the (height)
// color to change from bottom to top
@@ -110,8 +110,8 @@ public:
void setAxisZ(QCategoryAxis *axis);
// Set bar thickness. Y -component sets the thickness of z -direction.
- void setBarThickness(QSizeF thickness);
- QSizeF barThickness();
+ void setBarThickness(qreal thicknessRatio);
+ qreal barThickness();
// Set spacing between bars. Y -component sets the spacing of z -direction.
// If spacing is relative, 0.0f means side-to-side and 1.0f = one thickness in between.