diff options
Diffstat (limited to 'chart2/source/tools/MovingAverageRegressionCurveCalculator.cxx')
-rw-r--r-- | chart2/source/tools/MovingAverageRegressionCurveCalculator.cxx | 109 |
1 files changed, 89 insertions, 20 deletions
diff --git a/chart2/source/tools/MovingAverageRegressionCurveCalculator.cxx b/chart2/source/tools/MovingAverageRegressionCurveCalculator.cxx index 7774bec02a4f..f71262f738b9 100644 --- a/chart2/source/tools/MovingAverageRegressionCurveCalculator.cxx +++ b/chart2/source/tools/MovingAverageRegressionCurveCalculator.cxx @@ -22,9 +22,13 @@ #include <ResId.hxx> #include <strings.hrc> -#include <rtl/math.hxx> +#include <algorithm> +#include <limits> + +#include <com/sun/star/chart2/MovingAverageType.hpp> using namespace ::com::sun::star; +using namespace ::com::sun::star::chart2; namespace chart { @@ -40,40 +44,100 @@ void SAL_CALL MovingAverageRegressionCurveCalculator::recalculateRegression( const uno::Sequence< double >& aXValues, const uno::Sequence< double >& aYValues ) { - ::rtl::math::setNan( & m_fCorrelationCoefficient ); + m_fCorrelationCoefficient = std::numeric_limits<double>::quiet_NaN(); RegressionCalculationHelper::tDoubleVectorPair aValues( RegressionCalculationHelper::cleanup( aXValues, aYValues, RegressionCalculationHelper::isValid())); - const size_t aSize = aValues.first.size(); - aYList.clear(); aXList.clear(); - for( size_t i = mPeriod - 1; i < aSize; ++i ) + // For formulas, see + // https://docs.oasis-open.org/office/OpenDocument/v1.3/cs02/part3-schema/OpenDocument-v1.3-cs02-part3-schema.html#property-chart_regression-moving-type + + switch (mnMovingType) { - double yAvg; - yAvg = 0.0; + case MovingAverageType::Central: + { + + calculateValuesCentral(std::move(aValues)); + break; + } + + case MovingAverageType::AveragedAbscissa: + { + calculateValues(std::move(aValues), true); + break; + } + case MovingAverageType::Prior: + default: + { + calculateValues(std::move(aValues), false); + break; + } + } +} + +void MovingAverageRegressionCurveCalculator::calculateValuesCentral( + RegressionCalculationHelper::tDoubleVectorPair aValues) +{ + const size_t aSize = aValues.first.size(); + if (aSize == 0) + return; + for (size_t i = mPeriod - 1; i < aSize; ++i) + { + double yAvg = 0.0; for (sal_Int32 j = 0; j < mPeriod; j++) { yAvg += aValues.second[i - j]; } yAvg /= mPeriod; - - double x = aValues.first[i]; aYList.push_back(yAvg); + } + sal_Int32 nPeriodLocal = (mPeriod % 2 == 0) ? (mPeriod / 2) : ((mPeriod - 1) / 2); + for (size_t i = nPeriodLocal; i < aSize - 1; ++i) + { + double x = aValues.first[i]; aXList.push_back(x); } } +void MovingAverageRegressionCurveCalculator::calculateValues( + RegressionCalculationHelper::tDoubleVectorPair aValues, bool bUseXAvg) +{ + const size_t aSize = aValues.first.size(); + for (size_t i = mPeriod - 1; i < aSize; ++i) + { + double xAvg = 0.0; + double yAvg = 0.0; + + for (sal_Int32 j = 0; j < mPeriod; j++) + { + xAvg += aValues.first[i - j]; + yAvg += aValues.second[i - j]; + } + yAvg /= mPeriod; + xAvg /= mPeriod; + + aYList.push_back(yAvg); + if (bUseXAvg) + { + aXList.push_back(xAvg); + } + else + { + double x = aValues.first[i]; + aXList.push_back(x); + } + } +} + double SAL_CALL MovingAverageRegressionCurveCalculator::getCurveValue( double /*x*/ ) { - double fResult; - rtl::math::setNan(&fResult); - return fResult; + return std::numeric_limits<double>::quiet_NaN(); } uno::Sequence< geometry::RealPoint2D > SAL_CALL MovingAverageRegressionCurveCalculator::getCurveValues( @@ -82,13 +146,10 @@ uno::Sequence< geometry::RealPoint2D > SAL_CALL MovingAverageRegressionCurveCalc const uno::Reference< chart2::XScaling >& /*xScalingY*/, sal_Bool /*bMaySkipPointsInCalculation*/ ) { - uno::Sequence< geometry::RealPoint2D > aResult( aYList.size() ); - - for( size_t i = 0; i < aYList.size(); ++i ) - { - aResult[i].X = aXList[i]; - aResult[i].Y = aYList[i]; - } + size_t nSize = std::min(aXList.size(), aYList.size()); + uno::Sequence< geometry::RealPoint2D > aResult( nSize ); + std::transform(aXList.begin(), aXList.begin() + nSize, aYList.begin(), aResult.getArray(), + [](const auto& x, const auto& y) { return geometry::RealPoint2D(x, y); }); return aResult; } @@ -96,7 +157,15 @@ OUString MovingAverageRegressionCurveCalculator::ImplGetRepresentation( const uno::Reference< util::XNumberFormatter >& /*xNumFormatter*/, sal_Int32 /*nNumberFormatKey*/, sal_Int32* /*pFormulaLength = nullptr */ ) const { - return SchResId( STR_OBJECT_MOVING_AVERAGE_WITH_PARAMETERS ); + OUString aRet = SchResId( STR_OBJECT_MOVING_AVERAGE_WITH_PARAMETERS ); + // change text for Moving Average + OUString aWildcard( "%PERIOD" ); + sal_Int32 nIndex = aRet.indexOf( aWildcard ); + if( nIndex != -1 ) + { // replace period + aRet = aRet.replaceAt( nIndex, aWildcard.getLength(), OUString::number(mPeriod) ); + } + return aRet; } } // namespace chart |