diff options
author | Tomi Korpipää <tomi.korpipaa@digia.com> | 2013-10-31 10:08:06 +0200 |
---|---|---|
committer | Tomi Korpipää <tomi.korpipaa@digia.com> | 2013-10-31 10:28:17 +0200 |
commit | b44b030ec0c74649daee92160c73cbd2fe93d7c1 (patch) | |
tree | 9c2bbf798c547b24f773cad979f18ba97ec2ab5b | |
parent | 23c544c4881a5b72fef9d02c40a81cf894ac3309 (diff) |
Support for off-zero bar value ranges
Task-number: QTRD-2520
Change-Id: Id648ff3a8ff6c742c06b8f4b03482c4173ed2ffa
Reviewed-by: Miikka Heikkinen <miikka.heikkinen@digia.com>
-rw-r--r-- | src/datavisualization/engine/bars3drenderer.cpp | 82 | ||||
-rw-r--r-- | src/datavisualization/engine/bars3drenderer_p.h | 3 | ||||
-rw-r--r-- | tests/barstest/chart.cpp | 52 | ||||
-rw-r--r-- | tests/barstest/chart.h | 3 | ||||
-rw-r--r-- | tests/barstest/main.cpp | 30 |
5 files changed, 137 insertions, 33 deletions
diff --git a/src/datavisualization/engine/bars3drenderer.cpp b/src/datavisualization/engine/bars3drenderer.cpp index 2d018383..c2dc4941 100644 --- a/src/datavisualization/engine/bars3drenderer.cpp +++ b/src/datavisualization/engine/bars3drenderer.cpp @@ -87,7 +87,8 @@ Bars3DRenderer::Bars3DRenderer(Bars3DController *controller) m_visualSelectedBarPos(Bars3DController::noSelectionPoint()), m_clickedBarColor(invalidColorVector), m_hasHeightAdjustmentChanged(true), - m_selectedBarPos(Bars3DController::noSelectionPoint()) + m_selectedBarPos(Bars3DController::noSelectionPoint()), + m_noZeroInRange(false) { initializeOpenGLFunctions(); initializeOpenGL(); @@ -182,6 +183,7 @@ void Bars3DRenderer::updateDataModel(QBarDataProxy *dataProxy) int dataRowCount = dataProxy->rowCount(); int dataRowIndex = minRow; int updateSize = 0; + GLfloat heightValue = 0.0f; for (int i = 0; i < newRows; i++) { int j = 0; if (dataRowIndex < dataRowCount) { @@ -191,8 +193,22 @@ void Bars3DRenderer::updateDataModel(QBarDataProxy *dataProxy) int dataColIndex = minCol; for (; j < updateSize ; j++) { qreal value = dataRow->at(dataColIndex).value(); + if (!m_noZeroInRange) { + heightValue = GLfloat(value); + } else { + // Adjust height to range + if (!m_hasNegativeValues) { + heightValue = value - m_axisCacheY.min(); + if (heightValue < 0.0f) + heightValue = 0.0f; + } else if (m_axisCacheY.max() < 0.0) { + heightValue = value - m_axisCacheY.max(); + if (heightValue > 0.0f) + heightValue = 0.0f; + } + } m_renderItemArray[i][j].setValue(value); - m_renderItemArray[i][j].setHeight(GLfloat(value) / m_heightNormalizer); + m_renderItemArray[i][j].setHeight(heightValue / m_heightNormalizer); dataColIndex++; } } @@ -304,8 +320,12 @@ void Bars3DRenderer::drawSlicedScene(const LabelItem &xLabel, // Draw the selected row / column GLfloat barPosYAdjustment = 0.2f; // Add a bit of space for labels - if (m_hasNegativeValues) - barPosYAdjustment += m_yAdjustment / 2.0f; + if (m_hasNegativeValues) { + if (m_noZeroInRange) + barPosYAdjustment += 1.0f; + else + barPosYAdjustment += m_yAdjustment / 2.0f; + } QVector3D modelMatrixScaler(m_scaleX, 0.0f, m_scaleZ); QMatrix4x4 projectionViewMatrix = projectionMatrix * viewMatrix; QVector3D barHighlightColor(Utils::vectorFromColor(m_cachedTheme.m_highlightBarColor)); @@ -396,8 +416,12 @@ void Bars3DRenderer::drawSlicedScene(const LabelItem &xLabel, // Draw labels for bars QVector3D valuePositionComp = zeroVector; - if (m_hasNegativeValues) - valuePositionComp.setY(-barPosYAdjustment); + if (m_hasNegativeValues) { + if (m_noZeroInRange) + valuePositionComp.setY(-2.0f); + else + valuePositionComp.setY(-barPosYAdjustment); + } QVector3D sliceValueRotation(0.0f, 0.0f, 90.0f); QVector3D sliceLabelRotation(0.0f, 0.0f, -45.0f); @@ -407,10 +431,12 @@ void Bars3DRenderer::drawSlicedScene(const LabelItem &xLabel, for (int col = 0; col < stopBar; col++) { BarRenderItem *item = m_sliceSelection->at(col); // Draw values - m_drawer->drawLabel(*item, item->sliceLabelItem(), viewMatrix, projectionMatrix, - valuePositionComp, sliceValueRotation, item->height(), - m_cachedSelectionMode, m_labelShader, m_labelObj, activeCamera, - false, false, Drawer::LabelOver, Qt::AlignTop, true); + if (item->height() != 0.0f || (!m_noZeroInRange && item->value() == 0.0)) { + m_drawer->drawLabel(*item, item->sliceLabelItem(), viewMatrix, projectionMatrix, + valuePositionComp, sliceValueRotation, item->height(), + m_cachedSelectionMode, m_labelShader, m_labelObj, activeCamera, + false, false, Drawer::LabelOver, Qt::AlignTop, true); + } // Draw labels if (m_sliceCache->labelItems().size() > col) { @@ -1193,8 +1219,12 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle) if (m_zFlipped) zWallLinePosition = -zWallLinePosition; - if (m_hasNegativeValues) - startLine = m_axisCacheY.min(); + if (m_hasNegativeValues) { + if (m_noZeroInRange) + startLine = m_axisCacheY.min() - m_axisCacheY.max(); + else + startLine = m_axisCacheY.min(); + } GLfloat lineHeight = startLine; gridLineScaler = QVector3D(rowScaleFactor, gridLineWidth, gridLineWidth); @@ -1386,8 +1416,12 @@ void Bars3DRenderer::drawScene(GLuint defaultFboHandle) GLfloat heightStep = m_axisCacheY.segmentStep(); GLfloat startLine = 0.0f; int labelCount = m_axisCacheY.labels().size(); - if (m_hasNegativeValues) - startLine = m_axisCacheY.min(); + if (m_hasNegativeValues) { + if (m_noZeroInRange) + startLine = m_axisCacheY.min() - m_axisCacheY.max(); + else + startLine = m_axisCacheY.min(); + } GLfloat labelPos = startLine; GLfloat labelMarginXTrans = labelMargin; GLfloat labelMarginZTrans = labelMargin; @@ -1710,10 +1744,22 @@ void Bars3DRenderer::calculateSceneScalingFactors() void Bars3DRenderer::calculateHeightAdjustment() { - m_heightNormalizer = GLfloat(qFabs(m_axisCacheY.min()) + qFabs(m_axisCacheY.max())); + GLfloat newAdjustment = 0.0f; GLfloat maxAbs = qFabs(m_axisCacheY.max()); - GLfloat newAdjustment = maxAbs / m_heightNormalizer; + if (m_axisCacheY.max() < 0.0) + m_heightNormalizer = GLfloat(qFabs(m_axisCacheY.min()) - qFabs(m_axisCacheY.max())); + else + m_heightNormalizer = GLfloat(m_axisCacheY.max() - m_axisCacheY.min()); + + if (m_axisCacheY.max() < 0.0 || m_axisCacheY.min() > 0.0) + m_noZeroInRange = true; + else + m_noZeroInRange = false; + + if (m_axisCacheY.max() >= 0.0) + newAdjustment = qMin((maxAbs / m_heightNormalizer), 1.0f); // m_yAdjustment never needs to be over 1.0 + if (newAdjustment != m_yAdjustment) { m_hasHeightAdjustmentChanged = true; m_yAdjustment = newAdjustment; @@ -1728,10 +1774,10 @@ Bars3DController::SelectionType Bars3DRenderer::isSelected(GLint row, GLint bar) && (m_cachedSelectionMode.testFlag(QDataVis::SelectionItem))) { isSelectedType = Bars3DController::SelectionItem; } else if (row == m_visualSelectedBarPos.x() - && (m_cachedSelectionMode.testFlag(QDataVis::SelectionRow))) { + && (m_cachedSelectionMode.testFlag(QDataVis::SelectionRow))) { isSelectedType = Bars3DController::SelectionRow; } else if (bar == m_visualSelectedBarPos.y() - && (m_cachedSelectionMode.testFlag(QDataVis::SelectionColumn))) { + && (m_cachedSelectionMode.testFlag(QDataVis::SelectionColumn))) { isSelectedType = Bars3DController::SelectionColumn; } return isSelectedType; diff --git a/src/datavisualization/engine/bars3drenderer_p.h b/src/datavisualization/engine/bars3drenderer_p.h index 1d3d0896..85471a5c 100644 --- a/src/datavisualization/engine/bars3drenderer_p.h +++ b/src/datavisualization/engine/bars3drenderer_p.h @@ -102,10 +102,11 @@ private: int m_renderRows; int m_renderColumns; QVector3D m_clickedBarColor; - QPoint m_selectedBarPos; bool m_hasHeightAdjustmentChanged; + QPoint m_selectedBarPos; BarRenderItem m_dummyBarRenderItem; BarRenderItemArray m_renderItemArray; + bool m_noZeroInRange; public: explicit Bars3DRenderer(Bars3DController *controller); diff --git a/tests/barstest/chart.cpp b/tests/barstest/chart.cpp index 2044e990..266a561f 100644 --- a/tests/barstest/chart.cpp +++ b/tests/barstest/chart.cpp @@ -52,7 +52,8 @@ GraphModifier::GraphModifier(Q3DBars *barchart) m_genericColumnAxis(new Q3DCategoryAxis), m_temperatureData(new QBarDataProxy), m_genericData(new QBarDataProxy), - m_currentAxis(m_fixedRangeAxis) + m_currentAxis(m_fixedRangeAxis), + m_negativeValuesOn(false) { // Generate generic labels QStringList genericColumnLabels; @@ -105,6 +106,7 @@ GraphModifier::GraphModifier(Q3DBars *barchart) m_chart->addAxis(m_genericRowAxis); m_chart->addAxis(m_genericColumnAxis); + m_chart->setTheme(QDataVis::ThemeStoneMoss); m_chart->setShadowQuality(QDataVis::ShadowQualitySoftMedium); m_temperatureData->setItemLabelFormat(QStringLiteral("@valueTitle for @colLabel @rowLabel: @valueLabel")); @@ -142,17 +144,19 @@ void GraphModifier::restart(bool dynamicData) m_chart->setRowAxis(m_yearAxis); m_chart->setColumnAxis(m_monthAxis); - m_chart->setSelectionMode(QDataVis::SelectionItem); + m_chart->setSelectionMode(QDataVis::SelectionRow | QDataVis::SelectionSlice); } else { m_chart->setActiveDataProxy(m_genericData); m_chart->setTitle(QStringLiteral("Generic data")); + m_minval = m_fixedRangeAxis->min(); + m_maxval = m_fixedRangeAxis->max(); m_chart->setValueAxis(m_currentAxis); m_chart->setRowAxis(m_genericRowAxis); m_chart->setColumnAxis(m_genericColumnAxis); - m_chart->setSelectionMode(QDataVis::SelectionItem); + m_chart->setSelectionMode(QDataVis::SelectionRow | QDataVis::SelectionSlice); } } @@ -233,8 +237,13 @@ void GraphModifier::createMassiveArray() dataArray->reserve(arrayDimension); for (int i = 0; i < arrayDimension; i++) { QBarDataRow *dataRow = new QBarDataRow(arrayDimension); - for (int j = 0; j < arrayDimension; j++) - (*dataRow)[j].setValue((qreal(i % 300 + 1) / 300.0) * qreal(rand() % 100)); + for (int j = 0; j < arrayDimension; j++) { + if (!m_negativeValuesOn) + (*dataRow)[j].setValue((qreal(i % 300 + 1) / 300.0) * qreal(rand() % int(m_maxval))); + else + (*dataRow)[j].setValue((qreal(i % 300 + 1) / 300.0) * qreal(rand() % int(m_maxval)) + + m_minval); + } dataArray->append(dataRow); } @@ -286,8 +295,13 @@ static int changeCounter = 0; void GraphModifier::addRow() { QBarDataRow *dataRow = new QBarDataRow(m_columnCount); - for (qreal i = 0; i < m_columnCount; i++) - (*dataRow)[i].setValue(((i + 1) / (qreal)m_columnCount) * (qreal)(rand() % 100)); + for (qreal i = 0; i < m_columnCount; i++) { + if (!m_negativeValuesOn) + (*dataRow)[i].setValue(((i + 1) / (qreal)m_columnCount) * (qreal)(rand() % int(m_maxval))); + else + (*dataRow)[i].setValue(((i + 1) / (qreal)m_columnCount) * (qreal)(rand() % int(m_maxval)) + + m_minval); + } // TODO Needs to be changed to account for data window offset once it is implemented. QString label = QStringLiteral("Add %1").arg(addCounter++); @@ -301,7 +315,7 @@ void GraphModifier::addRows() for (int i = 0; i < m_rowCount; i++) { QBarDataRow *dataRow = new QBarDataRow(m_columnCount); for (int j = 0; j < m_columnCount; j++) - (*dataRow)[j].setValue(qreal(j + i + m_chart->activeDataProxy()->rowCount())); + (*dataRow)[j].setValue(qreal(j + i + m_chart->activeDataProxy()->rowCount()) + m_minval); dataArray.append(dataRow); labels.append(QStringLiteral("Add %1").arg(addCounter++)); } @@ -314,7 +328,8 @@ void GraphModifier::insertRow() { QBarDataRow *dataRow = new QBarDataRow(m_columnCount); for (qreal i = 0; i < m_columnCount; i++) - (*dataRow)[i].setValue(((i + 1) / (qreal)m_columnCount) * (qreal)(rand() % 100)); + (*dataRow)[i].setValue(((i + 1) / (qreal)m_columnCount) * (qreal)(rand() % int(m_maxval)) + + m_minval); // TODO Needs to be changed to account for data window offset once it is implemented. int row = qMax(m_selectedBar.x(), 0); @@ -331,7 +346,7 @@ void GraphModifier::insertRows() for (int i = 0; i < m_rowCount; i++) { QBarDataRow *dataRow = new QBarDataRow(m_columnCount); for (int j = 0; j < m_columnCount; j++) - (*dataRow)[j].setValue(qreal(j + i + m_chart->activeDataProxy()->rowCount())); + (*dataRow)[j].setValue(qreal(j + i + m_chart->activeDataProxy()->rowCount()) + m_minval); dataArray.append(dataRow); labels.append(QStringLiteral("Insert %1").arg(insertCounter++)); } @@ -360,7 +375,7 @@ void GraphModifier::changeRow() if (row >= 0) { QBarDataRow *newRow = new QBarDataRow(m_chart->activeDataProxy()->rowAt(row)->size()); for (int i = 0; i < newRow->size(); i++) - (*newRow)[i].setValue(qreal(rand() % 100)); + (*newRow)[i].setValue(qreal(rand() % int(m_maxval)) + m_minval); QString label = QStringLiteral("Change %1").arg(changeCounter++); m_chart->activeDataProxy()->setRow(row, newRow, label); } @@ -377,7 +392,7 @@ void GraphModifier::changeRows() for (int i = startRow; i <= row; i++ ) { QBarDataRow *newRow = new QBarDataRow(m_chart->activeDataProxy()->rowAt(i)->size()); for (int j = 0; j < newRow->size(); j++) - (*newRow)[j].setValue(qreal(rand() % 100)); + (*newRow)[j].setValue(qreal(rand() % int(m_maxval)) + m_minval); newArray.append(newRow); labels.append(QStringLiteral("Change %1").arg(changeCounter++)); } @@ -578,3 +593,16 @@ void GraphModifier::setMinZ(int min) { m_genericColumnAxis->setRange(min, min + m_rowCount - 1); } + +void GraphModifier::setMinY(int min) +{ + m_fixedRangeAxis->setMin(min); + m_negativeValuesOn = (min < 0) ? true : false; + m_minval = min; +} + +void GraphModifier::setMaxY(int max) +{ + m_fixedRangeAxis->setMax(max); + m_maxval = max; +} diff --git a/tests/barstest/chart.h b/tests/barstest/chart.h index 6d33bacb..79cb3cb3 100644 --- a/tests/barstest/chart.h +++ b/tests/barstest/chart.h @@ -64,6 +64,8 @@ public: void setSampleCountZ(int samples); void setMinX(int min); void setMinZ(int min); + void setMinY(int min); + void setMaxY(int max); void start(); void restart(bool dynamicData); void selectBar(); @@ -107,6 +109,7 @@ private: QBarDataProxy *m_temperatureData; QBarDataProxy *m_genericData; Q3DValueAxis *m_currentAxis; + bool m_negativeValuesOn; }; #endif diff --git a/tests/barstest/main.cpp b/tests/barstest/main.cpp index 0d3838a8..a36ebc7a 100644 --- a/tests/barstest/main.cpp +++ b/tests/barstest/main.cpp @@ -183,17 +183,33 @@ int main(int argc, char **argv) sampleSliderZ->setEnabled(false); QSlider *minSliderX = new QSlider(Qt::Horizontal, widget); - minSliderX->setTickInterval(1); + minSliderX->setTickInterval(10); + minSliderX->setTickPosition(QSlider::TicksBelow); minSliderX->setMinimum(0); minSliderX->setValue(0); minSliderX->setMaximum(200); minSliderX->setEnabled(false); QSlider *minSliderZ = new QSlider(Qt::Horizontal, widget); - minSliderZ->setTickInterval(1); + minSliderZ->setTickInterval(10); + minSliderZ->setTickPosition(QSlider::TicksAbove); minSliderZ->setMinimum(0); minSliderZ->setValue(0); minSliderZ->setMaximum(200); minSliderZ->setEnabled(false); + QSlider *minSliderY = new QSlider(Qt::Horizontal, widget); + minSliderY->setTickInterval(10); + minSliderY->setTickPosition(QSlider::TicksBelow); + minSliderY->setMinimum(-100); + minSliderY->setValue(0); + minSliderY->setMaximum(100); + minSliderY->setEnabled(false); + QSlider *maxSliderY = new QSlider(Qt::Horizontal, widget); + maxSliderY->setTickInterval(10); + maxSliderY->setTickPosition(QSlider::TicksAbove); + maxSliderY->setMinimum(-50); + maxSliderY->setValue(100); + maxSliderY->setMaximum(200); + maxSliderY->setEnabled(false); QSlider *fontSizeSlider = new QSlider(Qt::Horizontal, widget); fontSizeSlider->setTickInterval(1); @@ -248,6 +264,8 @@ int main(int argc, char **argv) vLayout2->addWidget(new QLabel(QStringLiteral("Adjust data window minimums")), 0, Qt::AlignTop); vLayout2->addWidget(minSliderX, 0, Qt::AlignTop); vLayout2->addWidget(minSliderZ, 0, Qt::AlignTop); + vLayout2->addWidget(minSliderY, 0, Qt::AlignTop); + vLayout2->addWidget(maxSliderY, 0, Qt::AlignTop); vLayout2->addWidget(backgroundCheckBox, 0, Qt::AlignTop); vLayout2->addWidget(gridCheckBox, 0, Qt::AlignTop); vLayout2->addWidget(new QLabel(QStringLiteral("Adjust shadow quality")), 0, Qt::AlignTop); @@ -280,6 +298,10 @@ int main(int argc, char **argv) &GraphModifier::setMinX); QObject::connect(minSliderZ, &QSlider::valueChanged, modifier, &GraphModifier::setMinZ); + QObject::connect(minSliderY, &QSlider::valueChanged, modifier, + &GraphModifier::setMinY); + QObject::connect(maxSliderY, &QSlider::valueChanged, modifier, + &GraphModifier::setMaxY); QObject::connect(shadowQuality, SIGNAL(currentIndexChanged(int)), modifier, SLOT(changeShadowQuality(int))); @@ -365,6 +387,10 @@ int main(int argc, char **argv) &QSlider::setEnabled); QObject::connect(staticCheckBox, &QCheckBox::stateChanged, minSliderZ, &QSlider::setEnabled); + QObject::connect(staticCheckBox, &QCheckBox::stateChanged, minSliderY, + &QSlider::setEnabled); + QObject::connect(staticCheckBox, &QCheckBox::stateChanged, maxSliderY, + &QSlider::setEnabled); QObject::connect(staticCheckBox, &QCheckBox::stateChanged, swapAxisButton, &QSlider::setEnabled); QObject::connect(staticCheckBox, &QCheckBox::stateChanged, modifier, &GraphModifier::restart); |