From 65526593187b905d3a35837c19f716918ea297b4 2012-04-18 13:06:07 From: Marek Rosa Date: 2012-04-18 13:06:07 Subject: [PATCH] PieSeries: model now supports custom mapping. --- diff --git a/src/animations/baranimation.cpp b/src/animations/baranimation.cpp index c983040..7882fe8 100644 --- a/src/animations/baranimation.cpp +++ b/src/animations/baranimation.cpp @@ -45,7 +45,7 @@ QVariant BarAnimation::interpolated(const QVariant &from, const QVariant &to, qr QVector endVector = qVariantValue >(to); QVector result; - Q_ASSERT(startVector.count() == endVector.count()) ; + Q_ASSERT(startVector.count() == endVector.count()); for(int i = 0; i < startVector.count(); i++) { qreal w = endVector[i].width(); diff --git a/src/barchart/qbarseries.cpp b/src/barchart/qbarseries.cpp index 21977fe..833714e 100644 --- a/src/barchart/qbarseries.cpp +++ b/src/barchart/qbarseries.cpp @@ -200,6 +200,12 @@ void QBarSeries::setModelMapping(int categories, int bottomBoundary, int topBoun d->setModelMapping(categories,bottomBoundary,topBoundary,orientation); } +void QBarSeries::setModelMappingRange(int first, int count) +{ + Q_D(QBarSeries); + d->setModelMappingRange(first, count); +} + /*! Returns the bar categories of the series. */ @@ -381,52 +387,226 @@ void QBarSeriesPrivate::setModelMapping(int categories, int bottomBoundry, int t m_mapOrientation = orientation; // connect the signals - connect(m_model,SIGNAL(dataChanged(QModelIndex,QModelIndex)), - this, SLOT(modelUpdated(QModelIndex,QModelIndex))); + connect(m_model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(modelUpdated(QModelIndex,QModelIndex))); + if (m_mapOrientation == Qt::Vertical) { + connect(m_model,SIGNAL(rowsInserted(QModelIndex,int,int)), this, SLOT(modelDataAdded(QModelIndex,int,int))); + connect(m_model,SIGNAL(rowsRemoved(QModelIndex,int,int)), this, SLOT(modelDataRemoved(QModelIndex,int,int))); + } else { + connect(m_model, SIGNAL(columnsInserted(QModelIndex,int,int)), this, SLOT(modelDataAdded(QModelIndex,int,int))); + connect(m_model, SIGNAL(columnsRemoved(QModelIndex,int,int)), this, SLOT(modelDataRemoved(QModelIndex,int,int))); + } // create the initial bars m_categories.clear(); if (m_mapOrientation == Qt::Vertical) { - for (int k = 0; k < m_model->rowCount(); k++) { + int rowCount = 0; + if(m_mapCount == -1) + rowCount = m_model->rowCount() - m_mapFirst; + else + rowCount = qMin(m_mapCount, m_model->rowCount() - m_mapFirst); + for (int k = m_mapFirst; k < m_mapFirst + rowCount; k++) { m_categories << m_model->data(m_model->index(k, m_mapCategories), Qt::DisplayRole).toString(); } for (int i = m_mapBarBottom; i <= m_mapBarTop; i++) { QBarSet* barSet = new QBarSet(m_model->headerData(i, Qt::Horizontal, Qt::DisplayRole).toString()); - for(int m = 0; m < m_model->rowCount(); m++) + for(int m = m_mapFirst; m < m_mapFirst + rowCount; m++) *barSet << m_model->data(m_model->index(m, i), Qt::DisplayRole).toDouble(); q->appendBarSet(barSet); } } else { - for (int k = 0; k < m_model->columnCount(); k++) { + int columnCount = 0; + if(m_mapCount == -1) + columnCount = m_model->columnCount() - m_mapFirst; + else + columnCount = qMin(m_mapCount, m_model->columnCount() - m_mapFirst); + for (int k = m_mapFirst; k < m_mapFirst + columnCount; k++) { m_categories << m_model->data(m_model->index(m_mapCategories, k), Qt::DisplayRole).toString(); } for (int i = m_mapBarBottom; i <= m_mapBarTop; i++) { QBarSet* barSet = new QBarSet(m_model->headerData(i, Qt::Vertical, Qt::DisplayRole).toString()); - for(int m = 0; m < m_model->columnCount(); m++) + for(int m = m_mapFirst; m < m_mapFirst + columnCount; m++) *barSet << m_model->data(m_model->index(i, m), Qt::DisplayRole).toDouble(); q->appendBarSet(barSet); } } } -void QBarSeriesPrivate::modelUpdated(QModelIndex topLeft, QModelIndex bottomRight) +void QBarSeriesPrivate::setModelMappingRange(int first, int count) { - Q_UNUSED(bottomRight) + m_mapFirst = first; + m_mapCount = count; +} - if (m_mapOrientation == Qt::Vertical) - { - // model update is relevant to BarSeries if the change was made to the part of the model that was mapped to BarSeries - if (topLeft.column() >= m_mapBarBottom && topLeft.column() <= m_mapBarTop) - barsetAt(topLeft.column() - m_mapBarBottom)->replace(topLeft.row(), m_model->data(topLeft, Qt::DisplayRole).toDouble()); +void QBarSeriesPrivate::modelUpdated(QModelIndex topLeft, QModelIndex bottomRight) +{ + for (int row = topLeft.row(); row <= bottomRight.row(); row++) { + for (int column = topLeft.column(); column <= bottomRight.column(); column++) { + if (m_mapOrientation == Qt::Vertical) + { + // model update is relevant to BarSeries if the change was made to the part of the model that was mapped to BarSeries + if ( row >= m_mapFirst && (m_mapCount == - 1 || row < m_mapFirst + m_mapCount)) { + if (column >= m_mapBarBottom && column <= m_mapBarTop) + barsetAt(column - m_mapBarBottom)->replace(row - m_mapFirst, m_model->data(topLeft, Qt::DisplayRole).toDouble()); + // if (column == m_mapCategories);// TODO: + } + } + else + { + // model update is relevant to BarSeries if the change was made to the part of the model that was mapped to BarSeries + if (column >= m_mapFirst && (m_mapCount == - 1 || column < m_mapFirst + m_mapCount)) { + if (row >= m_mapBarBottom && row <= m_mapBarTop) + barsetAt(row - m_mapBarBottom)->replace(column - m_mapFirst, m_model->data(topLeft, Qt::DisplayRole).toDouble()); + // if (row == m_mapCategories);// TODO: + } + } + } } - else - { - // model update is relevant to BarSeries if the change was made to the part of the model that was mapped to BarSeries - if (topLeft.row() >= m_mapBarBottom && topLeft.row() <= m_mapBarTop) - barsetAt(topLeft.row() - m_mapBarBottom)->replace(topLeft.column(), m_model->data(topLeft, Qt::DisplayRole).toDouble()); +} + +void QBarSeriesPrivate::modelDataAdded(QModelIndex parent, int start, int end) +{ + Q_UNUSED(parent); + Q_UNUSED(start); + Q_UNUSED(end); + initializeDataFromModel(); +// // series uses model as a data sourceupda +// int addedCount = end - start + 1; +// if (m_mapCount != -1 && start >= m_mapFirst + m_mapCount) { +// return; +// } else { + +// for (int bar = m_mapBarBottom; bar <= m_mapBarTop; bar++) { +// QBarSet *barSet = barsetAt(bar - m_mapBarBottom); +// // adding items to unlimited map +// if (m_mapCount == -1 && start >= m_mapFirst) { +// for (int i = start; i <= end; i++) { +// if (bar == m_mapBarBottom) +// insertCategory(i - m_mapFirst, m_model->data(m_model->index(i, m_mapCategories), Qt::DisplayRole).toString()); +// barSet->insert(i - m_mapFirst, m_model->data(m_model->index(i, bar), Qt::DisplayRole).toDouble()); +// } +// } else if (m_mapCount == - 1 && start < m_mapFirst) { +// // not all newly added items +// for (int i = m_mapFirst; i < m_mapFirst + addedCount; i++) { +// if (bar == m_mapBarBottom) +// insertCategory(i - m_mapFirst, m_model->data(m_model->index(i, m_mapCategories), Qt::DisplayRole).toString()); +// barSet->insert(i - m_mapFirst, m_model->data(m_model->index(i, bar), Qt::DisplayRole).toDouble()); +// } +// } + +// // adding items to limited map +// else if (start >= m_mapFirst) { +// // remove the items that will no longer fit into the map +// // int toRemove = addedCount - (count - points().size()); +// for (int i = start; i <= end; i++) { +// if (bar == m_mapBarBottom) +// insertCategory(i - m_mapFirst, m_model->data(m_model->index(i, m_mapCategories), Qt::DisplayRole).toString()); +// barSet->insert(i - m_mapFirst, m_model->data(m_model->index(i, bar), Qt::DisplayRole).toDouble()); +// } +// if (m_barSets.size() > m_mapCount) +// for (int i = m_barSets.size() - 1; i >= m_mapCount; i--) { +// if (bar == m_mapBarBottom) +// removeCategory(i); +// barSet->remove(i); +// } +// } else { +// // +// for (int i = m_mapFirst; i < m_mapFirst + addedCount; i++) { +// if (bar == m_mapBarBottom) +// insertCategory(i - m_mapFirst, m_model->data(m_model->index(i, m_mapCategories), Qt::DisplayRole).toString()); +// barSet->insert(i - m_mapFirst, m_model->data(m_model->index(i, bar), Qt::DisplayRole).toDouble()); +// } +// if (m_barSets.size() > m_mapCount) +// for (int i = m_barSets.size() - 1; i >= m_mapCount; i--) { +// if (bar == m_mapBarBottom) +// removeCategory(i); +// barSet->remove(i); +// } +// } +// } +// emit restructuredBars(); +// emit barsetChanged(); +// emit categoriesUpdated(); +// } +} + +void QBarSeriesPrivate::modelDataRemoved(QModelIndex parent, int start, int end) +{ + Q_UNUSED(parent); + Q_UNUSED(start); + Q_UNUSED(end); + initializeDataFromModel(); +} + +void QBarSeriesPrivate::initializeDataFromModel() +{ + Q_Q(QBarSeries); + + if (m_model == 0) + return; + + // connect the signals +// connect(m_model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(modelUpdated(QModelIndex,QModelIndex))); +// if (m_mapOrientation == Qt::Vertical) { +// connect(m_model,SIGNAL(rowsInserted(QModelIndex,int,int)), this, SLOT(modelDataAdded(QModelIndex,int,int))); +// connect(m_model,SIGNAL(rowsRemoved(QModelIndex,int,int)), this, SLOT(modelDataRemoved(QModelIndex,int,int))); +// } else { +// connect(m_model, SIGNAL(columnsInserted(QModelIndex,int,int)), this, SLOT(modelDataAdded(QModelIndex,int,int))); +// connect(m_model, SIGNAL(columnsRemoved(QModelIndex,int,int)), this, SLOT(modelDataRemoved(QModelIndex,int,int))); +// } + + // create the initial bars + m_categories.clear(); + m_barSets.clear(); + emit restructuredBars(); + if (m_mapOrientation == Qt::Vertical) { + int rowCount = 0; + if(m_mapCount == -1) + rowCount = m_model->rowCount() - m_mapFirst; + else + rowCount = qMin(m_mapCount, m_model->rowCount() - m_mapFirst); + for (int k = m_mapFirst; k < m_mapFirst + rowCount; k++) { + m_categories << m_model->data(m_model->index(k, m_mapCategories), Qt::DisplayRole).toString(); + } + + for (int i = m_mapBarBottom; i <= m_mapBarTop; i++) { + QBarSet* barSet = new QBarSet(m_model->headerData(i, Qt::Horizontal, Qt::DisplayRole).toString()); + for(int m = m_mapFirst; m < m_mapFirst + rowCount; m++) + *barSet << m_model->data(m_model->index(m, i), Qt::DisplayRole).toDouble(); + q->appendBarSet(barSet); + } + } else { + int columnCount = 0; + if(m_mapCount == -1) + columnCount = m_model->columnCount() - m_mapFirst; + else + columnCount = qMin(m_mapCount, m_model->columnCount() - m_mapFirst); + for (int k = m_mapFirst; k < m_mapFirst + columnCount; k++) { + m_categories << m_model->data(m_model->index(m_mapCategories, k), Qt::DisplayRole).toString(); + } + + for (int i = m_mapBarBottom; i <= m_mapBarTop; i++) { + QBarSet* barSet = new QBarSet(m_model->headerData(i, Qt::Vertical, Qt::DisplayRole).toString()); + for(int m = m_mapFirst; m < m_mapFirst + columnCount; m++) + *barSet << m_model->data(m_model->index(i, m), Qt::DisplayRole).toDouble(); + q->appendBarSet(barSet); + } } + emit restructuredBars(); + emit updatedBars(); +} + +void QBarSeriesPrivate::insertCategory(int index, const QString category) +{ + m_categories.insert(index, category); + emit categoriesUpdated(); +} + +void QBarSeriesPrivate::removeCategory(int index) +{ + m_categories.removeAt(index); + emit categoriesUpdated(); } void QBarSeriesPrivate::barsetChanged() diff --git a/src/barchart/qbarseries.h b/src/barchart/qbarseries.h index b85124e..42c00ae 100644 --- a/src/barchart/qbarseries.h +++ b/src/barchart/qbarseries.h @@ -57,6 +57,7 @@ public: bool setModel(QAbstractItemModel *model); void setModelMapping(int categories, int bottomBoundary, int topBoundary, Qt::Orientation orientation = Qt::Vertical); + void setModelMappingRange(int first, int count = -1); protected: explicit QBarSeries(QBarSeriesPrivate &d,QObject *parent = 0); diff --git a/src/barchart/qbarseries_p.h b/src/barchart/qbarseries_p.h index 605725d..29e5574 100644 --- a/src/barchart/qbarseries_p.h +++ b/src/barchart/qbarseries_p.h @@ -23,6 +23,10 @@ public: bool setModel(QAbstractItemModel *model); void setModelMapping(int categories, int bottomBoundry, int topBoundry, Qt::Orientation orientation = Qt::Vertical); + void setModelMappingRange(int first, int count = -1); + + void insertCategory(int index, const QString category); + void removeCategory(int index); QBarSet* barsetAt(int index); QString categoryName(int category); @@ -38,10 +42,14 @@ Q_SIGNALS: void clicked(QBarSet *barset, QString category); void updatedBars(); void restructuredBars(); + void categoriesUpdated(); private Q_SLOTS: // slots for updating bars when data in model changes void modelUpdated(QModelIndex topLeft, QModelIndex bottomRight); + void modelDataAdded(QModelIndex parent, int start, int end); + void modelDataRemoved(QModelIndex parent, int start, int end); + void initializeDataFromModel(); void barsetChanged(); protected: diff --git a/src/barchart/qbarset.cpp b/src/barchart/qbarset.cpp index 78d5103..c620605 100644 --- a/src/barchart/qbarset.cpp +++ b/src/barchart/qbarset.cpp @@ -110,7 +110,7 @@ QBarSet& QBarSet::operator << (const qreal &value) void QBarSet::insert(const int index, const qreal value) { d_ptr->m_values.insert(index, value); - emit d_ptr->updatedBars(); +// emit d_ptr->updatedBars(); } /*! @@ -120,7 +120,7 @@ void QBarSet::insert(const int index, const qreal value) void QBarSet::remove(const int index) { d_ptr->m_values.removeAt(index); - emit d_ptr->updatedBars(); +// emit d_ptr->updatedBars(); } /*! diff --git a/src/piechart/qpieseries.cpp b/src/piechart/qpieseries.cpp index 2860e33..b3a8339 100644 --- a/src/piechart/qpieseries.cpp +++ b/src/piechart/qpieseries.cpp @@ -449,18 +449,26 @@ void QPieSeries::setModelMapping(int modelValuesLine, int modelLabelsLine, Qt::O d->m_mapLabels = modelLabelsLine; d->m_mapOrientation = orientation; - // connect the signals - connect(d->m_model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), d, SLOT(modelUpdated(QModelIndex,QModelIndex))); + d->initializePieFromModel(); + // // connect the signals + // connect(d->m_model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), d, SLOT(modelUpdated(QModelIndex,QModelIndex))); - // create the initial slices set - if (d->m_mapOrientation == Qt::Vertical) { - for (int i = 0; i < d->m_model->rowCount(); i++) - append(d->m_model->data(d->m_model->index(i, d->m_mapValues), Qt::DisplayRole).toDouble(), d->m_model->data(d->m_model->index(i, d->m_mapLabels), Qt::DisplayRole).toString()); - } else { - for (int i = 0; i < d->m_model->columnCount(); i++) - append(d->m_model->data(d->m_model->index(d->m_mapValues, i), Qt::DisplayRole).toDouble(), d->m_model->data(d->m_model->index(d->m_mapLabels, i), Qt::DisplayRole).toString()); - } + // // create the initial slices set + // if (d->m_mapOrientation == Qt::Vertical) { + // for (int i = 0; i < d->m_model->rowCount(); i++) + // append(d->m_model->data(d->m_model->index(i, d->m_mapValues), Qt::DisplayRole).toDouble(), d->m_model->data(d->m_model->index(i, d->m_mapLabels), Qt::DisplayRole).toString()); + // } else { + // for (int i = 0; i < d->m_model->columnCount(); i++) + // append(d->m_model->data(d->m_model->index(d->m_mapValues, i), Qt::DisplayRole).toDouble(), d->m_model->data(d->m_model->index(d->m_mapLabels, i), Qt::DisplayRole).toString()); + // } +} + +void QPieSeries::setModelMappingRange(int first, int count) +{ + Q_D(QPieSeries); + d->m_mapFirst = first; + d->m_mapCount = count; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -553,37 +561,243 @@ void QPieSeriesPrivate::sliceHovered(bool state) void QPieSeriesPrivate::modelUpdated(QModelIndex topLeft, QModelIndex bottomRight) { - Q_UNUSED(bottomRight) - - if (m_mapOrientation == Qt::Vertical) - { - if (topLeft.column() == m_mapValues) - if (m_mapValues == m_mapLabels) + for (int row = topLeft.row(); row <= bottomRight.row(); row++) { + for (int column = topLeft.column(); column <= bottomRight.column(); column++) { + if (m_mapOrientation == Qt::Vertical) { - m_slices.at(topLeft.row())->setValue(m_model->data(topLeft, Qt::DisplayRole).toDouble()); - m_slices.at(topLeft.row())->setLabel(m_model->data(topLeft, Qt::DisplayRole).toString()); + if ( topLeft.row() >= m_mapFirst && (m_mapCount == - 1 || topLeft.row() < m_mapFirst + m_mapCount)) { + if (topLeft.column() == m_mapValues) + m_slices.at(topLeft.row() - m_mapFirst)->setValue(m_model->data(topLeft, Qt::DisplayRole).toDouble()); + if (topLeft.column() == m_mapLabels) + m_slices.at(topLeft.row() - m_mapFirst)->setLabel(m_model->data(topLeft, Qt::DisplayRole).toString()); + } } else { - m_slices.at(topLeft.row())->setValue(m_model->data(topLeft, Qt::DisplayRole).toDouble()); + if (topLeft.column() >= m_mapFirst && (m_mapCount == - 1 || topLeft.column() < m_mapFirst + m_mapCount)) { + if (topLeft.row() == m_mapValues) + m_slices.at(topLeft.column() - m_mapFirst)->setValue(m_model->data(topLeft, Qt::DisplayRole).toDouble()); + if (topLeft.row() == m_mapLabels) + m_slices.at(topLeft.column() - m_mapFirst)->setLabel(m_model->data(topLeft, Qt::DisplayRole).toString()); + } } - else if (topLeft.column() == m_mapLabels) - m_slices.at(topLeft.row())->setLabel(m_model->data(topLeft, Qt::DisplayRole).toString()); + } } - else - { - if (topLeft.row() == m_mapValues) - if (m_mapValues == m_mapLabels) - { - m_slices.at(topLeft.column())->setValue(m_model->data(topLeft, Qt::DisplayRole).toDouble()); - m_slices.at(topLeft.column())->setLabel(m_model->data(topLeft, Qt::DisplayRole).toString()); +} + + +void QPieSeriesPrivate::modelDataAdded(QModelIndex parent, int start, int end) +{ + Q_UNUSED(parent); + Q_Q(QPieSeries); + // series uses model as a data sourceupda + int addedCount = end - start + 1; + if (m_mapCount != -1 && start >= m_mapFirst + m_mapCount) { + return; + } else { + int first = qMax(start, m_mapFirst); + int last = qMin(first + addedCount - 1, end); + for (int i = first; i <= last; i++) { + QPieSlice *slice = new QPieSlice; + if (m_mapOrientation == Qt::Vertical) { + slice->setValue(m_model->data(m_model->index(i, m_mapValues), Qt::DisplayRole).toDouble()); + slice->setLabel(m_model->data(m_model->index(i, m_mapLabels), Qt::DisplayRole).toString()); + } else { + slice->setValue(m_model->data(m_model->index(m_mapValues, i), Qt::DisplayRole).toDouble()); + slice->setLabel(m_model->data(m_model->index(m_mapLabels, i), Qt::DisplayRole).toString()); } - else - { - m_slices.at(topLeft.column())->setValue(m_model->data(topLeft, Qt::DisplayRole).toDouble()); + slice->setLabelVisible(); + q->insert(i - m_mapFirst, slice); + } + if (m_mapCount != -1 && m_slices.size() > m_mapCount) + for (int i = m_slices.size() - 1; i >= m_mapCount; i--) + q->remove(q->slices().at(i)); + } + + // // adding items to unlimited map + // else if (m_mapCount == -1 && start >= m_mapFirst) { + // for (int i = start; i <= end; i++) { + // QPieSlice *slice = new QPieSlice; + // slice->setValue(m_model->data(m_model->index(i, m_mapValues), Qt::DisplayRole).toDouble()); + // slice->setLabel(m_model->data(m_model->index(i, m_mapLabels), Qt::DisplayRole).toString()); + // slice->setLabelVisible(true); + // q->insert(i - m_mapFirst, slice); + // // handlePointAdded(i - first); + // } + // } else if (m_mapCount == - 1 && start < m_mapFirst) { + // // not all newly added items + // for (int i = m_mapFirst; i < m_mapFirst + addedCount; i++) { + // QPieSlice *slice = new QPieSlice; + // slice->setValue(m_model->data(m_model->index(i, m_mapValues), Qt::DisplayRole).toDouble()); + // slice->setLabel(m_model->data(m_model->index(i, m_mapLabels), Qt::DisplayRole).toString()); + // slice->setLabelVisible(true); + // q->insert(i - m_mapFirst, slice); + // // handlePointAdded(i - first); + // } + // } + + // // adding items to limited map + // else if (start >= m_mapFirst) { + // // remove the items that will no longer fit into the map + // // int toRemove = addedCount - (count - points().size()); + // for (int i = start; i <= end; i++) { + // QPieSlice *slice = new QPieSlice; + // slice->setValue(m_model->data(m_model->index(i, m_mapValues), Qt::DisplayRole).toDouble()); + // slice->setLabel(m_model->data(m_model->index(i, m_mapLabels), Qt::DisplayRole).toString()); + // slice->setLabelVisible(true); + // q->insert(i - m_mapFirst, slice); + // } + // if (m_slices.size() > m_mapCount) + // for (int i = m_slices.size() - 1; i >= m_mapCount; i--) + // q->remove(q->slices().at(i)); + // // handlePointRemoved(i); + // // update(); + // } else { + // // + // for (int i = m_mapFirst; i < m_mapFirst + addedCount; i++) { + // QPieSlice *slice = new QPieSlice; + // slice->setValue(m_model->data(m_model->index(i, m_mapValues), Qt::DisplayRole).toDouble()); + // slice->setLabel(m_model->data(m_model->index(i, m_mapLabels), Qt::DisplayRole).toString()); + // slice->setLabelVisible(true); + // q->insert(i - m_mapFirst, slice); + // // handlePointAdded(i - first); + // } + // if (m_slices.size() > m_mapCount) + // for (int i = m_slices.size() - 1; i >= m_mapCount; i--) + // q->remove(q->slices().at(i)); + // // handlePointRemoved(i); + // } +} + +void QPieSeriesPrivate::modelDataRemoved(QModelIndex parent, int start, int end) +{ + Q_UNUSED(parent); + Q_Q(QPieSeries); + int removedCount = end - start + 1; + if (m_mapCount != -1 && start >= m_mapFirst + m_mapCount) { + return; + } + +// else if (m_mapCount == -1) { +// int first = qMax(start, m_mapFirst); +// int last = qMax(end, m_mapFirst + removedCount - 1); +// for (int i = last; i >= first; i--) +// q->remove(q->slices().at(i - m_mapFirst)); +// } +// else { +// int toRemove = qMin(m_slices.size() - 1, removedCount); +// int first = qMax(start, m_mapFirst); +// int last = qMax(end, m_mapFirst + toRemove - 1); + +// } + + // removing items from unlimited map + else if (m_mapCount == -1 && start >= m_mapFirst) { + for (int i = end; i >= start; i--) + q->remove(q->slices().at(i - m_mapFirst)); + // handlePointRemoved(i - m_mapFirst); + } else if (m_mapCount == - 1 && start < m_mapFirst) { + // not all removed items + for (int i = m_mapFirst + removedCount - 1; i >= m_mapFirst; i--) + q->remove(q->slices().at(i - m_mapFirst)); + // handlePointRemoved(i - m_mapFirst); + } + + // removing items from limited map + else if (start >= m_mapFirst) { + // +// int sizeAfter = m_slices.size(); + int lastExisting = qMin(m_mapFirst + m_slices.size() - 1, end); + for (int i = lastExisting; i >= start; i--) { + q->remove(q->slices().at(i - m_mapFirst)); +// sizeAfter--; + // handlePointRemoved(i - m_mapFirst); + } + + // the map is limited, so after removing the items some new items may have fall within the mapped area + int itemsAvailable; + if (m_mapOrientation == Qt::Vertical) + itemsAvailable = m_model->rowCount() - m_mapFirst - m_slices.size(); + else + itemsAvailable = m_model->columnCount() - m_mapFirst - m_slices.size(); + int toBeAdded = qMin(itemsAvailable, m_mapCount - m_slices.size()); + int currentSize = m_slices.size(); + if (itemsAvailable > 0) + for (int i = m_slices.size() + m_mapFirst; i < currentSize + toBeAdded + m_mapFirst; i++) { + // handlePointAdded(i); + QPieSlice *slice = new QPieSlice; + slice->setValue(m_model->data(m_model->index(i, m_mapValues), Qt::DisplayRole).toDouble()); + slice->setLabel(m_model->data(m_model->index(i, m_mapLabels), Qt::DisplayRole).toString()); + slice->setLabelVisible(true); + q->insert(i - m_mapFirst, slice); + } + + // for (int i = lastExisting; i >= start; i--) { + // q->remove(q->slices().at(i - m_mapFirst)); + //// sizeAfter--; + //// handlePointRemoved(i - m_mapFirst); + // } + } else { + // first remove item lays before the mapped area + int toRemove = qMin(m_slices.size(), removedCount); + for (int i = m_mapFirst; i < m_mapFirst + toRemove; i++) + q->remove(q->slices().at(0)); + // handlePointRemoved(0); + + // the map is limited, so after removing the items some new items may have fall into the map + int itemsAvailable; + if (m_mapOrientation == Qt::Vertical) + itemsAvailable = m_model->rowCount() - m_mapFirst - m_slices.size(); + else + itemsAvailable = m_model->columnCount() - m_mapFirst - m_slices.size(); + int toBeAdded = qMin(itemsAvailable, m_mapCount - m_slices.size()); + int currentSize = m_slices.size(); + if (itemsAvailable > 0) + for (int i = m_slices.size(); i < currentSize + toBeAdded; i++) { + QPieSlice *slice = new QPieSlice; + slice->setValue(m_model->data(m_model->index(i + m_mapFirst, m_mapValues), Qt::DisplayRole).toDouble()); + slice->setLabel(m_model->data(m_model->index(i + m_mapFirst, m_mapLabels), Qt::DisplayRole).toString()); + slice->setLabelVisible(true); + q->insert(i, slice); + // handlePointAdded(i); } - else if (topLeft.row() == m_mapLabels) - m_slices.at(topLeft.column())->setLabel(m_model->data(topLeft, Qt::DisplayRole).toString()); + } + +} + +void QPieSeriesPrivate::initializePieFromModel() +{ + Q_Q(QPieSeries); + // clear current content + q->clear(); + + // connect the signals + connect(m_model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(modelUpdated(QModelIndex,QModelIndex))); + if (m_mapOrientation == Qt::Vertical) { + connect(m_model,SIGNAL(rowsInserted(QModelIndex,int,int)), this, SLOT(modelDataAdded(QModelIndex,int,int))); + connect(m_model,SIGNAL(rowsRemoved(QModelIndex,int,int)), this, SLOT(modelDataRemoved(QModelIndex,int,int))); + } else { + connect(m_model, SIGNAL(columnsInserted(QModelIndex,int,int)), this, SLOT(modelDataAdded(QModelIndex,int,int))); + connect(m_model, SIGNAL(columnsRemoved(QModelIndex,int,int)), this, SLOT(modelDataRemoved(QModelIndex,int,int))); + } + + // create the initial slices set + if (m_mapOrientation == Qt::Vertical) { + int sliceCount = 0; + if(m_mapCount == -1) + sliceCount = m_model->rowCount() - m_mapFirst; + else + sliceCount = qMin(m_mapCount, m_model->rowCount() - m_mapFirst); + for (int i = m_mapFirst; i < m_mapFirst + sliceCount; i++) + q->append(m_model->data(m_model->index(i, m_mapValues), Qt::DisplayRole).toDouble(), m_model->data(m_model->index(i, m_mapLabels), Qt::DisplayRole).toString()); + } else { + int sliceCount = 0; + if(m_mapCount == -1) + sliceCount = m_model->columnCount() - m_mapFirst; + else + sliceCount = qMin(m_mapCount, m_model->columnCount() - m_mapFirst); + for (int i = m_mapFirst; i < m_mapFirst + sliceCount; i++) + q->append(m_model->data(m_model->index(m_mapValues, i), Qt::DisplayRole).toDouble(), m_model->data(m_model->index(m_mapLabels, i), Qt::DisplayRole).toString()); } } diff --git a/src/piechart/qpieseries.h b/src/piechart/qpieseries.h index a0a2530..24ba23a 100644 --- a/src/piechart/qpieseries.h +++ b/src/piechart/qpieseries.h @@ -73,6 +73,7 @@ public: bool setModel(QAbstractItemModel* model); void setModelMapping(int modelValuesLine, int modelLabelsLine, Qt::Orientation orientation = Qt::Vertical); + void setModelMappingRange(int first, int count = -1); Q_SIGNALS: void clicked(QPieSlice* slice); diff --git a/src/piechart/qpieseries_p.h b/src/piechart/qpieseries_p.h index 452cfdd..7faabc4 100644 --- a/src/piechart/qpieseries_p.h +++ b/src/piechart/qpieseries_p.h @@ -56,6 +56,9 @@ public Q_SLOTS: void sliceClicked(); void sliceHovered(bool state); void modelUpdated(QModelIndex topLeft, QModelIndex bottomRight); + void modelDataAdded(QModelIndex parent, int start, int end); + void modelDataRemoved(QModelIndex parent, int start, int end); + void initializePieFromModel(); bool setRealValue(qreal &value, qreal newValue, qreal max, qreal min = 0.0); public: @@ -70,6 +73,7 @@ public: // model map int m_mapValues; int m_mapLabels; + bool m_modelReady; private: friend class QLegendPrivate; diff --git a/src/xychart/xychartitem.cpp b/src/xychart/xychartitem.cpp index 1b2650f..e4c1b2b 100644 --- a/src/xychart/xychartitem.cpp +++ b/src/xychart/xychartitem.cpp @@ -220,7 +220,7 @@ void XYChartItem::handlePointsRemoved(int start, int end) handlePointRemoved(i - first); } - // the map is limited, so after removing the items some new items may have fall into the map + // the map is limited, so after removing the items some new items may have fall within the mapped area int itemsAvailable; if (m_series->mapOrientation() == Qt::Vertical) itemsAvailable = m_series->model()->rowCount() - first - m_points.size(); @@ -232,7 +232,7 @@ void XYChartItem::handlePointsRemoved(int start, int end) for (int i = m_points.size(); i < currentSize + toBeAdded; i++) handlePointAdded(i); } else { - // TODO: + // first removed item lays before the mapped area int toRemove = qMin(m_points.size() - 1, removedCount); for (int i = first; i < first + toRemove; i++) handlePointRemoved(0); diff --git a/test/tablemodelchart/customtablemodel.cpp b/test/tablemodelchart/customtablemodel.cpp index 0b4077b..f1c9382 100644 --- a/test/tablemodelchart/customtablemodel.cpp +++ b/test/tablemodelchart/customtablemodel.cpp @@ -43,7 +43,7 @@ CustomTableModel::CustomTableModel(QObject *parent) : qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); // m_data - for (int i = 0; i < 6; i++) + for (int i = 0; i < 8; i++) { QVector* dataVec = new QVector(6); // QVector* colorVec = new QVector(6); diff --git a/test/tablemodelchart/tablewidget.cpp b/test/tablemodelchart/tablewidget.cpp index 375e58a..305413e 100644 --- a/test/tablemodelchart/tablewidget.cpp +++ b/test/tablemodelchart/tablewidget.cpp @@ -21,6 +21,7 @@ #include "tablewidget.h" #include #include +#include #include #include #include @@ -38,9 +39,9 @@ #include TableWidget::TableWidget(QWidget *parent) - : QWidget(parent) + : QWidget(parent),specialPie(0) { - setGeometry(100, 100, 1000, 600); + setGeometry(1900, 100, 1000, 600); qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); // create simple model for storing data // user's table data model @@ -52,7 +53,7 @@ TableWidget::TableWidget(QWidget *parent) // tableView->setItemDelegate(new QStyledItemDelegate); m_chart = new QChart; m_chart->legend()->setVisible(true); -// m_chart->setAnimationOptions(QChart::SeriesAnimations); + m_chart->setAnimationOptions(QChart::SeriesAnimations); m_chartView = new QChartView(m_chart); m_chartView->setRenderHint(QPainter::Antialiasing); m_chartView->setMinimumSize(640, 480); @@ -67,6 +68,10 @@ TableWidget::TableWidget(QWidget *parent) QPushButton* removeRowButton = new QPushButton("Remove row"); connect(removeRowButton, SIGNAL(clicked()), this, SLOT(removeRow())); + QPushButton* specialPieButton = new QPushButton("Test pie"); + connect(specialPieButton, SIGNAL(clicked()), this, SLOT(testPie())); + + QLabel *spinBoxLabel = new QLabel("Rows affected:"); // spin box for setting number of affected items (add, remove) @@ -81,6 +86,7 @@ TableWidget::TableWidget(QWidget *parent) buttonsLayout->addWidget(addRowAboveButton); buttonsLayout->addWidget(addRowBelowButton); buttonsLayout->addWidget(removeRowButton); + buttonsLayout->addWidget(specialPieButton); buttonsLayout->addStretch(); // chart type radio buttons @@ -141,7 +147,8 @@ void TableWidget::updateChartType(bool toggle) // this if is needed, so that the function is only called once. // For the radioButton that was enabled. if (toggle) { - m_chart->removeAllSeries(); + specialPie = 0; + m_chart->removeAllSeries(); m_chart->axisX()->setNiceNumbersEnabled(false); m_chart->axisY()->setNiceNumbersEnabled(false); @@ -198,7 +205,7 @@ void TableWidget::updateChartType(bool toggle) m_series = new QSplineSeries; m_series->setModel(m_model); m_series->setModelMapping(0,1, Qt::Vertical); -// m_series->setModelMappingRange(1, 4); + // m_series->setModelMappingRange(1, 4); // series->setModelMapping(0,1, Qt::Horizontal); m_chart->addSeries(m_series); seriesColorHex = "#" + QString::number(m_series->pen().color().rgb(), 16).right(6).toUpper(); @@ -208,7 +215,7 @@ void TableWidget::updateChartType(bool toggle) m_series = new QSplineSeries; m_series->setModel(m_model); m_series->setModelMapping(2,3, Qt::Vertical); -// m_series->setModelMappingRange(0, 0); + // m_series->setModelMappingRange(0, 0); // series->setModelMapping(2,3, Qt::Horizontal); m_chart->addSeries(m_series); seriesColorHex = "#" + QString::number(m_series->pen().color().rgb(), 16).right(6).toUpper(); @@ -218,7 +225,7 @@ void TableWidget::updateChartType(bool toggle) m_series = new QSplineSeries; m_series->setModel(m_model); m_series->setModelMapping(4,5, Qt::Vertical); -// m_series->setModelMappingRange(2, 0); + // m_series->setModelMappingRange(2, 0); // series->setModelMapping(4,5, Qt::Horizontal); m_chart->addSeries(m_series); seriesColorHex = "#" + QString::number(m_series->pen().color().rgb(), 16).right(6).toUpper(); @@ -230,7 +237,7 @@ void TableWidget::updateChartType(bool toggle) m_series = new QScatterSeries; m_series->setModel(m_model); m_series->setModelMapping(0,1, Qt::Vertical); -// m_series->setModelMappingRange(2, 0); + // m_series->setModelMappingRange(2, 0); // series->setModelMapping(0,1, Qt::Horizontal); m_chart->addSeries(m_series); @@ -241,7 +248,7 @@ void TableWidget::updateChartType(bool toggle) m_series = new QScatterSeries; m_series->setModel(m_model); m_series->setModelMapping(2,3, Qt::Vertical); -// m_series->setModelMappingRange(1, 6); + // m_series->setModelMappingRange(1, 6); // series->setModelMapping(2,3, Qt::Horizontal); m_chart->addSeries(m_series); @@ -262,46 +269,62 @@ void TableWidget::updateChartType(bool toggle) // pie 1 QPieSeries* pieSeries = new QPieSeries; pieSeries->setModel(m_model); + pieSeries->setModelMappingRange(3, 3); pieSeries->setModelMapping(0,0, Qt::Vertical); pieSeries->setLabelsVisible(true); - pieSeries->setPieSize(0.4); + pieSeries->setPieSize(0.35); pieSeries->setHorizontalPosition(0.2); - pieSeries->setVerticalPosition(0.35); + pieSeries->setVerticalPosition(0.3); m_chart->addSeries(pieSeries); seriesColorHex = "#" + QString::number(pieSeries->slices().at(pieSeries->slices().count()/2)->brush().color().rgb(), 16).right(6).toUpper(); - m_model->addMapping(seriesColorHex, QRect(0, 0, 1, 1000)); + m_model->addMapping(seriesColorHex, QRect(0, 3, 1, 3)); // pie 2 pieSeries = new QPieSeries; pieSeries->setModel(m_model); + pieSeries->setModelMappingRange(2, -1); pieSeries->setModelMapping(1,1, Qt::Vertical); pieSeries->setLabelsVisible(true); - pieSeries->setPieSize(0.4); + pieSeries->setPieSize(0.35); pieSeries->setHorizontalPosition(0.8); - pieSeries->setVerticalPosition(0.35); + pieSeries->setVerticalPosition(0.3); m_chart->addSeries(pieSeries); seriesColorHex = "#" + QString::number(pieSeries->slices().at(pieSeries->slices().count()/2)->brush().color().rgb(), 16).right(6).toUpper(); - m_model->addMapping(seriesColorHex, QRect(1, 0, 1, 1000)); + m_model->addMapping(seriesColorHex, QRect(1, 2, 1, 1000)); // pie 3 pieSeries = new QPieSeries; pieSeries->setModel(m_model); pieSeries->setModelMapping(2,2, Qt::Vertical); pieSeries->setLabelsVisible(true); - pieSeries->setPieSize(0.4); - pieSeries->setHorizontalPosition(0.5); - pieSeries->setVerticalPosition(0.65); + pieSeries->setPieSize(0.35); + pieSeries->setHorizontalPosition(0.2); + pieSeries->setVerticalPosition(0.75); m_chart->addSeries(pieSeries); seriesColorHex = "#" + QString::number(pieSeries->slices().at(pieSeries->slices().count()/2)->brush().color().rgb(), 16).right(6).toUpper(); m_model->addMapping(seriesColorHex, QRect(2, 0, 1, 1000)); + + // special pie + specialPie = new QPieSeries; + specialPie->append(17, "1"); + specialPie->append(45, "2"); + specialPie->append(77, "3"); + specialPie->append(37, "4"); + specialPie->append(27, "5"); + specialPie->append(47, "6"); + specialPie->setPieSize(0.35); + specialPie->setHorizontalPosition(0.8); + specialPie->setVerticalPosition(0.75); + specialPie->setLabelsVisible(true); + m_chart->addSeries(specialPie); } else if (m_areaRadioButton->isChecked()) { QLineSeries* upperLineSeries = new QLineSeries; upperLineSeries->setModel(m_model); upperLineSeries->setModelMapping(0, 1, Qt::Vertical); -// upperLineSeries->setModelMappingRange(1, 5); + // upperLineSeries->setModelMappingRange(1, 5); QLineSeries* lowerLineSeries = new QLineSeries; lowerLineSeries->setModel(m_model); lowerLineSeries->setModelMapping(2, 3, Qt::Vertical); @@ -315,6 +338,7 @@ void TableWidget::updateChartType(bool toggle) { QBarSeries* barSeries = new QBarSeries(QStringList()); barSeries->setModel(m_model); +// barSeries->setModelMappingRange(2, 5); barSeries->setModelMapping(5, 2, 4, Qt::Vertical); m_chart->addSeries(barSeries); QList barsets = barSeries->barSets(); @@ -327,7 +351,7 @@ void TableWidget::updateChartType(bool toggle) if (!m_barRadioButton->isChecked()) m_chart->axisX()->setRange(0, 500); - m_chart->axisY()->setRange(0, 120); + // m_chart->axisY()->setRange(0, 120); m_chart->legend()->setVisible(true); // repaint table view colors @@ -336,6 +360,15 @@ void TableWidget::updateChartType(bool toggle) } } +void TableWidget::testPie() +{ + if (specialPie) { + specialPie->remove(specialPie->slices().at(2)); + // specialPie->insert(4, new QPieSlice(45, "Hello"));//specialPie->slices.at(2)); + specialPie->append(4, "heloo"); + } +} + TableWidget::~TableWidget() { diff --git a/test/tablemodelchart/tablewidget.h b/test/tablemodelchart/tablewidget.h index 437bb06..eb4a28b 100644 --- a/test/tablemodelchart/tablewidget.h +++ b/test/tablemodelchart/tablewidget.h @@ -22,16 +22,18 @@ #define TABLEWIDGET_H #include +//#include #include "qchartview.h" -#include "qxyseries.h" - -QTCOMMERCIALCHART_USE_NAMESPACE +//#include "qxyseries.h" +//#include class CustomTableModel; class QTableView; class QRadioButton; class QSpinBox; +QTCOMMERCIALCHART_USE_NAMESPACE + class TableWidget : public QWidget { Q_OBJECT @@ -46,6 +48,7 @@ public: void addRowBelow(); void removeRow(); void updateChartType(bool toggle); + void testPie(); private: QChartView* m_chartView; @@ -60,6 +63,7 @@ public: QRadioButton* m_areaRadioButton; QRadioButton* m_barRadioButton; QSpinBox* m_linesCountSpinBox; + QPieSeries* specialPie; }; #endif // TABLEWIDGET_H