summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiikka Heikkinen <miikka.heikkinen@digia.com>2014-04-29 14:50:04 +0300
committerMiikka Heikkinen <miikka.heikkinen@digia.com>2014-04-30 13:35:41 +0300
commit44b410f080c4820cea682c4d1278152d2767595c (patch)
treecebc33aae831beee71f52bddb6f4d4f9a768c69b
parent35a52776f687c43a4894fafbec9af3893f1d7f65 (diff)
Bar data item and row changing optimizations
No longer reset the entire render item array if single item or row changes, significantly speeding up these operations. Task-number: QTRD-2190 Change-Id: I44b8abd384003e252e4bfc34af5d73ac1dee34bf Reviewed-by: Tomi Korpipää <tomi.korpipaa@digia.com> Reviewed-by: Mika Salmela <mika.salmela@digia.com>
-rw-r--r--src/datavisualization/engine/bars3dcontroller.cpp81
-rw-r--r--src/datavisualization/engine/bars3dcontroller_p.h18
-rw-r--r--src/datavisualization/engine/bars3drenderer.cpp168
-rw-r--r--src/datavisualization/engine/bars3drenderer_p.h6
-rw-r--r--src/datavisualization/engine/scatter3drenderer.cpp6
-rw-r--r--src/datavisualization/engine/surface3dcontroller.cpp35
-rw-r--r--src/datavisualization/engine/surface3drenderer.cpp19
-rw-r--r--src/datavisualization/engine/surface3drenderer_p.h2
-rw-r--r--tests/barstest/chart.cpp269
-rw-r--r--tests/barstest/chart.h6
-rw-r--r--tests/barstest/main.cpp13
-rw-r--r--tests/surfacetest/graphmodifier.cpp4
12 files changed, 494 insertions, 133 deletions
diff --git a/src/datavisualization/engine/bars3dcontroller.cpp b/src/datavisualization/engine/bars3dcontroller.cpp
index 38870115..99fa8223 100644
--- a/src/datavisualization/engine/bars3dcontroller.cpp
+++ b/src/datavisualization/engine/bars3dcontroller.cpp
@@ -83,6 +83,18 @@ void Bars3DController::synchDataToRenderer()
Abstract3DController::synchDataToRenderer();
// Notify changes to renderer
+ if (m_changeTracker.rowsChanged) {
+ m_renderer->updateRows(m_changedRows);
+ m_changeTracker.rowsChanged = false;
+ m_changedRows.clear();
+ }
+
+ if (m_changeTracker.itemChanged) {
+ m_renderer->updateItems(m_changedItems);
+ m_changeTracker.itemChanged = false;
+ m_changedItems.clear();
+ }
+
if (m_changeTracker.multiSeriesScalingChanged) {
m_renderer->updateMultiSeriesScaling(m_isMultiSeriesUniform);
m_changeTracker.multiSeriesScalingChanged = false;
@@ -131,17 +143,39 @@ void Bars3DController::handleRowsAdded(int startIndex, int count)
void Bars3DController::handleRowsChanged(int startIndex, int count)
{
- Q_UNUSED(startIndex)
- Q_UNUSED(count)
QBar3DSeries *series = static_cast<QBarDataProxy *>(sender())->series();
- if (series->isVisible()) {
- adjustAxisRanges();
- m_isDataDirty = true;
- series->d_ptr->markItemLabelDirty();
+ int oldChangeCount = m_changedRows.size();
+ if (!oldChangeCount)
+ m_changedRows.reserve(count);
+
+ int selectedRow = m_selectedBar.x();
+ for (int i = 0; i < count; i++) {
+ bool newItem = true;
+ int candidate = startIndex + i;
+ for (int j = 0; j < oldChangeCount; j++) {
+ const ChangeRow &oldChangeItem = m_changedRows.at(j);
+ if (oldChangeItem.row == candidate && series == oldChangeItem.series) {
+ newItem = false;
+ break;
+ }
+ }
+ if (newItem) {
+ ChangeRow newChangeItem = {series, candidate};
+ m_changedRows.append(newChangeItem);
+ if (series == m_selectedBarSeries && selectedRow == candidate)
+ series->d_ptr->markItemLabelDirty();
+ }
+ }
+ if (count) {
+ m_changeTracker.rowsChanged = true;
+
+ if (series->isVisible())
+ adjustAxisRanges();
+
+ // Clear selection unless still valid (row length might have changed)
+ setSelectedBar(m_selectedBar, m_selectedBarSeries, false);
+ emitNeedRender();
}
- if (!m_changedSeriesList.contains(series))
- m_changedSeriesList.append(series);
- emitNeedRender();
}
void Bars3DController::handleRowsRemoved(int startIndex, int count)
@@ -199,17 +233,28 @@ void Bars3DController::handleRowsInserted(int startIndex, int count)
void Bars3DController::handleItemChanged(int rowIndex, int columnIndex)
{
- Q_UNUSED(rowIndex)
- Q_UNUSED(columnIndex)
QBar3DSeries *series = static_cast<QBarDataProxy *>(sender())->series();
- if (series->isVisible()) {
- adjustAxisRanges();
- m_isDataDirty = true;
- series->d_ptr->markItemLabelDirty();
+
+ bool newItem = true;
+ QPoint candidate(rowIndex, columnIndex);
+ foreach (ChangeItem item, m_changedItems) {
+ if (item.point == candidate && item.series == series) {
+ newItem = false;
+ break;
+ }
+ }
+
+ if (newItem) {
+ ChangeItem newItem = {series, candidate};
+ m_changedItems.append(newItem);
+ m_changeTracker.itemChanged = true;
+
+ if (series == m_selectedBarSeries && m_selectedBar == candidate)
+ series->d_ptr->markItemLabelDirty();
+ if (series->isVisible())
+ adjustAxisRanges();
+ emitNeedRender();
}
- if (!m_changedSeriesList.contains(series))
- m_changedSeriesList.append(series);
- emitNeedRender();
}
void Bars3DController::handleDataRowLabelsChanged()
diff --git a/src/datavisualization/engine/bars3dcontroller_p.h b/src/datavisualization/engine/bars3dcontroller_p.h
index 33928306..00eda402 100644
--- a/src/datavisualization/engine/bars3dcontroller_p.h
+++ b/src/datavisualization/engine/bars3dcontroller_p.h
@@ -42,12 +42,16 @@ struct Bars3DChangeBitField {
bool multiSeriesScalingChanged : 1;
bool barSpecsChanged : 1;
bool selectedBarChanged : 1;
+ bool rowsChanged : 1;
+ bool itemChanged : 1;
Bars3DChangeBitField() :
slicingActiveChanged(true),
multiSeriesScalingChanged(true),
barSpecsChanged(true),
- selectedBarChanged(true)
+ selectedBarChanged(true),
+ rowsChanged(false),
+ itemChanged(false)
{
}
};
@@ -56,8 +60,20 @@ class QT_DATAVISUALIZATION_EXPORT Bars3DController : public Abstract3DController
{
Q_OBJECT
+public:
+ struct ChangeItem {
+ QBar3DSeries *series;
+ QPoint point;
+ };
+ struct ChangeRow {
+ QBar3DSeries *series;
+ int row;
+ };
+
private:
Bars3DChangeBitField m_changeTracker;
+ QVector<ChangeItem> m_changedItems;
+ QVector<ChangeRow> m_changedRows;
// Interaction
QPoint m_selectedBar; // Points to row & column in data window.
diff --git a/src/datavisualization/engine/bars3drenderer.cpp b/src/datavisualization/engine/bars3drenderer.cpp
index 01fcebb2..ec1f0c7e 100644
--- a/src/datavisualization/engine/bars3drenderer.cpp
+++ b/src/datavisualization/engine/bars3drenderer.cpp
@@ -95,7 +95,8 @@ Bars3DRenderer::Bars3DRenderer(Bars3DController *controller)
m_clickedPosition(Bars3DController::invalidSelectionPosition()),
m_keepSeriesUniform(false),
m_haveUniformColorSeries(false),
- m_haveGradientSeries(false)
+ m_haveGradientSeries(false),
+ m_zeroPosition(0.0f)
{
m_axisCacheY.setScale(2.0f);
m_axisCacheY.setTranslate(-1.0f);
@@ -159,7 +160,6 @@ void Bars3DRenderer::updateData()
int maxCol = m_axisCacheX.max();
int newRows = maxRow - minRow + 1;
int newColumns = maxCol - minCol + 1;
- int updateSize = 0;
int dataRowCount = 0;
int maxDataRowCount = 0;
@@ -187,8 +187,7 @@ void Bars3DRenderer::updateData()
calculateSceneScalingFactors();
}
- const QValue3DAxisFormatter *axisFormatter = m_axisCacheY.formatter();
- float zeroPosition = axisFormatter->positionAt(0.0f);
+ m_zeroPosition = m_axisCacheY.formatter()->positionAt(0.0f);
foreach (SeriesRenderCache *baseCache, m_renderCacheList) {
BarSeriesRenderCache *cache = static_cast<BarSeriesRenderCache *>(baseCache);
@@ -212,50 +211,12 @@ void Bars3DRenderer::updateData()
if (maxDataRowCount < dataRowCount)
maxDataRowCount = qMin(dataRowCount, newRows);
int dataRowIndex = minRow;
- GLfloat heightValue = 0.0f;
for (int i = 0; i < newRows; i++) {
- int j = 0;
BarRenderItemRow &renderRow = renderArray[i];
- if (dataRowIndex < dataRowCount) {
- const QBarDataRow *dataRow = dataProxy->rowAt(dataRowIndex);
- updateSize = qMin((dataRow->size() - minCol), renderRow.size());
- if (dataRow) {
- int dataColIndex = minCol;
- for (; j < updateSize ; j++) {
- float value = dataRow->at(dataColIndex).value();
- heightValue = axisFormatter->positionAt(value);
- if (m_noZeroInRange) {
- if (m_hasNegativeValues) {
- heightValue = -1.0f + heightValue;
- if (heightValue > 0.0f)
- heightValue = 0.0f;
- } else {
- if (heightValue < 0.0f)
- heightValue = 0.0f;
- }
- } else {
- heightValue -= zeroPosition;
- }
- renderRow[j].setValue(value);
- renderRow[j].setHeight(heightValue);
-
- float angle = dataRow->at(dataColIndex).rotation();
- if (angle) {
- renderRow[j].setRotation(
- QQuaternion::fromAxisAndAngle(
- upVector, angle));
- } else {
- renderRow[j].setRotation(identityQuaternion);
- }
- dataColIndex++;
- }
- }
- }
- for (; j < newColumns; j++) {
- renderRow[j].setValue(0.0f);
- renderRow[j].setHeight(0.0f);
- renderRow[j].setRotation(identityQuaternion);
- }
+ const QBarDataRow *dataRow = 0;
+ if (dataRowIndex < dataRowCount)
+ dataRow = dataProxy->rowAt(dataRowIndex);
+ updateRenderRow(dataRow, renderRow);
dataRowIndex++;
}
cache->setDataDirty(false);
@@ -268,6 +229,56 @@ void Bars3DRenderer::updateData()
m_selectedSeriesCache ? m_selectedSeriesCache->series() : 0);
}
+void Bars3DRenderer::updateRenderRow(const QBarDataRow *dataRow, BarRenderItemRow &renderRow)
+{
+ int j = 0;
+ int renderRowSize = renderRow.size();
+ int startIndex = m_axisCacheX.min();
+
+ if (dataRow) {
+ int updateSize = qMin((dataRow->size() - startIndex), renderRowSize);
+ int dataColIndex = startIndex;
+ for (; j < updateSize ; j++) {
+ updateRenderItem(dataRow->at(dataColIndex), renderRow[j]);
+ dataColIndex++;
+ }
+ }
+ for (; j < renderRowSize; j++) {
+ renderRow[j].setValue(0.0f);
+ renderRow[j].setHeight(0.0f);
+ renderRow[j].setRotation(identityQuaternion);
+ }
+}
+
+void Bars3DRenderer::updateRenderItem(const QBarDataItem &dataItem, BarRenderItem &renderItem)
+{
+ float value = dataItem.value();
+ float heightValue = m_axisCacheY.formatter()->positionAt(value);
+ if (m_noZeroInRange) {
+ if (m_hasNegativeValues) {
+ heightValue = -1.0f + heightValue;
+ if (heightValue > 0.0f)
+ heightValue = 0.0f;
+ } else {
+ if (heightValue < 0.0f)
+ heightValue = 0.0f;
+ }
+ } else {
+ heightValue -= m_zeroPosition;
+ }
+ renderItem.setValue(value);
+ renderItem.setHeight(heightValue);
+
+ float angle = dataItem.rotation();
+ if (angle) {
+ renderItem.setRotation(
+ QQuaternion::fromAxisAndAngle(
+ upVector, angle));
+ } else {
+ renderItem.setRotation(identityQuaternion);
+ }
+}
+
void Bars3DRenderer::updateSeries(const QList<QAbstract3DSeries *> &seriesList)
{
Abstract3DRenderer::updateSeries(seriesList);
@@ -283,9 +294,9 @@ void Bars3DRenderer::updateSeries(const QList<QAbstract3DSeries *> &seriesList)
BarSeriesRenderCache *cache =
static_cast<BarSeriesRenderCache *>(m_renderCacheList.value(barSeries));
if (noSelection
- && barSeries->selectedBar() != QBar3DSeries::invalidSelectionPosition()
- && selectionLabel() != cache->itemLabel()) {
- m_selectionLabelDirty = true;
+ && barSeries->selectedBar() != QBar3DSeries::invalidSelectionPosition()) {
+ if (selectionLabel() != cache->itemLabel())
+ m_selectionLabelDirty = true;
noSelection = false;
}
cache->setVisualIndex(visualIndex++);
@@ -304,6 +315,65 @@ SeriesRenderCache *Bars3DRenderer::createNewCache(QAbstract3DSeries *series)
return new BarSeriesRenderCache(series, this);
}
+void Bars3DRenderer::updateRows(const QVector<Bars3DController::ChangeRow> &rows)
+{
+ int minRow = m_axisCacheZ.min();
+ int maxRow = m_axisCacheZ.max();
+ BarSeriesRenderCache *cache = 0;
+ const QBar3DSeries *prevSeries = 0;
+ const QBarDataArray *dataArray = 0;
+
+ foreach (Bars3DController::ChangeRow item, rows) {
+ const int row = item.row;
+ if (row < minRow || row > maxRow)
+ continue;
+ QBar3DSeries *currentSeries = item.series;
+ if (currentSeries != prevSeries) {
+ cache = static_cast<BarSeriesRenderCache *>(m_renderCacheList.value(currentSeries));
+ prevSeries = currentSeries;
+ dataArray = item.series->dataProxy()->array();
+ // Invisible series render caches are not updated, but instead just marked dirty, so that
+ // they can be completely recalculated when they are turned visible.
+ if (!cache->isVisible() && !cache->dataDirty())
+ cache->setDataDirty(true);
+ }
+ if (cache->isVisible())
+ updateRenderRow(dataArray->at(row), cache->renderArray()[row - minRow]);
+ }
+}
+
+void Bars3DRenderer::updateItems(const QVector<Bars3DController::ChangeItem> &points)
+{
+ int minRow = m_axisCacheZ.min();
+ int maxRow = m_axisCacheZ.max();
+ int minCol = m_axisCacheX.min();
+ int maxCol = m_axisCacheX.max();
+ BarSeriesRenderCache *cache = 0;
+ const QBar3DSeries *prevSeries = 0;
+ const QBarDataArray *dataArray = 0;
+
+ foreach (Bars3DController::ChangeItem item, points) {
+ const int row = item.point.x();
+ const int col = item.point.y();
+ if (row < minRow || row > maxRow || col < minCol || col > maxCol)
+ continue;
+ QBar3DSeries *currentSeries = item.series;
+ if (currentSeries != prevSeries) {
+ cache = static_cast<BarSeriesRenderCache *>(m_renderCacheList.value(currentSeries));
+ prevSeries = currentSeries;
+ dataArray = item.series->dataProxy()->array();
+ // Invisible series render caches are not updated, but instead just marked dirty, so that
+ // they can be completely recalculated when they are turned visible.
+ if (!cache->isVisible() && !cache->dataDirty())
+ cache->setDataDirty(true);
+ }
+ if (cache->isVisible()) {
+ updateRenderItem(dataArray->at(row)->at(col),
+ cache->renderArray()[row - minRow][col - minCol]);
+ }
+ }
+}
+
void Bars3DRenderer::updateScene(Q3DScene *scene)
{
if (m_hasNegativeValues)
diff --git a/src/datavisualization/engine/bars3drenderer_p.h b/src/datavisualization/engine/bars3drenderer_p.h
index ca0e690e..ddea546e 100644
--- a/src/datavisualization/engine/bars3drenderer_p.h
+++ b/src/datavisualization/engine/bars3drenderer_p.h
@@ -108,6 +108,7 @@ private:
bool m_keepSeriesUniform;
bool m_haveUniformColorSeries;
bool m_haveGradientSeries;
+ float m_zeroPosition;
public:
explicit Bars3DRenderer(Bars3DController *controller);
@@ -116,6 +117,8 @@ public:
void updateData();
void updateSeries(const QList<QAbstract3DSeries *> &seriesList);
SeriesRenderCache *createNewCache(QAbstract3DSeries *series);
+ void updateRows(const QVector<Bars3DController::ChangeRow> &rows);
+ void updateItems(const QVector<Bars3DController::ChangeItem> &points);
void updateScene(Q3DScene *scene);
void render(GLuint defaultFboHandle = 0);
@@ -169,6 +172,9 @@ private:
QPoint selectionColorToArrayPosition(const QVector4D &selectionColor);
QBar3DSeries *selectionColorToSeries(const QVector4D &selectionColor);
+ inline void updateRenderRow(const QBarDataRow *dataRow, BarRenderItemRow &renderRow);
+ inline void updateRenderItem(const QBarDataItem &dataItem, BarRenderItem &renderItem);
+
Q_DISABLE_COPY(Bars3DRenderer)
friend class BarRenderItem;
diff --git a/src/datavisualization/engine/scatter3drenderer.cpp b/src/datavisualization/engine/scatter3drenderer.cpp
index 5d37e6e1..3f91e9c3 100644
--- a/src/datavisualization/engine/scatter3drenderer.cpp
+++ b/src/datavisualization/engine/scatter3drenderer.cpp
@@ -240,9 +240,9 @@ void Scatter3DRenderer::updateSeries(const QList<QAbstract3DSeries *> &seriesLis
if (cache->itemSize() != itemSize)
cache->setItemSize(itemSize);
if (noSelection
- && scatterSeries->selectedItem() != QScatter3DSeries::invalidSelectionIndex()
- && m_selectionLabel != cache->itemLabel()) {
- m_selectionLabelDirty = true;
+ && scatterSeries->selectedItem() != QScatter3DSeries::invalidSelectionIndex()) {
+ if (m_selectionLabel != cache->itemLabel())
+ m_selectionLabelDirty = true;
noSelection = false;
}
diff --git a/src/datavisualization/engine/surface3dcontroller.cpp b/src/datavisualization/engine/surface3dcontroller.cpp
index 591cbdda..6f27c7df 100644
--- a/src/datavisualization/engine/surface3dcontroller.cpp
+++ b/src/datavisualization/engine/surface3dcontroller.cpp
@@ -76,7 +76,7 @@ void Surface3DController::synchDataToRenderer()
}
if (m_changeTracker.itemChanged) {
- m_renderer->updateItem(m_changedItems);
+ m_renderer->updateItems(m_changedItems);
m_changeTracker.itemChanged = false;
m_changedItems.clear();
}
@@ -309,36 +309,34 @@ void Surface3DController::handleFlatShadingSupportedChange(bool supported)
void Surface3DController::handleRowsChanged(int startIndex, int count)
{
- QSurfaceDataProxy *sender = static_cast<QSurfaceDataProxy *>(QObject::sender());
- if (m_changedRows.size() == 0)
- m_changedRows.reserve(sender->rowCount());
-
- QSurface3DSeries *series = sender->series();
+ QSurface3DSeries *series = static_cast<QSurfaceDataProxy *>(QObject::sender())->series();
int oldChangeCount = m_changedRows.size();
+ if (!oldChangeCount)
+ m_changedRows.reserve(count);
+
int selectedRow = m_selectedPoint.x();
for (int i = 0; i < count; i++) {
bool newItem = true;
int candidate = startIndex + i;
- for (int i = 0; i < oldChangeCount; i++) {
- if (m_changedRows.at(i).row == candidate &&
- series == m_changedRows.at(i).series) {
+ for (int j = 0; j < oldChangeCount; j++) {
+ const ChangeRow &oldChangeItem = m_changedRows.at(j);
+ if (oldChangeItem.row == candidate && series == oldChangeItem.series) {
newItem = false;
break;
}
}
if (newItem) {
- ChangeRow newItem = {series, candidate};
- m_changedRows.append(newItem);
+ ChangeRow newChangeItem = {series, candidate};
+ m_changedRows.append(newChangeItem);
if (series == m_selectedSeries && selectedRow == candidate)
series->d_ptr->markItemLabelDirty();
}
}
- if (m_changedRows.size()) {
+ if (count) {
m_changeTracker.rowsChanged = true;
- adjustAxisRanges();
- // Clear selection unless still valid
- setSelectedPoint(m_selectedPoint, m_selectedSeries, false);
+ if (series->isVisible())
+ adjustAxisRanges();
emitNeedRender();
}
}
@@ -349,7 +347,7 @@ void Surface3DController::handleItemChanged(int rowIndex, int columnIndex)
QSurface3DSeries *series = sender->series();
bool newItem = true;
- QPoint candidate(columnIndex, rowIndex);
+ QPoint candidate(rowIndex, columnIndex);
foreach (ChangeItem item, m_changedItems) {
if (item.point == candidate && item.series == series) {
newItem = false;
@@ -364,9 +362,8 @@ void Surface3DController::handleItemChanged(int rowIndex, int columnIndex)
if (series == m_selectedSeries && m_selectedPoint == candidate)
series->d_ptr->markItemLabelDirty();
- adjustAxisRanges();
- // Clear selection unless still valid
- setSelectedPoint(m_selectedPoint, m_selectedSeries, false);
+ if (series->isVisible())
+ adjustAxisRanges();
emitNeedRender();
}
}
diff --git a/src/datavisualization/engine/surface3drenderer.cpp b/src/datavisualization/engine/surface3drenderer.cpp
index f04277f7..198a034d 100644
--- a/src/datavisualization/engine/surface3drenderer.cpp
+++ b/src/datavisualization/engine/surface3drenderer.cpp
@@ -256,9 +256,9 @@ void Surface3DRenderer::updateSeries(const QList<QAbstract3DSeries *> &seriesLis
SurfaceSeriesRenderCache *cache =
static_cast<SurfaceSeriesRenderCache *>( m_renderCacheList.value(series));
if (noSelection
- && surfaceSeries->selectedPoint() != QSurface3DSeries::invalidSelectionPosition()
- && selectionLabel() != cache->itemLabel()) {
- m_selectionLabelDirty = true;
+ && surfaceSeries->selectedPoint() != QSurface3DSeries::invalidSelectionPosition()) {
+ if (selectionLabel() != cache->itemLabel())
+ m_selectionLabelDirty = true;
noSelection = false;
}
@@ -346,7 +346,7 @@ void Surface3DRenderer::updateRows(const QVector<Surface3DController::ChangeRow>
updateSelectedPoint(m_selectedPoint, m_selectedSeries);
}
-void Surface3DRenderer::updateItem(const QVector<Surface3DController::ChangeItem> &points)
+void Surface3DRenderer::updateItems(const QVector<Surface3DController::ChangeItem> &points)
{
foreach (Surface3DController::ChangeItem item, points) {
SurfaceSeriesRenderCache *cache =
@@ -364,14 +364,15 @@ void Surface3DRenderer::updateItem(const QVector<Surface3DController::ChangeItem
int sampleSpaceTop = sampleSpace.y() + sampleSpace.height();
int sampleSpaceRight = sampleSpace.x() + sampleSpace.width();
bool updateBuffers = false;
+ // Note: Point is (row, column), samplespace is (columns x rows)
QPoint point = item.point;
- if (point.y() <= sampleSpaceTop && point.y() >= sampleSpace.y() &&
- point.x() <= sampleSpaceRight && point.x() >= sampleSpace.x()) {
+ if (point.x() <= sampleSpaceTop && point.x() >= sampleSpace.y() &&
+ point.y() <= sampleSpaceRight && point.y() >= sampleSpace.x()) {
updateBuffers = true;
- int x = point.x() - sampleSpace.x();
- int y = point.y() - sampleSpace.y();
- (*(dstArray.at(y)))[x] = srcArray->at(point.y())->at(point.x());
+ int x = point.y() - sampleSpace.x();
+ int y = point.x() - sampleSpace.y();
+ (*(dstArray.at(y)))[x] = srcArray->at(point.x())->at(point.y());
if (cache->isFlatShadingEnabled())
cache->surfaceObject()->updateCoarseItem(dstArray, y, x);
diff --git a/src/datavisualization/engine/surface3drenderer_p.h b/src/datavisualization/engine/surface3drenderer_p.h
index 0cd4502a..db46a17b 100644
--- a/src/datavisualization/engine/surface3drenderer_p.h
+++ b/src/datavisualization/engine/surface3drenderer_p.h
@@ -110,7 +110,7 @@ public:
void cleanCache(SeriesRenderCache *cache);
void updateSelectionMode(QAbstract3DGraph::SelectionFlags mode);
void updateRows(const QVector<Surface3DController::ChangeRow> &rows);
- void updateItem(const QVector<Surface3DController::ChangeItem> &points);
+ void updateItems(const QVector<Surface3DController::ChangeItem> &points);
void updateScene(Q3DScene *scene);
void updateSlicingActive(bool isSlicing);
void updateSelectedPoint(const QPoint &position, QSurface3DSeries *series);
diff --git a/tests/barstest/chart.cpp b/tests/barstest/chart.cpp
index 2c095cf8..9bf21cbd 100644
--- a/tests/barstest/chart.cpp
+++ b/tests/barstest/chart.cpp
@@ -316,32 +316,14 @@ void GraphModifier::releaseAxes()
// Releases all axes - results in default axes for all dimensions.
// Axes reset when the graph is switched as set*Axis calls are made, which
// implicitly add axes.
- m_graph->releaseAxis(m_autoAdjustingAxis);
- m_graph->releaseAxis(m_fixedRangeAxis);
- m_graph->releaseAxis(m_temperatureAxis);
- m_graph->releaseAxis(m_yearAxis);
- m_graph->releaseAxis(m_monthAxis);
- m_graph->releaseAxis(m_genericRowAxis);
- m_graph->releaseAxis(m_genericColumnAxis);
+ foreach (QAbstract3DAxis *axis, m_graph->axes())
+ m_graph->releaseAxis(axis);
}
-void GraphModifier::releaseProxies()
+void GraphModifier::releaseSeries()
{
- // Releases all series/add all series toggle
- if (m_graph->seriesList().size() > 0) {
- m_graph->removeSeries(m_temperatureData);
- m_graph->removeSeries(m_temperatureData2);
- m_graph->removeSeries(m_genericData);
- m_graph->removeSeries(m_dummyData);
- m_graph->removeSeries(m_dummyData2);
- m_graph->removeSeries(m_dummyData3);
- m_graph->removeSeries(m_dummyData4);
- m_graph->removeSeries(m_dummyData5);
- } else {
- m_graph->addSeries(m_temperatureData);
- m_graph->addSeries(m_temperatureData2);
- m_graph->addSeries(m_genericData);
- }
+ foreach (QBar3DSeries *series, m_graph->seriesList())
+ m_graph->removeSeries(series);
}
void GraphModifier::flipViews()
@@ -771,7 +753,7 @@ void GraphModifier::changeShadowQuality(int quality)
void GraphModifier::showFiveSeries()
{
- releaseProxies();
+ releaseSeries();
releaseAxes();
m_graph->setSelectionMode(QAbstract3DGraph::SelectionItemRowAndColumn | QAbstract3DGraph::SelectionMultiSeries);
@@ -838,7 +820,7 @@ void GraphModifier::primarySeriesTest()
case 0: {
qDebug() << "Step 0 - Init:";
m_graph->addSeries(m_dummyData); // Add one series to enforce release in releaseProxies()
- releaseProxies();
+ releaseSeries();
releaseAxes();
m_dummyData->dataProxy()->resetArray(makeDummyData(),
testLabels,
@@ -1028,11 +1010,11 @@ void GraphModifier::insertRemoveTestToggle()
m_selectionTimer.stop();
m_graph->removeSeries(m_dummyData);
m_graph->removeSeries(m_dummyData2);
- releaseProxies();
+ releaseSeries();
releaseAxes();
m_graph->setActiveInputHandler(m_defaultInputHandler);
} else {
- releaseProxies();
+ releaseSeries();
releaseAxes();
m_graph->rowAxis()->setRange(0, 32);
m_graph->columnAxis()->setRange(0, 10);
@@ -1211,6 +1193,213 @@ void GraphModifier::addRemoveSeries()
counter++;
}
+void GraphModifier::testItemAndRowChanges()
+{
+ static int counter = 0;
+ const int rowCount = 12;
+ const int colCount = 10;
+ const float flatValue = 10.0f;
+ static QBar3DSeries *series0 = 0;
+ static QBar3DSeries *series1 = 0;
+ static QBar3DSeries *series2 = 0;
+ QBarDataItem item25;
+ QBarDataItem item50;
+ QBarDataItem item75;
+ item25.setValue(25);
+ item50.setValue(50);
+ item75.setValue(75);
+
+ switch (counter) {
+ case 0: {
+ qDebug() << __FUNCTION__ << counter << "Setup test";
+ releaseSeries();
+ releaseAxes();
+ delete series0;
+ delete series1;
+ delete series2;
+ series0 = new QBar3DSeries;
+ series1 = new QBar3DSeries;
+ series2 = new QBar3DSeries;
+ populateFlatSeries(series0, rowCount, colCount, flatValue);
+ populateFlatSeries(series1, rowCount, colCount, flatValue);
+ populateFlatSeries(series2, rowCount, colCount, flatValue);
+ m_graph->rowAxis()->setRange(4.0f, 8.0f);
+ m_graph->columnAxis()->setRange(3.0f, 6.0f);
+ m_graph->valueAxis()->setRange(0.0f, 100.0f);
+ m_graph->addSeries(series0);
+ m_graph->addSeries(series1);
+ m_graph->addSeries(series2);
+ //counter = 11; // skip single item tests
+ }
+ break;
+ case 1: {
+ qDebug() << __FUNCTION__ << counter << "Change single item, unselected";
+ series0->dataProxy()->setItem(4, 3, item50);
+ }
+ break;
+ case 2: {
+ qDebug() << __FUNCTION__ << counter << "Change single item, selected";
+ series1->setSelectedBar(QPoint(4, 5));
+ series1->dataProxy()->setItem(4, 5, item25);
+ }
+ break;
+ case 3: {
+ qDebug() << __FUNCTION__ << counter << "Change item outside visible area";
+ series1->dataProxy()->setItem(0, 3, item25);
+ }
+ break;
+ case 4: {
+ qDebug() << __FUNCTION__ << counter << "Change single item from two series, unselected";
+ series0->dataProxy()->setItem(5, 3, item25);
+ series1->dataProxy()->setItem(5, 3, item75);
+ }
+ break;
+ case 5: {
+ qDebug() << __FUNCTION__ << counter << "Change single item from two series, one selected";
+ series0->dataProxy()->setItem(5, 4, item25);
+ series1->dataProxy()->setItem(4, 5, item75);
+ }
+ break;
+ case 6: {
+ qDebug() << __FUNCTION__ << counter << "Change single item from two series, one outside range";
+ series0->dataProxy()->setItem(1, 2, item25);
+ series1->dataProxy()->setItem(6, 6, item75);
+ }
+ break;
+ case 7: {
+ qDebug() << __FUNCTION__ << counter << "Change single item from two series, both outside range";
+ series0->dataProxy()->setItem(1, 2, item25);
+ series1->dataProxy()->setItem(8, 8, item75);
+ }
+ break;
+ case 8: {
+ qDebug() << __FUNCTION__ << counter << "Change item to same value";
+ series1->dataProxy()->setItem(6, 6, item75);
+ }
+ break;
+ case 9: {
+ qDebug() << __FUNCTION__ << counter << "Change 3 items on each series";
+ series0->dataProxy()->setItem(7, 3, item25);
+ series0->dataProxy()->setItem(7, 4, item50);
+ series0->dataProxy()->setItem(7, 5, item75);
+ series1->dataProxy()->setItem(6, 3, item25);
+ series1->dataProxy()->setItem(6, 4, item50);
+ series1->dataProxy()->setItem(6, 5, item75);
+ }
+ break;
+ case 10: {
+ qDebug() << __FUNCTION__ << counter << "Level the field single item at a time";
+ QBarDataItem item;
+ item.setValue(15.0f);
+ for (int i = 0; i < rowCount; i++) {
+ for (int j = 0; j < colCount; j++) {
+ series0->dataProxy()->setItem(i, j, item);
+ series1->dataProxy()->setItem(i, j, item);
+ series2->dataProxy()->setItem(i, j, item);
+ }
+ }
+ }
+ break;
+ case 11: {
+ qDebug() << __FUNCTION__ << counter << "Change same items multiple times";
+ series0->dataProxy()->setItem(7, 3, item25);
+ series1->dataProxy()->setItem(7, 3, item25);
+ series0->dataProxy()->setItem(7, 3, item50);
+ series1->dataProxy()->setItem(7, 3, item50);
+ series0->dataProxy()->setItem(7, 3, item75);
+ series1->dataProxy()->setItem(7, 3, item75);
+ }
+ break;
+ case 12: {
+ qDebug() << __FUNCTION__ << counter << "Change row";
+ series0->dataProxy()->setRow(5, createFlatRow(colCount, 50.0f));
+ }
+ break;
+ case 13: {
+ qDebug() << __FUNCTION__ << counter << "Change row with selected item";
+ series1->setSelectedBar(QPoint(6, 6));
+ series1->dataProxy()->setRow(6, createFlatRow(colCount, 40.0f));
+ }
+ break;
+ case 14: {
+ qDebug() << __FUNCTION__ << counter << "Change hidden row";
+ series1->dataProxy()->setRow(9, createFlatRow(colCount, 50.0f));
+ }
+ break;
+ case 15: {
+ qDebug() << __FUNCTION__ << counter << "Change multiple rows singly";
+ series0->dataProxy()->setRow(6, createFlatRow(colCount, 70.0f));
+ series1->dataProxy()->setRow(6, createFlatRow(colCount, 80.0f));
+ series2->dataProxy()->setRow(6, createFlatRow(colCount, 90.0f));
+ }
+ break;
+ case 16: {
+ qDebug() << __FUNCTION__ << counter << "Change multiple rows many at a time";
+ QBarDataArray newRows;
+ newRows.reserve(4);
+ newRows.append(createFlatRow(colCount, 26.0f));
+ newRows.append(createFlatRow(colCount, 30.0f));
+ newRows.append(createFlatRow(colCount, 34.0f));
+ newRows.append(createFlatRow(colCount, 38.0f));
+ series0->dataProxy()->setRows(2, newRows);
+ newRows[0] = createFlatRow(colCount, 26.0f);
+ newRows[1] = createFlatRow(colCount, 30.0f);
+ newRows[2] = createFlatRow(colCount, 34.0f);
+ newRows[3] = createFlatRow(colCount, 38.0f);
+ series1->dataProxy()->setRows(3, newRows);
+ newRows[0] = createFlatRow(colCount, 26.0f);
+ newRows[1] = createFlatRow(colCount, 30.0f);
+ newRows[2] = createFlatRow(colCount, 34.0f);
+ newRows[3] = createFlatRow(colCount, 38.0f);
+ series2->dataProxy()->setRows(4, newRows);
+ }
+ break;
+ case 17: {
+ qDebug() << __FUNCTION__ << counter << "Change same rows multiple times";
+ QBarDataArray newRows;
+ newRows.reserve(4);
+ newRows.append(createFlatRow(colCount, 65.0f));
+ newRows.append(createFlatRow(colCount, 65.0f));
+ newRows.append(createFlatRow(colCount, 65.0f));
+ newRows.append(createFlatRow(colCount, 65.0f));
+ series0->dataProxy()->setRows(4, newRows);
+ newRows[0] = createFlatRow(colCount, 65.0f);
+ newRows[1] = createFlatRow(colCount, 65.0f);
+ newRows[2] = createFlatRow(colCount, 65.0f);
+ newRows[3] = createFlatRow(colCount, 65.0f);
+ series1->dataProxy()->setRows(4, newRows);
+ newRows[0] = createFlatRow(colCount, 65.0f);
+ newRows[1] = createFlatRow(colCount, 65.0f);
+ newRows[2] = createFlatRow(colCount, 65.0f);
+ newRows[3] = createFlatRow(colCount, 65.0f);
+ series2->dataProxy()->setRows(4, newRows);
+ series0->dataProxy()->setRow(6, createFlatRow(colCount, 20.0f));
+ series1->dataProxy()->setRow(6, createFlatRow(colCount, 20.0f));
+ series2->dataProxy()->setRow(6, createFlatRow(colCount, 20.0f));
+ series0->dataProxy()->setRow(6, createFlatRow(colCount, 90.0f));
+ series1->dataProxy()->setRow(6, createFlatRow(colCount, 90.0f));
+ series2->dataProxy()->setRow(6, createFlatRow(colCount, 90.0f));
+ }
+ break;
+ case 18: {
+ qDebug() << __FUNCTION__ << counter << "Change row to different length";
+ series0->dataProxy()->setRow(4, createFlatRow(5, 20.0f));
+ series1->dataProxy()->setRow(4, createFlatRow(0, 20.0f));
+ series2->dataProxy()->setRow(4, 0);
+ }
+ break;
+ case 19: {
+ qDebug() << __FUNCTION__ << counter << "Change selected row shorter so that selected item is no longer valid";
+ series1->dataProxy()->setRow(6, createFlatRow(6, 20.0f));
+ }
+ break;
+ default:
+ qDebug() << __FUNCTION__ << "Resetting test";
+ counter = -1;
+ }
+ counter++;
+}
+
void GraphModifier::changeValueAxisSegments(int value)
{
qDebug() << __FUNCTION__ << value;
@@ -1285,6 +1474,32 @@ void GraphModifier::handleFpsChange(qreal fps)
m_fpsLabel->setText(fpsPrefix + QString::number(qRound(fps)));
}
+void GraphModifier::populateFlatSeries(QBar3DSeries *series, int rows, int columns, float value)
+{
+ QBarDataArray *dataArray = new QBarDataArray;
+ dataArray->reserve(rows);
+ for (int i = 0; i < rows; i++) {
+ QBarDataRow *dataRow = new QBarDataRow(columns);
+ for (int j = 0; j < columns; j++)
+ (*dataRow)[j].setValue(value);
+ dataArray->append(dataRow);
+ }
+ QStringList axisLabels;
+ int count = qMax(rows, columns);
+ for (int i = 0; i < count; i++)
+ axisLabels << QString::number(i);
+
+ series->dataProxy()->resetArray(dataArray, axisLabels, axisLabels);
+}
+
+QBarDataRow *GraphModifier::createFlatRow(int columns, float value)
+{
+ QBarDataRow *dataRow = new QBarDataRow(columns);
+ for (int j = 0; j < columns; j++)
+ (*dataRow)[j].setValue(value);
+ return dataRow;
+}
+
void GraphModifier::setBackgroundEnabled(int enabled)
{
m_graph->activeTheme()->setBackgroundEnabled(bool(enabled));
diff --git a/tests/barstest/chart.h b/tests/barstest/chart.h
index e64b282a..385e139c 100644
--- a/tests/barstest/chart.h
+++ b/tests/barstest/chart.h
@@ -77,7 +77,7 @@ public:
void selectBar();
void swapAxis();
void releaseAxes();
- void releaseProxies();
+ void releaseSeries();
void createMassiveArray();
void useOwnTheme();
void changeBaseColor(const QColor &color);
@@ -92,6 +92,7 @@ public:
void changeLogBase(const QString & text);
void setFpsLabel(QLabel *fpsLabel) { m_fpsLabel = fpsLabel; }
void addRemoveSeries();
+ void testItemAndRowChanges();
public slots:
void flipViews();
@@ -118,6 +119,9 @@ signals:
void shadowQualityChanged(int quality);
private:
+ void populateFlatSeries(QBar3DSeries *series, int rows, int columns, float value);
+ QBarDataRow *createFlatRow(int columns, float value);
+
Q3DBars *m_graph;
QColorDialog *m_colorDialog;
int m_columnCount;
diff --git a/tests/barstest/main.cpp b/tests/barstest/main.cpp
index e02bddce..1182ffdf 100644
--- a/tests/barstest/main.cpp
+++ b/tests/barstest/main.cpp
@@ -175,6 +175,10 @@ int main(int argc, char **argv)
logAxisButton->setText(QStringLiteral("Use Log Axis"));
logAxisButton->setEnabled(true);
+ QPushButton *testItemAndRowChangesButton = new QPushButton(widget);
+ testItemAndRowChangesButton->setText(QStringLiteral("Test Item/Row changing"));
+ testItemAndRowChangesButton->setEnabled(true);
+
QColorDialog *colorDialog = new QColorDialog(widget);
QLinearGradient grBtoY(0, 0, 100, 0);
@@ -337,7 +341,9 @@ int main(int argc, char **argv)
vLayout->addWidget(ownThemeButton, 0, Qt::AlignTop);
vLayout->addWidget(primarySeriesTestsButton, 0, Qt::AlignTop);
vLayout->addWidget(toggleRotationButton, 0, Qt::AlignTop);
- vLayout->addWidget(gradientBtoYPB, 1, Qt::AlignTop);
+ vLayout->addWidget(gradientBtoYPB, 0, Qt::AlignTop);
+ vLayout->addWidget(logAxisButton, 0, Qt::AlignTop);
+ vLayout->addWidget(testItemAndRowChangesButton, 1, Qt::AlignTop);
vLayout2->addWidget(staticCheckBox, 0, Qt::AlignTop);
vLayout2->addWidget(rotationCheckBox, 0, Qt::AlignTop);
@@ -372,7 +378,6 @@ int main(int argc, char **argv)
vLayout2->addWidget(logBaseEdit, 0, Qt::AlignTop);
vLayout2->addWidget(new QLabel(QStringLiteral("Value axis segments")), 0, Qt::AlignTop);
vLayout2->addWidget(valueAxisSegmentsSpin, 0, Qt::AlignTop);
- vLayout->addWidget(logAxisButton, 1, Qt::AlignTop);
// TODO: Add example for setMeshFileName
widget->show();
@@ -446,7 +451,7 @@ int main(int argc, char **argv)
QObject::connect(releaseAxesButton, &QPushButton::clicked, modifier,
&GraphModifier::releaseAxes);
QObject::connect(releaseProxiesButton, &QPushButton::clicked, modifier,
- &GraphModifier::releaseProxies);
+ &GraphModifier::releaseSeries);
QObject::connect(flipViewsButton, &QPushButton::clicked, modifier,
&GraphModifier::flipViews);
@@ -460,6 +465,8 @@ int main(int argc, char **argv)
&GraphModifier::toggleRotation);
QObject::connect(logAxisButton, &QPushButton::clicked, modifier,
&GraphModifier::useLogAxis);
+ QObject::connect(testItemAndRowChangesButton, &QPushButton::clicked, modifier,
+ &GraphModifier::testItemAndRowChanges);
QObject::connect(colorDialog, &QColorDialog::currentColorChanged, modifier,
&GraphModifier::changeBaseColor);
QObject::connect(gradientBtoYPB, &QPushButton::clicked, modifier,
diff --git a/tests/surfacetest/graphmodifier.cpp b/tests/surfacetest/graphmodifier.cpp
index a4eb3a27..0f3aa985 100644
--- a/tests/surfacetest/graphmodifier.cpp
+++ b/tests/surfacetest/graphmodifier.cpp
@@ -143,7 +143,7 @@ void GraphModifier::fillSeries()
for (int i = 0; i < m_zCount; i++) {
QSurfaceDataRow *newRow[4];
float zAdjust = 0.0f;
- if (i == 3)
+ if (i == 2)
zAdjust = 0.7f;
for (int s = 0; s < 4; s++) {
@@ -151,7 +151,7 @@ void GraphModifier::fillSeries()
float z = float(i) - m_limitZ + 0.5f + m_multiSampleOffsetZ[s] + zAdjust;
for (int j = 0; j < m_xCount; j++) {
float xAdjust = 0.0f;
- if (j == 3)
+ if (j == 4)
xAdjust = 0.7f;
float x = float(j) - m_limitX + 0.5f + m_multiSampleOffsetX[s] + xAdjust;
float angle = (z * x) / full * 1.57f;