diff options
author | Laurent Balland-Poirier <laurent.balland-poirier@laposte.net> | 2016-03-11 23:28:35 +0100 |
---|---|---|
committer | Markus Mohrhard <markus.mohrhard@googlemail.com> | 2016-05-22 19:12:07 +0000 |
commit | 033b2ae8775d1dcf49f798e267761000cc51627c (patch) | |
tree | 83e276940761096572bc75875a381ffe4d88b13c /chart2/source | |
parent | beeb71085036d09494e44f43670d6d26f30c6277 (diff) |
tdf#94004 Trendline: wrap equation to fit in chart area
If equation is too long compared to chart width:
equation is wrapped
and if equation has General format, the number of digits is reduced
In this patch, only polynomial equation is treated. If this approach is ok,
I will extend to other regression curves.
Conflicts:
chart2/source/view/charttypes/VSeriesPlotter.cxx
Change-Id: I1bfd897881d752655faec6df034c0dde7f78c51b
Reviewed-on: https://gerrit.libreoffice.org/18397
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Markus Mohrhard <markus.mohrhard@googlemail.com>
Diffstat (limited to 'chart2/source')
15 files changed, 246 insertions, 109 deletions
diff --git a/chart2/source/inc/ExponentialRegressionCurveCalculator.hxx b/chart2/source/inc/ExponentialRegressionCurveCalculator.hxx index c62af6d4b301..d3746757d8ca 100644 --- a/chart2/source/inc/ExponentialRegressionCurveCalculator.hxx +++ b/chart2/source/inc/ExponentialRegressionCurveCalculator.hxx @@ -33,7 +33,7 @@ public: protected: virtual OUString ImplGetRepresentation( const css::uno::Reference<css::util::XNumberFormatter>& xNumFormatter, - sal_Int32 nNumberFormatKey ) const override; + sal_Int32 nNumberFormatKey, sal_Int32* pFormulaLength = nullptr ) const override; private: // ____ XRegressionCurveCalculator ____ diff --git a/chart2/source/inc/LogarithmicRegressionCurveCalculator.hxx b/chart2/source/inc/LogarithmicRegressionCurveCalculator.hxx index f8bda777535c..922562fa3c85 100644 --- a/chart2/source/inc/LogarithmicRegressionCurveCalculator.hxx +++ b/chart2/source/inc/LogarithmicRegressionCurveCalculator.hxx @@ -33,7 +33,7 @@ public: protected: virtual OUString ImplGetRepresentation( const css::uno::Reference<css::util::XNumberFormatter>& xNumFormatter, - sal_Int32 nNumberFormatKey ) const override; + sal_Int32 nNumberFormatKey, sal_Int32* pFormulaLength = nullptr ) const override; private: // ____ XRegressionCurveCalculator ____ diff --git a/chart2/source/inc/MeanValueRegressionCurveCalculator.hxx b/chart2/source/inc/MeanValueRegressionCurveCalculator.hxx index c0fb501ff9e7..fbd307735d7e 100644 --- a/chart2/source/inc/MeanValueRegressionCurveCalculator.hxx +++ b/chart2/source/inc/MeanValueRegressionCurveCalculator.hxx @@ -33,7 +33,7 @@ public: protected: virtual OUString ImplGetRepresentation( const css::uno::Reference<css::util::XNumberFormatter>& xNumFormatter, - sal_Int32 nNumberFormatKey ) const override; + sal_Int32 nNumberFormatKey, sal_Int32* pFormulaLength = nullptr ) const override; private: // ____ XRegressionCurveCalculator ____ diff --git a/chart2/source/inc/MovingAverageRegressionCurveCalculator.hxx b/chart2/source/inc/MovingAverageRegressionCurveCalculator.hxx index 81ee90cd2175..ccfcc7adf636 100644 --- a/chart2/source/inc/MovingAverageRegressionCurveCalculator.hxx +++ b/chart2/source/inc/MovingAverageRegressionCurveCalculator.hxx @@ -34,7 +34,7 @@ public: protected: virtual OUString ImplGetRepresentation( const css::uno::Reference<css::util::XNumberFormatter>& xNumFormatter, - sal_Int32 nNumberFormatKey ) const override; + sal_Int32 nNumberFormatKey, sal_Int32* pFormulaLength = nullptr ) const override; private: // ____ XRegressionCurveCalculator ____ diff --git a/chart2/source/inc/PolynomialRegressionCurveCalculator.hxx b/chart2/source/inc/PolynomialRegressionCurveCalculator.hxx index f6858f2319b6..81b580409f31 100644 --- a/chart2/source/inc/PolynomialRegressionCurveCalculator.hxx +++ b/chart2/source/inc/PolynomialRegressionCurveCalculator.hxx @@ -34,7 +34,7 @@ public: protected: virtual OUString ImplGetRepresentation( const css::uno::Reference<css::util::XNumberFormatter>& xNumFormatter, - sal_Int32 nNumberFormatKey ) const override; + sal_Int32 nNumberFormatKey, sal_Int32* pFormulaMaxWidth = nullptr ) const override; virtual double SAL_CALL getCurveValue( double x ) throw (css::lang::IllegalArgumentException, diff --git a/chart2/source/inc/PotentialRegressionCurveCalculator.hxx b/chart2/source/inc/PotentialRegressionCurveCalculator.hxx index 1051d11d8678..a201152234b1 100644 --- a/chart2/source/inc/PotentialRegressionCurveCalculator.hxx +++ b/chart2/source/inc/PotentialRegressionCurveCalculator.hxx @@ -34,7 +34,7 @@ public: protected: virtual OUString ImplGetRepresentation( const css::uno::Reference<css::util::XNumberFormatter>& xNumFormatter, - sal_Int32 nNumberFormatKey ) const override; + sal_Int32 nNumberFormatKey, sal_Int32* pFormulaLength = nullptr ) const override; private: // ____ XRegressionCurveCalculator ____ diff --git a/chart2/source/inc/RegressionCurveCalculator.hxx b/chart2/source/inc/RegressionCurveCalculator.hxx index afd0164e15fc..f40587fdca82 100644 --- a/chart2/source/inc/RegressionCurveCalculator.hxx +++ b/chart2/source/inc/RegressionCurveCalculator.hxx @@ -20,6 +20,7 @@ #define INCLUDED_CHART2_SOURCE_INC_REGRESSIONCURVECALCULATOR_HXX #include <cppuhelper/implbase.hxx> +#include <rtl/ustrbuf.hxx> #include <com/sun/star/chart2/XRegressionCurveCalculator.hpp> #include <com/sun/star/util/XNumberFormatter.hpp> @@ -43,12 +44,15 @@ public: protected: virtual OUString ImplGetRepresentation( const css::uno::Reference< css::util::XNumberFormatter >& xNumFormatter, - sal_Int32 nNumberFormatKey ) const = 0; + sal_Int32 nNumberFormatKey, sal_Int32* pFormulaLength = nullptr ) const = 0; static OUString getFormattedString( const css::uno::Reference< css::util::XNumberFormatter >& xNumFormatter, sal_Int32 nNumberFormatKey, - double fNumber ); + double fNumber, + sal_Int32* pStringLength = nullptr ); + + static void addStringToEquation( OUStringBuffer& aStrEquation, sal_Int32& nLineLength, OUStringBuffer& aAddString, sal_Int32* pMaxLength ); double m_fCorrelationCoeffitient; @@ -92,7 +96,7 @@ protected: virtual OUString SAL_CALL getFormattedRepresentation( const css::uno::Reference< css::util::XNumberFormatsSupplier >& xNumFmtSupplier, - sal_Int32 nNumberFormatKey ) + sal_Int32 nNumberFormatKey, sal_Int32 nFormulaLength ) throw (css::uno::RuntimeException, std::exception) override; }; diff --git a/chart2/source/tools/ExponentialRegressionCurveCalculator.cxx b/chart2/source/tools/ExponentialRegressionCurveCalculator.cxx index 0c79ff4cef27..75e92aa79536 100644 --- a/chart2/source/tools/ExponentialRegressionCurveCalculator.cxx +++ b/chart2/source/tools/ExponentialRegressionCurveCalculator.cxx @@ -154,7 +154,7 @@ uno::Sequence< geometry::RealPoint2D > SAL_CALL ExponentialRegressionCurveCalcul OUString ExponentialRegressionCurveCalculator::ImplGetRepresentation( const uno::Reference< util::XNumberFormatter >& xNumFormatter, - ::sal_Int32 nNumberFormatKey ) const + sal_Int32 nNumberFormatKey, sal_Int32* /*pFormulaLength = nullptr */ ) const { double fIntercept = m_fSign * exp(m_fLogIntercept); bool bHasSlope = !rtl::math::approxEqual( exp(m_fLogSlope), 1.0 ); diff --git a/chart2/source/tools/LogarithmicRegressionCurveCalculator.cxx b/chart2/source/tools/LogarithmicRegressionCurveCalculator.cxx index 3370454bcbe6..e2ca7d4bfe8d 100644 --- a/chart2/source/tools/LogarithmicRegressionCurveCalculator.cxx +++ b/chart2/source/tools/LogarithmicRegressionCurveCalculator.cxx @@ -130,7 +130,7 @@ uno::Sequence< geometry::RealPoint2D > SAL_CALL LogarithmicRegressionCurveCalcul OUString LogarithmicRegressionCurveCalculator::ImplGetRepresentation( const uno::Reference< util::XNumberFormatter >& xNumFormatter, - ::sal_Int32 nNumberFormatKey ) const + sal_Int32 nNumberFormatKey, sal_Int32* /* pFormulaLength = nullptr */ ) const { OUStringBuffer aBuf( "f(x) = "); diff --git a/chart2/source/tools/MeanValueRegressionCurveCalculator.cxx b/chart2/source/tools/MeanValueRegressionCurveCalculator.cxx index b40243e373ff..4703fe4f8af2 100644 --- a/chart2/source/tools/MeanValueRegressionCurveCalculator.cxx +++ b/chart2/source/tools/MeanValueRegressionCurveCalculator.cxx @@ -23,6 +23,7 @@ #include <osl/diagnose.h> #include <rtl/math.hxx> #include <rtl/ustrbuf.hxx> +#include <SpecialUnicodes.hxx> using namespace ::com::sun::star; @@ -118,12 +119,16 @@ uno::Sequence< geometry::RealPoint2D > SAL_CALL MeanValueRegressionCurveCalculat OUString MeanValueRegressionCurveCalculator::ImplGetRepresentation( const uno::Reference< util::XNumberFormatter >& xNumFormatter, - ::sal_Int32 nNumberFormatKey ) const + sal_Int32 nNumberFormatKey, sal_Int32* pFormulaLength /* = nullptr */ ) const { - OUString aBuf = "f(x) = " + - getFormattedString( xNumFormatter, nNumberFormatKey, m_fMeanValue ); - - return aBuf; + OUString aBuf = "f(x) = "; + if ( pFormulaLength ) + { + *pFormulaLength -= aBuf.getLength(); + if ( *pFormulaLength <= 0 ) + return aHashString; + } + return ( aBuf + getFormattedString( xNumFormatter, nNumberFormatKey, m_fMeanValue, pFormulaLength ) ); } } // namespace chart diff --git a/chart2/source/tools/MovingAverageRegressionCurveCalculator.cxx b/chart2/source/tools/MovingAverageRegressionCurveCalculator.cxx index 410f8d6be021..dac1616b7ab7 100644 --- a/chart2/source/tools/MovingAverageRegressionCurveCalculator.cxx +++ b/chart2/source/tools/MovingAverageRegressionCurveCalculator.cxx @@ -101,7 +101,7 @@ uno::Sequence< geometry::RealPoint2D > SAL_CALL MovingAverageRegressionCurveCalc OUString MovingAverageRegressionCurveCalculator::ImplGetRepresentation( const uno::Reference< util::XNumberFormatter >& /*xNumFormatter*/, - ::sal_Int32 /*nNumberFormatKey*/ ) const + sal_Int32 /*nNumberFormatKey*/, sal_Int32* /*pFormulaLength = nullptr */ ) const { return SCH_RESSTR( STR_OBJECT_MOVING_AVERAGE_WITH_PARAMETERS ); } diff --git a/chart2/source/tools/PolynomialRegressionCurveCalculator.cxx b/chart2/source/tools/PolynomialRegressionCurveCalculator.cxx index 6dba3a26fa27..2a135b1f4277 100644 --- a/chart2/source/tools/PolynomialRegressionCurveCalculator.cxx +++ b/chart2/source/tools/PolynomialRegressionCurveCalculator.cxx @@ -27,7 +27,6 @@ #include <SpecialUnicodes.hxx> - using namespace com::sun::star; namespace chart @@ -236,15 +235,53 @@ uno::Sequence< geometry::RealPoint2D > SAL_CALL PolynomialRegressionCurveCalcula OUString PolynomialRegressionCurveCalculator::ImplGetRepresentation( const uno::Reference< util::XNumberFormatter >& xNumFormatter, - sal_Int32 nNumberFormatKey ) const + sal_Int32 nNumberFormatKey, sal_Int32* pFormulaMaxWidth /* = nullptr */ ) const { OUStringBuffer aBuf( "f(x) = " ); + sal_Int32 nValueLength=0; sal_Int32 aLastIndex = mCoefficients.size() - 1; + + if ( pFormulaMaxWidth && *pFormulaMaxWidth > 0 ) + { + sal_Int32 nCharMin = aBuf.getLength(); // count characters different from coefficients + double nCoefficients = aLastIndex + 1.0; // number of coefficients + for (sal_Int32 i = aLastIndex; i >= 0; i--) + { + double aValue = mCoefficients[i]; + if ( aValue == 0.0 ) + { // do not count coeffitient if it is 0 + nCoefficients --; + continue; + } + if ( rtl::math::approxEqual( fabs( aValue ) , 1.0 ) ) + { // do not count coeffitient if it is 1 + nCoefficients --; + if ( i == 0 ) // intercept = 1 + nCharMin ++; + } + if ( i != aLastIndex ) + nCharMin += 3; // " + " + if ( i > 0 ) + { + nCharMin += 1; // "x" + if ( i > 1 ) + nCharMin +=1; // "^i" + if ( i >= 10 ) + nCharMin ++; // 2 digits for i + } + } + nValueLength = ( *pFormulaMaxWidth - nCharMin ) / nCoefficients; + if ( nValueLength <= 0 ) + nValueLength = 1; + } + bool bFindValue = false; + sal_Int32 nLineLength = aBuf.getLength(); for (sal_Int32 i = aLastIndex; i >= 0; i--) { double aValue = mCoefficients[i]; + OUStringBuffer aTmpBuf(""); // temporary buffer if (aValue == 0.0) { continue; @@ -252,38 +289,42 @@ OUString PolynomialRegressionCurveCalculator::ImplGetRepresentation( else if (aValue < 0.0) { if ( bFindValue ) // if it is not the first aValue - aBuf.append( " " ); - aBuf.append( aMinusSign + " "); + aTmpBuf.append( " " ); + aTmpBuf.append( aMinusSign + " "); aValue = - aValue; } else { if ( bFindValue ) // if it is not the first aValue - aBuf.append( " + " ); + aTmpBuf.append( " + " ); } bFindValue = true; - if ( i == 0 || !rtl::math::approxEqual( aValue , 1.0 ) ) - aBuf.append( getFormattedString( xNumFormatter, nNumberFormatKey, aValue ) ); + // if nValueLength not calculated then nullptr + sal_Int32* pValueLength = nValueLength ? &nValueLength : nullptr; + OUString aValueString = getFormattedString( xNumFormatter, nNumberFormatKey, aValue, pValueLength ); + if ( i == 0 || aValueString != "1" ) // aValueString may be rounded to 1 if nValueLength is small + aTmpBuf.append( aValueString ); if(i > 0) { - aBuf.append( "x" ); + aTmpBuf.append( "x" ); if (i > 1) { if (i < 10) // simple case if only one digit - aBuf.append( aSuperscriptFigures[ i ] ); + aTmpBuf.append( aSuperscriptFigures[ i ] ); else { OUString aValueOfi = OUString::number( i ); for ( sal_Int32 n = 0; n < aValueOfi.getLength() ; n++ ) { sal_Int32 nIndex = aValueOfi[n] - sal_Unicode ( '0' ); - aBuf.append( aSuperscriptFigures[ nIndex ] ); + aTmpBuf.append( aSuperscriptFigures[ nIndex ] ); } } } } + addStringToEquation( aBuf, nLineLength, aTmpBuf, pFormulaMaxWidth ); } if ( aBuf.toString() == "f(x) = " ) aBuf.append( "0" ); diff --git a/chart2/source/tools/PotentialRegressionCurveCalculator.cxx b/chart2/source/tools/PotentialRegressionCurveCalculator.cxx index 1a9c2be98a14..8ea92c1d8909 100644 --- a/chart2/source/tools/PotentialRegressionCurveCalculator.cxx +++ b/chart2/source/tools/PotentialRegressionCurveCalculator.cxx @@ -142,7 +142,7 @@ uno::Sequence< geometry::RealPoint2D > SAL_CALL PotentialRegressionCurveCalculat OUString PotentialRegressionCurveCalculator::ImplGetRepresentation( const uno::Reference< util::XNumberFormatter >& xNumFormatter, - ::sal_Int32 nNumberFormatKey ) const + sal_Int32 nNumberFormatKey, sal_Int32* /* pFormulaLength = nullptr */ ) const { OUStringBuffer aBuf( "f(x) = "); diff --git a/chart2/source/tools/RegressionCurveCalculator.cxx b/chart2/source/tools/RegressionCurveCalculator.cxx index 1ecb681d8289..09f03cc1d00c 100644 --- a/chart2/source/tools/RegressionCurveCalculator.cxx +++ b/chart2/source/tools/RegressionCurveCalculator.cxx @@ -27,6 +27,11 @@ #include <com/sun/star/lang/XServiceName.hpp> #include <com/sun/star/util/NumberFormatter.hpp> +#include <comphelper/numbers.hxx> +#include <comphelper/extract.hxx> + +#include <SpecialUnicodes.hxx> + using namespace ::com::sun::star; using ::com::sun::star::uno::Reference; @@ -82,17 +87,46 @@ void RegressionCurveCalculator::setRegressionProperties( OUString RegressionCurveCalculator::getFormattedString( const Reference< util::XNumberFormatter >& xNumFormatter, sal_Int32 nNumberFormatKey, - double fNumber ) + double fNumber, sal_Int32* pStringLength /* = nullptr */ ) { + if ( pStringLength && *pStringLength <= 0 ) + return aHashString; OUString aResult; - if( xNumFormatter.is()) + if( xNumFormatter.is() ) + { + bool bStandard = ::cppu::any2bool( ::comphelper::getNumberFormatProperty( xNumFormatter, nNumberFormatKey, "StandardFormat" ) ); + if( pStringLength && bStandard ) + { // round fNumber to *pStringLength characters + const sal_Int32 nMinDigit = 6; // minimum significant digits for General format + sal_Int32 nSignificantDigit = ( *pStringLength <= nMinDigit ? nMinDigit : *pStringLength ); + aResult = OStringToOUString( + ::rtl::math::doubleToString( fNumber, rtl_math_StringFormat_G1, nSignificantDigit, '.', true ), + RTL_TEXTENCODING_ASCII_US ); + // count characters different from significant digits (decimal separator, scientific notation) + sal_Int32 nExtraChar = aResult.getLength() - *pStringLength; + if ( nExtraChar > 0 && *pStringLength > nMinDigit ) + { + nSignificantDigit = *pStringLength - nExtraChar; + if ( nSignificantDigit < nMinDigit ) + nSignificantDigit = nMinDigit; + aResult = OStringToOUString( + ::rtl::math::doubleToString( fNumber, rtl_math_StringFormat_G1, nSignificantDigit, '.', true ), + RTL_TEXTENCODING_ASCII_US ); + } + fNumber = ::rtl::math::stringToDouble( aResult, '.', ',' ); + } aResult = xNumFormatter->convertNumberToString( nNumberFormatKey, fNumber ); + } else + { + sal_Int32 nStringLength = 4; // default length + if ( pStringLength ) + nStringLength = *pStringLength; aResult = OStringToOUString( - ::rtl::math::doubleToString( fNumber, rtl_math_StringFormat_G1, 4, '.', true ), + ::rtl::math::doubleToString( fNumber, rtl_math_StringFormat_G1, nStringLength, '.', true ), RTL_TEXTENCODING_ASCII_US ); - + } return aResult; } @@ -150,8 +184,8 @@ OUString SAL_CALL RegressionCurveCalculator::getRepresentation() OUString SAL_CALL RegressionCurveCalculator::getFormattedRepresentation( const Reference< util::XNumberFormatsSupplier > & xNumFmtSupplier, - sal_Int32 nNumberFormatKey ) - throw (uno::RuntimeException, std::exception) + sal_Int32 nNumberFormatKey, sal_Int32 nFormulaLength ) +throw (uno::RuntimeException, std::exception) { // create and prepare a number formatter if( !xNumFmtSupplier.is()) @@ -160,9 +194,23 @@ OUString SAL_CALL RegressionCurveCalculator::getFormattedRepresentation( Reference< util::XNumberFormatter > xNumFormatter( util::NumberFormatter::create(xContext), uno::UNO_QUERY_THROW ); xNumFormatter->attachNumberFormatsSupplier( xNumFmtSupplier ); + if ( nFormulaLength > 0 ) + return ImplGetRepresentation( xNumFormatter, nNumberFormatKey, &nFormulaLength ); return ImplGetRepresentation( xNumFormatter, nNumberFormatKey ); } +void RegressionCurveCalculator::addStringToEquation( + OUStringBuffer& aStrEquation, sal_Int32& nLineLength, OUStringBuffer& aAddString, sal_Int32* pMaxWidth) +{ + if ( pMaxWidth && ( nLineLength + aAddString.getLength() > *pMaxWidth ) ) + { // wrap line + aStrEquation.append( aNewLine + " " ); // start new line with a blank + nLineLength = 1; + } + aStrEquation.append( aAddString ); + nLineLength += aAddString.getLength(); +} + } // namespace chart /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/chart2/source/view/charttypes/VSeriesPlotter.cxx b/chart2/source/view/charttypes/VSeriesPlotter.cxx index 62966d3e790f..4d17b16e7ecd 100644 --- a/chart2/source/view/charttypes/VSeriesPlotter.cxx +++ b/chart2/source/view/charttypes/VSeriesPlotter.cxx @@ -20,6 +20,7 @@ #include "VSeriesPlotter.hxx" #include "AbstractShapeFactory.hxx" #include "chartview/ExplicitValueProvider.hxx" +#include <svl/zformat.hxx> #include "CommonConverters.hxx" #include "macros.hxx" @@ -52,6 +53,7 @@ #include "BubbleChart.hxx" #include "NetChart.hxx" #include <unonames.hxx> +#include <SpecialUnicodes.hxx> #include <com/sun/star/chart/ErrorBarStyle.hpp> #include <com/sun/star/chart/TimeUnit.hpp> @@ -407,7 +409,6 @@ OUString VSeriesPlotter::getLabelTextForValue( VDataSeries& rDataSeries } else { - const LocaleDataWrapper& rLocaleDataWrapper = Application::GetSettings().GetLocaleDataWrapper(); const OUString& aNumDecimalSep = rLocaleDataWrapper.getNumDecimalSep(); assert(aNumDecimalSep.getLength() > 0); @@ -1207,6 +1208,25 @@ void VSeriesPlotter::createRegressionCurvesShapes( VDataSeries& rVDataSeries, } } +sal_Int32 lcl_getOUStringMaxLineLength ( OUStringBuffer& aString ) +{ + const sal_Int32 nStringLength = aString.getLength(); + sal_Int32 nMaxLineLength = 0; + + for ( sal_Int32 i=0; i<nStringLength; i++ ) + { + sal_Int32 indexSep = aString.indexOf( aNewLine, i ); + if ( indexSep < 0 ) + indexSep = nStringLength; + sal_Int32 nLineLength = indexSep - i; + if ( nLineLength > nMaxLineLength ) + nMaxLineLength = nLineLength; + i = indexSep; + } + + return nMaxLineLength; +} + void VSeriesPlotter::createRegressionCurveEquationShapes( const OUString & rEquationCID, const uno::Reference< beans::XPropertySet > & xEquationProperties, @@ -1220,7 +1240,6 @@ void VSeriesPlotter::createRegressionCurveEquationShapes( bool bShowEquation = false; bool bShowCorrCoeff = false; - OUString aSep( "\n" ); if(( xEquationProperties->getPropertyValue( "ShowEquation") >>= bShowEquation ) && ( xEquationProperties->getPropertyValue( "ShowCorrelationCoefficient") >>= bShowCorrCoeff )) { @@ -1229,93 +1248,113 @@ void VSeriesPlotter::createRegressionCurveEquationShapes( OUStringBuffer aFormula; sal_Int32 nNumberFormatKey = 0; + sal_Int32 nFormulaWidth = 0; xEquationProperties->getPropertyValue(CHART_UNONAME_NUMFMT) >>= nNumberFormatKey; + bool bResizeEquation = true; + sal_Int32 nMaxIteration = 2; - if( bShowEquation ) + for ( sal_Int32 nCountIteration = 0; bResizeEquation && nCountIteration < nMaxIteration ; nCountIteration++ ) { - if( m_apNumberFormatterWrapper.get()) - { - aFormula = xRegressionCurveCalculator->getFormattedRepresentation( - m_apNumberFormatterWrapper->getNumberFormatsSupplier(), - nNumberFormatKey ); - } - else + bResizeEquation = false; + if( bShowEquation ) { - aFormula = xRegressionCurveCalculator->getRepresentation(); - } + if( m_apNumberFormatterWrapper.get()) + { // iteration 0: default representation (no wrap) + // iteration 1: expected width (nFormulaWidth) is calculated + aFormula = xRegressionCurveCalculator->getFormattedRepresentation( + m_apNumberFormatterWrapper->getNumberFormatsSupplier(), + nNumberFormatKey, nFormulaWidth ); + nFormulaWidth = lcl_getOUStringMaxLineLength( aFormula ); + } + else + { + aFormula = xRegressionCurveCalculator->getRepresentation(); + } + if( bShowCorrCoeff ) + { + aFormula.append( aNewLine ); + } + } if( bShowCorrCoeff ) { - aFormula.append( aSep ); + aFormula.append( "R" + OUString( aSuperscriptFigures[2] ) + " = " ); + double fR( xRegressionCurveCalculator->getCorrelationCoefficient()); + if( m_apNumberFormatterWrapper.get()) + { + sal_Int32 nLabelCol = 0; + bool bColChanged; + aFormula.append( + m_apNumberFormatterWrapper->getFormattedString( + nNumberFormatKey, fR*fR, nLabelCol, bColChanged )); + //@todo: change color of label if bColChanged is true + } + else + { + const LocaleDataWrapper& rLocaleDataWrapper = Application::GetSettings().GetLocaleDataWrapper(); + const OUString& aNumDecimalSep = rLocaleDataWrapper.getNumDecimalSep(); + assert(aNumDecimalSep.getLength() > 0); + sal_Unicode aDecimalSep = aNumDecimalSep.getStr()[0]; + aFormula.append( ::rtl::math::doubleToUString( + fR*fR, rtl_math_StringFormat_G, 4, aDecimalSep, true )); + } } - } - if( bShowCorrCoeff ) - { - aFormula.append( "R" ); - aFormula.append( sal_Unicode( 0x00b2 )); - aFormula.append( " = "); - double fR( xRegressionCurveCalculator->getCorrelationCoefficient()); - if( m_apNumberFormatterWrapper.get()) + + awt::Point aScreenPosition2D; + chart2::RelativePosition aRelativePosition; + if( xEquationProperties->getPropertyValue( "RelativePosition") >>= aRelativePosition ) { - sal_Int32 nLabelCol = 0; - bool bColChanged; - aFormula.append( - m_apNumberFormatterWrapper->getFormattedString( - nNumberFormatKey, fR*fR, nLabelCol, bColChanged )); - //@todo: change color of label if bColChanged is true + //@todo decide whether x is primary or secondary + double fX = aRelativePosition.Primary*m_aPageReferenceSize.Width; + double fY = aRelativePosition.Secondary*m_aPageReferenceSize.Height; + aScreenPosition2D.X = static_cast< sal_Int32 >( ::rtl::math::round( fX )); + aScreenPosition2D.Y = static_cast< sal_Int32 >( ::rtl::math::round( fY )); } else - { - const LocaleDataWrapper& rLocaleDataWrapper = Application::GetSettings().GetLocaleDataWrapper(); - const OUString& aNumDecimalSep = rLocaleDataWrapper.getNumDecimalSep(); - assert(aNumDecimalSep.getLength() > 0); - sal_Unicode aDecimalSep = aNumDecimalSep.getStr()[0]; - aFormula.append( ::rtl::math::doubleToUString( - fR*fR, rtl_math_StringFormat_G, 4, aDecimalSep, true )); - } - } - - awt::Point aScreenPosition2D; - chart2::RelativePosition aRelativePosition; - if( xEquationProperties->getPropertyValue( "RelativePosition") >>= aRelativePosition ) - { - //@todo decide whether x is primary or secondary - double fX = aRelativePosition.Primary*m_aPageReferenceSize.Width; - double fY = aRelativePosition.Secondary*m_aPageReferenceSize.Height; - aScreenPosition2D.X = static_cast< sal_Int32 >( ::rtl::math::round( fX )); - aScreenPosition2D.Y = static_cast< sal_Int32 >( ::rtl::math::round( fY )); - } - else - aScreenPosition2D = aDefaultPos; + aScreenPosition2D = aDefaultPos; - if( !aFormula.isEmpty()) - { - // set fill and line properties on creation - tNameSequence aNames; - tAnySequence aValues; - PropertyMapper::getPreparedTextShapePropertyLists( xEquationProperties, aNames, aValues ); + if( !aFormula.isEmpty()) + { + // set fill and line properties on creation + tNameSequence aNames; + tAnySequence aValues; + PropertyMapper::getPreparedTextShapePropertyLists( xEquationProperties, aNames, aValues ); - uno::Reference< drawing::XShape > xTextShape = m_pShapeFactory->createText( - xEquationTarget, aFormula.makeStringAndClear(), - aNames, aValues, AbstractShapeFactory::makeTransformation( aScreenPosition2D )); + uno::Reference< drawing::XShape > xTextShape = m_pShapeFactory->createText( + xEquationTarget, aFormula.makeStringAndClear(), + aNames, aValues, AbstractShapeFactory::makeTransformation( aScreenPosition2D )); - OSL_ASSERT( xTextShape.is()); - if( xTextShape.is()) - { - AbstractShapeFactory::setShapeName( xTextShape, rEquationCID ); - awt::Size aSize( xTextShape->getSize() ); - awt::Point aPos( RelativePositionHelper::getUpperLeftCornerOfAnchoredObject( - aScreenPosition2D, aSize, aRelativePosition.Anchor ) ); - //ensure that the equation is fully placed within the page (if possible) - if( (aPos.X + aSize.Width) > m_aPageReferenceSize.Width ) - aPos.X = m_aPageReferenceSize.Width - aSize.Width; - if( aPos.X < 0 ) - aPos.X = 0; - if( (aPos.Y + aSize.Height) > m_aPageReferenceSize.Height ) - aPos.Y = m_aPageReferenceSize.Height - aSize.Height; - if( aPos.Y < 0 ) - aPos.Y = 0; - xTextShape->setPosition(aPos); + OSL_ASSERT( xTextShape.is()); + if( xTextShape.is()) + { + AbstractShapeFactory::setShapeName( xTextShape, rEquationCID ); + awt::Size aSize( xTextShape->getSize() ); + awt::Point aPos( RelativePositionHelper::getUpperLeftCornerOfAnchoredObject( + aScreenPosition2D, aSize, aRelativePosition.Anchor ) ); + //ensure that the equation is fully placed within the page (if possible) + if( (aPos.X + aSize.Width) > m_aPageReferenceSize.Width ) + aPos.X = m_aPageReferenceSize.Width - aSize.Width; + if( aPos.X < 0 ) + { + aPos.X = 0; + if ( nFormulaWidth > 0 ) + { + bResizeEquation = true; + if ( nCountIteration < nMaxIteration-1 ) + xEquationTarget->remove( xTextShape ); // remove equation + nFormulaWidth *= m_aPageReferenceSize.Width / static_cast< double >(aSize.Width); + nFormulaWidth -= nCountIteration; + if ( nFormulaWidth < 0 ) + nFormulaWidth = 0; + } + } + if( (aPos.Y + aSize.Height) > m_aPageReferenceSize.Height ) + aPos.Y = m_aPageReferenceSize.Height - aSize.Height; + if( aPos.Y < 0 ) + aPos.Y = 0; + if ( !bResizeEquation || nCountIteration == nMaxIteration-1 ) + xTextShape->setPosition(aPos); // if equation was not removed + } } } } |