| /**************************************************************************** |
| ** |
| ** Copyright (C) 2017 The Qt Company Ltd. |
| ** Contact: https://www.qt.io/licensing/ |
| ** |
| ** This file is part of the Qt Data Visualization module of the Qt Toolkit. |
| ** |
| ** $QT_BEGIN_LICENSE:GPL$ |
| ** Commercial License Usage |
| ** Licensees holding valid commercial Qt licenses may use this file in |
| ** accordance with the commercial license agreement provided with the |
| ** Software or, alternatively, in accordance with the terms contained in |
| ** a written agreement between you and The Qt Company. For licensing terms |
| ** and conditions see https://www.qt.io/terms-conditions. For further |
| ** information use the contact form at https://www.qt.io/contact-us. |
| ** |
| ** GNU General Public License Usage |
| ** Alternatively, this file may be used under the terms of the GNU |
| ** General Public License version 3 or (at your option) any later version |
| ** approved by the KDE Free Qt Foundation. The licenses are as published by |
| ** the Free Software Foundation and appearing in the file LICENSE.GPL3 |
| ** included in the packaging of this file. Please review the following |
| ** information to ensure the GNU General Public License requirements will |
| ** be met: https://www.gnu.org/licenses/gpl-3.0.html. |
| ** |
| ** $QT_END_LICENSE$ |
| ** |
| ****************************************************************************/ |
| |
| #include "qbardataproxy_p.h" |
| #include "qbar3dseries_p.h" |
| |
| QT_BEGIN_NAMESPACE_DATAVISUALIZATION |
| |
| /*! |
| * \class QBarDataProxy |
| * \inmodule QtDataVisualization |
| * \brief The QBarDataProxy class is the data proxy for a 3D bars graph. |
| * \since QtDataVisualization 1.0 |
| * |
| * A bar data proxy handles adding, inserting, changing, and removing rows of |
| * data. |
| * |
| * The data array is a list of vectors (rows) of QBarDataItem instances. |
| * Each row can contain a different number of items or even be null. |
| * |
| * QBarDataProxy takes ownership of all QtDataVisualization::QBarDataRow objects |
| * passed to it, whether directly or in a QtDataVisualization::QBarDataArray container. |
| * If bar data row pointers are used to directly modify data after adding the |
| * array to the proxy, the appropriate signal must be emitted to update the |
| * graph. |
| * |
| * QBarDataProxy optionally keeps track of row and column labels, which QCategory3DAxis can utilize |
| * to show axis labels. The row and column labels are stored in a separate array from the data and |
| * row manipulation methods provide alternate versions that do not 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. |
| * |
| * \sa {Qt Data Visualization Data Handling} |
| */ |
| |
| /*! |
| * \typedef QBarDataRow |
| * \relates QBarDataProxy |
| * |
| * A vector of \l {QBarDataItem} objects. |
| */ |
| |
| /*! |
| * \typedef QBarDataArray |
| * \relates QBarDataProxy |
| * |
| * A list of pointers to \l {QBarDataRow} objects. |
| */ |
| |
| /*! |
| * \qmltype BarDataProxy |
| * \inqmlmodule QtDataVisualization |
| * \since QtDataVisualization 1.0 |
| * \ingroup datavisualization_qml |
| * \instantiates QBarDataProxy |
| * \inherits AbstractDataProxy |
| * \brief The data proxy for a 3D bars graph. |
| * |
| * This type handles adding, inserting, changing, and removing rows of data with Qt Quick 2. |
| * |
| * This type is uncreatable, but contains properties that are exposed via subtypes. |
| * |
| * For a more complete description, see QBarDataProxy. |
| * |
| * \sa ItemModelBarDataProxy, {Qt Data Visualization Data Handling} |
| */ |
| |
| /*! |
| * \qmlproperty int BarDataProxy::rowCount |
| * The number of rows in the array. |
| */ |
| |
| /*! |
| * \qmlproperty list BarDataProxy::rowLabels |
| * |
| * The optional row labels for the array. Indexes in this array match the row |
| * indexes in the data array. |
| * If the list is shorter than the number of rows, all rows will not get labels. |
| */ |
| |
| /*! |
| * \qmlproperty list BarDataProxy::columnLabels |
| * |
| * The 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. |
| */ |
| |
| /*! |
| * \qmlproperty Bar3DSeries BarDataProxy::series |
| * |
| * The series this proxy is attached to. |
| */ |
| |
| /*! |
| * Constructs a bar data proxy with the given \a parent. |
| */ |
| QBarDataProxy::QBarDataProxy(QObject *parent) : |
| QAbstractDataProxy(new QBarDataProxyPrivate(this), parent) |
| { |
| } |
| |
| /*! |
| * \internal |
| */ |
| QBarDataProxy::QBarDataProxy(QBarDataProxyPrivate *d, QObject *parent) : |
| QAbstractDataProxy(d, parent) |
| { |
| } |
| |
| /*! |
| * Deletes the bar data proxy. |
| */ |
| QBarDataProxy::~QBarDataProxy() |
| { |
| } |
| |
| /*! |
| * \property QBarDataProxy::series |
| * |
| * \brief The series this proxy is attached to. |
| */ |
| QBar3DSeries *QBarDataProxy::series() const |
| { |
| return static_cast<QBar3DSeries *>(d_ptr->series()); |
| } |
| |
| /*! |
| * Clears the existing array and row and column labels. |
| */ |
| void QBarDataProxy::resetArray() |
| { |
| resetArray(0, QStringList(), QStringList()); |
| emit rowCountChanged(rowCount()); |
| } |
| |
| /*! |
| * Takes ownership of the array \a newArray. Clears the existing array if the |
| * new array differs from it. If the arrays are the same, this function |
| * just triggers the arrayReset() signal. |
| * |
| * Passing a null array deletes the old array and creates a new empty array. |
| * Row and column labels are not affected. |
| */ |
| void QBarDataProxy::resetArray(QBarDataArray *newArray) |
| { |
| dptr()->resetArray(newArray, 0, 0); |
| emit arrayReset(); |
| emit rowCountChanged(rowCount()); |
| } |
| |
| /*! |
| * Takes ownership of the array \a newArray. Clears the existing array if the |
| * new array differs from it. If the arrays are the same, this function |
| * just triggers the arrayReset() signal. |
| * |
| * Passing a null array deletes the old array and creates a new empty array. |
| * |
| * 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) |
| { |
| dptr()->resetArray(newArray, &rowLabels, &columnLabels); |
| emit arrayReset(); |
| emit rowCountChanged(rowCount()); |
| } |
| |
| /*! |
| * Changes an existing row by replacing the row at the position \a rowIndex |
| * with the new row specified by \a row. The new row can be |
| * the same as the existing row already stored at \a rowIndex. |
| * Existing row labels are not affected. |
| */ |
| void QBarDataProxy::setRow(int rowIndex, QBarDataRow *row) |
| { |
| dptr()->setRow(rowIndex, row, 0); |
| emit rowsChanged(rowIndex, 1); |
| } |
| |
| /*! |
| * Changes an existing row by replacing the row at the position \a rowIndex |
| * with the new row specified by \a row. The new row can be |
| * the same as the existing row already stored at \a rowIndex. |
| * Changes the row label to \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 the rows starting at the position |
| * \a rowIndex with the new rows specifies by \a rows. |
| * Existing row labels are not affected. The rows in the \a rows array can be |
| * the same as the existing rows already stored at \a rowIndex. |
| */ |
| void QBarDataProxy::setRows(int rowIndex, const QBarDataArray &rows) |
| { |
| dptr()->setRows(rowIndex, rows, 0); |
| emit rowsChanged(rowIndex, rows.size()); |
| } |
| |
| /*! |
| * Changes existing rows by replacing the rows starting at the position |
| * \a rowIndex with the new rows specifies by \a rows. |
| * The row labels are changed to \a labels. The rows in the \a rows array can be |
| * the same as the existing rows already stored at \a rowIndex. |
| */ |
| 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 the position specified by \a rowIndex and |
| * \a columnIndex to the item \a item. |
| */ |
| void QBarDataProxy::setItem(int rowIndex, int columnIndex, const QBarDataItem &item) |
| { |
| dptr()->setItem(rowIndex, columnIndex, item); |
| emit itemChanged(rowIndex, columnIndex); |
| } |
| |
| /*! |
| * Changes a single item at the position \a position to the item \a item. |
| * The x-value of \a position indicates the row and the y-value indicates the |
| * column. |
| */ |
| void QBarDataProxy::setItem(const QPoint &position, const QBarDataItem &item) |
| { |
| setItem(position.x(), position.y(), item); |
| } |
| |
| /*! |
| * Adds the new row \a row to the end of an array. |
| * Existing row labels are not affected. |
| * |
| * Returns the index of the added row. |
| */ |
| int QBarDataProxy::addRow(QBarDataRow *row) |
| { |
| int addIndex = dptr()->addRow(row, 0); |
| emit rowsAdded(addIndex, 1); |
| emit rowCountChanged(rowCount()); |
| return addIndex; |
| } |
| |
| /*! |
| * Adds a the new row \a row with the label \a label to the end of an array. |
| * |
| * Returns the index of the added row. |
| */ |
| int QBarDataProxy::addRow(QBarDataRow *row, const QString &label) |
| { |
| int addIndex = dptr()->addRow(row, &label); |
| emit rowsAdded(addIndex, 1); |
| emit rowCountChanged(rowCount()); |
| return addIndex; |
| } |
| |
| /*! |
| * Adds the new \a rows to the end of an array. |
| * Existing row labels are not affected. |
| * |
| * Returns the index of the first added row. |
| */ |
| int QBarDataProxy::addRows(const QBarDataArray &rows) |
| { |
| int addIndex = dptr()->addRows(rows, 0); |
| emit rowsAdded(addIndex, rows.size()); |
| emit rowCountChanged(rowCount()); |
| return addIndex; |
| } |
| |
| /*! |
| * Adds the new \a rows with \a labels to the end of the array. |
| * |
| * Returns the 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()); |
| emit rowCountChanged(rowCount()); |
| return addIndex; |
| } |
| |
| /*! |
| * Inserts the new row \a row into \a rowIndex. |
| * If \a rowIndex is equal to the array size, the rows are added to the end of |
| * the array. |
| * The existing row labels are not affected. |
| * \note The row labels array will be out of sync with the 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, 0); |
| emit rowsInserted(rowIndex, 1); |
| emit rowCountChanged(rowCount()); |
| } |
| |
| /*! |
| * Inserts the new row \a row with the label \a label into \a rowIndex. |
| * If \a rowIndex is equal to array size, rows are added to the end of the |
| * array. |
| */ |
| void QBarDataProxy::insertRow(int rowIndex, QBarDataRow *row, const QString &label) |
| { |
| dptr()->insertRow(rowIndex, row, &label); |
| emit rowsInserted(rowIndex, 1); |
| emit rowCountChanged(rowCount()); |
| } |
| |
| /*! |
| * Inserts new \a rows into \a rowIndex. |
| * If \a rowIndex is equal to the array size, the rows are added to the end of |
| * the array. The existing row labels are not affected. |
| * \note The row labels array will be out of sync with the 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, 0); |
| emit rowsInserted(rowIndex, rows.size()); |
| emit rowCountChanged(rowCount()); |
| } |
| |
| /*! |
| * Inserts new \a rows with \a labels into \a rowIndex. |
| * If \a rowIndex is equal to the array size, the rows are added to the 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()); |
| emit rowCountChanged(rowCount()); |
| } |
| |
| /*! |
| * Removes the number of rows specified by \a removeCount starting at the |
| * position \a rowIndex. Attempting to remove rows past the end of the |
| * array does nothing. If \a removeLabels is \c true, the corresponding row |
| * labels are also removed. Otherwise, the row labels are not affected. |
| * \note If \a removeLabels is \c 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, bool removeLabels) |
| { |
| if (rowIndex < rowCount() && removeCount >= 1) { |
| dptr()->removeRows(rowIndex, removeCount, removeLabels); |
| emit rowsRemoved(rowIndex, removeCount); |
| emit rowCountChanged(rowCount()); |
| } |
| } |
| |
| /*! |
| * \property QBarDataProxy::rowCount |
| * |
| * \brief The number of rows in the array. |
| */ |
| int QBarDataProxy::rowCount() const |
| { |
| return dptrc()->m_dataArray->size(); |
| } |
| |
| /*! |
| * \property QBarDataProxy::rowLabels |
| * |
| * \brief The optional row labels for the array. |
| * |
| * Indexes in this array match the row indexes in the data array. |
| * If the list is shorter than the number of rows, 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 |
| * |
| * \brief The 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(); |
| } |
| } |
| |
| /*! |
| * Returns the pointer to the data array. |
| */ |
| const QBarDataArray *QBarDataProxy::array() const |
| { |
| return dptrc()->m_dataArray; |
| } |
| |
| /*! |
| * Returns the pointer to the row at the position \a rowIndex. It is guaranteed |
| * to be valid only until the next call that modifies data. |
| */ |
| const QBarDataRow *QBarDataProxy::rowAt(int rowIndex) const |
| { |
| const QBarDataArray &dataArray = *dptrc()->m_dataArray; |
| Q_ASSERT(rowIndex >= 0 && rowIndex < dataArray.size()); |
| return dataArray[rowIndex]; |
| } |
| |
| /*! |
| * Returns the pointer to the item at the position specified by \a rowIndex and |
| * \a columnIndex. It is guaranteed to be valid only |
| * until the next call that modifies data. |
| */ |
| const QBarDataItem *QBarDataProxy::itemAt(int rowIndex, int columnIndex) const |
| { |
| const QBarDataArray &dataArray = *dptrc()->m_dataArray; |
| Q_ASSERT(rowIndex >= 0 && rowIndex < dataArray.size()); |
| const QBarDataRow &dataRow = *dataArray[rowIndex]; |
| Q_ASSERT(columnIndex >= 0 && columnIndex < dataRow.size()); |
| return &dataRow.at(columnIndex); |
| } |
| |
| /*! |
| * Returns the pointer to the item at the position \a position. The x-value of |
| * \a position indicates the row and the y-value indicates the column. The item |
| * is guaranteed to be valid only until the next call that modifies data. |
| */ |
| const QBarDataItem *QBarDataProxy::itemAt(const QPoint &position) const |
| { |
| return itemAt(position.x(), position.y()); |
| } |
| |
| /*! |
| * \internal |
| */ |
| QBarDataProxyPrivate *QBarDataProxy::dptr() |
| { |
| return static_cast<QBarDataProxyPrivate *>(d_ptr.data()); |
| } |
| |
| /*! |
| * \internal |
| */ |
| const QBarDataProxyPrivate *QBarDataProxy::dptrc() const |
| { |
| return static_cast<const QBarDataProxyPrivate *>(d_ptr.data()); |
| } |
| |
| /*! |
| * \fn void QBarDataProxy::arrayReset() |
| * |
| * This signal is emitted when the data array is reset. |
| * If the contents of the whole array are changed without calling resetArray(), |
| * this signal needs to be emitted to update the graph. |
| */ |
| |
| /*! |
| * \fn void QBarDataProxy::rowsAdded(int startIndex, int count) |
| * |
| * This signal is emitted when the number of rows specified by \a count is |
| * added starting at the position \a startIndex. |
| * If rows are added to the array without calling addRow() or addRows(), |
| * this signal needs to be emitted to update the graph. |
| */ |
| |
| /*! |
| * \fn void QBarDataProxy::rowsChanged(int startIndex, int count) |
| * |
| * This signal is emitted when the number of rows specified by \a count is |
| * changed starting at the position \a startIndex. |
| * If rows are changed in the array without calling setRow() or setRows(), |
| * this signal needs to be emitted to update the graph. |
| */ |
| |
| /*! |
| * \fn void QBarDataProxy::rowsRemoved(int startIndex, int count) |
| * |
| * This signal is emitted when the number of rows specified by \a count is |
| * removed starting at the position \a startIndex. |
| * |
| * The index is the current array size if the rows were removed from the end of |
| * the array. If rows are removed from the array without calling removeRows(), |
| * this signal needs to be emitted to update the graph. |
| */ |
| |
| /*! |
| * \fn void QBarDataProxy::rowsInserted(int startIndex, int count) |
| * |
| * This signal is emitted when the number of rows specified by \a count is |
| * inserted at the position \a startIndex. |
| * |
| * If rows are inserted into the array without calling insertRow() or |
| * insertRows(), this signal needs to be emitted to update the graph. |
| */ |
| |
| /*! |
| * \fn void QBarDataProxy::itemChanged(int rowIndex, int columnIndex) |
| * |
| * This signal is emitted when the item at the position specified by \a rowIndex |
| * and \a columnIndex changes. |
| * If the item is changed in the array without calling setItem(), |
| * this signal needs to be emitted to update the graph. |
| */ |
| |
| // QBarDataProxyPrivate |
| |
| QBarDataProxyPrivate::QBarDataProxyPrivate(QBarDataProxy *q) |
| : QAbstractDataProxyPrivate(q, QAbstractDataProxy::DataTypeBar), |
| m_dataArray(new QBarDataArray) |
| { |
| } |
| |
| QBarDataProxyPrivate::~QBarDataProxyPrivate() |
| { |
| clearArray(); |
| } |
| |
| void QBarDataProxyPrivate::resetArray(QBarDataArray *newArray, const QStringList *rowLabels, |
| const QStringList *columnLabels) |
| { |
| if (rowLabels) |
| qptr()->setRowLabels(*rowLabels); |
| if (columnLabels) |
| qptr()->setColumnLabels(*columnLabels); |
| |
| if (!newArray) |
| newArray = new QBarDataArray; |
| |
| if (newArray != m_dataArray) { |
| clearArray(); |
| m_dataArray = newArray; |
| } |
| } |
| |
| 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); |
| if (row != m_dataArray->at(rowIndex)) { |
| clearRow(rowIndex); |
| (*m_dataArray)[rowIndex] = row; |
| } |
| } |
| |
| 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++) { |
| if (rows.at(i) != dataArray.at(rowIndex)) { |
| clearRow(rowIndex); |
| dataArray[rowIndex] = rows.at(i); |
| } |
| rowIndex++; |
| } |
| } |
| |
| void QBarDataProxyPrivate::setItem(int rowIndex, int columnIndex, const QBarDataItem &item) |
| { |
| Q_ASSERT(rowIndex >= 0 && rowIndex < m_dataArray->size()); |
| QBarDataRow &row = *(*m_dataArray)[rowIndex]; |
| Q_ASSERT(columnIndex < row.size()); |
| row[columnIndex] = item; |
| } |
| |
| 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, 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, 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, |
| 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, 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) |
| { |
| if (m_dataArray->at(rowIndex)) { |
| delete m_dataArray->at(rowIndex); |
| (*m_dataArray)[rowIndex] = 0; |
| } |
| } |
| |
| void QBarDataProxyPrivate::clearArray() |
| { |
| for (int i = 0; i < m_dataArray->size(); i++) |
| clearRow(i); |
| m_dataArray->clear(); |
| 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) const |
| { |
| QPair<GLfloat, GLfloat> limits = qMakePair(0.0f, 0.0f); |
| endRow = qMin(endRow, m_dataArray->size() - 1); |
| for (int i = startRow; i <= endRow; i++) { |
| QBarDataRow *row = m_dataArray->at(i); |
| if (row) { |
| int lastColumn = qMin(endColumn, row->size() - 1); |
| for (int j = startColumn; j <= lastColumn; j++) { |
| const QBarDataItem &item = row->at(j); |
| float itemValue = item.value(); |
| if (limits.second < itemValue) |
| limits.second = itemValue; |
| if (limits.first > itemValue) |
| limits.first = itemValue; |
| } |
| } |
| } |
| return limits; |
| } |
| |
| void QBarDataProxyPrivate::setSeries(QAbstract3DSeries *series) |
| { |
| QAbstractDataProxyPrivate::setSeries(series); |
| QBar3DSeries *barSeries = static_cast<QBar3DSeries *>(series); |
| emit qptr()->seriesChanged(barSeries); |
| } |
| |
| QT_END_NAMESPACE_DATAVISUALIZATION |