diff options
author | Miikka Heikkinen <miikka.heikkinen@digia.com> | 2014-04-30 15:36:19 +0300 |
---|---|---|
committer | Miikka Heikkinen <miikka.heikkinen@digia.com> | 2014-05-02 10:53:05 +0300 |
commit | 13d1117087e66c77d2eea2f0a046fc556c19cb3c (patch) | |
tree | f003ec51145278cea0fd2d123da6c0478c961297 | |
parent | 44b410f080c4820cea682c4d1278152d2767595c (diff) |
Scatter data changing optimization.
No longer reset the entire render item array if single item
changes, significantly speeding up this operation.
Task-number: QTRD-2190
Change-Id: Ia3de833b761dc6f24acff581ad79668f51c3e9c5
Reviewed-by: Titta Heikkala <titta.heikkala@digia.com>
Reviewed-by: Mika Salmela <mika.salmela@digia.com>
-rw-r--r-- | src/datavisualization/engine/bars3drenderer.cpp | 4 | ||||
-rw-r--r-- | src/datavisualization/engine/bars3drenderer_p.h | 2 | ||||
-rw-r--r-- | src/datavisualization/engine/scatter3dcontroller.cpp | 42 | ||||
-rw-r--r-- | src/datavisualization/engine/scatter3dcontroller_p.h | 10 | ||||
-rw-r--r-- | src/datavisualization/engine/scatter3drenderer.cpp | 67 | ||||
-rw-r--r-- | src/datavisualization/engine/scatter3drenderer_p.h | 2 | ||||
-rw-r--r-- | tests/scattertest/main.cpp | 20 | ||||
-rw-r--r-- | tests/scattertest/scatterchart.cpp | 197 | ||||
-rw-r--r-- | tests/scattertest/scatterchart.h | 6 |
9 files changed, 311 insertions, 39 deletions
diff --git a/src/datavisualization/engine/bars3drenderer.cpp b/src/datavisualization/engine/bars3drenderer.cpp index ec1f0c7e..ab7bb4ca 100644 --- a/src/datavisualization/engine/bars3drenderer.cpp +++ b/src/datavisualization/engine/bars3drenderer.cpp @@ -342,7 +342,7 @@ void Bars3DRenderer::updateRows(const QVector<Bars3DController::ChangeRow> &rows } } -void Bars3DRenderer::updateItems(const QVector<Bars3DController::ChangeItem> &points) +void Bars3DRenderer::updateItems(const QVector<Bars3DController::ChangeItem> &items) { int minRow = m_axisCacheZ.min(); int maxRow = m_axisCacheZ.max(); @@ -352,7 +352,7 @@ void Bars3DRenderer::updateItems(const QVector<Bars3DController::ChangeItem> &po const QBar3DSeries *prevSeries = 0; const QBarDataArray *dataArray = 0; - foreach (Bars3DController::ChangeItem item, points) { + foreach (Bars3DController::ChangeItem item, items) { const int row = item.point.x(); const int col = item.point.y(); if (row < minRow || row > maxRow || col < minCol || col > maxCol) diff --git a/src/datavisualization/engine/bars3drenderer_p.h b/src/datavisualization/engine/bars3drenderer_p.h index ddea546e..8e39ee11 100644 --- a/src/datavisualization/engine/bars3drenderer_p.h +++ b/src/datavisualization/engine/bars3drenderer_p.h @@ -118,7 +118,7 @@ public: 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 updateItems(const QVector<Bars3DController::ChangeItem> &items); void updateScene(Q3DScene *scene); void render(GLuint defaultFboHandle = 0); diff --git a/src/datavisualization/engine/scatter3dcontroller.cpp b/src/datavisualization/engine/scatter3dcontroller.cpp index 05c0efe7..2d38a4a7 100644 --- a/src/datavisualization/engine/scatter3dcontroller.cpp +++ b/src/datavisualization/engine/scatter3dcontroller.cpp @@ -71,6 +71,12 @@ void Scatter3DController::synchDataToRenderer() Abstract3DController::synchDataToRenderer(); // Notify changes to renderer + if (m_changeTracker.itemChanged) { + m_renderer->updateItems(m_changedItems); + m_changeTracker.itemChanged = false; + m_changedItems.clear(); + } + if (m_changeTracker.selectedItemChanged) { m_renderer->updateSelectedItem(m_selectedItem, m_selectedItemSeries); m_changeTracker.selectedItemChanged = false; @@ -144,17 +150,35 @@ void Scatter3DController::handleItemsAdded(int startIndex, int count) void Scatter3DController::handleItemsChanged(int startIndex, int count) { - Q_UNUSED(startIndex) - Q_UNUSED(count) QScatter3DSeries *series = static_cast<QScatterDataProxy *>(sender())->series(); - if (series->isVisible()) { - adjustAxisRanges(); - m_isDataDirty = true; - series->d_ptr->markItemLabelDirty(); + int oldChangeCount = m_changedItems.size(); + if (!oldChangeCount) + m_changedItems.reserve(count); + + for (int i = 0; i < count; i++) { + bool newItem = true; + int candidate = startIndex + i; + for (int j = 0; j < oldChangeCount; j++) { + const ChangeItem &oldChangeItem = m_changedItems.at(j); + if (oldChangeItem.index == candidate && series == oldChangeItem.series) { + newItem = false; + break; + } + } + if (newItem) { + ChangeItem newChangeItem = {series, candidate}; + m_changedItems.append(newChangeItem); + if (series == m_selectedItemSeries && m_selectedItem == candidate) + series->d_ptr->markItemLabelDirty(); + } + } + + if (count) { + m_changeTracker.itemChanged = true; + if (series->isVisible()) + adjustAxisRanges(); + emitNeedRender(); } - if (!m_changedSeriesList.contains(series)) - m_changedSeriesList.append(series); - emitNeedRender(); } void Scatter3DController::handleItemsRemoved(int startIndex, int count) diff --git a/src/datavisualization/engine/scatter3dcontroller_p.h b/src/datavisualization/engine/scatter3dcontroller_p.h index 1194bc3a..db5a95f5 100644 --- a/src/datavisualization/engine/scatter3dcontroller_p.h +++ b/src/datavisualization/engine/scatter3dcontroller_p.h @@ -40,9 +40,11 @@ class QScatter3DSeries; struct Scatter3DChangeBitField { bool selectedItemChanged : 1; + bool itemChanged : 1; Scatter3DChangeBitField() : - selectedItemChanged(true) + selectedItemChanged(true), + itemChanged(false) { } }; @@ -51,8 +53,14 @@ class QT_DATAVISUALIZATION_EXPORT Scatter3DController : public Abstract3DControl { Q_OBJECT +public: + struct ChangeItem { + QScatter3DSeries *series; + int index; + }; private: Scatter3DChangeBitField m_changeTracker; + QVector<ChangeItem> m_changedItems; // Rendering Scatter3DRenderer *m_renderer; diff --git a/src/datavisualization/engine/scatter3drenderer.cpp b/src/datavisualization/engine/scatter3drenderer.cpp index 3f91e9c3..c1705179 100644 --- a/src/datavisualization/engine/scatter3drenderer.cpp +++ b/src/datavisualization/engine/scatter3drenderer.cpp @@ -165,12 +165,6 @@ void Scatter3DRenderer::initializeOpenGL() void Scatter3DRenderer::updateData() { calculateSceneScalingFactors(); - float minX = float(m_axisCacheX.min()); - float maxX = float(m_axisCacheX.max()); - float minY = float(m_axisCacheY.min()); - float maxY = float(m_axisCacheY.max()); - float minZ = float(m_axisCacheZ.min()); - float maxZ = float(m_axisCacheZ.max()); int totalDataSize = 0; foreach (SeriesRenderCache *baseCache, m_renderCacheList) { @@ -185,23 +179,8 @@ void Scatter3DRenderer::updateData() if (dataSize != renderArray.size()) renderArray.resize(dataSize); - for (int i = 0; i < dataSize; i++) { - QVector3D dotPos = dataArray.at(i).position(); - ScatterRenderItem &renderItem = renderArray[i]; - if ((dotPos.x() >= minX && dotPos.x() <= maxX ) - && (dotPos.y() >= minY && dotPos.y() <= maxY) - && (dotPos.z() >= minZ && dotPos.z() <= maxZ)) { - renderItem.setPosition(dotPos); - renderItem.setVisible(true); - if (!dataArray.at(i).rotation().isIdentity()) - renderItem.setRotation(dataArray.at(i).rotation().normalized()); - else - renderItem.setRotation(identityQuaternion); - calculateTranslation(renderItem); - } else { - renderItem.setVisible(false); - } - } + for (int i = 0; i < dataSize; i++) + updateRenderItem(dataArray.at(i), renderArray[i]); cache->setDataDirty(false); } } @@ -272,6 +251,30 @@ SeriesRenderCache *Scatter3DRenderer::createNewCache(QAbstract3DSeries *series) return new ScatterSeriesRenderCache(series, this); } +void Scatter3DRenderer::updateItems(const QVector<Scatter3DController::ChangeItem> &items) +{ + ScatterSeriesRenderCache *cache = 0; + const QScatter3DSeries *prevSeries = 0; + const QScatterDataArray *dataArray = 0; + + foreach (Scatter3DController::ChangeItem item, items) { + QScatter3DSeries *currentSeries = item.series; + if (currentSeries != prevSeries) { + cache = static_cast<ScatterSeriesRenderCache *>(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()) { + const int index = item.index; + updateRenderItem(dataArray->at(index), cache->renderArray()[index]); + } + } +} + void Scatter3DRenderer::updateScene(Q3DScene *scene) { scene->activeCamera()->d_ptr->setMinYRotation(-90.0f); @@ -1802,6 +1805,24 @@ void Scatter3DRenderer::selectionColorToSeriesAndIndex(const QVector4D &color, series = 0; } +void Scatter3DRenderer::updateRenderItem(const QScatterDataItem &dataItem, ScatterRenderItem &renderItem) +{ + QVector3D dotPos = dataItem.position(); + if ((dotPos.x() >= m_axisCacheX.min() && dotPos.x() <= m_axisCacheX.max() ) + && (dotPos.y() >= m_axisCacheY.min() && dotPos.y() <= m_axisCacheY.max()) + && (dotPos.z() >= m_axisCacheZ.min() && dotPos.z() <= m_axisCacheZ.max())) { + renderItem.setPosition(dotPos); + renderItem.setVisible(true); + if (!dataItem.rotation().isIdentity()) + renderItem.setRotation(dataItem.rotation().normalized()); + else + renderItem.setRotation(identityQuaternion); + calculateTranslation(renderItem); + } else { + renderItem.setVisible(false); + } +} + QVector3D Scatter3DRenderer::convertPositionToTranslation(const QVector3D &position) { float xTrans = m_axisCacheX.positionAt(position.x()); float yTrans = m_axisCacheY.positionAt(position.y()); diff --git a/src/datavisualization/engine/scatter3drenderer_p.h b/src/datavisualization/engine/scatter3drenderer_p.h index 172d0c46..09b8dace 100644 --- a/src/datavisualization/engine/scatter3drenderer_p.h +++ b/src/datavisualization/engine/scatter3drenderer_p.h @@ -105,6 +105,7 @@ public: void updateData(); void updateSeries(const QList<QAbstract3DSeries *> &seriesList); SeriesRenderCache *createNewCache(QAbstract3DSeries *series); + void updateItems(const QVector<Scatter3DController::ChangeItem> &items); void updateScene(Q3DScene *scene); QVector3D convertPositionToTranslation(const QVector3D &position); @@ -154,6 +155,7 @@ public slots: private: void selectionColorToSeriesAndIndex(const QVector4D &color, int &index, QAbstract3DSeries *&series); + inline void updateRenderItem(const QScatterDataItem &dataItem, ScatterRenderItem &renderItem); }; QT_END_NAMESPACE_DATAVISUALIZATION diff --git a/tests/scattertest/main.cpp b/tests/scattertest/main.cpp index 78bab934..82d025aa 100644 --- a/tests/scattertest/main.cpp +++ b/tests/scattertest/main.cpp @@ -123,6 +123,9 @@ int main(int argc, char **argv) QPushButton *massiveDataTestButton = new QPushButton(widget); massiveDataTestButton->setText(QStringLiteral("Massive data test")); + QPushButton *testItemChangesButton = new QPushButton(widget); + testItemChangesButton->setText(QStringLiteral("Test Item changing")); + QLinearGradient grBtoY(0, 0, 100, 0); grBtoY.setColorAt(1.0, Qt::black); grBtoY.setColorAt(0.67, Qt::blue); @@ -137,6 +140,12 @@ int main(int argc, char **argv) gradientBtoYPB->setIcon(QIcon(pm)); gradientBtoYPB->setIconSize(QSize(100, 24)); + QLabel *fpsLabel = new QLabel(QStringLiteral("")); + + QCheckBox *fpsCheckBox = new QCheckBox(widget); + fpsCheckBox->setText(QStringLiteral("Measure Fps")); + fpsCheckBox->setChecked(false); + QCheckBox *backgroundCheckBox = new QCheckBox(widget); backgroundCheckBox->setText(QStringLiteral("Show background")); backgroundCheckBox->setChecked(true); @@ -232,9 +241,12 @@ int main(int argc, char **argv) vLayout->addWidget(toggleSeriesVisibilityButton, 0, Qt::AlignTop); vLayout->addWidget(changeSeriesNameButton, 0, Qt::AlignTop); vLayout->addWidget(startTimerButton, 0, Qt::AlignTop); - vLayout->addWidget(massiveDataTestButton, 1, Qt::AlignTop); + vLayout->addWidget(massiveDataTestButton, 0, Qt::AlignTop); + vLayout->addWidget(testItemChangesButton, 1, Qt::AlignTop); vLayout2->addWidget(gradientBtoYPB, 0, Qt::AlignTop); + vLayout2->addWidget(fpsLabel, 0, Qt::AlignTop); + vLayout2->addWidget(fpsCheckBox, 0, Qt::AlignTop); vLayout2->addWidget(backgroundCheckBox); vLayout2->addWidget(gridCheckBox); vLayout2->addWidget(new QLabel(QStringLiteral("Adjust shadow quality"))); @@ -302,6 +314,8 @@ int main(int argc, char **argv) &ScatterDataModifier::startStopTimer); QObject::connect(massiveDataTestButton, &QPushButton::clicked, modifier, &ScatterDataModifier::massiveDataTest); + QObject::connect(testItemChangesButton, &QPushButton::clicked, modifier, + &ScatterDataModifier::testItemChanges); QObject::connect(gradientBtoYPB, &QPushButton::clicked, modifier, &ScatterDataModifier::setGradient); QObject::connect(themeButton, &QPushButton::clicked, modifier, @@ -316,6 +330,8 @@ int main(int argc, char **argv) QObject::connect(fontList, &QFontComboBox::currentFontChanged, modifier, &ScatterDataModifier::changeFont); + QObject::connect(fpsCheckBox, &QCheckBox::stateChanged, modifier, + &ScatterDataModifier::setFpsMeasurement); QObject::connect(backgroundCheckBox, &QCheckBox::stateChanged, modifier, &ScatterDataModifier::setBackgroundEnabled); QObject::connect(gridCheckBox, &QCheckBox::stateChanged, modifier, @@ -335,6 +351,8 @@ int main(int argc, char **argv) &ScatterDataModifier::setMaxZ); + modifier->setFpsLabel(fpsLabel); + modifier->start(); return app.exec(); diff --git a/tests/scattertest/scatterchart.cpp b/tests/scattertest/scatterchart.cpp index c9404736..13a0f040 100644 --- a/tests/scattertest/scatterchart.cpp +++ b/tests/scattertest/scatterchart.cpp @@ -134,7 +134,6 @@ void ScatterDataModifier::massiveDataTest() xAxis->setSegmentCount(1); yAxis->setSegmentCount(1); zAxis->setSegmentCount(1); - m_chart->setMeasureFps(true); m_chart->setAxisX(xAxis); m_chart->setAxisY(yAxis); m_chart->setAxisZ(zAxis); @@ -231,6 +230,187 @@ void ScatterDataModifier::massiveTestAppendAndScroll() m_chart->axisZ()->setRange(min, max); } +void ScatterDataModifier::setFpsMeasurement(bool enable) +{ + m_chart->setMeasureFps(enable); +} + +void ScatterDataModifier::testItemChanges() +{ + static int counter = 0; + const int rowCount = 12; + const int colCount = 10; + static QScatter3DSeries *series0 = 0; + static QScatter3DSeries *series1 = 0; + static QScatter3DSeries *series2 = 0; + + switch (counter) { + case 0: { + qDebug() << __FUNCTION__ << counter << "Setup test"; + foreach (QScatter3DSeries *series, m_chart->seriesList()) + m_chart->removeSeries(series); + foreach (QValue3DAxis *axis, m_chart->axes()) + m_chart->releaseAxis(axis); + delete series0; + delete series1; + delete series2; + series0 = new QScatter3DSeries; + series1 = new QScatter3DSeries; + series2 = new QScatter3DSeries; + populateFlatSeries(series0, rowCount, colCount, 10.0f); + populateFlatSeries(series1, rowCount, colCount, 30.0f); + populateFlatSeries(series2, rowCount, colCount, 50.0f); + m_chart->axisX()->setRange(3.0f, 6.0f); + m_chart->axisY()->setRange(0.0f, 100.0f); + m_chart->axisZ()->setRange(4.0f, 8.0f); + m_chart->addSeries(series0); + m_chart->addSeries(series1); + m_chart->addSeries(series2); + } + break; + case 1: { + qDebug() << __FUNCTION__ << counter << "Change single item, unselected"; + int itemIndex = 3 * colCount + 5; + QScatterDataItem item = *series0->dataProxy()->itemAt(itemIndex); + item.setY(75.0f); + series0->dataProxy()->setItem(itemIndex, item); + } + break; + case 2: { + qDebug() << __FUNCTION__ << counter << "Change single item, selected"; + int itemIndex = 4 * colCount + 4; + series1->setSelectedItem(itemIndex); + QScatterDataItem item = *series1->dataProxy()->itemAt(itemIndex); + item.setY(75.0f); + series1->dataProxy()->setItem(itemIndex, item); + } + break; + case 3: { + qDebug() << __FUNCTION__ << counter << "Change item outside visible area"; + int itemIndex = 2; + QScatterDataItem item = *series1->dataProxy()->itemAt(itemIndex); + item.setY(75.0f); + series1->dataProxy()->setItem(itemIndex, item); + } + break; + case 4: { + qDebug() << __FUNCTION__ << counter << "Change single item from two series, unselected"; + int itemIndex = 4 * colCount + 6; + QScatterDataItem item0 = *series0->dataProxy()->itemAt(itemIndex); + QScatterDataItem item1 = *series1->dataProxy()->itemAt(itemIndex); + item0.setY(65.0f); + item1.setY(85.0f); + series0->dataProxy()->setItem(itemIndex, item0); + series1->dataProxy()->setItem(itemIndex, item1); + } + break; + case 5: { + qDebug() << __FUNCTION__ << counter << "Change single item from two series, one selected"; + int itemIndex0 = 5 * colCount + 5; + int itemIndex1 = 4 * colCount + 4; + QScatterDataItem item0 = *series0->dataProxy()->itemAt(itemIndex0); + QScatterDataItem item1 = *series1->dataProxy()->itemAt(itemIndex1); + item0.setY(65.0f); + item1.setY(85.0f); + series0->dataProxy()->setItem(itemIndex0, item0); + series1->dataProxy()->setItem(itemIndex1, item1); + } + break; + case 6: { + qDebug() << __FUNCTION__ << counter << "Change single item from two series, one outside range"; + int itemIndex0 = 6 * colCount + 6; + int itemIndex1 = 9 * colCount + 2; + QScatterDataItem item0 = *series0->dataProxy()->itemAt(itemIndex0); + QScatterDataItem item1 = *series1->dataProxy()->itemAt(itemIndex1); + item0.setY(65.0f); + item1.setY(85.0f); + series0->dataProxy()->setItem(itemIndex0, item0); + series1->dataProxy()->setItem(itemIndex1, item1); + } + break; + case 7: { + qDebug() << __FUNCTION__ << counter << "Change single item from two series, both outside range"; + int itemIndex0 = 1 * colCount + 3; + int itemIndex1 = 9 * colCount + 2; + QScatterDataItem item0 = *series0->dataProxy()->itemAt(itemIndex0); + QScatterDataItem item1 = *series1->dataProxy()->itemAt(itemIndex1); + item0.setY(65.0f); + item1.setY(85.0f); + series0->dataProxy()->setItem(itemIndex0, item0); + series1->dataProxy()->setItem(itemIndex1, item1); + } + break; + case 8: { + qDebug() << __FUNCTION__ << counter << "Change item to same value as previously"; + int itemIndex0 = 5 * colCount + 7; + int itemIndex1 = 4 * colCount + 7; + QScatterDataItem item0 = *series0->dataProxy()->itemAt(itemIndex0); + QScatterDataItem item1 = *series1->dataProxy()->itemAt(itemIndex1); + series0->dataProxy()->setItem(itemIndex0, item0); + series1->dataProxy()->setItem(itemIndex1, item1); + } + break; + case 9: { + qDebug() << __FUNCTION__ << counter << "Change 3 items on each series"; + int itemIndex0 = 5 * colCount + 6; + int itemIndex1 = 4 * colCount + 6; + QScatterDataItem item00 = *series0->dataProxy()->itemAt(itemIndex0); + QScatterDataItem item01 = *series0->dataProxy()->itemAt(itemIndex0 + 1); + QScatterDataItem item02 = *series0->dataProxy()->itemAt(itemIndex0 + 2); + QScatterDataItem item10 = *series1->dataProxy()->itemAt(itemIndex1); + QScatterDataItem item11 = *series1->dataProxy()->itemAt(itemIndex1 + 1); + QScatterDataItem item12 = *series1->dataProxy()->itemAt(itemIndex1 + 2); + item00.setY(65.0f); + item01.setY(70.0f); + item02.setY(75.0f); + item10.setY(80.0f); + item11.setY(85.0f); + item12.setY(90.0f); + series0->dataProxy()->setItem(itemIndex0, item00); + series0->dataProxy()->setItem(itemIndex0 + 1, item01); + series0->dataProxy()->setItem(itemIndex0 + 2, item02); + series1->dataProxy()->setItem(itemIndex1, item10); + series1->dataProxy()->setItem(itemIndex1 + 1, item11); + series1->dataProxy()->setItem(itemIndex1 + 2, item12); + } + break; + case 10: { + qDebug() << __FUNCTION__ << counter << "Level the field single item at a time"; + QScatterDataItem item; + for (int i = 0; i < rowCount; i++) { + for (int j = 0; j < colCount; j++) { + int itemIndex = i * colCount + j; + QScatterDataItem item0 = *series0->dataProxy()->itemAt(itemIndex); + QScatterDataItem item1 = *series1->dataProxy()->itemAt(itemIndex); + QScatterDataItem item2 = *series2->dataProxy()->itemAt(itemIndex); + item0.setY(10.0f); + item1.setY(15.0f); + item2.setY(20.0f); + series0->dataProxy()->setItem(itemIndex, item0); + series1->dataProxy()->setItem(itemIndex, item1); + series2->dataProxy()->setItem(itemIndex, item2); + } + } + } + break; + case 11: { + qDebug() << __FUNCTION__ << counter << "Change same items multiple times"; + int itemIndex0 = 6 * colCount + 6; + QScatterDataItem item0 = *series0->dataProxy()->itemAt(itemIndex0); + item0.setY(90.0f); + series0->dataProxy()->setItem(itemIndex0, item0); + series0->dataProxy()->setItem(itemIndex0, item0); + series0->dataProxy()->setItem(itemIndex0, item0); + series0->dataProxy()->setItem(itemIndex0, item0); + } + break; + default: + qDebug() << __FUNCTION__ << "Resetting test"; + counter = -1; + } + counter++; +} + void ScatterDataModifier::addData() { // Add labels @@ -673,7 +853,8 @@ void ScatterDataModifier::handleAxisZChanged(QValue3DAxis *axis) void ScatterDataModifier::handleFpsChange(qreal fps) { - qDebug() << "FPS:" << fps; + static const QString fpsPrefix(QStringLiteral("FPS: ")); + m_fpsLabel->setText(fpsPrefix + QString::number(qRound(fps))); } void ScatterDataModifier::changeShadowQuality(int quality) @@ -757,3 +938,15 @@ QScatter3DSeries *ScatterDataModifier::createAndAddSeries() return series; } + +void ScatterDataModifier::populateFlatSeries(QScatter3DSeries *series, int rows, int columns, + float value) +{ + QScatterDataArray *dataArray = new QScatterDataArray; + dataArray->resize(rows * columns); + for (int i = 0; i < rows; i++) { + for (int j = 0; j < columns; j++) + (*dataArray)[i * columns + j].setPosition(QVector3D(float(i), value, float(j))); + } + series->dataProxy()->resetArray(dataArray); +} diff --git a/tests/scattertest/scatterchart.h b/tests/scattertest/scatterchart.h index 66f69625..f239cb73 100644 --- a/tests/scattertest/scatterchart.h +++ b/tests/scattertest/scatterchart.h @@ -25,6 +25,7 @@ #include <QFont> #include <QDebug> #include <QTimer> +#include <QLabel> using namespace QtDataVisualization; @@ -55,6 +56,9 @@ public: void massiveDataTest(); void massiveTestScroll(); void massiveTestAppendAndScroll(); + void setFpsMeasurement(bool enable); + void setFpsLabel(QLabel *fpsLabel) { m_fpsLabel = fpsLabel; } + void testItemChanges(); public slots: void changeShadowQuality(int quality); @@ -91,6 +95,7 @@ signals: private: QVector3D randVector(); QScatter3DSeries *createAndAddSeries(); + void populateFlatSeries(QScatter3DSeries *series, int rows, int columns, float value); Q3DScatter *m_chart; int m_fontSize; @@ -99,6 +104,7 @@ private: int m_selectedItem; QScatter3DSeries *m_targetSeries; QScatterDataArray m_massiveTestCacheArray; + QLabel *m_fpsLabel; }; #endif |