summaryrefslogtreecommitdiff
path: root/chart2/source/tools/MovingAverageRegressionCurveCalculator.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'chart2/source/tools/MovingAverageRegressionCurveCalculator.cxx')
-rw-r--r--chart2/source/tools/MovingAverageRegressionCurveCalculator.cxx109
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