diff options
31 files changed, 622 insertions, 527 deletions
diff --git a/examples/barchart/main.cpp b/examples/barchart/main.cpp index 9f17f8d9..d8bfa5b4 100644 --- a/examples/barchart/main.cpp +++ b/examples/barchart/main.cpp @@ -169,9 +169,6 @@ void ChartDataGenerator::setupModel() m_tableWidget->model()->setData(index, hours[week][day]); } } - - // Set up sample space based on prepared data - m_chart->setDataWindow(weeks.size(), days.size()); } void ChartDataGenerator::addRow() diff --git a/examples/qmlbarchart/qml/qmlbarchart/data.qml b/examples/qmlbarchart/qml/qmlbarchart/data.qml index a6313fb4..fff568cc 100644 --- a/examples/qmlbarchart/qml/qmlbarchart/data.qml +++ b/examples/qmlbarchart/qml/qmlbarchart/data.qml @@ -39,95 +39,95 @@ Item { ListModel { id: dataModel - ListElement{ year: "1998"; month: "Jan"; expenses: "4"; income: "5" } - ListElement{ year: "1998"; month: "Feb"; expenses: "5"; income: "6" } - ListElement{ year: "1998"; month: "Mar"; expenses: "7"; income: "4" } - ListElement{ year: "1998"; month: "Apr"; expenses: "3"; income: "2" } - ListElement{ year: "1998"; month: "May"; expenses: "4"; income: "1" } - ListElement{ year: "1998"; month: "Jun"; expenses: "2"; income: "2" } - ListElement{ year: "1998"; month: "Jul"; expenses: "1"; income: "3" } - ListElement{ year: "1998"; month: "Aug"; expenses: "5"; income: "1" } - ListElement{ year: "1998"; month: "Sep"; expenses: "2"; income: "3" } - ListElement{ year: "1998"; month: "Oct"; expenses: "5"; income: "2" } - ListElement{ year: "1998"; month: "Nov"; expenses: "8"; income: "5" } - ListElement{ year: "1998"; month: "Dec"; expenses: "3"; income: "3" } + ListElement{ year: "2006"; month: "Jan"; expenses: "4"; income: "5" } + ListElement{ year: "2006"; month: "Feb"; expenses: "5"; income: "6" } + ListElement{ year: "2006"; month: "Mar"; expenses: "7"; income: "4" } + ListElement{ year: "2006"; month: "Apr"; expenses: "3"; income: "2" } + ListElement{ year: "2006"; month: "May"; expenses: "4"; income: "1" } + ListElement{ year: "2006"; month: "Jun"; expenses: "2"; income: "2" } + ListElement{ year: "2006"; month: "Jul"; expenses: "1"; income: "3" } + ListElement{ year: "2006"; month: "Aug"; expenses: "5"; income: "1" } + ListElement{ year: "2006"; month: "Sep"; expenses: "2"; income: "3" } + ListElement{ year: "2006"; month: "Oct"; expenses: "5"; income: "2" } + ListElement{ year: "2006"; month: "Nov"; expenses: "8"; income: "5" } + ListElement{ year: "2006"; month: "Dec"; expenses: "3"; income: "3" } - ListElement{ year: "1999"; month: "Jan"; expenses: "3"; income: "1" } - ListElement{ year: "1999"; month: "Feb"; expenses: "4"; income: "2" } - ListElement{ year: "1999"; month: "Mar"; expenses: "12"; income: "4" } - ListElement{ year: "1999"; month: "Apr"; expenses: "13"; income: "6" } - ListElement{ year: "1999"; month: "May"; expenses: "14"; income: "11" } - ListElement{ year: "1999"; month: "Jun"; expenses: "7"; income: "7" } - ListElement{ year: "1999"; month: "Jul"; expenses: "6"; income: "4" } - ListElement{ year: "1999"; month: "Aug"; expenses: "4"; income: "15" } - ListElement{ year: "1999"; month: "Sep"; expenses: "2"; income: "18" } - ListElement{ year: "1999"; month: "Oct"; expenses: "29"; income: "25" } - ListElement{ year: "1999"; month: "Nov"; expenses: "23"; income: "29" } - ListElement{ year: "1999"; month: "Dec"; expenses: "5"; income: "9" } + ListElement{ year: "2007"; month: "Jan"; expenses: "3"; income: "1" } + ListElement{ year: "2007"; month: "Feb"; expenses: "4"; income: "2" } + ListElement{ year: "2007"; month: "Mar"; expenses: "12"; income: "4" } + ListElement{ year: "2007"; month: "Apr"; expenses: "13"; income: "6" } + ListElement{ year: "2007"; month: "May"; expenses: "14"; income: "11" } + ListElement{ year: "2007"; month: "Jun"; expenses: "7"; income: "7" } + ListElement{ year: "2007"; month: "Jul"; expenses: "6"; income: "4" } + ListElement{ year: "2007"; month: "Aug"; expenses: "4"; income: "15" } + ListElement{ year: "2007"; month: "Sep"; expenses: "2"; income: "18" } + ListElement{ year: "2007"; month: "Oct"; expenses: "29"; income: "25" } + ListElement{ year: "2007"; month: "Nov"; expenses: "23"; income: "29" } + ListElement{ year: "2007"; month: "Dec"; expenses: "5"; income: "9" } - ListElement{ year: "2000"; month: "Jan"; expenses: "3"; income: "8" } - ListElement{ year: "2000"; month: "Feb"; expenses: "8"; income: "14" } - ListElement{ year: "2000"; month: "Mar"; expenses: "10"; income: "20" } - ListElement{ year: "2000"; month: "Apr"; expenses: "12"; income: "24" } - ListElement{ year: "2000"; month: "May"; expenses: "10"; income: "19" } - ListElement{ year: "2000"; month: "Jun"; expenses: "5"; income: "8" } - ListElement{ year: "2000"; month: "Jul"; expenses: "1"; income: "4" } - ListElement{ year: "2000"; month: "Aug"; expenses: "7"; income: "12" } - ListElement{ year: "2000"; month: "Sep"; expenses: "4"; income: "16" } - ListElement{ year: "2000"; month: "Oct"; expenses: "22"; income: "33" } - ListElement{ year: "2000"; month: "Nov"; expenses: "16"; income: "25" } - ListElement{ year: "2000"; month: "Dec"; expenses: "2"; income: "7" } + ListElement{ year: "2008"; month: "Jan"; expenses: "3"; income: "8" } + ListElement{ year: "2008"; month: "Feb"; expenses: "8"; income: "14" } + ListElement{ year: "2008"; month: "Mar"; expenses: "10"; income: "20" } + ListElement{ year: "2008"; month: "Apr"; expenses: "12"; income: "24" } + ListElement{ year: "2008"; month: "May"; expenses: "10"; income: "19" } + ListElement{ year: "2008"; month: "Jun"; expenses: "5"; income: "8" } + ListElement{ year: "2008"; month: "Jul"; expenses: "1"; income: "4" } + ListElement{ year: "2008"; month: "Aug"; expenses: "7"; income: "12" } + ListElement{ year: "2008"; month: "Sep"; expenses: "4"; income: "16" } + ListElement{ year: "2008"; month: "Oct"; expenses: "22"; income: "33" } + ListElement{ year: "2008"; month: "Nov"; expenses: "16"; income: "25" } + ListElement{ year: "2008"; month: "Dec"; expenses: "2"; income: "7" } - ListElement{ year: "2001"; month: "Jan"; expenses: "4"; income: "5" } - ListElement{ year: "2001"; month: "Feb"; expenses: "4"; income: "7" } - ListElement{ year: "2001"; month: "Mar"; expenses: "11"; income: "14" } - ListElement{ year: "2001"; month: "Apr"; expenses: "16"; income: "22" } - ListElement{ year: "2001"; month: "May"; expenses: "3"; income: "5" } - ListElement{ year: "2001"; month: "Jun"; expenses: "4"; income: "8" } - ListElement{ year: "2001"; month: "Jul"; expenses: "7"; income: "9" } - ListElement{ year: "2001"; month: "Aug"; expenses: "9"; income: "13" } - ListElement{ year: "2001"; month: "Sep"; expenses: "1"; income: "6" } - ListElement{ year: "2001"; month: "Oct"; expenses: "14"; income: "25" } - ListElement{ year: "2001"; month: "Nov"; expenses: "19"; income: "29" } - ListElement{ year: "2001"; month: "Dec"; expenses: "5"; income: "7" } + ListElement{ year: "2009"; month: "Jan"; expenses: "4"; income: "5" } + ListElement{ year: "2009"; month: "Feb"; expenses: "4"; income: "7" } + ListElement{ year: "2009"; month: "Mar"; expenses: "11"; income: "14" } + ListElement{ year: "2009"; month: "Apr"; expenses: "16"; income: "22" } + ListElement{ year: "2009"; month: "May"; expenses: "3"; income: "5" } + ListElement{ year: "2009"; month: "Jun"; expenses: "4"; income: "8" } + ListElement{ year: "2009"; month: "Jul"; expenses: "7"; income: "9" } + ListElement{ year: "2009"; month: "Aug"; expenses: "9"; income: "13" } + ListElement{ year: "2009"; month: "Sep"; expenses: "1"; income: "6" } + ListElement{ year: "2009"; month: "Oct"; expenses: "14"; income: "25" } + ListElement{ year: "2009"; month: "Nov"; expenses: "19"; income: "29" } + ListElement{ year: "2009"; month: "Dec"; expenses: "5"; income: "7" } - ListElement{ year: "2002"; month: "Jan"; expenses: "14"; income: "22" } - ListElement{ year: "2002"; month: "Feb"; expenses: "5"; income: "7" } - ListElement{ year: "2002"; month: "Mar"; expenses: "1"; income: "9" } - ListElement{ year: "2002"; month: "Apr"; expenses: "1"; income: "12" } - ListElement{ year: "2002"; month: "May"; expenses: "5"; income: "9" } - ListElement{ year: "2002"; month: "Jun"; expenses: "5"; income: "8" } - ListElement{ year: "2002"; month: "Jul"; expenses: "3"; income: "7" } - ListElement{ year: "2002"; month: "Aug"; expenses: "1"; income: "5" } - ListElement{ year: "2002"; month: "Sep"; expenses: "2"; income: "4" } - ListElement{ year: "2002"; month: "Oct"; expenses: "10"; income: "13" } - ListElement{ year: "2002"; month: "Nov"; expenses: "12"; income: "17" } - ListElement{ year: "2002"; month: "Dec"; expenses: "6"; income: "9" } + ListElement{ year: "2010"; month: "Jan"; expenses: "14"; income: "22" } + ListElement{ year: "2010"; month: "Feb"; expenses: "5"; income: "7" } + ListElement{ year: "2010"; month: "Mar"; expenses: "1"; income: "9" } + ListElement{ year: "2010"; month: "Apr"; expenses: "1"; income: "12" } + ListElement{ year: "2010"; month: "May"; expenses: "5"; income: "9" } + ListElement{ year: "2010"; month: "Jun"; expenses: "5"; income: "8" } + ListElement{ year: "2010"; month: "Jul"; expenses: "3"; income: "7" } + ListElement{ year: "2010"; month: "Aug"; expenses: "1"; income: "5" } + ListElement{ year: "2010"; month: "Sep"; expenses: "2"; income: "4" } + ListElement{ year: "2010"; month: "Oct"; expenses: "10"; income: "13" } + ListElement{ year: "2010"; month: "Nov"; expenses: "12"; income: "17" } + ListElement{ year: "2010"; month: "Dec"; expenses: "6"; income: "9" } - ListElement{ year: "2003"; month: "Jan"; expenses: "2"; income: "6" } - ListElement{ year: "2003"; month: "Feb"; expenses: "4"; income: "8" } - ListElement{ year: "2003"; month: "Mar"; expenses: "7"; income: "12" } - ListElement{ year: "2003"; month: "Apr"; expenses: "9"; income: "15" } - ListElement{ year: "2003"; month: "May"; expenses: "7"; income: "19" } - ListElement{ year: "2003"; month: "Jun"; expenses: "9"; income: "18" } - ListElement{ year: "2003"; month: "Jul"; expenses: "13"; income: "17" } - ListElement{ year: "2003"; month: "Aug"; expenses: "5"; income: "9" } - ListElement{ year: "2003"; month: "Sep"; expenses: "3"; income: "8" } - ListElement{ year: "2003"; month: "Oct"; expenses: "13"; income: "15" } - ListElement{ year: "2003"; month: "Nov"; expenses: "8"; income: "17" } - ListElement{ year: "2003"; month: "Dec"; expenses: "7"; income: "10" } + ListElement{ year: "2011"; month: "Jan"; expenses: "2"; income: "6" } + ListElement{ year: "2011"; month: "Feb"; expenses: "4"; income: "8" } + ListElement{ year: "2011"; month: "Mar"; expenses: "7"; income: "12" } + ListElement{ year: "2011"; month: "Apr"; expenses: "9"; income: "15" } + ListElement{ year: "2011"; month: "May"; expenses: "7"; income: "19" } + ListElement{ year: "2011"; month: "Jun"; expenses: "9"; income: "18" } + ListElement{ year: "2011"; month: "Jul"; expenses: "13"; income: "17" } + ListElement{ year: "2011"; month: "Aug"; expenses: "5"; income: "9" } + ListElement{ year: "2011"; month: "Sep"; expenses: "3"; income: "8" } + ListElement{ year: "2011"; month: "Oct"; expenses: "13"; income: "15" } + ListElement{ year: "2011"; month: "Nov"; expenses: "8"; income: "17" } + ListElement{ year: "2011"; month: "Dec"; expenses: "7"; income: "10" } - ListElement{ year: "2004"; month: "Jan"; expenses: "12"; income: "16" } - ListElement{ year: "2004"; month: "Feb"; expenses: "24"; income: "28" } - ListElement{ year: "2004"; month: "Mar"; expenses: "27"; income: "22" } - ListElement{ year: "2004"; month: "Apr"; expenses: "29"; income: "25" } - ListElement{ year: "2004"; month: "May"; expenses: "27"; income: "29" } - ListElement{ year: "2004"; month: "Jun"; expenses: "19"; income: "18" } - ListElement{ year: "2004"; month: "Jul"; expenses: "13"; income: "17" } - ListElement{ year: "2004"; month: "Aug"; expenses: "15"; income: "19" } - ListElement{ year: "2004"; month: "Sep"; expenses: "3"; income: "8" } - ListElement{ year: "2004"; month: "Oct"; expenses: "3"; income: "6" } - ListElement{ year: "2004"; month: "Nov"; expenses: "4"; income: "8" } - ListElement{ year: "2004"; month: "Dec"; expenses: "5"; income: "9" } + ListElement{ year: "2012"; month: "Jan"; expenses: "12"; income: "16" } + ListElement{ year: "2012"; month: "Feb"; expenses: "24"; income: "28" } + ListElement{ year: "2012"; month: "Mar"; expenses: "27"; income: "22" } + ListElement{ year: "2012"; month: "Apr"; expenses: "29"; income: "25" } + ListElement{ year: "2012"; month: "May"; expenses: "27"; income: "29" } + ListElement{ year: "2012"; month: "Jun"; expenses: "19"; income: "18" } + ListElement{ year: "2012"; month: "Jul"; expenses: "13"; income: "17" } + ListElement{ year: "2012"; month: "Aug"; expenses: "15"; income: "19" } + ListElement{ year: "2012"; month: "Sep"; expenses: "3"; income: "8" } + ListElement{ year: "2012"; month: "Oct"; expenses: "3"; income: "6" } + ListElement{ year: "2012"; month: "Nov"; expenses: "4"; income: "8" } + ListElement{ year: "2012"; month: "Dec"; expenses: "5"; income: "9" } } } diff --git a/examples/qmlbarchart/qml/qmlbarchart/main.qml b/examples/qmlbarchart/qml/qmlbarchart/main.qml index f9a89ef6..fa7cd638 100644 --- a/examples/qmlbarchart/qml/qmlbarchart/main.qml +++ b/examples/qmlbarchart/qml/qmlbarchart/main.qml @@ -42,15 +42,13 @@ Item { anchors.right: parent.right; Bars3D { - id: testchart + id: testChart width: dataView.width height: dataView.height shadowQuality: Bars3D.ShadowMedium selectionMode: Bars3D.ModeItem font.pointSize: 35 theme: Bars3D.ThemeBrownSand - rows: 7 - columns: 12 dataProxy: chartData.proxy barThickness: 0.5 barSpacing: Qt.size(0.5, 0.5) @@ -71,7 +69,6 @@ Item { for (var i = 0; i < totalRows; i++) { var currentRowRole = chartData.model.get(i).year var currentColRole = chartData.model.get(i).month - console.log(currentRowRole, currentColRole) if (currentRowRole === rowRole && currentColRole === colRole) { tableView.currentRow = i break @@ -97,7 +94,7 @@ Item { onCurrentRowChanged: { var rowIndex = chartData.proxy.activeMapping.rowCategoryIndex(chartData.model.get(currentRow).year) var colIndex = chartData.proxy.activeMapping.columnCategoryIndex(chartData.model.get(currentRow).month) - testchart.selectedBarPos = Qt.point(rowIndex, colIndex) + testChart.selectedBarPos = Qt.point(rowIndex, colIndex) } } @@ -110,11 +107,11 @@ Item { if (chartData.mapping.valueRole === "expenses") { chartData.mapping.valueRole = "income" text = "Show Expenses" - testchart.valueAxis = chartAxes.income + testChart.valueAxis = chartAxes.income } else { chartData.mapping.valueRole = "expenses" text = "Show Income" - testchart.valueAxis = chartAxes.expenses + testChart.valueAxis = chartAxes.expenses } } } @@ -125,11 +122,11 @@ Item { width: tableView.width text: "Hide Shadows" onClicked: { - if (testchart.shadowQuality == Bars3D.ShadowNone) { - testchart.shadowQuality = Bars3D.ShadowMedium; + if (testChart.shadowQuality == Bars3D.ShadowNone) { + testChart.shadowQuality = Bars3D.ShadowMedium; text = "Hide Shadows" } else { - testchart.shadowQuality = Bars3D.ShadowNone; + testChart.shadowQuality = Bars3D.ShadowNone; text = "Show Shadows" } } @@ -139,19 +136,17 @@ Item { id: dataToggle anchors.bottom: shadowToggle.top width: tableView.width - text: "Show 2000 - 2002" + text: "Show 2010 - 2012" onClicked: { - if (testchart.rows !== 7) { - text = "Show 2000 - 2002" + if (testChart.rowAxis.max !== 6) { + text = "Show 2010 - 2012" chartData.mapping.autoRowCategories = true - testchart.rows = 7; } else { - testchart.rows = 3; text = "Show all years" // Explicitly defining row categories, since we do not want to show data for // all years in the model, just for the selected ones. chartData.mapping.autoRowCategories = false - chartData.mapping.rowCategories = ["2000", "2001", "2002"] + chartData.mapping.rowCategories = ["2010", "2011", "2012"] } } } diff --git a/examples/rainfall/rainfallchart.cpp b/examples/rainfall/rainfallchart.cpp index 95e9d25a..42e78b52 100644 --- a/examples/rainfall/rainfallchart.cpp +++ b/examples/rainfall/rainfallchart.cpp @@ -100,9 +100,6 @@ void RainfallChart::updateYearsList(int start, int end) m_years << QString::number(i); m_rowCount = m_years.size(); - - // Set up sample space; make it match actual resolved data size - m_chart->setDataWindow(m_rowCount, m_columnCount); } void RainfallChart::addDataSet() diff --git a/examples/widget/chart.cpp b/examples/widget/chart.cpp index 534b135c..6ecee12b 100644 --- a/examples/widget/chart.cpp +++ b/examples/widget/chart.cpp @@ -28,8 +28,8 @@ const QString celsiusString = QString(QChar(0xB0)) + "C"; ChartModifier::ChartModifier(Q3DBars *barchart) : m_chart(barchart), - m_xRotation(0.0f), - m_yRotation(0.0f), + m_xRotation(0.0), + m_yRotation(0.0), m_fontSize(20), m_segments(4), m_subSegments(3), @@ -88,21 +88,19 @@ void ChartModifier::start() m_chart->setValueAxis(m_temperatureAxis); m_chart->setRowAxis(m_yearAxis); m_chart->setColumnAxis(m_monthAxis); - - m_chart->setDataWindow(m_years.size(), m_months.size()); } void ChartModifier::resetTemperatureData() { // Set up data - static const float temp[7][12] = { - {-6.7f, -11.7f, -9.7f, 3.3f, 9.2f, 14.0f, 16.3f, 17.8f, 10.2f, 2.1f, -2.6f, -0.3f}, // 2006 - {-6.8f, -13.3f, 0.2f, 1.5f, 7.9f, 13.4f, 16.1f, 15.5f, 8.2f, 5.4f, -2.6f, -0.8f}, // 2007 - {-4.2f, -4.0f, -4.6f, 1.9f, 7.3f, 12.5f, 15.0f, 12.8f, 7.6f, 5.1f, -0.9f, -1.3f}, // 2008 - {-7.8f, -8.8f, -4.2f, 0.7f, 9.3f, 13.2f, 15.8f, 15.5f, 11.2f, 0.6f, 0.7f, -8.4f}, // 2009 - {-14.4f, -12.1f, -7.0f, 2.3f, 11.0f, 12.6f, 18.8f, 13.8f, 9.4f, 3.9f, -5.6f, -13.0f}, // 2010 - {-9.0f, -15.2f, -3.8f, 2.6f, 8.3f, 15.9f, 18.6f, 14.9f, 11.1f, 5.3f, 1.8f, -0.2f}, // 2011 - {-8.7f, -11.3f, -2.3f, 0.4f, 7.5f, 12.2f, 16.4f, 14.1f, 9.2f, 3.1f, 0.3f, -12.1f} // 2012 + static const qreal temp[7][12] = { + {-6.7, -11.7, -9.7, 3.3, 9.2, 14.0, 16.3, 17.8, 10.2, 2.1, -2.6, -0.3}, // 2006 + {-6.8, -13.3, 0.2, 1.5, 7.9, 13.4, 16.1, 15.5, 8.2, 5.4, -2.6, -0.8}, // 2007 + {-4.2, -4.0, -4.6, 1.9, 7.3, 12.5, 15.0, 12.8, 7.6, 5.1, -0.9, -1.3}, // 2008 + {-7.8, -8.8, -4.2, 0.7, 9.3, 13.2, 15.8, 15.5, 11.2, 0.6, 0.7, -8.4}, // 2009 + {-14.4, -12.1, -7.0, 2.3, 11.0, 12.6, 18.8, 13.8, 9.4, 3.9, -5.6, -13.0}, // 2010 + {-9.0, -15.2, -3.8, 2.6, 8.3, 15.9, 18.6, 14.9, 11.1, 5.3, 1.8, -0.2}, // 2011 + {-8.7, -11.3, -2.3, 0.4, 7.5, 12.2, 16.4, 14.1, 9.2, 3.1, 0.3, -12.1} // 2012 }; // Create data rows diff --git a/examples/widget/chart.h b/examples/widget/chart.h index 3b1f2682..66051ad4 100644 --- a/examples/widget/chart.h +++ b/examples/widget/chart.h @@ -59,8 +59,8 @@ signals: private: Q3DBars *m_chart; - float m_xRotation; - float m_yRotation; + qreal m_xRotation; + qreal m_yRotation; int m_fontSize; int m_segments; int m_subSegments; diff --git a/src/datavisualization/axis/q3dabstractaxis.cpp b/src/datavisualization/axis/q3dabstractaxis.cpp index ce3b582f..8e1e6a35 100644 --- a/src/datavisualization/axis/q3dabstractaxis.cpp +++ b/src/datavisualization/axis/q3dabstractaxis.cpp @@ -60,6 +60,29 @@ QT_DATAVISUALIZATION_BEGIN_NAMESPACE */ /*! + * \qmlproperty real AbstractAxis3D::min + * + * Defines the minimum value on the axis. + * When setting this property the max is adjusted if necessary, to ensure that the range remains + * valid. + */ + +/*! + * \qmlproperty real AbstractAxis3D::max + * + * Defines the maximum value on the axis. + * When setting this property the min is adjusted if necessary, to ensure that the range remains + * valid. + */ + +/*! + * \qmlproperty bool AbstractAxis3D::autoAdjustRange + * + * If set, the axis will automatically adjust the range so that all data fits in it. + */ + + +/*! * \enum Q3DAbstractAxis::AxisOrientation * * The orientation of the axis object. @@ -145,6 +168,75 @@ void Q3DAbstractAxis::setTitle(QString title) } } +/*! + * Sets value range of the axis from \a min to \a max. + * When setting the range, the max is adjusted if necessary, to ensure that the range remains valid. + * \note For Q3DCategoryAxis this specifies the index range of rows or columns to show. + */ +void Q3DAbstractAxis::setRange(qreal min, qreal max) +{ + d_ptr->setRange(min, max); + setAutoAdjustRange(false); +} + +/*! + * \property Q3DAbstractAxis::min + * + * Defines the minimum value on the axis. + * When setting this property the max is adjusted if necessary, to ensure that the range remains + * valid. + * \note For Q3DCategoryAxis this specifies the index of the first row or column to show. + */ +void Q3DAbstractAxis::setMin(qreal min) +{ + d_ptr->setMin(min); + setAutoAdjustRange(false); +} + +/*! + * \property Q3DAbstractAxis::max + * + * Defines the maximum value on the axis. + * When setting this property the min is adjusted if necessary, to ensure that the range remains + * valid. + * \note For Q3DCategoryAxis this specifies the index of the last row or column to show. + */ +void Q3DAbstractAxis::setMax(qreal max) +{ + d_ptr->setMax(max); + setAutoAdjustRange(false); +} + +qreal Q3DAbstractAxis::min() const +{ + return d_ptr->m_min; +} + +qreal Q3DAbstractAxis::max() const +{ + return d_ptr->m_max; +} + +/*! + * \property Q3DAbstractAxis::autoAdjustRange + * + * If set, the axis will automatically adjust the range so that all data fits in it. + * + * \sa setRange(), setMin(), setMax() + */ +void Q3DAbstractAxis::setAutoAdjustRange(bool autoAdjust) +{ + if (d_ptr->m_autoAdjust != autoAdjust) { + d_ptr->m_autoAdjust = autoAdjust; + emit autoAdjustRangeChanged(autoAdjust); + } +} + +bool Q3DAbstractAxis::isAutoAdjustRange() const +{ + return d_ptr->m_autoAdjust; +} + // Q3DAbstractAxisPrivate Q3DAbstractAxisPrivate::Q3DAbstractAxisPrivate(Q3DAbstractAxis *q, Q3DAbstractAxis::AxisType type) @@ -152,7 +244,12 @@ Q3DAbstractAxisPrivate::Q3DAbstractAxisPrivate(Q3DAbstractAxis *q, Q3DAbstractAx q_ptr(q), m_orientation(Q3DAbstractAxis::AxisOrientationNone), m_type(type), - m_isDefaultAxis(false) + m_isDefaultAxis(false), + m_min(0.0), + m_max(10.0), + m_autoAdjust(true), + m_onlyPositiveValues(false), + m_allowMinMaxSame(false) { } @@ -173,4 +270,100 @@ void Q3DAbstractAxisPrivate::updateLabels() // Default implementation does nothing } +void Q3DAbstractAxisPrivate::setRange(qreal min, qreal max) +{ + bool adjusted = false; + if (m_onlyPositiveValues) { + if (min < 0.0) { + min = 0.0; + adjusted = true; + } + if (max < 0.0) { + max = 0.0; + adjusted = true; + } + } + // If min >= max, we adjust ranges so that + // m_max becomes (min + 1.0) + // as axes need some kind of valid range. + bool dirty = false; + if (m_min != min) { + m_min = min; + dirty = true; + } + if (m_max != max || min > max || (!m_allowMinMaxSame && min == max)) { + if (min > max || (!m_allowMinMaxSame && min == max)) { + m_max = min + 1.0; + adjusted = true; + } else { + m_max = max; + } + dirty = true; + } + + if (dirty) { + if (adjusted) { + qWarning() << "Warning: Tried to set invalid range for axis." + " Range automatically adjusted to a valid one:" + << min << "-" << max << "-->" << m_min << "-" << m_max; + } + emit q_ptr->rangeChanged(m_min, m_max); + } +} + +void Q3DAbstractAxisPrivate::setMin(qreal min) +{ + if (m_onlyPositiveValues) { + if (min < 0.0) { + min = 0.0; + qWarning() << "Warning: Tried to set negative minimum for an axis that only supports" + " positive values:" << min; + } + } + + if (m_min != min) { + if (min > m_max || (!m_allowMinMaxSame && min == m_max)) { + qreal oldMax = m_max; + m_max = min + 1.0; + qWarning() << "Warning: Tried to set minimum to equal or larger than maximum for" + " value axis. Maximum automatically adjusted to a valid one:" + << oldMax << "-->" << m_max; + } + m_min = min; + + emit q_ptr->rangeChanged(m_min, m_max); + } +} + +void Q3DAbstractAxisPrivate::setMax(qreal max) +{ + if (m_onlyPositiveValues) { + if (max < 0.0) { + max = 0.0; + qWarning() << "Warning: Tried to set negative maximum for an axis that only supports" + " positive values:" << max; + } + } + + if (m_max != max) { + if (m_min > max || (!m_allowMinMaxSame && m_min == max)) { + qreal oldMin = m_min; + m_min = max - 1.0; + if (m_onlyPositiveValues && m_min < 0.0) { + m_min = 0.0; + if (!m_allowMinMaxSame && max == 0.0) { + m_min = oldMin; + qWarning() << "Unable to set maximum value to zero."; + return; + } + } + qWarning() << "Warning: Tried to set maximum to equal or smaller than minimum for" + " value axis. Minimum automatically adjusted to a valid one:" + << oldMin << "-->" << m_min; + } + m_max = max; + emit q_ptr->rangeChanged(m_min, m_max); + } +} + QT_DATAVISUALIZATION_END_NAMESPACE diff --git a/src/datavisualization/axis/q3dabstractaxis.h b/src/datavisualization/axis/q3dabstractaxis.h index 6e89723a..31b7ab55 100644 --- a/src/datavisualization/axis/q3dabstractaxis.h +++ b/src/datavisualization/axis/q3dabstractaxis.h @@ -38,6 +38,9 @@ class QT_DATAVISUALIZATION_EXPORT Q3DAbstractAxis : public QObject Q_PROPERTY(QStringList labels READ labels NOTIFY labelsChanged) Q_PROPERTY(AxisOrientation orientation READ orientation) Q_PROPERTY(AxisType type READ type) + Q_PROPERTY(qreal min READ min WRITE setMin NOTIFY rangeChanged) + Q_PROPERTY(qreal max READ max WRITE setMax NOTIFY rangeChanged) + Q_PROPERTY(bool autoAdjustRange READ isAutoAdjustRange WRITE setAutoAdjustRange NOTIFY autoAdjustRangeChanged) public: enum AxisOrientation { @@ -66,12 +69,22 @@ public: AxisOrientation orientation() const; AxisType type() const; + qreal min() const; + qreal max() const; + bool isAutoAdjustRange() const; + public slots: void setTitle(QString title); + void setRange(qreal min, qreal max); + void setMin(qreal min); + void setMax(qreal max); + void setAutoAdjustRange(bool autoAdjust); signals: void titleChanged(QString newTitle); void labelsChanged(); + void rangeChanged(qreal min, qreal max); + void autoAdjustRangeChanged(bool autoAdjust); protected: QScopedPointer<Q3DAbstractAxisPrivate> d_ptr; diff --git a/src/datavisualization/axis/q3dabstractaxis_p.h b/src/datavisualization/axis/q3dabstractaxis_p.h index f961e82e..902f65be 100644 --- a/src/datavisualization/axis/q3dabstractaxis_p.h +++ b/src/datavisualization/axis/q3dabstractaxis_p.h @@ -47,6 +47,10 @@ public: inline bool isDefaultAxis() { return m_isDefaultAxis; } inline void setDefaultAxis(bool isDefault) { m_isDefaultAxis = isDefault; } + virtual void setRange(qreal min, qreal max); + virtual void setMin(qreal min); + virtual void setMax (qreal max); + protected: virtual void updateLabels(); @@ -57,6 +61,11 @@ protected: Q3DAbstractAxis::AxisOrientation m_orientation; Q3DAbstractAxis::AxisType m_type; bool m_isDefaultAxis; + qreal m_min; + qreal m_max; + bool m_autoAdjust; + bool m_onlyPositiveValues; + bool m_allowMinMaxSame; friend class Q3DAbstractAxis; friend class Q3DValueAxis; diff --git a/src/datavisualization/axis/q3dcategoryaxis.cpp b/src/datavisualization/axis/q3dcategoryaxis.cpp index 57c545c8..3f032534 100644 --- a/src/datavisualization/axis/q3dcategoryaxis.cpp +++ b/src/datavisualization/axis/q3dcategoryaxis.cpp @@ -119,6 +119,8 @@ Q3DCategoryAxisPrivate::Q3DCategoryAxisPrivate(Q3DCategoryAxis *q) : Q3DAbstractAxisPrivate(q, Q3DAbstractAxis::AxisTypeCategory), m_labelsExplicitlySet(false) { + m_onlyPositiveValues = true; + m_allowMinMaxSame = true; } Q3DCategoryAxisPrivate::~Q3DCategoryAxisPrivate() diff --git a/src/datavisualization/axis/q3dcategoryaxis.h b/src/datavisualization/axis/q3dcategoryaxis.h index bf5e66fd..7376760b 100644 --- a/src/datavisualization/axis/q3dcategoryaxis.h +++ b/src/datavisualization/axis/q3dcategoryaxis.h @@ -36,6 +36,7 @@ public: QStringList categoryLabels() const; + public slots: void setCategoryLabels(const QStringList &labels); diff --git a/src/datavisualization/axis/q3dvalueaxis.cpp b/src/datavisualization/axis/q3dvalueaxis.cpp index 86b16fd9..a32a96e7 100644 --- a/src/datavisualization/axis/q3dvalueaxis.cpp +++ b/src/datavisualization/axis/q3dvalueaxis.cpp @@ -45,21 +45,6 @@ QT_DATAVISUALIZATION_BEGIN_NAMESPACE * counts to divide the range into. */ -/*! - * \qmlproperty real ValueAxis3D::min - * - * Defines the minimum value on the axis. - * When setting this property the max is adjusted if necessary, to ensure that the range remains - * valid. - */ - -/*! - * \qmlproperty real ValueAxis3D::max - * - * Defines the maximum value on the axis. - * When setting this property the min is adjusted if necessary, to ensure that the range remains - * valid. - */ /*! * \qmlproperty int ValueAxis3D::segmentCount @@ -78,13 +63,6 @@ QT_DATAVISUALIZATION_BEGIN_NAMESPACE */ /*! - * \qmlproperty bool ValueAxis3D::autoAdjustRange - * - * Determines if the axis is to automatically calculate the range instead of setting range or - * adjusting min or max property. - */ - -/*! * \qmlproperty string ValueAxis3D::labelFormat * * Defines the label format to be used for the labels on this axis. Supported specifiers are: @@ -106,51 +84,6 @@ Q3DValueAxis::~Q3DValueAxis() { } -/*! - * Sets value range of the axis from \a min to \a max. - * When setting the range, the max is adjusted if necessary, to ensure that the range remains valid. - */ -void Q3DValueAxis::setRange(qreal min, qreal max) -{ - dptr()->setRange(min, max); - setAutoAdjustRange(false); -} - -/*! - * \property Q3DValueAxis::min - * - * Defines the minimum value on the axis. - * When setting this property the max is adjusted if necessary, to ensure that the range remains - * valid. - */ -void Q3DValueAxis::setMin(qreal min) -{ - dptr()->setMin(min); - setAutoAdjustRange(false); -} - -/*! - * \property Q3DValueAxis::max - * - * Defines the maximum value on the axis. - * When setting this property the min is adjusted if necessary, to ensure that the range remains - * valid. - */ -void Q3DValueAxis::setMax(qreal max) -{ - dptr()->setMax(max); - setAutoAdjustRange(false); -} - -qreal Q3DValueAxis::min() const -{ - return dptrc()->m_min; -} - -qreal Q3DValueAxis::max() const -{ - return dptrc()->m_max; -} /*! * \property Q3DValueAxis::segmentCount @@ -208,27 +141,6 @@ int Q3DValueAxis::subSegmentCount() const } /*! - * \property Q3DValueAxis::autoAdjustRange - * - * Tells the axis to automatically calculate the range instead of setting range or adjusting min or - * max property. - * - * \sa setRange(), setMin(), setMax() - */ -void Q3DValueAxis::setAutoAdjustRange(bool autoAdjust) -{ - if (dptr()->m_autoAdjust != autoAdjust) { - dptr()->m_autoAdjust = autoAdjust; - emit autoAdjustRangeChanged(autoAdjust); - } -} - -bool Q3DValueAxis::isAutoAdjustRange() const -{ - return dptrc()->m_autoAdjust; -} - -/*! * \property Q3DValueAxis::labelFormat * * Defines the label format to be used for the labels on this axis. Supported specifiers are: @@ -270,11 +182,8 @@ const Q3DValueAxisPrivate *Q3DValueAxis::dptrc() const Q3DValueAxisPrivate::Q3DValueAxisPrivate(Q3DValueAxis *q) : Q3DAbstractAxisPrivate(q, Q3DAbstractAxis::AxisTypeValue), - m_min(0.0), - m_max(10.0), m_segmentCount(5), m_subSegmentCount(1), - m_autoAdjust(true), m_labelFormat(Utils::defaultLabelFormat()), m_labelsDirty(true) { @@ -286,62 +195,32 @@ Q3DValueAxisPrivate::~Q3DValueAxisPrivate() void Q3DValueAxisPrivate::setRange(qreal min, qreal max) { - // If min >= max, we adjust ranges so that - // m_max becomes (min + 1.0) - // as axes need some kind of valid range. - // TODO: Make "reverse" axes work (i.e. min > max) - bool dirty = false; - if (m_min != min) { - m_min = min; - dirty = true; - } - if (m_max != max || min >= max) { - if (min >= max) { - m_max = min + 1.0; - qWarning() << "Warning: Tried to set invalid range for value axis." - " Range automatically adjusted to a valid one:" - << min << "-" << max << "-->" << m_min << "-" << m_max; - } else { - m_max = max; - } - dirty = true; - } - if (dirty) { + bool dirty = (min != m_min || max != m_max); + + Q3DAbstractAxisPrivate::setRange(min, max); + + if (dirty) emitLabelsChanged(); - emit qptr()->rangeChanged(min, max); - } } void Q3DValueAxisPrivate::setMin(qreal min) { - if (m_min != min) { - if (min >= m_max) { - qreal oldMax = m_max; - m_max = min + 1.0; - qWarning() << "Warning: Tried to set minimum to equal or larger than maximum for" - " value axis. Maximum automatically adjusted to a valid one:" - << oldMax << "-->" << m_max; - } - m_min = min; + bool dirty = (min != m_min); + + Q3DAbstractAxisPrivate::setMin(min); + + if (dirty) emitLabelsChanged(); - emit qptr()->rangeChanged(m_min, m_max); - } } void Q3DValueAxisPrivate::setMax(qreal max) { - if (m_max != max) { - if (max <= m_min) { - qreal oldMin = m_min; - m_min = max - 1.0; - qWarning() << "Warning: Tried to set maximum to equal or smaller than minimum for" - " value axis. Minimum automatically adjusted to a valid one:" - << oldMin << "-->" << m_min; - } - m_max = max; + bool dirty = (max != m_max); + + Q3DAbstractAxisPrivate::setMax(max); + + if (dirty) emitLabelsChanged(); - emit qptr()->rangeChanged(m_min, m_max); - } } void Q3DValueAxisPrivate::emitLabelsChanged() diff --git a/src/datavisualization/axis/q3dvalueaxis.h b/src/datavisualization/axis/q3dvalueaxis.h index eb00f27f..8ff7a531 100644 --- a/src/datavisualization/axis/q3dvalueaxis.h +++ b/src/datavisualization/axis/q3dvalueaxis.h @@ -28,38 +28,26 @@ class Q3DValueAxisPrivate; class QT_DATAVISUALIZATION_EXPORT Q3DValueAxis : public Q3DAbstractAxis { Q_OBJECT - Q_PROPERTY(qreal min READ min WRITE setMin NOTIFY rangeChanged) - Q_PROPERTY(qreal max READ max WRITE setMax NOTIFY rangeChanged) Q_PROPERTY(int segmentCount READ segmentCount WRITE setSegmentCount NOTIFY segmentCountChanged) Q_PROPERTY(int subSegmentCount READ subSegmentCount WRITE setSubSegmentCount NOTIFY subSegmentCountChanged) - Q_PROPERTY(bool autoAdjustRange READ isAutoAdjustRange WRITE setAutoAdjustRange NOTIFY autoAdjustRangeChanged) Q_PROPERTY(QString labelFormat READ labelFormat WRITE setLabelFormat NOTIFY labelFormatChanged) public: explicit Q3DValueAxis(QObject *parent = 0); virtual ~Q3DValueAxis(); - qreal min() const; - qreal max() const; int segmentCount() const; int subSegmentCount() const; - bool isAutoAdjustRange() const; QString labelFormat() const; public slots: - void setRange(qreal min, qreal max); - void setMin(qreal min); - void setMax(qreal max); void setSegmentCount(int count); void setSubSegmentCount(int count); - void setAutoAdjustRange(bool autoAdjust); void setLabelFormat(const QString &format); signals: - void rangeChanged(qreal min, qreal max); void segmentCountChanged(int count); void subSegmentCountChanged(int count); - void autoAdjustRangeChanged(bool autoAdjust); void labelFormatChanged(QString format); protected: diff --git a/src/datavisualization/axis/q3dvalueaxis_p.h b/src/datavisualization/axis/q3dvalueaxis_p.h index 8fcf50da..5d0084e6 100644 --- a/src/datavisualization/axis/q3dvalueaxis_p.h +++ b/src/datavisualization/axis/q3dvalueaxis_p.h @@ -42,19 +42,16 @@ public: Q3DValueAxisPrivate(Q3DValueAxis *q); virtual ~Q3DValueAxisPrivate(); - void setRange(qreal min, qreal max); - void setMin(qreal min); - void setMax (qreal max); + virtual void setRange(qreal min, qreal max); + virtual void setMin(qreal min); + virtual void setMax (qreal max); protected: void emitLabelsChanged(); virtual void updateLabels(); - qreal m_min; - qreal m_max; int m_segmentCount; int m_subSegmentCount; - bool m_autoAdjust; QString m_labelFormat; bool m_labelsDirty; diff --git a/src/datavisualization/data/qbardataproxy.cpp b/src/datavisualization/data/qbardataproxy.cpp index 79821aca..badbfb7b 100644 --- a/src/datavisualization/data/qbardataproxy.cpp +++ b/src/datavisualization/data/qbardataproxy.cpp @@ -654,7 +654,8 @@ void QBarDataProxyPrivate::fixRowLabels(int startIndex, int count, const QString emit qptr()->rowLabelsChanged(); } -QPair<GLfloat, GLfloat> QBarDataProxyPrivate::limitValues(int startRow, int endRow, int startColumn, int endColumn) +QPair<GLfloat, GLfloat> QBarDataProxyPrivate::limitValues(int startRow, int endRow, + int startColumn, int endColumn) const { QPair<GLfloat, GLfloat> limits = qMakePair(0.0f, 0.0f); endRow = qMin(endRow, m_dataArray->size() - 1); diff --git a/src/datavisualization/data/qbardataproxy_p.h b/src/datavisualization/data/qbardataproxy_p.h index 6aa9d2cb..a0f95d35 100644 --- a/src/datavisualization/data/qbardataproxy_p.h +++ b/src/datavisualization/data/qbardataproxy_p.h @@ -54,7 +54,7 @@ public: void removeRows(int rowIndex, int removeCount, bool removeLabels); QPair<GLfloat, GLfloat> limitValues(int startRow, int startColumn, int rowCount, - int columnCount); + int columnCount) const; private: QBarDataProxy *qptr(); diff --git a/src/datavisualization/engine/abstract3dcontroller.cpp b/src/datavisualization/engine/abstract3dcontroller.cpp index bcccf833..e9ba1739 100644 --- a/src/datavisualization/engine/abstract3dcontroller.cpp +++ b/src/datavisualization/engine/abstract3dcontroller.cpp @@ -194,30 +194,21 @@ void Abstract3DController::synchDataToRenderer() } if (m_changeTracker.axisXRangeChanged) { + m_renderer->updateAxisRange(Q3DAbstractAxis::AxisOrientationX, m_axisX->min(), + m_axisX->max()); m_changeTracker.axisXRangeChanged = false; - if (m_axisX->type() & Q3DAbstractAxis::AxisTypeValue) { - Q3DValueAxis *valueAxisX = static_cast<Q3DValueAxis *>(m_axisX); - m_renderer->updateAxisRange(Q3DAbstractAxis::AxisOrientationX, - valueAxisX->min(), valueAxisX->max()); - } } if (m_changeTracker.axisYRangeChanged) { + m_renderer->updateAxisRange(Q3DAbstractAxis::AxisOrientationY, m_axisY->min(), + m_axisY->max()); m_changeTracker.axisYRangeChanged = false; - if (m_axisY->type() & Q3DAbstractAxis::AxisTypeValue) { - Q3DValueAxis *valueAxisY = static_cast<Q3DValueAxis *>(m_axisY); - m_renderer->updateAxisRange(Q3DAbstractAxis::AxisOrientationY, - valueAxisY->min(), valueAxisY->max()); - } } if (m_changeTracker.axisZRangeChanged) { + m_renderer->updateAxisRange(Q3DAbstractAxis::AxisOrientationZ, m_axisZ->min(), + m_axisZ->max()); m_changeTracker.axisZRangeChanged = false; - if (m_axisZ->type() & Q3DAbstractAxis::AxisTypeValue) { - Q3DValueAxis *valueAxisZ = static_cast<Q3DValueAxis *>(m_axisZ); - m_renderer->updateAxisRange(Q3DAbstractAxis::AxisOrientationZ, - valueAxisZ->min(), valueAxisZ->max()); - } } if (m_changeTracker.axisXSegmentCountChanged) { @@ -989,6 +980,10 @@ void Abstract3DController::setAxisHelper(Q3DAbstractAxis::AxisOrientation orient this, &Abstract3DController::handleAxisTitleChanged); QObject::connect(axis, &Q3DAbstractAxis::labelsChanged, this, &Abstract3DController::handleAxisLabelsChanged); + QObject::connect(axis, &Q3DAbstractAxis::rangeChanged, + this, &Abstract3DController::handleAxisRangeChanged); + QObject::connect(axis, &Q3DAbstractAxis::autoAdjustRangeChanged, + this, &Abstract3DController::handleAxisAutoAdjustRangeChanged); if (orientation == Q3DAbstractAxis::AxisOrientationX) m_changeTracker.axisXTypeChanged = true; @@ -999,25 +994,21 @@ void Abstract3DController::setAxisHelper(Q3DAbstractAxis::AxisOrientation orient handleAxisTitleChangedBySender(axis); handleAxisLabelsChangedBySender(axis); + handleAxisRangeChangedBySender(axis); + handleAxisAutoAdjustRangeChangedInOrientation(axis->orientation(), + axis->isAutoAdjustRange()); if (axis->type() & Q3DAbstractAxis::AxisTypeValue) { Q3DValueAxis *valueAxis = static_cast<Q3DValueAxis *>(axis); - QObject::connect(valueAxis, &Q3DValueAxis::rangeChanged, - this, &Abstract3DController::handleAxisRangeChanged); QObject::connect(valueAxis, &Q3DValueAxis::segmentCountChanged, this, &Abstract3DController::handleAxisSegmentCountChanged); QObject::connect(valueAxis, &Q3DValueAxis::subSegmentCountChanged, this, &Abstract3DController::handleAxisSubSegmentCountChanged); - QObject::connect(valueAxis, &Q3DValueAxis::autoAdjustRangeChanged, - this, &Abstract3DController::handleAxisAutoAdjustRangeChanged); QObject::connect(valueAxis, &Q3DValueAxis::labelFormatChanged, this, &Abstract3DController::handleAxisLabelFormatChanged); - handleAxisRangeChangedBySender(valueAxis); handleAxisSegmentCountChangedBySender(valueAxis); handleAxisSubSegmentCountChangedBySender(valueAxis); - handleAxisAutoAdjustRangeChangedInOrientation(valueAxis->orientation(), - valueAxis->isAutoAdjustRange()); handleAxisLabelFormatChangedBySender(valueAxis); } } @@ -1051,6 +1042,7 @@ Q3DCategoryAxis *Abstract3DController::createDefaultCategoryAxis() // Default category axis has no labels // TODO: Grid should be also hidden, but that is not currently controlled by axis. Q3DCategoryAxis *defaultAxis = new Q3DCategoryAxis; + defaultAxis->setAutoAdjustRange(true); defaultAxis->d_ptr->setDefaultAxis(true); return defaultAxis; } diff --git a/src/datavisualization/engine/bars3dcontroller.cpp b/src/datavisualization/engine/bars3dcontroller.cpp index 1f4d44c0..5ec6f01f 100644 --- a/src/datavisualization/engine/bars3dcontroller.cpp +++ b/src/datavisualization/engine/bars3dcontroller.cpp @@ -32,8 +32,6 @@ QT_DATAVISUALIZATION_BEGIN_NAMESPACE Bars3DController::Bars3DController(QRect boundRect) : Abstract3DController(boundRect), - m_rowCount(10), - m_columnCount(10), m_selectedBarPos(noSelectionPoint()), m_isBarSpecRelative(true), m_barThicknessRatio(1.0f), @@ -81,11 +79,6 @@ void Bars3DController::synchDataToRenderer() return; // Notify changes to renderer - if (m_changeTracker.sampleSpaceChanged) { - m_renderer->updateSampleSpace(m_rowCount, m_columnCount); - m_changeTracker.sampleSpaceChanged = false; - } - if (m_changeTracker.barSpecsChanged) { m_renderer->updateBarSpecs(m_barThicknessRatio, m_barSpacing, m_isBarSpecRelative); m_changeTracker.barSpecsChanged = false; @@ -133,7 +126,7 @@ void Bars3DController::setActiveDataProxy(QAbstractDataProxy *proxy) QObject::connect(barDataProxy, &QBarDataProxy::columnLabelsChanged, this, &Bars3DController::handleDataColumnLabelsChanged); - adjustValueAxisRange(); + adjustAxisRanges(); // Always clear selection on proxy change setSelectedBarPos(noSelectionPoint()); @@ -145,7 +138,7 @@ void Bars3DController::setActiveDataProxy(QAbstractDataProxy *proxy) void Bars3DController::handleArrayReset() { scene()->setSlicingActivated(false); - adjustValueAxisRange(); + adjustAxisRanges(); m_isDataDirty = true; // Clear selection unless still valid setSelectedBarPos(m_selectedBarPos); @@ -156,10 +149,9 @@ void Bars3DController::handleRowsAdded(int startIndex, int count) { Q_UNUSED(startIndex) Q_UNUSED(count) - // TODO check if affects data window // TODO should update slice instead of deactivating? scene()->setSlicingActivated(false); - adjustValueAxisRange(); + adjustAxisRanges(); m_isDataDirty = true; emitNeedRender(); } @@ -168,10 +160,9 @@ void Bars3DController::handleRowsChanged(int startIndex, int count) { Q_UNUSED(startIndex) Q_UNUSED(count) - // TODO check if affects data window // TODO should update slice instead of deactivating? scene()->setSlicingActivated(false); - adjustValueAxisRange(); + adjustAxisRanges(); m_isDataDirty = true; emitNeedRender(); } @@ -180,10 +171,9 @@ void Bars3DController::handleRowsRemoved(int startIndex, int count) { Q_UNUSED(startIndex) Q_UNUSED(count) - // TODO check if affects data window // TODO should update slice instead of deactivating? scene()->setSlicingActivated(false); - adjustValueAxisRange(); + adjustAxisRanges(); m_isDataDirty = true; // Clear selection unless still valid @@ -196,10 +186,9 @@ void Bars3DController::handleRowsInserted(int startIndex, int count) { Q_UNUSED(startIndex) Q_UNUSED(count) - // TODO check if affects data window // TODO should update slice instead of deactivating? scene()->setSlicingActivated(false); - adjustValueAxisRange(); + adjustAxisRanges(); m_isDataDirty = true; emitNeedRender(); } @@ -208,10 +197,9 @@ void Bars3DController::handleItemChanged(int rowIndex, int columnIndex) { Q_UNUSED(rowIndex) Q_UNUSED(columnIndex) - // TODO check if affects data window // TODO should update slice instead of deactivating? scene()->setSlicingActivated(false); - adjustValueAxisRange(); + adjustAxisRanges(); m_isDataDirty = true; emitNeedRender(); } @@ -220,8 +208,9 @@ void Bars3DController::handleDataRowLabelsChanged() { if (m_axisX && m_data) { // Grab a sublist equal to data window (no need to have more labels in axis) - // TODO once axis controls data window, this needs to change - QStringList subList = static_cast<QBarDataProxy *>(m_data)->rowLabels().mid(0, m_rowCount); + int min = int(m_axisX->min()); + int count = int(m_axisX->max()) - min + 1; + QStringList subList = static_cast<QBarDataProxy *>(m_data)->rowLabels().mid(min, count); static_cast<Q3DCategoryAxis *>(m_axisX)->dptr()->setDataLabels(subList); } } @@ -230,8 +219,9 @@ void Bars3DController::handleDataColumnLabelsChanged() { if (m_axisZ && m_data) { // Grab a sublist equal to data window (no need to have more labels in axis) - // TODO once axis controls data window, this needs to change - QStringList subList = static_cast<QBarDataProxy *>(m_data)->columnLabels().mid(0, m_columnCount); + int min = int(m_axisZ->min()); + int count = int(m_axisZ->max()) - min + 1; + QStringList subList = static_cast<QBarDataProxy *>(m_data)->columnLabels().mid(min, count); static_cast<Q3DCategoryAxis *>(m_axisZ)->dptr()->setDataLabels(subList); } } @@ -253,7 +243,7 @@ void Bars3DController::handleAxisAutoAdjustRangeChangedInOrientation( { Q_UNUSED(orientation) Q_UNUSED(autoAdjust) - adjustValueAxisRange(); + adjustAxisRanges(); } QPoint Bars3DController::noSelectionPoint() @@ -274,6 +264,25 @@ void Bars3DController::setAxisZ(Q3DAbstractAxis *axis) handleDataColumnLabelsChanged(); } +void Bars3DController::handleAxisRangeChangedBySender(QObject *sender) +{ + // Data window changed + if (sender == m_axisX || sender == m_axisZ) { + // Disable zoom mode if we're in it (causes crash if not, as zoom selection is deleted) + scene()->setSlicingActivated(false); + + // Clear selection unless still valid + setSelectedBarPos(m_selectedBarPos); + + if (sender == m_axisX) + handleDataRowLabelsChanged(); + if (sender == m_axisZ) + handleDataColumnLabelsChanged(); + } + + Abstract3DController::handleAxisRangeChangedBySender(sender); +} + void Bars3DController::setBarSpecs(GLfloat thicknessRatio, const QSizeF &spacing, bool relative) { m_barThicknessRatio = thicknessRatio; @@ -319,29 +328,6 @@ void Bars3DController::setBarType(QDataVis::MeshStyle style, bool smooth) Abstract3DController::setMeshFileName(objFile); } -// TODO: This sets data window. Needs more parameters, now assumes window always starts at 0,0. -void Bars3DController::setDataWindow(int rowCount, int columnCount) -{ - // Disable zoom mode if we're in it (causes crash if not, as zoom selection is deleted) - scene()->setSlicingActivated(false); - - m_rowCount = rowCount; - m_columnCount = columnCount; - - adjustValueAxisRange(); - - // Clear selection unless still valid - setSelectedBarPos(m_selectedBarPos); - - m_changeTracker.sampleSpaceChanged = true; - m_isDataDirty = true; // Render item array is recreated in renderer - - handleDataRowLabelsChanged(); - handleDataColumnLabelsChanged(); - - emitNeedRender(); -} - void Bars3DController::setSelectionMode(QDataVis::SelectionMode mode) { // Disable zoom if selection mode changes @@ -353,13 +339,19 @@ void Bars3DController::setSelectedBarPos(const QPoint &position) { // If the selection is outside data window or targets non-existent // bar, clear selection instead. - // TODO this will break once data window offset is implemented QPoint pos = position; - if (pos.x() < 0 || pos.y() < 0 - || pos.x() >= static_cast<QBarDataProxy *>(m_data)->rowCount() - || pos.y() >= static_cast<QBarDataProxy *>(m_data)->rowAt(pos.x())->size() - || pos.x() >= m_rowCount || pos.y() >= m_columnCount) { - pos = noSelectionPoint(); + + if (pos != noSelectionPoint()) { + int minRow = int(m_axisX->min()); + int maxRow = int(m_axisX->max()); + int minCol = int(m_axisZ->min()); + int maxCol = int(m_axisZ->max()); + + if (pos.x() < minRow || pos.x() > maxRow || pos.y() < minCol || pos.y() > maxCol + || pos.x() + minRow >= static_cast<QBarDataProxy *>(m_data)->rowCount() + || pos.y() + minCol >= static_cast<QBarDataProxy *>(m_data)->rowAt(pos.x())->size()) { + pos = noSelectionPoint(); + } } if (pos != m_selectedBarPos) { @@ -375,23 +367,37 @@ QPoint Bars3DController::selectedBarPos() const return m_selectedBarPos; } -int Bars3DController::columnCount() +void Bars3DController::adjustAxisRanges() { - return m_columnCount; -} + const QBarDataProxy *proxy = static_cast<QBarDataProxy *>(m_data); + const QBarDataArray *array = proxy->array(); + + Q3DCategoryAxis *categoryAxisX = static_cast<Q3DCategoryAxis *>(m_axisX); + if (categoryAxisX && categoryAxisX->isAutoAdjustRange() && proxy) { + int rowCount = proxy->rowCount(); + if (rowCount) + rowCount--; + categoryAxisX->dptr()->setRange(0.0, qreal(rowCount)); + } -int Bars3DController::rowCount() -{ - return m_rowCount; -} + Q3DCategoryAxis *categoryAxisZ = static_cast<Q3DCategoryAxis *>(m_axisZ); + if (categoryAxisZ && categoryAxisZ->isAutoAdjustRange() && proxy) { + int columnCount = 0; + for (int i = 0; i < array->size(); i++) { + if (columnCount < array->at(i)->size()) + columnCount = array->at(i)->size(); + } + if (columnCount) + columnCount--; + categoryAxisZ->dptr()->setRange(0.0, qreal(columnCount)); + } -void Bars3DController::adjustValueAxisRange() -{ Q3DValueAxis *valueAxis = static_cast<Q3DValueAxis *>(m_axisY); - if (valueAxis && valueAxis->isAutoAdjustRange() && m_data) { - QPair<GLfloat, GLfloat> limits = - static_cast<QBarDataProxy *>(m_data)->dptr()->limitValues(0, m_rowCount, - 0, m_columnCount); + if (valueAxis && categoryAxisX && categoryAxisZ && valueAxis->isAutoAdjustRange() && proxy) { + QPair<GLfloat, GLfloat> limits = proxy->dptrc()->limitValues(categoryAxisX->min(), + categoryAxisX->max(), + categoryAxisZ->min(), + categoryAxisZ->max()); if (limits.first < 0) { // TODO: Currently we only support symmetric y-axis for bar chart if there are negative values qreal maxAbs = qMax(qFabs(limits.first), qFabs(limits.second)); diff --git a/src/datavisualization/engine/bars3dcontroller_p.h b/src/datavisualization/engine/bars3dcontroller_p.h index 6dbaf742..8398dd81 100644 --- a/src/datavisualization/engine/bars3dcontroller_p.h +++ b/src/datavisualization/engine/bars3dcontroller_p.h @@ -41,13 +41,11 @@ class QBarDataProxy; struct Bars3DChangeBitField { bool slicingActiveChanged : 1; - bool sampleSpaceChanged : 1; bool barSpecsChanged : 1; bool selectedBarPosChanged : 1; Bars3DChangeBitField() : slicingActiveChanged(true), - sampleSpaceChanged(true), barSpecsChanged(true), selectedBarPosChanged(true) { @@ -61,10 +59,6 @@ class QT_DATAVISUALIZATION_EXPORT Bars3DController : public Abstract3DController private: Bars3DChangeBitField m_changeTracker; - // Data - int m_rowCount; - int m_columnCount; - // Interaction QPoint m_selectedBarPos; // Points to row & column in data window. @@ -83,9 +77,6 @@ public: void initializeOpenGL(); virtual void synchDataToRenderer(); - int columnCount(); - int rowCount(); - // bar thickness, spacing between bars, and is spacing relative to thickness or absolute // y -component sets the thickness/spacing of z -direction // With relative 0.0f means side-to-side, 1.0f = one thickness in between @@ -99,9 +90,6 @@ public: // bar type; bars (=cubes), pyramids, cones, cylinders, etc. void setBarType(QDataVis::MeshStyle style, bool smooth = false); - // how many samples per row and column, and names for axes - void setDataWindow(int samplesRow, int samplesColumn); - // Change selection mode; single bar, bar and row, bar and column, or all void setSelectionMode(QDataVis::SelectionMode mode); @@ -117,6 +105,8 @@ public: virtual void setAxisX(Q3DAbstractAxis *axis); virtual void setAxisZ(Q3DAbstractAxis *axis); + virtual void handleAxisRangeChangedBySender(QObject *sender); + public slots: void handleArrayReset(); void handleRowsAdded(int startIndex, int count); @@ -136,7 +126,7 @@ protected: virtual Q3DAbstractAxis *createDefaultAxis(Q3DAbstractAxis::AxisOrientation orientation); private: - void adjustValueAxisRange(); + void adjustAxisRanges(); Q_DISABLE_COPY(Bars3DController) diff --git a/src/datavisualization/engine/bars3drenderer.cpp b/src/datavisualization/engine/bars3drenderer.cpp index 5d7abb16..adc3c257 100644 --- a/src/datavisualization/engine/bars3drenderer.cpp +++ b/src/datavisualization/engine/bars3drenderer.cpp @@ -150,18 +150,49 @@ void Bars3DRenderer::initializeOpenGL() void Bars3DRenderer::updateDataModel(QBarDataProxy *dataProxy) { + int minRow = m_axisCacheX.min(); + int maxRow = m_axisCacheX.max(); + int minCol = m_axisCacheZ.min(); + int maxCol = m_axisCacheZ.max(); + int newRows = maxRow - minRow + 1; + int newColumns = maxCol - minCol + 1; + if (newRows != m_renderItemArray.size() || newColumns != m_renderItemArray.at(0).size()) { + // Destroy old render items and reallocate new array + m_renderItemArray.clear(); + m_renderItemArray.resize(newRows); + for (int i = 0; i < newRows; i++) + m_renderItemArray[i].resize(newColumns); + + // Force update for selection related items + m_sliceCache = 0; + m_sliceTitleItem = 0; + if (m_sliceSelection) + m_sliceSelection->clear(); + + m_cachedColumnCount = newColumns; + m_cachedRowCount = newRows; + // TODO: Invent foolproof max scene size formula + // This seems to work ok if spacing is not negative (and row/column or column/row ratio is not too high) + m_maxSceneSize = 2 * qSqrt(newColumns * newRows); + // Calculate here and at setting bar specs + calculateSceneScalingFactors(); + } + // Update cached data window int dataRowCount = dataProxy->rowCount(); - for (int i = 0; i < m_renderItemArray.size(); i++) { + int dataRowIndex = minRow; + for (int i = 0; i < newRows; i++) { int j = 0; - if (i < dataRowCount) { - const QBarDataRow *dataRow = dataProxy->rowAt(i); - int updateSize = qMin(dataRow->size(), m_renderItemArray[i].size()); + if (dataRowIndex < dataRowCount) { + const QBarDataRow *dataRow = dataProxy->rowAt(dataRowIndex); + int updateSize = qMin((dataRow->size() - minCol), m_renderItemArray[i].size()); if (dataRow) { + int dataColIndex = minCol; for (; j < updateSize ; j++) { - qreal value = dataRow->at(j).value(); + qreal value = dataRow->at(dataColIndex).value(); m_renderItemArray[i][j].setValue(value); m_renderItemArray[i][j].setHeight(value / m_heightNormalizer); + dataColIndex++; } } } @@ -169,6 +200,7 @@ void Bars3DRenderer::updateDataModel(QBarDataProxy *dataProxy) m_renderItemArray[i][j].setValue(0.0); m_renderItemArray[i][j].setHeight(0.0f); } + dataRowIndex++; } Abstract3DRenderer::updateDataModel(dataProxy); @@ -1489,47 +1521,26 @@ void Bars3DRenderer::updateBarSpecs(GLfloat thicknessRatio, const QSizeF &spacin void Bars3DRenderer::updateAxisRange(Q3DAbstractAxis::AxisOrientation orientation, qreal min, qreal max) { Abstract3DRenderer::updateAxisRange(orientation, min, max); - calculateHeightAdjustment(); - // Check if we have negative values - if (min < 0 && !m_hasNegativeValues) { - m_hasNegativeValues = true; - // Reload background - loadBackgroundMesh(); - - } else if (min >= 0 && m_hasNegativeValues) { - m_hasNegativeValues = false; - // Reload background - loadBackgroundMesh(); - } - // TODO Currently barchart only supports zero centered or zero minimum ranges - if (min > 0.0 || (min != 0.0 && (qFabs(min) != qFabs(max)))) - qWarning() << __FUNCTION__ << "Bar chart currently properly supports only zero-centered and zero minimum ranges for Y-axis."; -} + if (orientation == Q3DAbstractAxis::AxisOrientationY) { + calculateHeightAdjustment(); + // Check if we have negative values + if (min < 0 && !m_hasNegativeValues) { + m_hasNegativeValues = true; + // Reload background + loadBackgroundMesh(); + emit needRender(); + } else if (min >= 0 && m_hasNegativeValues) { + m_hasNegativeValues = false; + // Reload background + loadBackgroundMesh(); + emit needRender(); + } -void Bars3DRenderer::updateSampleSpace(int rowCount, int columnCount) -{ - // Destroy old render items and reallocate new array - // TODO is there a way to allocate the whole array with one allocation? - m_renderItemArray.clear(); - m_renderItemArray.resize(rowCount); - for (int i = 0; i < rowCount; i++) - m_renderItemArray[i].resize(columnCount); - - // Force update for selection related items - m_sliceCache = 0; - m_sliceTitleItem = 0; - if (m_sliceSelection) - m_sliceSelection->clear(); - - m_cachedColumnCount = columnCount; - m_cachedRowCount = rowCount; - // TODO: Invent "idiotproof" max scene size formula.. - // This seems to work ok if spacing is not negative (and row/column or column/row ratio is not too high) - m_maxSceneSize = 2 * qSqrt(columnCount * rowCount); - //qDebug() << "maxSceneSize" << m_maxSceneSize; - // Calculate here and at setting bar specs - calculateSceneScalingFactors(); + // TODO Currently barchart only supports zero centered or zero minimum ranges + if (min > 0.0 || (min != 0.0 && (qFabs(min) != qFabs(max)))) + qWarning() << __FUNCTION__ << "Bar chart currently properly supports only zero-centered and zero minimum ranges for Y-axis."; + } } void Bars3DRenderer::updateSelectionMode(QDataVis::SelectionMode mode) diff --git a/src/datavisualization/engine/bars3drenderer_p.h b/src/datavisualization/engine/bars3drenderer_p.h index 3be0ebf9..9b612474 100644 --- a/src/datavisualization/engine/bars3drenderer_p.h +++ b/src/datavisualization/engine/bars3drenderer_p.h @@ -126,7 +126,6 @@ public slots: bool relative = true); void updateSelectionMode(QDataVis::SelectionMode newMode); void updateSlicingActive(bool isSlicing); - void updateSampleSpace(int rowCount, int columnCount); void updateBackgroundEnabled(bool enable); void updateSelectedBarPos(const QPoint &position); diff --git a/src/datavisualization/engine/q3dbars.cpp b/src/datavisualization/engine/q3dbars.cpp index be8b3a88..e892367e 100644 --- a/src/datavisualization/engine/q3dbars.cpp +++ b/src/datavisualization/engine/q3dbars.cpp @@ -231,7 +231,7 @@ QT_DATAVISUALIZATION_BEGIN_NAMESPACE /*! * \qmlproperty point Bars3D::selectedBarPos - * Position of the selected bar, if any. Only one bar can be selected at a time. + * Position of the selected bar in data window. Only one bar can be selected at a time. * To clear selection, specify an illegal position, e.g. Qt.point(-1.0, -1.0). */ @@ -405,23 +405,6 @@ void Q3DBars::setBarType(QDataVis::MeshStyle style, bool smooth) } /*! - * Set up data window to \a samplesRow rows and \a samplesColumn columns. Both are preset to \c 10 - * by default. - */ -void Q3DBars::setDataWindow(int samplesRow, int samplesColumn) -{ - d_ptr->m_shared->setDataWindow(samplesRow, samplesColumn); -} - -/*! - * \return size of the sample space in QSize. - */ -QSize Q3DBars::dataWindow() const -{ - return QSize(d_ptr->m_shared->rowCount(), d_ptr->m_shared->columnCount()); -} - -/*! * \property Q3DBars::cameraPreset * * The \a preset position of the camera. The position can be one of \c QDataVis::CameraPreset. @@ -584,7 +567,8 @@ bool Q3DBars::isBackgroundVisible() const /*! * \property Q3DBars::selectedBarPos * - * Selects a bar in a \a position. Only one bar can be selected at a time. + * Selects a bar in a \a position. The position is the position in data window. + * Only one bar can be selected at a time. * To clear selection, specify an illegal \a position, e.g. (-1, -1). */ void Q3DBars::setSelectedBarPos(const QPoint &position) diff --git a/src/datavisualization/engine/q3dbars.h b/src/datavisualization/engine/q3dbars.h index 1404ea05..9a8e97bb 100644 --- a/src/datavisualization/engine/q3dbars.h +++ b/src/datavisualization/engine/q3dbars.h @@ -57,10 +57,6 @@ public: void setBarType(QDataVis::MeshStyle style, bool smooth = false); - // TODO: This defines the data window, needs additional parameters startRow, startColumn - void setDataWindow(int samplesRow, int samplesColumn); - QSize dataWindow() const; // TODO: Return QRect once data window properly implemented? - void setCameraPreset(QDataVis::CameraPreset preset); QDataVis::CameraPreset cameraPreset() const; diff --git a/src/datavisualization/input/q3dinputhandler.cpp b/src/datavisualization/input/q3dinputhandler.cpp index 51f0670a..2b16c942 100644 --- a/src/datavisualization/input/q3dinputhandler.cpp +++ b/src/datavisualization/input/q3dinputhandler.cpp @@ -23,6 +23,17 @@ QT_DATAVISUALIZATION_BEGIN_NAMESPACE +const int minZoomLevel = 10; +const int halfSizeZoomLevel = 50; +const int oneToOneZoomLevel = 100; +const int maxZoomLevel = 500; + +const int nearZoomRangeDivider = 12; +const int midZoomRangeDivider = 60; +const int farZoomRangeDivider = 120; + +const qreal rotationSpeed = 100.0; + Q3DInputHandler::Q3DInputHandler(QObject *parent) : QAbstract3DInputHandler(parent) { diff --git a/src/datavisualization/input/q3dinputhandler.h b/src/datavisualization/input/q3dinputhandler.h index d87966d6..a337d4d6 100644 --- a/src/datavisualization/input/q3dinputhandler.h +++ b/src/datavisualization/input/q3dinputhandler.h @@ -23,17 +23,6 @@ QT_DATAVISUALIZATION_BEGIN_NAMESPACE -const int minZoomLevel = 10; -const int halfSizeZoomLevel = 50; -const int oneToOneZoomLevel = 100; -const int maxZoomLevel = 500; - -const int nearZoomRangeDivider = 12; -const int midZoomRangeDivider = 60; -const int farZoomRangeDivider = 120; - -const float rotationSpeed = 100.0f; - class QT_DATAVISUALIZATION_EXPORT Q3DInputHandler : public QAbstract3DInputHandler { Q_OBJECT diff --git a/src/datavisualizationqml2/declarativebars.cpp b/src/datavisualizationqml2/declarativebars.cpp index 010409e8..dd575d35 100644 --- a/src/datavisualizationqml2/declarativebars.cpp +++ b/src/datavisualizationqml2/declarativebars.cpp @@ -82,11 +82,6 @@ QSGNode *DeclarativeBars::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData return node; } -void DeclarativeBars::setDataWindow(int rowCount, int columnCount) -{ - m_shared->setDataWindow(rowCount, columnCount); -} - void DeclarativeBars::setBarColor(const QColor &baseColor, bool uniform) { m_shared->setObjectColor(baseColor, uniform); @@ -299,26 +294,6 @@ QDataVis::ShadowQuality DeclarativeBars::shadowQuality() return m_shared->shadowQuality(); } -int DeclarativeBars::rows() const -{ - return m_shared->rowCount(); -} - -void DeclarativeBars::setRows(int rows) -{ - setDataWindow(rows, columns()); -} - -int DeclarativeBars::columns() const -{ - return m_shared->columnCount(); -} - -void DeclarativeBars::setColumns(int columns) -{ - setDataWindow(rows(), columns); -} - void DeclarativeBars::setItemLabelFormat(const QString &format) { m_shared->activeDataProxy()->setItemLabelFormat(format); diff --git a/src/datavisualizationqml2/declarativebars_p.h b/src/datavisualizationqml2/declarativebars_p.h index ebf565fe..b2e64eae 100644 --- a/src/datavisualizationqml2/declarativebars_p.h +++ b/src/datavisualizationqml2/declarativebars_p.h @@ -64,8 +64,6 @@ class DeclarativeBars : public QQuickItem Q_PROPERTY(QFont font READ font WRITE setFont) Q_PROPERTY(bool gridVisible READ isGridVisible WRITE setGridVisible) Q_PROPERTY(bool backgroundVisible READ isBackgroundVisible WRITE setBackgroundVisible) - Q_PROPERTY(int rows READ rows WRITE setRows) - Q_PROPERTY(int columns READ columns WRITE setColumns) Q_PROPERTY(QString itemLabelFormat READ itemLabelFormat WRITE setItemLabelFormat) Q_PROPERTY(QPointF selectedBarPos READ selectedBarPos WRITE setSelectedBarPos NOTIFY selectedBarPosChanged) Q_ENUMS(QtDataVisualization::QDataVis::SelectionMode) @@ -79,9 +77,6 @@ public: explicit DeclarativeBars(QQuickItem *parent = 0); ~DeclarativeBars(); - // how many samples per row and column - Q_INVOKABLE void setDataWindow(int rowCount, int columnCount); - // Set color if you don't want to use themes. Set uniform to false if you want the (height) // color to change from bottom to top Q_INVOKABLE void setBarColor(const QColor &baseColor, bool uniform = true); @@ -159,12 +154,6 @@ public: void setShadowQuality(QDataVis::ShadowQuality quality); QDataVis::ShadowQuality shadowQuality(); - int rows() const; - void setRows(int rows); - - int columns() const; - void setColumns(int columns); - void setItemLabelFormat(const QString &format); QString itemLabelFormat(); diff --git a/tests/barstest/chart.cpp b/tests/barstest/chart.cpp index b534f54c..b8ef0758 100644 --- a/tests/barstest/chart.cpp +++ b/tests/barstest/chart.cpp @@ -30,11 +30,11 @@ ChartModifier::ChartModifier(Q3DBars *barchart) : m_chart(barchart), m_columnCount(21), m_rowCount(21), - m_xRotation(0.0f), - m_yRotation(0.0f), + m_xRotation(0.0), + m_yRotation(0.0), m_static(true), - m_barSpacingX(0.1f), - m_barSpacingZ(0.1f), + m_barSpacingX(0.1), + m_barSpacingZ(0.1), m_fontSize(20), m_segments(4), m_subSegments(3), @@ -54,7 +54,7 @@ ChartModifier::ChartModifier(Q3DBars *barchart) { // Generate generic labels QStringList genericColumnLabels; - for (int i = 0; i < 200; i++) { + for (int i = 0; i < 400; i++) { if (i % 5) genericColumnLabels << QString(); else @@ -80,9 +80,10 @@ ChartModifier::ChartModifier(Q3DBars *barchart) m_fixedRangeAxis->setRange(0.0, 100.0); m_genericRowAxis->setTitle("Generic Row"); + m_genericRowAxis->setRange(0, m_rowCount - 1); m_genericColumnAxis->setTitle("Generic Column"); - m_genericColumnAxis->setCategoryLabels(genericColumnLabels); + m_genericColumnAxis->setRange(0, m_columnCount - 1); m_temperatureAxis->setTitle("Average temperature"); m_temperatureAxis->setSegmentCount(m_segments); @@ -106,6 +107,7 @@ ChartModifier::ChartModifier(Q3DBars *barchart) m_temperatureData->setItemLabelFormat(QStringLiteral("@valueTitle for @colLabel @rowLabel: @valueLabel")); m_genericData->setItemLabelFormat(QStringLiteral("@valueTitle for (@rowIdx, @colIdx): @valueLabel")); + m_genericData->setColumnLabels(genericColumnLabels); m_chart->addDataProxy(m_temperatureData); m_chart->addDataProxy(m_genericData); @@ -138,7 +140,6 @@ void ChartModifier::restart(bool dynamicData) m_chart->setRowAxis(m_yearAxis); m_chart->setColumnAxis(m_monthAxis); - m_chart->setDataWindow(m_years.size(), m_months.size()); m_chart->setSelectionMode(QDataVis::ModeItem); } else { m_chart->setActiveDataProxy(m_genericData); @@ -149,7 +150,6 @@ void ChartModifier::restart(bool dynamicData) m_chart->setRowAxis(m_genericRowAxis); m_chart->setColumnAxis(m_genericColumnAxis); - m_chart->setDataWindow(m_rowCount, m_columnCount); m_chart->setSelectionMode(QDataVis::ModeItem); } } @@ -205,18 +205,54 @@ void ChartModifier::releaseProxies() m_chart->releaseDataProxy(m_genericData); } +void ChartModifier::createMassiveArray() +{ + const int arrayDimension = 1000; + QTime timer; + timer.start(); + + QStringList genericColumnLabels; + for (int i = 0; i < arrayDimension; i++) { + if (i % 5) + genericColumnLabels << QString(); + else + genericColumnLabels << QStringLiteral("Column %1").arg(i); + } + + QStringList genericRowLabels; + for (int i = 0; i < arrayDimension; i++) { + if (i % 5) + genericRowLabels << QString(); + else + genericRowLabels << QStringLiteral("Row %1").arg(i); + } + + QBarDataArray *dataArray = new QBarDataArray; + 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)); + dataArray->append(dataRow); + } + + m_chart->activeDataProxy()->resetArray(dataArray, genericRowLabels, genericColumnLabels); + + qDebug() << "Created Massive Array (" << arrayDimension << "), time:" << timer.elapsed(); +} + void ChartModifier::resetTemperatureData() { // Set up data - static const float temp[7][12] = { - {-6.7f, -11.7f, -9.7f, 3.3f, 9.2f, 14.0f, 16.3f, 17.8f, 10.2f, 2.1f, -2.6f, -0.3f}, // 2006 - {-6.8f, -13.3f, 0.2f, 1.5f, 7.9f, 13.4f, 16.1f, 15.5f, 8.2f, 5.4f, -2.6f, -0.8f}, // 2007 - {-4.2f, -4.0f, -4.6f, 1.9f, 7.3f, 12.5f, 15.0f, 12.8f, 7.6f, 5.1f, -0.9f, -1.3f}, // 2008 - {-7.8f, -8.8f, -4.2f, 0.7f, 9.3f, 13.2f, 15.8f, 15.5f, 11.2f, 0.6f, 0.7f, -8.4f}, // 2009 - {-14.4f, -12.1f, -7.0f, 2.3f, 11.0f, 12.6f, 18.8f, 13.8f, 9.4f, 3.9f, -5.6f, -13.0f}, // 2010 - {-9.0f, -15.2f, -3.8f, 2.6f, 8.3f, 15.9f, 18.6f, 14.9f, 11.1f, 5.3f, 1.8f, -0.2f}, // 2011 - {-8.7f, -11.3f, -2.3f, 0.4f, 7.5f, 12.2f, 16.4f, 14.1f, 9.2f, 3.1f, 0.3f, -12.1f} // 2012 + static const qreal temp[7][12] = { + {-6.7, -11.7, -9.7, 3.3, 9.2, 14.0, 16.3, 17.8, 10.2, 2.1, -2.6, -0.3}, // 2006 + {-6.8, -13.3, 0.2, 1.5, 7.9, 13.4, 16.1, 15.5, 8.2, 5.4, -2.6, -0.8}, // 2007 + {-4.2, -4.0, -4.6, 1.9, 7.3, 12.5, 15.0, 12.8, 7.6, 5.1, -0.9, -1.3}, // 2008 + {-7.8, -8.8, -4.2, 0.7, 9.3, 13.2, 15.8, 15.5, 11.2, 0.6, 0.7, -8.4}, // 2009 + {-14.4, -12.1, -7.0, 2.3, 11.0, 12.6, 18.8, 13.8, 9.4, 3.9, -5.6, -13.0}, // 2010 + {-9.0, -15.2, -3.8, 2.6, 8.3, 15.9, 18.6, 14.9, 11.1, 5.3, 1.8, -0.2}, // 2011 + {-8.7, -11.3, -2.3, 0.4, 7.5, 12.2, 16.4, 14.1, 9.2, 3.1, 0.3, -12.1} // 2012 }; // Create data rows @@ -248,8 +284,8 @@ static int changeCounter = 0; void ChartModifier::addRow() { QBarDataRow *dataRow = new QBarDataRow(m_columnCount); - for (float i = 0; i < m_columnCount; i++) - (*dataRow)[i].setValue(((i + 1) / (float)m_columnCount) * (float)(rand() % 100)); + for (qreal i = 0; i < m_columnCount; i++) + (*dataRow)[i].setValue(((i + 1) / (qreal)m_columnCount) * (qreal)(rand() % 100)); // TODO Needs to be changed to account for data window offset once it is implemented. QString label = QStringLiteral("Add %1").arg(addCounter++); @@ -275,8 +311,8 @@ void ChartModifier::addRows() void ChartModifier::insertRow() { QBarDataRow *dataRow = new QBarDataRow(m_columnCount); - for (float i = 0; i < m_columnCount; i++) - (*dataRow)[i].setValue(((i + 1) / (float)m_columnCount) * (float)(rand() % 100)); + for (qreal i = 0; i < m_columnCount; i++) + (*dataRow)[i].setValue(((i + 1) / (qreal)m_columnCount) * (qreal)(rand() % 100)); // TODO Needs to be changed to account for data window offset once it is implemented. int row = qMax(m_selectedBarPos.x(), 0); @@ -509,24 +545,34 @@ void ChartModifier::setSpecsRatio(int barwidth) void ChartModifier::setSpacingSpecsX(int spacing) { - m_barSpacingX = (float)spacing / 100.0f; + m_barSpacingX = (qreal)spacing / 100.0; m_chart->setBarSpacing(QSizeF(m_barSpacingX, m_barSpacingZ)); } void ChartModifier::setSpacingSpecsZ(int spacing) { - m_barSpacingZ = (float)spacing / 100.0f; + m_barSpacingZ = (qreal)spacing / 100.0; m_chart->setBarSpacing(QSizeF(m_barSpacingX, m_barSpacingZ)); } void ChartModifier::setSampleCountX(int samples) { m_columnCount = samples; - m_chart->setDataWindow(m_rowCount, m_columnCount); + m_genericColumnAxis->setRange(m_genericRowAxis->min(), m_genericRowAxis->min() + samples - 1); } void ChartModifier::setSampleCountZ(int samples) { m_rowCount = samples; - m_chart->setDataWindow(m_rowCount, m_columnCount); + m_genericRowAxis->setRange(m_genericColumnAxis->min(), m_genericColumnAxis->min() + samples - 1); +} + +void ChartModifier::setMinX(int min) +{ + m_genericRowAxis->setRange(min, min + m_rowCount - 1); +} + +void ChartModifier::setMinZ(int min) +{ + m_genericColumnAxis->setRange(min, min + m_rowCount - 1); } diff --git a/tests/barstest/chart.h b/tests/barstest/chart.h index 65d404e0..8c8d9b81 100644 --- a/tests/barstest/chart.h +++ b/tests/barstest/chart.h @@ -62,12 +62,15 @@ public: void setSpacingSpecsZ(int spacing); void setSampleCountX(int samples); void setSampleCountZ(int samples); + void setMinX(int min); + void setMinZ(int min); void start(); void restart(bool dynamicData); void selectBar(); void swapAxis(); void releaseAxes(); void releaseProxies(); + void createMassiveArray(); public slots: void changeShadowQuality(int quality); @@ -81,11 +84,11 @@ private: Q3DBars *m_chart; int m_columnCount; int m_rowCount; - float m_xRotation; - float m_yRotation; + qreal m_xRotation; + qreal m_yRotation; bool m_static; - float m_barSpacingX; - float m_barSpacingZ; + qreal m_barSpacingX; + qreal m_barSpacingZ; int m_fontSize; int m_segments; int m_subSegments; diff --git a/tests/barstest/main.cpp b/tests/barstest/main.cpp index 39341471..0dd61c1d 100644 --- a/tests/barstest/main.cpp +++ b/tests/barstest/main.cpp @@ -87,9 +87,13 @@ int main(int argc, char **argv) removeRowButton->setEnabled(false); QPushButton *removeRowsButton = new QPushButton(widget); - removeRowsButton->setText(QStringLiteral("remove three rows from selected")); + removeRowsButton->setText(QStringLiteral("Remove three rows from selected")); removeRowsButton->setEnabled(false); + QPushButton *massiveArrayButton = new QPushButton(widget); + massiveArrayButton->setText(QStringLiteral("Create massive array")); + massiveArrayButton->setEnabled(false); + QPushButton *themeButton = new QPushButton(widget); themeButton->setText(QStringLiteral("Change theme")); @@ -167,17 +171,30 @@ int main(int argc, char **argv) QSlider *sampleSliderX = new QSlider(Qt::Horizontal, widget); sampleSliderX->setTickInterval(1); - sampleSliderX->setMinimum(2); - sampleSliderX->setValue(10); + sampleSliderX->setMinimum(1); + sampleSliderX->setValue(21); sampleSliderX->setMaximum(200); sampleSliderX->setEnabled(false); QSlider *sampleSliderZ = new QSlider(Qt::Horizontal, widget); sampleSliderZ->setTickInterval(1); - sampleSliderZ->setMinimum(2); - sampleSliderZ->setValue(10); + sampleSliderZ->setMinimum(1); + sampleSliderZ->setValue(21); sampleSliderZ->setMaximum(200); sampleSliderZ->setEnabled(false); + QSlider *minSliderX = new QSlider(Qt::Horizontal, widget); + minSliderX->setTickInterval(1); + minSliderX->setMinimum(0); + minSliderX->setValue(0); + minSliderX->setMaximum(200); + minSliderX->setEnabled(false); + QSlider *minSliderZ = new QSlider(Qt::Horizontal, widget); + minSliderZ->setTickInterval(1); + minSliderZ->setMinimum(0); + minSliderZ->setValue(0); + minSliderZ->setMaximum(200); + minSliderZ->setEnabled(false); + QSlider *fontSizeSlider = new QSlider(Qt::Horizontal, widget); fontSizeSlider->setTickInterval(1); fontSizeSlider->setMinimum(1); @@ -205,6 +222,7 @@ int main(int argc, char **argv) vLayout->addWidget(changeRowsButton, 0, Qt::AlignTop); vLayout->addWidget(removeRowButton, 0, Qt::AlignTop); vLayout->addWidget(removeRowsButton, 0, Qt::AlignTop); + vLayout->addWidget(massiveArrayButton, 0, Qt::AlignTop); vLayout->addWidget(themeButton, 0, Qt::AlignTop); vLayout->addWidget(labelButton, 0, Qt::AlignTop); vLayout->addWidget(styleButton, 0, Qt::AlignTop); @@ -227,6 +245,9 @@ int main(int argc, char **argv) vLayout2->addWidget(new QLabel(QStringLiteral("Adjust sample count")), 0, Qt::AlignTop); vLayout2->addWidget(sampleSliderX, 0, Qt::AlignTop); vLayout2->addWidget(sampleSliderZ, 0, Qt::AlignTop); + 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(backgroundCheckBox, 0, Qt::AlignTop); vLayout2->addWidget(gridCheckBox, 0, Qt::AlignTop); vLayout2->addWidget(new QLabel(QStringLiteral("Adjust shadow quality")), 0, Qt::AlignTop); @@ -255,6 +276,10 @@ int main(int argc, char **argv) &ChartModifier::setSampleCountX); QObject::connect(sampleSliderZ, &QSlider::valueChanged, modifier, &ChartModifier::setSampleCountZ); + QObject::connect(minSliderX, &QSlider::valueChanged, modifier, + &ChartModifier::setMinX); + QObject::connect(minSliderZ, &QSlider::valueChanged, modifier, + &ChartModifier::setMinZ); QObject::connect(shadowQuality, SIGNAL(currentIndexChanged(int)), modifier, SLOT(changeShadowQuality(int))); @@ -283,6 +308,7 @@ int main(int argc, char **argv) QObject::connect(changeRowsButton, &QPushButton::clicked, modifier, &ChartModifier::changeRows); QObject::connect(removeRowButton, &QPushButton::clicked, modifier, &ChartModifier::removeRow); QObject::connect(removeRowsButton, &QPushButton::clicked, modifier, &ChartModifier::removeRows); + QObject::connect(massiveArrayButton, &QPushButton::clicked, modifier, &ChartModifier::createMassiveArray); QObject::connect(selectionButton, &QPushButton::clicked, modifier, &ChartModifier::changeSelectionMode); QObject::connect(setSelectedBarButton, &QPushButton::clicked, modifier, @@ -329,10 +355,16 @@ int main(int argc, char **argv) &QPushButton::setEnabled); QObject::connect(staticCheckBox, &QCheckBox::stateChanged, removeRowsButton, &QPushButton::setEnabled); + QObject::connect(staticCheckBox, &QCheckBox::stateChanged, massiveArrayButton, + &QPushButton::setEnabled); QObject::connect(staticCheckBox, &QCheckBox::stateChanged, sampleSliderX, &QSlider::setEnabled); QObject::connect(staticCheckBox, &QCheckBox::stateChanged, sampleSliderZ, &QSlider::setEnabled); + QObject::connect(staticCheckBox, &QCheckBox::stateChanged, minSliderX, + &QSlider::setEnabled); + QObject::connect(staticCheckBox, &QCheckBox::stateChanged, minSliderZ, + &QSlider::setEnabled); QObject::connect(staticCheckBox, &QCheckBox::stateChanged, swapAxisButton, &QSlider::setEnabled); QObject::connect(staticCheckBox, &QCheckBox::stateChanged, modifier, &ChartModifier::restart); diff --git a/tests/spectrum/spectrumapp/main.cpp b/tests/spectrum/spectrumapp/main.cpp index 51e864e8..c6e2e04f 100644 --- a/tests/spectrum/spectrumapp/main.cpp +++ b/tests/spectrum/spectrumapp/main.cpp @@ -22,6 +22,7 @@ #include <QtDataVisualization/q3dbars.h> #include <QtDataVisualization/qbardataproxy.h> #include <QtDataVisualization/q3dvalueaxis.h> +#include <QtDataVisualization/q3dcategoryaxis.h> #include <QGuiApplication> #include <QAudio> @@ -66,7 +67,8 @@ MainApp::MainApp(Q3DBars *window) m_lowFreq(SpectrumLowFreq), m_highFreq(SpectrumHighFreq) { - m_chart->setDataWindow(SpectrumNumBands * 2, SpectrumNumBands); + m_chart->rowAxis()->setMax(SpectrumNumBands * 2); + m_chart->columnAxis()->setMax(SpectrumNumBands - 1); // Disable grid m_chart->setGridVisible(false); // Disable auto-scaling of height by defining explicit range |