summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiikka Heikkinen <miikka.heikkinen@digia.com>2013-07-05 11:34:47 +0300
committerMiikka Heikkinen <miikka.heikkinen@digia.com>2013-07-05 12:52:57 +0300
commit03276f3187bc58162e335b9a5739c1631344fa84 (patch)
treed491698251a0320fd2f8eadf8cd262211baebb59
parent0963cf7feda67225700f4291264e68c9060046f6 (diff)
Miscellaneous fixes
- Widget example now uses default QBarDataProxy directly - Axes store labels in QStringLists instead of vectors - Axes LabelItems as QList<LabelItem *> instead of QVector<LabelItem> This allows better control of when label items are constructed and destructed -> easier to keep track of textures. - Removed label setting from QAbstractDataItem api, it should be replaced with label format setter if we want individual items to have custom labels. - Added functionality to QBarDataItem - Misc bug fixes Change-Id: I01b3a5f3fc4acb8c1a826f19fa2762864430a088 Reviewed-by: Mika Salmela <mika.salmela@digia.com>
-rw-r--r--examples/barchart/main.cpp10
-rw-r--r--examples/qmlbarchart/qml/qmlbarchart/main.qml2
-rw-r--r--examples/rainfall/main.cpp6
-rw-r--r--examples/spectrum/spectrumapp/main.cpp2
-rw-r--r--examples/widget/chart.cpp63
-rw-r--r--examples/widget/chart.h4
-rw-r--r--src/datavis3d/axis/qabstractaxis.cpp4
-rw-r--r--src/datavis3d/axis/qabstractaxis.h3
-rw-r--r--src/datavis3d/axis/qabstractaxis_p.h6
-rw-r--r--src/datavis3d/axis/qcategoryaxis.cpp14
-rw-r--r--src/datavis3d/axis/qcategoryaxis.h2
-rw-r--r--src/datavis3d/data/labelitem_p.h6
-rw-r--r--src/datavis3d/data/qabstractdataitem.cpp16
-rw-r--r--src/datavis3d/data/qabstractdataitem.h4
-rw-r--r--src/datavis3d/data/qabstractdataitem_p.h6
-rw-r--r--src/datavis3d/data/qabstractdataproxy.h3
-rw-r--r--src/datavis3d/data/qbardataitem.cpp14
-rw-r--r--src/datavis3d/data/qbardataitem.h1
-rw-r--r--src/datavis3d/data/qbardataproxy.cpp221
-rw-r--r--src/datavis3d/data/qbardataproxy.h42
-rw-r--r--src/datavis3d/data/qbardataproxy_p.h9
-rw-r--r--src/datavis3d/data/qolddataproxy.cpp2
-rw-r--r--src/datavis3d/engine/bars3dcontroller.cpp6
-rw-r--r--src/datavis3d/engine/bars3drenderer.cpp68
-rw-r--r--src/datavis3d/engine/drawer.cpp2
-rw-r--r--src/datavis3d/engine/maps3dcontroller.cpp1
-rw-r--r--src/datavis3d/engine/q3dbars.h19
27 files changed, 323 insertions, 213 deletions
diff --git a/examples/barchart/main.cpp b/examples/barchart/main.cpp
index caa5b9dc..040be325 100644
--- a/examples/barchart/main.cpp
+++ b/examples/barchart/main.cpp
@@ -94,7 +94,7 @@ ChartDataGenerator::ChartDataGenerator(Q3DBars *barchart)
#ifndef USE_STATIC_DATA
// Set up sample space; make it as deep as it's wide
- m_chart->setupSampleSpace(m_columnCount, m_rowCount);
+ m_chart->setupSampleSpace(m_rowCount, m_columnCount);
#endif
// Set bar type to smooth bar
@@ -201,7 +201,7 @@ void ChartDataGenerator::addDataSet()
row.clear();
}
// Set up sample space based on inserted data
- m_chart->setupSampleSpace(m_columnCount, m_rowCount);
+ m_chart->setupSampleSpace(m_rowCount, m_columnCount);
// Add data to chart
m_chart->addDataSet(data);
#else
@@ -212,9 +212,9 @@ void ChartDataGenerator::addDataSet()
m_chart->setWindowTitle(QStringLiteral("Hours playing banjo"));
// Set up row and column names
- QVector<QString> days;
+ QStringList days;
days << "Monday" << "Tuesday" << "Wednesday" << "Thursday" << "Friday" << "Saturday" << "Sunday";
- QVector<QString> weeks;
+ QStringList weeks;
weeks << "week 1" << "week 2" << "week 3" << "week 4" << "week 5";
// Set up data Mon Tue Wed Thu Fri Sat Sun
@@ -253,7 +253,7 @@ void ChartDataGenerator::addDataSet()
}
// Set up sample space based on prepared data
- m_chart->setupSampleSpace(days.size(), weeks.size());
+ m_chart->setupSampleSpace(weeks.size(), days.size());
// Add data to chart
static_cast<QOldDataProxy *>(m_chart->dataProxy())->addDataSet(dataSet);
diff --git a/examples/qmlbarchart/qml/qmlbarchart/main.qml b/examples/qmlbarchart/qml/qmlbarchart/main.qml
index 28b3326d..748a5241 100644
--- a/examples/qmlbarchart/qml/qmlbarchart/main.qml
+++ b/examples/qmlbarchart/qml/qmlbarchart/main.qml
@@ -125,7 +125,7 @@ Item {
testset1.addRow(testrow1);
testset1.addRow(testrow2);
- testchart.setupSampleSpace(4, 2);
+ testchart.setupSampleSpace(2, 4);
testchart.addDataSet(testset1);
}
diff --git a/examples/rainfall/main.cpp b/examples/rainfall/main.cpp
index 46757e46..be1b120f 100644
--- a/examples/rainfall/main.cpp
+++ b/examples/rainfall/main.cpp
@@ -74,12 +74,12 @@ RainfallChart::RainfallChart(Q3DBars *rainfall)
m_chart->setBarSpecs(QSizeF(1.0f, 1.0f), QSizeF(0.2f, 0.2f), true);
// Set up sample space; make it match actual data size
- m_chart->setupSampleSpace(m_columnCount, m_rowCount);
+ m_chart->setupSampleSpace(m_rowCount, m_columnCount);
// Set axis labels and titles
- QVector<QString> months;
+ QStringList months;
months << "January" << "February" << "March" << "April" << "May" << "June" << "July" << "August" << "September" << "October" << "November" << "December";
- QVector<QString> years;
+ QStringList years;
years << "2000" << "2001" << "2002" << "2003" << "2004" << "2005" << "2006" << "2007" << "2008" << "2009" << "2010" << "2011" << "2012";
m_chart->rowAxis()->setTitle("Year");
diff --git a/examples/spectrum/spectrumapp/main.cpp b/examples/spectrum/spectrumapp/main.cpp
index 19f195fa..2fa0be8f 100644
--- a/examples/spectrum/spectrumapp/main.cpp
+++ b/examples/spectrum/spectrumapp/main.cpp
@@ -86,7 +86,7 @@ MainApp::MainApp(Q3DBars *window)
m_lowFreq(SpectrumLowFreq),
m_highFreq(SpectrumHighFreq)
{
- m_chart->setupSampleSpace(SpectrumNumBands, SpectrumNumBands * 2);
+ m_chart->setupSampleSpace(SpectrumNumBands * 2, SpectrumNumBands);
// Disable grid
m_chart->setGridVisible(false);
// Disable auto-scaling of height by defining tick count and step, even though we don't draw grid
diff --git a/examples/widget/chart.cpp b/examples/widget/chart.cpp
index 00cdd3c3..f2928f7b 100644
--- a/examples/widget/chart.cpp
+++ b/examples/widget/chart.cpp
@@ -41,9 +41,9 @@
#include "chart.h"
#include "qcategoryaxis.h"
#include "qvalueaxis.h"
-#include "qolddataproxy.h"
+#include "qbardataproxy.h"
-using namespace QtDataVis3D;
+QT_DATAVIS3D_USE_NAMESPACE
const QString celsiusString = QString(QChar(0xB0)) + "C";
@@ -64,6 +64,12 @@ ChartModifier::ChartModifier(Q3DBars *barchart)
m_minval(-15.2f)
{
// Don't set any styles or specifications, start from defaults
+ // Generate generic labels
+ for (int i = 0; i < m_rowCount; i++)
+ m_genericRowLabels << QStringLiteral("Row %1").arg(i);
+ for (int i = 0; i < m_columnCount; i++)
+ m_genericColumnLabels << QStringLiteral("Column %1").arg(i);
+
}
ChartModifier::~ChartModifier()
@@ -88,12 +94,20 @@ void ChartModifier::restart(bool dynamicData)
m_chart->setFont(QFont("Times Roman", 20));
m_chart->setTickCount(m_ticks, m_tickStep, m_minval);
} else {
+ m_chart->dataProxy()->resetArray(0, 0);
// Set up sample space
- m_chart->setupSampleSpace(m_columnCount, m_rowCount);
+ m_chart->setupSampleSpace(m_rowCount, m_columnCount);
// Set selection mode to full
m_chart->setSelectionMode(ModeBarRowAndColumn);
// Reset tick count to default
m_chart->setTickCount(0, 0);
+
+ m_chart->rowAxis()->setTitle("Generic Row");
+ m_chart->columnAxis()->setTitle("Generic Column");
+ m_chart->valueAxis()->setTitle("Generic Value");
+
+ m_chart->rowAxis()->setLabels(QStringList());
+ m_chart->columnAxis()->setLabels(m_genericColumnLabels);
}
}
@@ -106,9 +120,9 @@ void ChartModifier::addDataSet()
m_chart->setWindowTitle(QStringLiteral("Average temperatures in Oulu, Finland (2006-2012)"));
// Set up row and column names
- QVector<QString> months;
+ QStringList months;
months << "January" << "February" << "March" << "April" << "May" << "June" << "July" << "August" << "September" << "October" << "November" << "December";
- QVector<QString> years;
+ QStringList years;
years << "2006" << "2007" << "2008" << "2009" << "2010" << "2011" << "2012";
// Set up data
@@ -120,8 +134,9 @@ void ChartModifier::addDataSet()
{-9.0f, -15.2f, -3.8f, 2.6f, 8.3f, 15.9f, 18.6f, 14.9f, 11.1f, 5.3f, 1.8f, -0.2f}, // 2011
{-8.7f, -11.3f, -2.3f, 0.4f, 7.5f, 12.2f, 16.4f, 14.1f, 9.2f, 3.1f, 0.3f, -12.1f}}; // 2012
- // Create data set
- QDataSet *dataSet = new QDataSet();
+ // Use default data proxy to feed data directly in expected format
+ QBarDataProxy *proxy = m_chart->dataProxy();
+ proxy->setItemLabelFormat(celsiusString);
// Add labels
m_chart->rowAxis()->setTitle("Year");
@@ -131,18 +146,19 @@ void ChartModifier::addDataSet()
m_chart->columnAxis()->setLabels(months);
// Create data rows
- QDataRow *dataRow;
+ QBarDataArray *dataSet = new QBarDataArray;
+ QBarDataRow *dataRow;
+
+ dataSet->reserve(years.size());
for (int year = 0; year < years.size(); year++) {
- dataRow = new QDataRow();
+ dataRow = new QBarDataRow;
// Create data items
for (int month = 0; month < months.size(); month++) {
// Add data to rows
- dataRow->addItem(new QDataItem(temp[year][month], celsiusString));
+ dataRow->append(new QBarDataItem(temp[year][month]));
}
// Add row to set
- dataSet->addRow(dataRow);
- // Get next pointer
- dataRow++;
+ dataSet->append(dataRow);
}
// Set tick count (4 steps of 5 degrees, with absolute minimum of -16C, even though we don't have quite that low temperatures in the data)
@@ -151,20 +167,21 @@ void ChartModifier::addDataSet()
m_chart->setTickCount(m_ticks, m_tickStep, m_minval);
// Set up sample space based on prepared data
- m_chart->setupSampleSpace(months.size(), years.size());
+ m_chart->setupSampleSpace(years.size(), months.size());
- QOldDataProxy *proxy = new QOldDataProxy;
- m_chart->setDataProxy(proxy);
- // Add data to chart
- static_cast<QOldDataProxy *>(m_chart->dataProxy())->addDataSet(dataSet);
+ // Add data to chart (chart assumes ownership)
+ proxy->resetArray(dataSet);
}
void ChartModifier::addBars()
{
- QVector<float> data;
+ QBarDataRow *dataRow = new QBarDataRow;
for (float i = 0; i < m_columnCount; i++)
- data.append(((i + 1) / (float)m_columnCount) * (float)(rand() % 100));
- static_cast<QOldDataProxy *>(m_chart->dataProxy())->addDataRow(data);
+ dataRow->append(new QBarDataItem(i + m_chart->dataProxy()->rowCount()));
+ //dataRow->append(new QBarDataItem(((i + 1) / (float)m_columnCount) * (float)(rand() % 100)));
+ m_chart->dataProxy()->insertRow(0, dataRow);
+ if (m_chart->dataProxy()->rowCount() <= m_rowCount)
+ m_chart->rowAxis()->setLabels(m_genericRowLabels.mid(0, m_chart->dataProxy()->rowCount()));
}
void ChartModifier::changeStyle()
@@ -347,11 +364,11 @@ void ChartModifier::setSpacingSpecsZ(int spacing)
void ChartModifier::setSampleCountX(int samples)
{
m_columnCount = samples;
- m_chart->setupSampleSpace(m_columnCount, m_rowCount);
+ m_chart->setupSampleSpace(m_rowCount, m_columnCount);
}
void ChartModifier::setSampleCountZ(int samples)
{
m_rowCount = samples;
- m_chart->setupSampleSpace(m_columnCount, m_rowCount);
+ m_chart->setupSampleSpace(m_rowCount, m_columnCount);
}
diff --git a/examples/widget/chart.h b/examples/widget/chart.h
index 20748564..3c943588 100644
--- a/examples/widget/chart.h
+++ b/examples/widget/chart.h
@@ -42,10 +42,10 @@
#define CHARTMODIFIER_H
#include "q3dbars.h"
-#include "qdataset.h"
#include <QFont>
#include <QDebug>
+#include <QStringList>
using namespace QtDataVis3D;
@@ -100,6 +100,8 @@ private:
int m_ticks;
float m_tickStep;
float m_minval;
+ QStringList m_genericRowLabels;
+ QStringList m_genericColumnLabels;
};
#endif
diff --git a/src/datavis3d/axis/qabstractaxis.cpp b/src/datavis3d/axis/qabstractaxis.cpp
index eb47542e..4b3de4ff 100644
--- a/src/datavis3d/axis/qabstractaxis.cpp
+++ b/src/datavis3d/axis/qabstractaxis.cpp
@@ -59,7 +59,7 @@ QString QAbstractAxis::title() const
return d_ptr->m_title;
}
-QVector<QString> &QAbstractAxis::labels() const
+QStringList &QAbstractAxis::labels() const
{
return d_ptr->m_labels;
}
@@ -100,7 +100,7 @@ QAbstractAxisPrivate::~QAbstractAxisPrivate()
{
m_titleItem.clear();
for (int i = 0; i < m_labelItems.size(); i++)
- m_labelItems[i].clear();
+ delete m_labelItems[i];
}
void QAbstractAxisPrivate::setDrawer(Drawer *drawer)
diff --git a/src/datavis3d/axis/qabstractaxis.h b/src/datavis3d/axis/qabstractaxis.h
index 398643b1..a5dd6951 100644
--- a/src/datavis3d/axis/qabstractaxis.h
+++ b/src/datavis3d/axis/qabstractaxis.h
@@ -46,6 +46,7 @@
#include <QObject>
#include <QScopedPointer>
#include <QVector>
+#include <QStringList>
QT_DATAVIS3D_BEGIN_NAMESPACE
@@ -81,7 +82,7 @@ public:
virtual ~QAbstractAxis();
QString title() const;
- QVector<QString> &labels() const;
+ QStringList &labels() const;
AxisOrientation orientation() const;
AxisType type() const;
diff --git a/src/datavis3d/axis/qabstractaxis_p.h b/src/datavis3d/axis/qabstractaxis_p.h
index 7d64c957..5319fc6e 100644
--- a/src/datavis3d/axis/qabstractaxis_p.h
+++ b/src/datavis3d/axis/qabstractaxis_p.h
@@ -66,7 +66,7 @@ public:
virtual ~QAbstractAxisPrivate();
void setDrawer(Drawer *drawer);
- QVector<LabelItem> &labelItems() { return m_labelItems; }
+ QList<LabelItem *> &labelItems() { return m_labelItems; }
LabelItem &titleItem() { return m_titleItem; }
void setOrientation(QAbstractAxis::AxisOrientation orientation);
@@ -83,8 +83,8 @@ protected:
// TODO: Replace Drawer with AbstractRenderer?
LabelItem m_titleItem;
Drawer *m_drawer; // not owned
- QVector<QString> m_labels;
- QVector<LabelItem> m_labelItems;
+ QStringList m_labels;
+ QList<LabelItem *> m_labelItems;
QAbstractAxis::AxisOrientation m_orientation;
QAbstractAxis::AxisType m_type;
diff --git a/src/datavis3d/axis/qcategoryaxis.cpp b/src/datavis3d/axis/qcategoryaxis.cpp
index 346e0685..d268c98b 100644
--- a/src/datavis3d/axis/qcategoryaxis.cpp
+++ b/src/datavis3d/axis/qcategoryaxis.cpp
@@ -53,20 +53,22 @@ QCategoryAxis::~QCategoryAxis()
{
}
-void QCategoryAxis::setLabels(const QVector<QString> &labels)
+void QCategoryAxis::setLabels(const QStringList &labels)
{
int newSize(labels.size());
int oldSize(d_ptr->m_labels.size());
- for (int i = oldSize - 1; i >= newSize; i--)
- d_ptr->m_labelItems[i].clear();
+ for (int i = newSize; i < oldSize; i++)
+ delete d_ptr->m_labelItems.takeLast();
- d_ptr->m_labelItems.resize(newSize);
+ d_ptr->m_labelItems.reserve(newSize);
if (d_ptr->m_drawer) {
for (int i = 0; i < newSize; i++) {
+ if (i >= oldSize)
+ d_ptr->m_labelItems.append(new LabelItem);
if (i >= oldSize || labels.at(i) != d_ptr->m_labels.at(i))
- d_ptr->m_drawer->generateLabelItem(d_ptr->m_labelItems[i], labels.at(i));
+ d_ptr->m_drawer->generateLabelItem(*d_ptr->m_labelItems[i], labels.at(i));
}
}
@@ -90,7 +92,7 @@ QCategoryAxisPrivate::~QCategoryAxisPrivate()
void QCategoryAxisPrivate::updateLabels()
{
for (int i = 0; i < m_labels.size(); i++)
- m_drawer->generateLabelItem(m_labelItems[i], m_labels.at(i));
+ m_drawer->generateLabelItem(*m_labelItems[i], m_labels.at(i));
}
QT_DATAVIS3D_END_NAMESPACE
diff --git a/src/datavis3d/axis/qcategoryaxis.h b/src/datavis3d/axis/qcategoryaxis.h
index 6d7c8ce3..ae0d2ee8 100644
--- a/src/datavis3d/axis/qcategoryaxis.h
+++ b/src/datavis3d/axis/qcategoryaxis.h
@@ -55,7 +55,7 @@ public:
explicit QCategoryAxis();
~QCategoryAxis();
- void setLabels(const QVector<QString> &labels);
+ void setLabels(const QStringList &labels);
protected:
QCategoryAxisPrivate *dptr();
diff --git a/src/datavis3d/data/labelitem_p.h b/src/datavis3d/data/labelitem_p.h
index 4d80642a..32ae305b 100644
--- a/src/datavis3d/data/labelitem_p.h
+++ b/src/datavis3d/data/labelitem_p.h
@@ -71,10 +71,8 @@ public:
void clear();
private:
- // LabelItem owns a global texture id resource, and deletes it at destructor,
- // so we disable assignment operator as a safety measure. We don't use Q_DISABLE_COPY
- // macro, because that also disables the default constructor, which we need.
- LabelItem &operator=(const LabelItem &);
+ Q_DISABLE_COPY(LabelItem);
+
QSize m_size;
GLuint m_textureId;
};
diff --git a/src/datavis3d/data/qabstractdataitem.cpp b/src/datavis3d/data/qabstractdataitem.cpp
index fa86fd91..b955f7a7 100644
--- a/src/datavis3d/data/qabstractdataitem.cpp
+++ b/src/datavis3d/data/qabstractdataitem.cpp
@@ -70,16 +70,6 @@ QAbstractDataItem::~QAbstractDataItem()
{
}
-/*!
- * \a label A formatted label for the data item.
- *
- * Sets the formatted label for the data item.
- */
-void QAbstractDataItem::setLabel(const QString &label)
-{
- d_ptr->m_label = label;
-}
-
QString &QAbstractDataItem::label() const
{
if (d_ptr->m_label.isNull())
@@ -96,4 +86,10 @@ QAbstractDataItemPrivate::~QAbstractDataItemPrivate()
{
}
+void QAbstractDataItemPrivate::setLabel(const QString &label)
+{
+ m_labelItem.clear();
+ m_label = label;
+}
+
QT_DATAVIS3D_END_NAMESPACE
diff --git a/src/datavis3d/data/qabstractdataitem.h b/src/datavis3d/data/qabstractdataitem.h
index 999f3c3d..be69bf49 100644
--- a/src/datavis3d/data/qabstractdataitem.h
+++ b/src/datavis3d/data/qabstractdataitem.h
@@ -57,8 +57,10 @@ protected:
public:
virtual ~QAbstractDataItem();
+ // Set custom label format for this item - otherwise uses label format specified by the proxy
+ //TODO void setLabelFormat(const QString &labelFormat);
+
// formatted label for value
- void setLabel(const QString &label);
QString &label() const;
protected:
diff --git a/src/datavis3d/data/qabstractdataitem_p.h b/src/datavis3d/data/qabstractdataitem_p.h
index 9630a914..ff86b8fc 100644
--- a/src/datavis3d/data/qabstractdataitem_p.h
+++ b/src/datavis3d/data/qabstractdataitem_p.h
@@ -82,12 +82,16 @@ public:
// Selection label item (containing special selection texture, if mode is activated)
// Ownership of the label texture (if any) transfers to QAbstractDataItemPrivate
- void setSelectionLabel(const LabelItem &labelItem);
const LabelItem &selectionLabel() const { return m_selectionLabel; }
LabelItem &selectionLabel() { return m_selectionLabel; }
void setDataProxy(QAbstractDataProxy *proxy) { m_dataProxy = proxy; }
+ // setLabel is not public because changing value automatically reformats it.
+ // If we want to enable custom labels for items, we should have item specific
+ // labelFormat instead.
+ void setLabel(const QString &label);
+
protected:
virtual void formatLabel() = 0;
diff --git a/src/datavis3d/data/qabstractdataproxy.h b/src/datavis3d/data/qabstractdataproxy.h
index b861e8ed..e06e52d3 100644
--- a/src/datavis3d/data/qabstractdataproxy.h
+++ b/src/datavis3d/data/qabstractdataproxy.h
@@ -72,8 +72,6 @@ public:
DataType type() const;
- // TODO: Maybe proxy should be just
-
// Items use this string to format single item labels, unless custom proxy initializes
// item labels with something else.
void setItemLabelFormat(const QString &format);
@@ -82,7 +80,6 @@ public:
QMutex *mutex();
signals:
-// void dataHintChanged();
void itemLabelFormatChanged();
protected:
diff --git a/src/datavis3d/data/qbardataitem.cpp b/src/datavis3d/data/qbardataitem.cpp
index d093e69f..ad70d6e2 100644
--- a/src/datavis3d/data/qbardataitem.cpp
+++ b/src/datavis3d/data/qbardataitem.cpp
@@ -50,7 +50,7 @@ QT_DATAVIS3D_BEGIN_NAMESPACE
* \brief The QBarDataItem class provides a container for resolved data to be added to bar graphs.
* \since 1.0.0
*
- * A QAbstractDataItem holds data for a single rendered bar in a graph.
+ * A QBarDataItem holds data for a single rendered bar in a graph.
* Bar data proxies parse data into QBarDataItem instances for visualizing.
*
* \sa QAbstractDataItem, QBarDataProxy, {Qt Data Visualization 3D C++ Classes}
@@ -64,6 +64,12 @@ QBarDataItem::QBarDataItem()
{
}
+QBarDataItem::QBarDataItem(float value)
+ : QAbstractDataItem(new QBarDataItemPrivate())
+{
+ setValue(value);
+}
+
/*!
* Destroys QBarDataItem.
@@ -75,7 +81,7 @@ QBarDataItem::~QBarDataItem()
void QBarDataItem::setValue(float value)
{
dptr()->m_value = value;
- setLabel(QString()); // Forces reformatting on next access
+ d_ptr->setLabel(QString()); // Forces reformatting on next access
}
float QBarDataItem::value()
@@ -98,10 +104,10 @@ void QBarDataItemPrivate::formatLabel()
// Format the string on first access
QString numStr;
numStr.setNum(m_value);
- // TODO actually format instead of just appending the value
+ // TODO actually format instead of just prepending the value
m_label.clear();
- m_label.append(m_dataProxy->itemLabelFormat());
m_label.append(numStr);
+ m_label.append(m_dataProxy->itemLabelFormat());
}
QT_DATAVIS3D_END_NAMESPACE
diff --git a/src/datavis3d/data/qbardataitem.h b/src/datavis3d/data/qbardataitem.h
index d68e283b..19f77617 100644
--- a/src/datavis3d/data/qbardataitem.h
+++ b/src/datavis3d/data/qbardataitem.h
@@ -52,6 +52,7 @@ class QT_DATAVIS3D_EXPORT QBarDataItem : public QAbstractDataItem
{
public:
QBarDataItem();
+ QBarDataItem(float value);
~QBarDataItem();
void setValue(float value);
diff --git a/src/datavis3d/data/qbardataproxy.cpp b/src/datavis3d/data/qbardataproxy.cpp
index 6495886c..ea77b870 100644
--- a/src/datavis3d/data/qbardataproxy.cpp
+++ b/src/datavis3d/data/qbardataproxy.cpp
@@ -57,49 +57,91 @@ QBarDataProxy::~QBarDataProxy()
void QBarDataProxy::resetArray(int rowCount, int columnCount)
{
- dptr()->resetArray(rowCount, columnCount);
+ resetArray(0, rowCount, columnCount);
+}
+
+void QBarDataProxy::resetArray(QBarDataArray *newArray, int rowCount, int columnCount)
+{
+ dptr()->resetArray(newArray, rowCount, columnCount);
emit arrayReset();
}
+void QBarDataProxy::resetArray(QBarDataArray *newArray)
+{
+ int rowCount(newArray->size());
+ int columnCount(0);
+
+ if (rowCount)
+ columnCount = newArray->at(0)->size();
+
+ resetArray(newArray, rowCount, columnCount);
+}
+
void QBarDataProxy::setRow(int rowIndex, QBarDataRow *row)
{
dptr()->setRow(rowIndex, row);
emit rowsChanged(rowIndex, 1);
}
+int QBarDataProxy::addRow(QBarDataRow *row)
+{
+ int addIndex = dptr()->addRow(row);
+ emit rowsAdded(addIndex, 1);
+ return addIndex;
+}
+
int QBarDataProxy::addRows(QBarDataArray *rows)
{
int addCount = rows->size();
- int addIndex = dptr()->addRows(rows); // deletes rows
+ int addIndex = dptr()->addRows(rows); // deletes original rows array
emit rowsAdded(addIndex, addCount);
return addIndex;
}
+void QBarDataProxy::insertRow(int rowIndex, QBarDataRow *row)
+{
+ dptr()->insertRow(rowIndex, row);
+ emit rowsInserted(rowIndex, 1);
+}
+
void QBarDataProxy::insertRows(int rowIndex, QBarDataArray *rows)
{
int insertCount = rows->size();
- dptr()->insertRows(rowIndex, rows); // deletes rows
+ dptr()->insertRows(rowIndex, rows); // deletes original rows array
emit rowsInserted(rowIndex, insertCount);
}
-int QBarDataProxy::rowCount()
+void QBarDataProxy::setRowCount(int count)
{
- return dptr()->m_rowCount;
+ QMutexLocker locker(mutex());
+ int oldCount = dptr()->m_rowCount;
+
+ dptr()->setRowCount(count);
+
+ locker.unlock();
+
+ if (oldCount < count)
+ emit rowsAdded(oldCount, count - oldCount);
+ else if (oldCount > count)
+ emit rowsRemoved(count, oldCount - count);
}
-void QBarDataProxy::setRowCount(int count)
+void QBarDataProxy::setColumnCount(int count)
{
- dptr()->setRowCount(count);
+ QMutexLocker locker(mutex());
+ dptr()->setColumnCount(count);
+ // TODO emit columnsAdded/columnsRemoved
}
-int QBarDataProxy::columnCount()
+// Mutexing data accessors should be done by user
+int QBarDataProxy::rowCount()
{
- return dptr()->m_columnCount;
+ return dptr()->m_rowCount;
}
-void QBarDataProxy::setColumnCount(int count)
+int QBarDataProxy::columnCount()
{
- dptr()->setColumnCount(count);
+ return dptr()->m_columnCount;
}
const QBarDataArray &QBarDataProxy::array() const
@@ -138,37 +180,59 @@ QBarDataProxyPrivate::QBarDataProxyPrivate(QBarDataProxy *q)
QBarDataProxyPrivate::~QBarDataProxyPrivate()
{
- resetArray(0, 0);
+ clearArray();
}
-void QBarDataProxyPrivate::resetArray(int rowCount, int columnCount)
+void QBarDataProxyPrivate::resetArray(QBarDataArray *newArray, int rowCount, int columnCount)
{
QMutexLocker locker(&m_mutex);
- for (int i = 0; i < m_rowCount; i++)
- clearRow(i);
- m_dataArray.clear();
+ clearArray();
m_rowCount = rowCount;
m_columnCount = columnCount;
+ if (newArray) {
+ m_dataArray = *newArray;
+ delete newArray;
+ }
- m_dataArray.reserve(m_rowCount);
- for (int i = 0; i < m_rowCount; i++)
- addEmptyRow();
-}
+ int oldSize = m_dataArray.size();
-//void QBarDataProxyPrivate::resetRow(int rowIndex)
-//{
-// QMutexLocker locker(&m_mutex);
-//}
+ if (oldSize < m_rowCount) {
+ m_dataArray.reserve(m_rowCount);
+ for (int i = oldSize; i < m_rowCount; i++)
+ m_dataArray.append(0);
+ } else if (oldSize > m_rowCount) {
+ for (int i = oldSize - 1; i >= m_rowCount; i--) {
+ clearRow(i);
+ m_dataArray.removeLast();
+ }
+ }
+
+ for (int i = 0; i < m_dataArray.size(); i++)
+ fixRow(m_dataArray.at(i));
+}
void QBarDataProxyPrivate::setRow(int rowIndex, QBarDataRow *row)
{
QMutexLocker locker(&m_mutex);
clearRow(rowIndex);
- fixRow(*row);
+ fixRow(row);
m_dataArray[rowIndex] = row;
}
+int QBarDataProxyPrivate::addRow(QBarDataRow *row)
+{
+ QMutexLocker locker(&m_mutex);
+ int currentSize = m_rowCount;
+ // Init column count to row size if not yet explicitly set
+ if (!m_columnCount)
+ m_columnCount = row->size();
+ fixRow(row);
+ m_dataArray.append(row);
+ m_rowCount++;
+ return currentSize;
+}
+
int QBarDataProxyPrivate::addRows(QBarDataArray *rows)
{
QMutexLocker locker(&m_mutex);
@@ -177,7 +241,7 @@ int QBarDataProxyPrivate::addRows(QBarDataArray *rows)
if (!m_columnCount && rows->size())
m_columnCount = rows->at(0)->size();
for (int i = 0; i < rows->size(); i++) {
- fixRow(*rows->at(i));
+ fixRow(rows->at(i));
m_dataArray.append(rows->at(i));
}
m_rowCount += rows->size();
@@ -185,6 +249,17 @@ int QBarDataProxyPrivate::addRows(QBarDataArray *rows)
return currentSize;
}
+void QBarDataProxyPrivate::insertRow(int rowIndex, QBarDataRow *row)
+{
+ QMutexLocker locker(&m_mutex);
+ // Init column count to row size if not yet explicitly set
+ if (!m_columnCount)
+ m_columnCount = row->size();
+ fixRow(row);
+ m_dataArray.insert(rowIndex, row);
+ m_rowCount++;
+}
+
void QBarDataProxyPrivate::insertRows(int rowIndex, QBarDataArray *rows)
{
QMutexLocker locker(&m_mutex);
@@ -192,55 +267,87 @@ void QBarDataProxyPrivate::insertRows(int rowIndex, QBarDataArray *rows)
if (!m_columnCount && rows->size())
m_columnCount = rows->at(0)->size();
for (int i = 0; i < rows->size(); i++) {
- fixRow(*rows->at(i));
+ fixRow(rows->at(i));
m_dataArray.insert(rowIndex, rows->at(i));
}
m_rowCount += rows->size();
delete rows;
}
+void QBarDataProxyPrivate::setRowCount(int count)
+{
+ // Locked already in public implementatation to avoid multiple lockings per call
+ if (m_rowCount != count) {
+ if (count < m_columnCount) {
+ for (int i = m_columnCount - 1; i >= count; i--) {
+ clearRow(i);
+ m_dataArray.removeLast();
+ }
+ } else if (count > m_columnCount) {
+ for (int i = m_columnCount; i < count; i++)
+ m_dataArray.append(0);
+ }
+ m_rowCount = count;
+ }
+}
+
+void QBarDataProxyPrivate::setColumnCount(int count)
+{
+ QMutexLocker locker(&m_mutex);
+ if (m_columnCount != count) {
+ m_columnCount = count;
+ for (int i = 0; i < m_rowCount; i++)
+ fixRow(m_dataArray.at(i));
+ }
+}
+
// Protected & private functions. Do not mutex as these are used from mutexed functions.
void QBarDataProxyPrivate::clearRow(int rowIndex)
{
- for (int i = 0; i < m_columnCount; i++)
- delete m_dataArray[rowIndex]->at(i);
- delete m_dataArray[rowIndex];
- m_dataArray[rowIndex] = 0;
+ if (m_dataArray[rowIndex]) {
+ for (int i = 0; i < m_columnCount; i++)
+ delete m_dataArray[rowIndex]->at(i);
+ delete m_dataArray[rowIndex];
+ m_dataArray[rowIndex] = 0;
+ }
}
-// Note that this function doesn't change rowCount
-void QBarDataProxyPrivate::addEmptyRow()
+void QBarDataProxyPrivate::clearArray()
{
- QBarDataRow *newRow = new QBarDataRow;
- newRow->reserve(m_columnCount);
- for (int i = 0; i < m_columnCount; i++)
- newRow->append(0);
- m_dataArray.append(newRow);
+ for (int i = 0; i < m_rowCount; i++)
+ clearRow(i);
+ m_dataArray.clear();
}
-void QBarDataProxyPrivate::fixRow(QBarDataRow &row)
+void QBarDataProxyPrivate::fixRow(QBarDataRow *row)
{
- int rowSize = row.size();
+ if (!row)
+ return;
+
+ int rowSize = row->size();
if (rowSize < m_columnCount) {
for (int i = rowSize; i < m_columnCount; i++)
- row.append(new QBarDataItem);
+ row->append(new QBarDataItem);
} else if (rowSize > m_columnCount) {
for (int i = m_columnCount; i < rowSize; i++)
- delete row.takeLast();
+ delete row->takeLast();
}
for (int i = 0; i < m_columnCount; i++) {
- if (row.at(i))
- row.at(i)->d_ptr->setDataProxy(q_ptr);
+ if (row->at(i))
+ row->at(i)->d_ptr->setDataProxy(q_ptr);
}
}
QPair<GLfloat, GLfloat> QBarDataProxyPrivate::limitValues(int startRow, int endRow, int startColumn, int endColumn)
{
+ QMutexLocker locker(&m_mutex);
QPair<GLfloat, GLfloat> limits = qMakePair(100.0f, -100.0f);
endRow = qMin(endRow, m_rowCount - 1);
endColumn = qMin(endColumn, m_columnCount - 1);
for (int i = startRow; i <= endRow; i++) {
+ if (!m_dataArray.at(i))
+ continue;
for (int j = startColumn; j <= endColumn; j++) {
QBarDataItem *item = m_dataArray.at(i)->at(j);
if (item) {
@@ -255,30 +362,4 @@ QPair<GLfloat, GLfloat> QBarDataProxyPrivate::limitValues(int startRow, int endR
return limits;
}
-void QBarDataProxyPrivate::setRowCount(int count)
-{
- if (m_rowCount != count) {
- if (count < m_columnCount) {
- for (int i = m_columnCount - 1; i >= count; i--) {
- clearRow(i);
- m_dataArray.removeLast();
- }
- } else if (count > m_columnCount) {
- for (int i = m_columnCount; i < count; i++) {
- addEmptyRow();
- }
- }
- m_rowCount = count;
- }
-}
-
-void QBarDataProxyPrivate::setColumnCount(int count)
-{
- if (m_columnCount != count) {
- m_columnCount = count;
- for (int i = 0; i < m_rowCount; i++)
- fixRow(*m_dataArray.at(i));
- }
-}
-
QT_DATAVIS3D_END_NAMESPACE
diff --git a/src/datavis3d/data/qbardataproxy.h b/src/datavis3d/data/qbardataproxy.h
index a2631a23..3ac13f78 100644
--- a/src/datavis3d/data/qbardataproxy.h
+++ b/src/datavis3d/data/qbardataproxy.h
@@ -63,46 +63,53 @@ public:
explicit QBarDataProxy();
virtual ~QBarDataProxy();
+ // Anyone accessing the data needs to protect the access with QAbstractDataProxy::mutex().
+ // However, unprotected use from same thread that handles data setting to proxy is generally
+ // not very risky, as QtDataVis3D does very little automatic changing of data that can be changed via
+ // public interface. E.g. Item labels is one such example that could conflict.
+ int rowCount();
+ int columnCount();
+ const QBarDataArray &array() const;
+ const QBarDataRow *rowAt(int rowIndex) const;
+ QBarDataItem *itemAt(int rowIndex, int columnIndex);
+
// The data array is a list of list (rows) of QBarDataItem instances.
- // Each row can contains exactly the column count items, empty items are added if
+ // Each row can contains exactly zero or the column count items, empty items are added if
// adding too short rows or removed if adding too long rows.
// All array/item manipulation functions are internally protected by data mutex.
// TODO: Should we remove internal mutexing and require user to mutex also on data manipulations?
- // TODO: That would lead to signal emissions from inside the mutex, potential for deadlock?
+ // TODO: Upside would be enabling user to mix data setters and getters within same mutex scope.
+ // TODO: Downside would be signal emissions from inside the mutex scope, which has potential for deadlock.
- // TODO Should data manipulation/access methods be protected to enforce subclassing use of proxy?
+ // TODO Should data manipulation/access methods be protected rather than public to enforce subclassing use of proxy?
// TODO Leaving them public gives user more options.
- // Anyone accessing the data needs to protect the access with QAbstractDataProxy::mutex().
- const QBarDataArray &array() const;
- const QBarDataRow *rowAt(int rowIndex) const;
- QBarDataItem *itemAt(int rowIndex, int columnIndex);
+ // QBarDataProxy takes ownership of all QBarDataArrays, QBarDataRows, and QBarDataItems passed to it.
- int rowCount();
void setRowCount(int count);
- int columnCount();
void setColumnCount(int count);
- // QBarDataProxy takes ownership of all QBarDataArrays, QBarDataRows, and QBarDataItems passed to it.
-
// Clears the array and reserves specified amount of new empty rows.
void resetArray(int rowCount, int columnCount);
- // TODO void resetArray(QBarDataArray *newArray);
- // TODO void resetRow(int rowIndex); // Clear a row
- // TODO void resetColumn(int columnIndex);
- // TODO void resetItem(int rowIndex, int columnIndex); // deletes the item
+ // Clears the existing array and sets it data to new array. Fixes the array according to
+ // specified row and column counts.
+ void resetArray(QBarDataArray *newArray, int rowCount, int columnCount);
+ // Clears the existing array and sets it data to new array.
+ // Row count is the row count of new array, and column count is the column count of
+ // the first row of the new array. Rest of the rows are fixed to this count.
+ void resetArray(QBarDataArray *newArray);
void setRow(int rowIndex, QBarDataRow *row);
// TODO void setColumn(int columnIndex, QBarDataRow *column);
// TODO void setItem(int rowIndex, int columnIndex, QBarDataItem *item);
- // TODO int addRow(QBarDataRow *row); // returns the index of added row
+ int addRow(QBarDataRow *row); // returns the index of added row
int addRows(QBarDataArray *rows); // returns the index of first added row
// TODO int addColumns(QBarDataArray *columns); // returns the index of first added column
- // TODO void insertRow(int rowIndex, QBarDataRow *row);
+ void insertRow(int rowIndex, QBarDataRow *row);
void insertRows(int rowIndex, QBarDataArray *rows);
// TODO void insertColumns(int columnIndex, QBarDataArray *columns);
@@ -120,7 +127,6 @@ signals:
void rowsChanged(int startIndex, int count);
void rowsRemoved(int startIndex, int count); // Index may be over current array size if removed from end
void rowsInserted(int startIndex, int count);
- // TODO void itemChanged(int rowIndex, int columnIndex);
protected:
QBarDataProxyPrivate *dptr();
diff --git a/src/datavis3d/data/qbardataproxy_p.h b/src/datavis3d/data/qbardataproxy_p.h
index 276b1e56..83af659b 100644
--- a/src/datavis3d/data/qbardataproxy_p.h
+++ b/src/datavis3d/data/qbardataproxy_p.h
@@ -66,10 +66,11 @@ public:
QBarDataProxyPrivate(QBarDataProxy *q);
virtual ~QBarDataProxyPrivate();
- void resetArray(int rowCount, int columnCount);
- // TODO void resetRow(int rowIndex);
+ void resetArray(QBarDataArray *newArray, int rowCount, int columnCount);
void setRow(int rowIndex, QBarDataRow *row);
+ int addRow(QBarDataRow *row);
int addRows(QBarDataArray *rows);
+ void insertRow(int rowIndex, QBarDataRow *row);
void insertRows(int rowIndex, QBarDataArray *rows);
QPair<GLfloat, GLfloat> limitValues(int startRow, int startColumn, int rowCount, int columnCount);
@@ -79,8 +80,8 @@ public:
protected:
void clearRow(int rowIndex);
- void addEmptyRow();
- void fixRow(QBarDataRow &row);
+ void clearArray();
+ void fixRow(QBarDataRow *row);
QBarDataArray m_dataArray;
diff --git a/src/datavis3d/data/qolddataproxy.cpp b/src/datavis3d/data/qolddataproxy.cpp
index 1bdfd2ee..d2fb2cb0 100644
--- a/src/datavis3d/data/qolddataproxy.cpp
+++ b/src/datavis3d/data/qolddataproxy.cpp
@@ -176,7 +176,7 @@ void QOldDataProxy::addProxySet(QDataSet *dataSet)
newProxyArray->append(newProxyRow);
}
- resetArray(rowCount(), columnCount());
+ resetArray(0, 0);
addRows(newProxyArray);
}
diff --git a/src/datavis3d/engine/bars3dcontroller.cpp b/src/datavis3d/engine/bars3dcontroller.cpp
index 90390149..c3f7aa5f 100644
--- a/src/datavis3d/engine/bars3dcontroller.cpp
+++ b/src/datavis3d/engine/bars3dcontroller.cpp
@@ -76,12 +76,14 @@ Bars3dController::Bars3dController(QRect boundRect)
m_tickStep(0),
m_tickMinimum(0.0f),
m_renderer(0),
- m_data(new QBarDataProxy)
+ m_data(0)
{
// Default axes. Only Y axis can actually be changed by user.
setAxisX(new QCategoryAxis());
setAxisY(new QValueAxis());
setAxisZ(new QCategoryAxis());
+
+ setDataProxy(new QBarDataProxy);
}
Bars3dController::~Bars3dController()
@@ -406,7 +408,7 @@ void Bars3dController::setMeshFileName(const QString &objFileName)
}
// TODO: This sets data window. Needs more parameters, now assumes window always starts at 0,0.
-void Bars3dController::setupSampleSpace(int columnCount, int rowCount)
+void Bars3dController::setupSampleSpace(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/bars3drenderer.cpp b/src/datavis3d/engine/bars3drenderer.cpp
index d3cdfdaf..6e13b82f 100644
--- a/src/datavis3d/engine/bars3drenderer.cpp
+++ b/src/datavis3d/engine/bars3drenderer.cpp
@@ -310,7 +310,6 @@ void Bars3dRenderer::render(const QBarDataArray &dataArray,
const LabelItem &zLabel,
const GLuint defaultFboHandle)
{
- // TODO: Protect access to data with mutex!
#ifdef DISPLAY_RENDER_SPEED
// For speed computation
if (m_isFirstFrame) {
@@ -481,11 +480,13 @@ void Bars3dRenderer::drawSlicedScene(CameraHelper *camera,
QBarDataItem *dummyItem = NULL;
const LabelItem &sliceSelectionLabel = *m_sliceTitleItem;
if (ModeZoomRow == m_cachedSelectionMode) {
- m_drawer->drawLabel(*dummyItem, sliceSelectionLabel, viewMatrix, projectionMatrix,
- QVector3D(0.0f, m_yAdjustment, zComp),
- QVector3D(0.0f, 0.0f, 0.0f), 0,
- m_cachedSelectionMode, m_labelShader,
- m_labelObj, camera, false, false, LabelTop);
+ if (m_sliceTitleItem) {
+ m_drawer->drawLabel(*dummyItem, sliceSelectionLabel, viewMatrix, projectionMatrix,
+ QVector3D(0.0f, m_yAdjustment, zComp),
+ QVector3D(0.0f, 0.0f, 0.0f), 0,
+ m_cachedSelectionMode, m_labelShader,
+ m_labelObj, camera, false, false, LabelTop);
+ }
m_drawer->drawLabel(*dummyItem, zLabel, viewMatrix, projectionMatrix,
QVector3D(0.0f, m_yAdjustment, zComp),
QVector3D(0.0f, 0.0f, 0.0f), 0,
@@ -497,11 +498,13 @@ void Bars3dRenderer::drawSlicedScene(CameraHelper *camera,
QVector3D(0.0f, 0.0f, 0.0f), 0,
m_cachedSelectionMode, m_labelShader,
m_labelObj, camera, false, false, LabelBottom);
- m_drawer->drawLabel(*dummyItem, sliceSelectionLabel, viewMatrix, projectionMatrix,
- QVector3D(0.0f, m_yAdjustment, zComp),
- QVector3D(0.0f, 0.0f, 0.0f), 0,
- m_cachedSelectionMode, m_labelShader,
- m_labelObj, camera, false, false, LabelTop);
+ if (m_sliceTitleItem) {
+ m_drawer->drawLabel(*dummyItem, sliceSelectionLabel, viewMatrix, projectionMatrix,
+ QVector3D(0.0f, m_yAdjustment, zComp),
+ QVector3D(0.0f, 0.0f, 0.0f), 0,
+ m_cachedSelectionMode, m_labelShader,
+ m_labelObj, camera, false, false, LabelTop);
+ }
}
m_drawer->drawLabel(*dummyItem, yLabel, viewMatrix, projectionMatrix,
QVector3D(0.0f, m_yAdjustment, zComp),
@@ -520,22 +523,22 @@ void Bars3dRenderer::drawSlicedScene(CameraHelper *camera,
m_labelObj, camera);
// Draw labels
- const LabelItem *labelItem;
// TODO: Protect with mutex or redesign axis label handling?
if (m_sliceAxisP->labelItems().size() > col) {
+ const LabelItem *labelItem(0);
// If draw order of bars is flipped, label draw order should be too
if (m_xFlipped) {
- labelItem = &m_sliceAxisP->labelItems().at(col);
+ labelItem = m_sliceAxisP->labelItems().at(col);
} else {
- labelItem = &m_sliceAxisP->labelItems().at(
+ labelItem = m_sliceAxisP->labelItems().at(
m_sliceAxisP->labelItems().size() - col - 1);
}
+ m_drawer->drawLabel(*item, *labelItem, viewMatrix, projectionMatrix,
+ QVector3D(0.0f, m_yAdjustment, zComp),
+ QVector3D(0.0f, 0.0f, -45.0f), (item->value() / m_heightNormalizer),
+ m_cachedSelectionMode, m_labelShader,
+ m_labelObj, camera, false, false, LabelBelow);
}
- m_drawer->drawLabel(*item, *labelItem, viewMatrix, projectionMatrix,
- QVector3D(0.0f, m_yAdjustment, zComp),
- QVector3D(0.0f, 0.0f, -45.0f), (item->value() / m_heightNormalizer),
- m_cachedSelectionMode, m_labelShader,
- m_labelObj, camera, false, false, LabelBelow);
}
glDisable(GL_TEXTURE_2D);
@@ -668,6 +671,8 @@ void Bars3dRenderer::drawScene(const QBarDataArray &dataArray,
if (dataArray.size() <= row || !dataArray.at(row))
continue;
for (int bar = startBar; bar != stopBar; bar += stepBar) {
+ if (dataArray.at(row)->size() <= bar)
+ continue;
QBarDataItem *item = dataArray.at(row)->at(bar);
if (!item)
continue;
@@ -770,6 +775,8 @@ void Bars3dRenderer::drawScene(const QBarDataArray &dataArray,
if (dataArray.size() <= row || !dataArray.at(row))
continue;
for (int bar = startBar; bar != stopBar; bar += stepBar) {
+ if (dataArray.at(row)->size() <= bar)
+ continue;
QBarDataItem *item = dataArray.at(row)->at(bar);
if (!item)
continue;
@@ -877,12 +884,15 @@ void Bars3dRenderer::drawScene(const QBarDataArray &dataArray,
if (!m_cachedIsSlicingActivated && m_sliceSelection) {
m_sliceSelection->clear(); // Slice doesn't own its items
m_sliceAxisP = 0;
+ m_sliceTitleItem = 0;
}
bool barSelectionFound = false;
for (int row = startRow; row != stopRow; row += stepRow) {
if (dataArray.size() <= row || !dataArray.at(row))
continue;
for (int bar = startBar; bar != stopBar; bar += stepBar) {
+ if (dataArray.at(row)->size() <= bar)
+ continue;
QBarDataItem *item = dataArray.at(row)->at(bar);
if (!item)
continue;
@@ -959,8 +969,10 @@ void Bars3dRenderer::drawScene(const QBarDataArray &dataArray,
if (!m_sliceAxisP) {
// m_sliceAxisP is the axis for labels, while title comes from different axis.
m_sliceAxisP = m_controller->axisZ()->d_ptr.data();
- m_sliceTitleItem = &m_controller->axisX()->d_ptr->labelItems().at(
- m_controller->axisX()->d_ptr->labelItems().size() - row - 1);
+ if (m_controller->axisX()->d_ptr->labelItems().size() > row) {
+ m_sliceTitleItem = m_controller->axisX()->d_ptr->labelItems().at(
+ m_controller->axisX()->d_ptr->labelItems().size() - row - 1);
+ }
}
}
break;
@@ -975,8 +987,10 @@ void Bars3dRenderer::drawScene(const QBarDataArray &dataArray,
if (!m_sliceAxisP) {
// m_sliceAxisP is the axis for labels, while title comes from different axis.
m_sliceAxisP = m_controller->axisX()->d_ptr.data();
- m_sliceTitleItem = &m_controller->axisZ()->d_ptr->labelItems().at(
- m_controller->axisZ()->d_ptr->labelItems().size() - bar - 1);
+ if (m_controller->axisZ()->d_ptr->labelItems().size() > bar) {
+ m_sliceTitleItem = m_controller->axisZ()->d_ptr->labelItems().at(
+ m_controller->axisZ()->d_ptr->labelItems().size() - bar - 1);
+ }
}
}
break;
@@ -1384,10 +1398,9 @@ void Bars3dRenderer::drawScene(const QBarDataArray &dataArray,
#else
// TODO: using static is bad, cannot use two barcharts at the same time!
// TODO: Besides, doesn't m_previouslySelectedBar mechanic already cover this?
- static bool firstSelection = true;
// Draw the value string followed by row label and column label
LabelItem &labelItem = m_selectedBar->d_ptr->selectionLabel();
- if (firstSelection || m_previouslySelectedBar != m_selectedBar || m_updateLabels) {
+ if (m_previouslySelectedBar != m_selectedBar || m_updateLabels) {
QString labelText = m_selectedBar->label();
if ((m_controller->axisZ()->labels().size() > m_selectedBar->dptr()->position().y())
&& (m_controller->axisX()->labels().size() > m_selectedBar->dptr()->position().x())) {
@@ -1400,7 +1413,6 @@ void Bars3dRenderer::drawScene(const QBarDataArray &dataArray,
}
m_drawer->generateLabelItem(labelItem, labelText);
m_previouslySelectedBar = m_selectedBar;
- firstSelection = false;
}
m_drawer->drawLabel(*m_selectedBar, labelItem, viewMatrix, projectionMatrix,
@@ -1462,7 +1474,7 @@ void Bars3dRenderer::drawScene(const QBarDataArray &dataArray,
// TODO: Try it; draw the label here
m_dummyBarDataItem->d_ptr->setTranslation(labelPos);
- const LabelItem &axisLabelItem = m_controller->axisX()->d_ptr->labelItems().at(
+ const LabelItem &axisLabelItem = *m_controller->axisX()->d_ptr->labelItems().at(
m_controller->axisX()->d_ptr->labelItems().size() - row - 1);
//qDebug() << "labelPos, row" << row + 1 << ":" << labelPos << dataSet->rowLabels().at(row);
@@ -1505,7 +1517,7 @@ void Bars3dRenderer::drawScene(const QBarDataArray &dataArray,
// TODO: Try it; draw the label here
m_dummyBarDataItem->d_ptr->setTranslation(labelPos);
- const LabelItem &axisLabelItem = m_controller->axisZ()->d_ptr->labelItems().at(
+ const LabelItem &axisLabelItem = *m_controller->axisZ()->d_ptr->labelItems().at(
m_controller->axisZ()->d_ptr->labelItems().size() - bar - 1);
//qDebug() << "labelPos, col" << bar + 1 << ":" << labelPos << dataSet->columnLabels().at(bar);
diff --git a/src/datavis3d/engine/drawer.cpp b/src/datavis3d/engine/drawer.cpp
index 79344c6f..b5a59607 100644
--- a/src/datavis3d/engine/drawer.cpp
+++ b/src/datavis3d/engine/drawer.cpp
@@ -305,6 +305,8 @@ void Drawer::generateLabelItem(LabelItem &item, const QString &text)
{
initializeOpenGL();
+ item.clear();
+
// Create labels
// Print label into a QImage using QPainter
QImage label = Utils::printTextToImage(m_font,
diff --git a/src/datavis3d/engine/maps3dcontroller.cpp b/src/datavis3d/engine/maps3dcontroller.cpp
index fc06f3a5..8df4b53e 100644
--- a/src/datavis3d/engine/maps3dcontroller.cpp
+++ b/src/datavis3d/engine/maps3dcontroller.cpp
@@ -840,7 +840,6 @@ void Maps3DController::drawScene(const GLuint defaultFboHandle)
// Draw just the value string of the selected bar
QBarDataItem dummyItem; // TODO temporary solution
dummyItem.setValue(m_selectedBar->d_ptr->value());
- dummyItem.setLabel(m_selectedBar->d_ptr->valueStr());
if (prevItem != m_selectedBar || m_updateLabels) {
m_drawer->generateLabelTexture(&dummyItem);
prevItem = m_selectedBar;
diff --git a/src/datavis3d/engine/q3dbars.h b/src/datavis3d/engine/q3dbars.h
index b38db363..6a9922e2 100644
--- a/src/datavis3d/engine/q3dbars.h
+++ b/src/datavis3d/engine/q3dbars.h
@@ -73,25 +73,6 @@ public:
explicit Q3DBars();
~Q3DBars();
- // Add a row of data. Each new row is added to the front of the sample space, moving previous
- // rows back (if sample space is more than one row deep)
- //void addDataRow(const QVector<float> &dataRow);
-
- // ownership of dataItems is transferred
- //void addDataRow(const QVector<QDataItem*> &dataRow);
-
- // ownership of dataRow is transferred
- //void addDataRow(QDataRow *dataRow);
-
- // Add complete data set at a time, as a vector of data rows
- //void addDataSet(const QVector< QVector<float> > &data);
-
- // ownership of dataItems is transferred
- //void addDataSet(const QVector< QVector<QDataItem*> > &data);
-
- // ownership of dataSet is transferred
- //void addDataSet(QDataSet* dataSet);
-
// 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