summaryrefslogtreecommitdiffstats
path: root/src/datavisualization/data/qbardataproxy.cpp
diff options
context:
space:
mode:
authorMiikka Heikkinen <miikka.heikkinen@digia.com>2013-09-10 16:26:11 +0300
committerMiikka Heikkinen <miikka.heikkinen@digia.com>2013-09-11 10:42:53 +0300
commitd93f5f3b64fdb52cc150232f6b6d80ffdb57db78 (patch)
tree4a99ecc02c2e885b56abb1082527e482967b84f8 /src/datavisualization/data/qbardataproxy.cpp
parentd315336b202ec1c1260f96945a23fde6d2c41b69 (diff)
QBarDataProxy now has list of row and column labels
Category axes use those labels if no explicit labels are set to them. + Other misc fixes Task-number: QTRD-2252 Change-Id: Idc15e0cc1cdeb08195b2e2baeead9cfef2533e04 Reviewed-by: Tomi Korpipää <tomi.korpipaa@digia.com>
Diffstat (limited to 'src/datavisualization/data/qbardataproxy.cpp')
-rw-r--r--src/datavisualization/data/qbardataproxy.cpp291
1 files changed, 266 insertions, 25 deletions
diff --git a/src/datavisualization/data/qbardataproxy.cpp b/src/datavisualization/data/qbardataproxy.cpp
index 85400831..418bb747 100644
--- a/src/datavisualization/data/qbardataproxy.cpp
+++ b/src/datavisualization/data/qbardataproxy.cpp
@@ -37,6 +37,12 @@ QT_DATAVISUALIZATION_BEGIN_NAMESPACE
* QBarDataRow pointers should not be used to modify data further after they have been passed to
* the proxy, as such modifications will not trigger proper signals.
*
+ * QBarDataProxy optionally keeps track of row and column labels, which Q3DCategoryAxis can utilize
+ * to show axis labels. The row and column labels are stored in separate array from the data and
+ * row manipulation methods provide an alternate versions that don't affect the row labels.
+ * This enables the option of having row labels that relate to the position of the data in the
+ * array rather than the data itself.
+ *
* QBarDataProxy supports the following format tags for QAbstractDataProxy::setItemLabelFormat():
* \table
* \row
@@ -88,37 +94,82 @@ QBarDataProxy::~QBarDataProxy()
}
/*!
+ * Clears the existing array and row and column labels.
+ */
+void QBarDataProxy::resetArray()
+{
+ resetArray(0, QStringList(), QStringList());
+}
+
+/*!
* Clears the existing array and takes ownership of the \a newArray. Do not use \a newArray pointer
* to further modify data after QBarDataProxy assumes ownership of it, as such modifications will
* not trigger proper signals.
* Passing null array clears all data.
+ * Row and column labels are not affected.
*/
void QBarDataProxy::resetArray(QBarDataArray *newArray)
{
- if (dptr()->resetArray(newArray))
+ if (dptr()->resetArray(newArray, 0, 0))
+ emit arrayReset();
+}
+
+/*!
+ * Clears the existing array and takes ownership of the \a newArray. Do not use \a newArray pointer
+ * to further modify data after QBarDataProxy assumes ownership of it, as such modifications will
+ * not trigger proper signals.
+ * Passing null array clears all data.
+ * The \a rowLabels and \a columnLabels lists specify the new labels for rows and columns.
+ */
+void QBarDataProxy::resetArray(QBarDataArray *newArray, const QStringList &rowLabels,
+ const QStringList &columnLabels)
+{
+ if (dptr()->resetArray(newArray, &rowLabels, &columnLabels))
emit arrayReset();
}
/*!
* Changes existing rows by replacing a row at \a rowIndex with \a row.
+ * Existing row labels are not affected.
*/
void QBarDataProxy::setRow(int rowIndex, QBarDataRow *row)
{
- dptr()->setRow(rowIndex, row);
+ dptr()->setRow(rowIndex, row, 0);
+ emit rowsChanged(rowIndex, 1);
+}
+
+/*!
+ * Changes existing rows by replacing a row at \a rowIndex with \a row.
+ * Changes the row label to the \a label.
+ */
+void QBarDataProxy::setRow(int rowIndex, QBarDataRow *row, const QString &label)
+{
+ dptr()->setRow(rowIndex, row, &label);
emit rowsChanged(rowIndex, 1);
}
/*!
* Changes existing rows by replacing a rows starting at \a rowIndex with \a rows.
+ * Existing row labels are not affected.
*/
void QBarDataProxy::setRows(int rowIndex, const QBarDataArray &rows)
{
- dptr()->setRows(rowIndex, rows);
+ dptr()->setRows(rowIndex, rows, 0);
emit rowsChanged(rowIndex, rows.size());
}
/*!
- * Changes a single item at \a rowIndex, \a columnIndex with \a item.
+ * Changes existing rows by replacing a rows starting at \a rowIndex with \a rows.
+ * The row labels are changed to \a labels.
+ */
+void QBarDataProxy::setRows(int rowIndex, const QBarDataArray &rows, const QStringList &labels)
+{
+ dptr()->setRows(rowIndex, rows, &labels);
+ emit rowsChanged(rowIndex, rows.size());
+}
+
+/*!
+ * Changes a single item at \a rowIndex, \a columnIndex to the \a item.
*/
void QBarDataProxy::setItem(int rowIndex, int columnIndex, const QBarDataItem &item)
{
@@ -128,56 +179,111 @@ void QBarDataProxy::setItem(int rowIndex, int columnIndex, const QBarDataItem &i
/*!
* Adds a new \a row to the end of array.
+ * Existing row labels are not affected.
*
* \return index of the added row.
*/
int QBarDataProxy::addRow(QBarDataRow *row)
{
- int addIndex = dptr()->addRow(row);
+ int addIndex = dptr()->addRow(row, 0);
+ emit rowsAdded(addIndex, 1);
+ return addIndex;
+}
+
+/*!
+ * Adds a new \a row with the \a label to the end of array.
+ *
+ * \return index of the added row.
+ */
+int QBarDataProxy::addRow(QBarDataRow *row, const QString &label)
+{
+ int addIndex = dptr()->addRow(row, &label);
emit rowsAdded(addIndex, 1);
return addIndex;
}
/*!
* Adds new \a rows to the end of array.
+ * Existing row labels are not affected.
*
* \return index of the first added row.
*/
int QBarDataProxy::addRows(const QBarDataArray &rows)
{
- int addIndex = dptr()->addRows(rows);
+ int addIndex = dptr()->addRows(rows, 0);
+ emit rowsAdded(addIndex, rows.size());
+ return addIndex;
+}
+
+/*!
+ * Adds new \a rows with \a labels to the end of array.
+ *
+ * \return index of the first added row.
+ */
+int QBarDataProxy::addRows(const QBarDataArray &rows, const QStringList &labels)
+{
+ int addIndex = dptr()->addRows(rows, &labels);
emit rowsAdded(addIndex, rows.size());
return addIndex;
}
/*!
- * Inserts a new \a row to \a rowIndex. If rowIndex is equal to array size, rows are added to end
- * of the array.
+ * Inserts a new \a row into \a rowIndex.
+ * If rowIndex is equal to array size, rows are added to end of the array.
+ * Any existing row labels are not affected.
+ * \note Row labels array will be out of sync with row array after this call,
+ * if there were labeled rows beyond the inserted row.
*/
void QBarDataProxy::insertRow(int rowIndex, QBarDataRow *row)
{
- dptr()->insertRow(rowIndex, row);
+ dptr()->insertRow(rowIndex, row, 0);
emit rowsInserted(rowIndex, 1);
}
/*!
- * Inserts new \a rows to \a rowIndex. If rowIndex is equal to array size, rows are added to end
- * of the array.
+ * Inserts a new \a row with the \a label into \a rowIndex.
+ * If rowIndex is equal to array size, rows are added to end of the array.
+ */
+void QBarDataProxy::insertRow(int rowIndex, QBarDataRow *row, const QString &label)
+{
+ dptr()->insertRow(rowIndex, row, &label);
+ emit rowsInserted(rowIndex, 1);
+}
+
+/*!
+ * Inserts new \a rows into \a rowIndex.
+ * If rowIndex is equal to array size, rows are added to end of the array.
+ * Any existing row labels are not affected.
+ * \note Row labels array will be out of sync with row array after this call,
+ * if there were labeled rows beyond the inserted rows.
*/
void QBarDataProxy::insertRows(int rowIndex, const QBarDataArray &rows)
{
- dptr()->insertRows(rowIndex, rows);
+ dptr()->insertRows(rowIndex, rows, 0);
+ emit rowsInserted(rowIndex, rows.size());
+}
+
+/*!
+ * Inserts new \a rows with \a labels into \a rowIndex.
+ * If rowIndex is equal to array size, rows are added to end of the array.
+ */
+void QBarDataProxy::insertRows(int rowIndex, const QBarDataArray &rows, const QStringList &labels)
+{
+ dptr()->insertRows(rowIndex, rows, &labels);
emit rowsInserted(rowIndex, rows.size());
}
/*!
* Removes \a removeCount rows staring at \a rowIndex. Attempting to remove rows past the end of the
- * array does nothing.
+ * array does nothing. If \a removeLabels is true, corresponding row labels are also removed. Otherwise
+ * the row labels are not affected.
+ * \note If \a removeLabels is false, the row labels array will be out of sync with the row array
+ * if there are labeled rows beyond the removed rows.
*/
-void QBarDataProxy::removeRows(int rowIndex, int removeCount)
+void QBarDataProxy::removeRows(int rowIndex, int removeCount, bool removeLabels)
{
- if (rowIndex < rowCount()) {
- dptr()->removeRows(rowIndex, removeCount);
+ if (rowIndex < rowCount() && removeCount >= 1) {
+ dptr()->removeRows(rowIndex, removeCount, removeLabels);
emit rowsRemoved(rowIndex, removeCount);
}
}
@@ -185,7 +291,7 @@ void QBarDataProxy::removeRows(int rowIndex, int removeCount)
/*!
* \property QBarDataProxy::rowCount
*
- * \return row count in the array.
+ * Row count in the array.
*/
int QBarDataProxy::rowCount() const
{
@@ -193,6 +299,45 @@ int QBarDataProxy::rowCount() const
}
/*!
+ * \property QBarDataProxy::rowLabels
+ *
+ * Optional row labels for the array. Indexes in this array match row indexes in data array.
+ * If the list is shorter than row count, all rows will not get labels.
+ */
+
+QStringList QBarDataProxy::rowLabels() const
+{
+ return dptrc()->m_rowLabels;
+}
+
+void QBarDataProxy::setRowLabels(const QStringList &labels)
+{
+ if (dptr()->m_rowLabels != labels) {
+ dptr()->m_rowLabels = labels;
+ emit rowLabelsChanged();
+ }
+}
+
+/*!
+ * \property QBarDataProxy::columnLabels
+ *
+ * Optional column labels for the array. Indexes in this array match column indexes in rows.
+ * If the list is shorter than the longest row, all columns will not get labels.
+ */
+QStringList QBarDataProxy::columnLabels() const
+{
+ return dptrc()->m_columnLabels;
+}
+
+void QBarDataProxy::setColumnLabels(const QStringList &labels)
+{
+ if (dptr()->m_columnLabels != labels) {
+ dptr()->m_columnLabels = labels;
+ emit columnLabelsChanged();
+ }
+}
+
+/*!
* \return pointer to the data array.
*/
const QBarDataArray *QBarDataProxy::array() const
@@ -291,8 +436,14 @@ QBarDataProxyPrivate::~QBarDataProxyPrivate()
clearArray();
}
-bool QBarDataProxyPrivate::resetArray(QBarDataArray *newArray)
+bool QBarDataProxyPrivate::resetArray(QBarDataArray *newArray, const QStringList *rowLabels,
+ const QStringList *columnLabels)
{
+ if (rowLabels)
+ qptr()->setRowLabels(*rowLabels);
+ if (columnLabels)
+ qptr()->setColumnLabels(*columnLabels);
+
if (!m_dataArray->size() && (!newArray || !newArray->size()))
return false;
@@ -306,17 +457,22 @@ bool QBarDataProxyPrivate::resetArray(QBarDataArray *newArray)
return true;
}
-void QBarDataProxyPrivate::setRow(int rowIndex, QBarDataRow *row)
+void QBarDataProxyPrivate::setRow(int rowIndex, QBarDataRow *row, const QString *label)
{
Q_ASSERT(rowIndex >= 0 && rowIndex < m_dataArray->size());
+
+ if (label)
+ fixRowLabels(rowIndex, 1, QStringList(*label), false);
clearRow(rowIndex);
(*m_dataArray)[rowIndex] = row;
}
-void QBarDataProxyPrivate::setRows(int rowIndex, const QBarDataArray &rows)
+void QBarDataProxyPrivate::setRows(int rowIndex, const QBarDataArray &rows, const QStringList *labels)
{
QBarDataArray &dataArray = *m_dataArray;
Q_ASSERT(rowIndex >= 0 && (rowIndex + rows.size()) <= dataArray.size());
+ if (labels)
+ fixRowLabels(rowIndex, rows.size(), *labels, false);
for (int i = 0; i < rows.size(); i++) {
clearRow(rowIndex);
dataArray[rowIndex] = rows.at(i);
@@ -332,43 +488,63 @@ void QBarDataProxyPrivate::setItem(int rowIndex, int columnIndex, const QBarData
row[columnIndex] = item;
}
-int QBarDataProxyPrivate::addRow(QBarDataRow *row)
+int QBarDataProxyPrivate::addRow(QBarDataRow *row, const QString *label)
{
int currentSize = m_dataArray->size();
+ if (label)
+ fixRowLabels(currentSize, 1, QStringList(*label), false);
m_dataArray->append(row);
return currentSize;
}
-int QBarDataProxyPrivate::addRows(const QBarDataArray &rows)
+int QBarDataProxyPrivate::addRows(const QBarDataArray &rows, const QStringList *labels)
{
int currentSize = m_dataArray->size();
+ if (labels)
+ fixRowLabels(currentSize, rows.size(), *labels, false);
for (int i = 0; i < rows.size(); i++)
m_dataArray->append(rows.at(i));
return currentSize;
}
-void QBarDataProxyPrivate::insertRow(int rowIndex, QBarDataRow *row)
+void QBarDataProxyPrivate::insertRow(int rowIndex, QBarDataRow *row, const QString *label)
{
Q_ASSERT(rowIndex >= 0 && rowIndex <= m_dataArray->size());
+ if (label)
+ fixRowLabels(rowIndex, 1, QStringList(*label), true);
m_dataArray->insert(rowIndex, row);
}
-void QBarDataProxyPrivate::insertRows(int rowIndex, const QBarDataArray &rows)
+void QBarDataProxyPrivate::insertRows(int rowIndex, const QBarDataArray &rows, const QStringList *labels)
{
Q_ASSERT(rowIndex >= 0 && rowIndex <= m_dataArray->size());
+ if (labels)
+ fixRowLabels(rowIndex, rows.size(), *labels, true);
for (int i = 0; i < rows.size(); i++)
m_dataArray->insert(rowIndex++, rows.at(i));
}
-void QBarDataProxyPrivate::removeRows(int rowIndex, int removeCount)
+void QBarDataProxyPrivate::removeRows(int rowIndex, int removeCount, bool removeLabels)
{
Q_ASSERT(rowIndex >= 0);
int maxRemoveCount = m_dataArray->size() - rowIndex;
removeCount = qMin(removeCount, maxRemoveCount);
+ bool labelsChanged = false;
for (int i = 0; i < removeCount; i++) {
clearRow(rowIndex);
m_dataArray->removeAt(rowIndex);
+ if (removeLabels && m_rowLabels.size() > rowIndex) {
+ m_rowLabels.removeAt(rowIndex);
+ labelsChanged = true;
+ }
}
+ if (labelsChanged)
+ emit qptr()->rowLabelsChanged();
+}
+
+QBarDataProxy *QBarDataProxyPrivate::qptr()
+{
+ return static_cast<QBarDataProxy *>(q_ptr);
}
void QBarDataProxyPrivate::clearRow(int rowIndex)
@@ -387,6 +563,71 @@ void QBarDataProxyPrivate::clearArray()
delete m_dataArray;
}
+/*!
+ * \internal
+ * Fixes the row label array to include specified labels.
+ */
+void QBarDataProxyPrivate::fixRowLabels(int startIndex, int count, const QStringList &newLabels, bool isInsert)
+{
+ bool changed = false;
+ int currentSize = m_rowLabels.size();
+
+ int newSize = newLabels.size();
+ if (startIndex >= currentSize) {
+ // Adding labels past old label array, create empty strings to fill intervening space
+ if (newSize) {
+ for (int i = currentSize; i < startIndex; i++)
+ m_rowLabels << QString();
+ // Doesn't matter if insert, append, or just change when there were no existing
+ // strings, just append new strings.
+ m_rowLabels << newLabels;
+ changed = true;
+ }
+ } else {
+ if (isInsert) {
+ int insertIndex = startIndex;
+ if (count)
+ changed = true;
+ for (int i = 0; i < count; i++) {
+ if (i < newSize)
+ m_rowLabels.insert(insertIndex++, newLabels.at(i));
+ else
+ m_rowLabels.insert(insertIndex++, QString());
+ }
+ } else {
+ // Either append or change, replace labels up to array end and then add new ones
+ int lastChangeIndex = count + startIndex;
+ int newIndex = 0;
+ for (int i = startIndex; i < lastChangeIndex; i++) {
+ if (i >= currentSize) {
+ // Label past the current size, so just append the new label
+ if (newSize < newIndex) {
+ changed = true;
+ m_rowLabels << newLabels.at(newIndex);
+ } else {
+ break; // No point appending empty strings, so just exit
+ }
+ } else if (newSize > newIndex) {
+ // Replace existing label
+ if (m_rowLabels.at(i) != newLabels.at(newIndex)) {
+ changed = true;
+ m_rowLabels[i] = newLabels.at(newIndex);
+ }
+ } else {
+ // No more new labels, so clear existing label
+ if (!m_rowLabels.at(i).isEmpty()) {
+ changed = true;
+ m_rowLabels[i] = QString();
+ }
+ }
+ newIndex++;
+ }
+ }
+ }
+ if (changed)
+ emit qptr()->rowLabelsChanged();
+}
+
QPair<GLfloat, GLfloat> QBarDataProxyPrivate::limitValues(int startRow, int endRow, int startColumn, int endColumn)
{
QPair<GLfloat, GLfloat> limits = qMakePair(0.0f, 0.0f);