[Libreoffice-commits] core.git: chart2/inc chart2/source offapi/com

Laurent Balland-Poirier laurent.balland-poirier at laposte.net
Sun May 22 19:12:33 UTC 2016


 chart2/inc/SpecialUnicodes.hxx                                 |    2 
 chart2/source/inc/ExponentialRegressionCurveCalculator.hxx     |    2 
 chart2/source/inc/LogarithmicRegressionCurveCalculator.hxx     |    2 
 chart2/source/inc/MeanValueRegressionCurveCalculator.hxx       |    2 
 chart2/source/inc/MovingAverageRegressionCurveCalculator.hxx   |    2 
 chart2/source/inc/PolynomialRegressionCurveCalculator.hxx      |    2 
 chart2/source/inc/PotentialRegressionCurveCalculator.hxx       |    2 
 chart2/source/inc/RegressionCurveCalculator.hxx                |   10 
 chart2/source/tools/ExponentialRegressionCurveCalculator.cxx   |    2 
 chart2/source/tools/LogarithmicRegressionCurveCalculator.cxx   |    2 
 chart2/source/tools/MeanValueRegressionCurveCalculator.cxx     |   15 
 chart2/source/tools/MovingAverageRegressionCurveCalculator.cxx |    2 
 chart2/source/tools/PolynomialRegressionCurveCalculator.cxx    |   61 ++-
 chart2/source/tools/PotentialRegressionCurveCalculator.cxx     |    2 
 chart2/source/tools/RegressionCurveCalculator.cxx              |   60 ++-
 chart2/source/view/charttypes/VSeriesPlotter.cxx               |  189 ++++++----
 offapi/com/sun/star/chart2/XRegressionCurveCalculator.idl      |    6 
 17 files changed, 252 insertions(+), 111 deletions(-)

New commits:
commit 033b2ae8775d1dcf49f798e267761000cc51627c
Author: Laurent Balland-Poirier <laurent.balland-poirier at laposte.net>
Date:   Fri Mar 11 23:28:35 2016 +0100

    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 at libreoffice.org>
    Reviewed-by: Markus Mohrhard <markus.mohrhard at googlemail.com>

diff --git a/chart2/inc/SpecialUnicodes.hxx b/chart2/inc/SpecialUnicodes.hxx
index 6b3398d..db6e3b6 100644
--- a/chart2/inc/SpecialUnicodes.hxx
+++ b/chart2/inc/SpecialUnicodes.hxx
@@ -11,6 +11,8 @@
 #define INCLUDED_CHART2_INC_SPECIALUNICODES_HXX
 
 const OUString aMinusSign ( sal_Unicode (0x2212) );
+const OUString aNewLine ("\n");
+const OUString aHashString ("###");
 const sal_Unicode aSuperscriptFigures[10]={ 0x2070, 0x00B9, 0x00B2, 0x00B3, 0x2074, 0x2075, 0x2076, 0x2077, 0x2078, 0x2079 };
 
 #endif
diff --git a/chart2/source/inc/ExponentialRegressionCurveCalculator.hxx b/chart2/source/inc/ExponentialRegressionCurveCalculator.hxx
index c62af6d..d374675 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 f8bda77..922562f 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 c0fb501..fbd3077 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 81ee90cd..ccfcc7a 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 f6858f2..81b5804 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 1051d11..a201152 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 afd0164..f40587f 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 0c79ff4..75e92aa 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 3370454..e2ca7d4 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 b40243e..4703fe4 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 410f8d6..dac1616 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 6dba3a2..2a135b1 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 1a9c2be..8ea92c1 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 1ecb681..09f03cc 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 62966d3..4d17b16 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
+                }
             }
         }
     }
diff --git a/offapi/com/sun/star/chart2/XRegressionCurveCalculator.idl b/offapi/com/sun/star/chart2/XRegressionCurveCalculator.idl
index 7151059..ce0632c 100644
--- a/offapi/com/sun/star/chart2/XRegressionCurveCalculator.idl
+++ b/offapi/com/sun/star/chart2/XRegressionCurveCalculator.idl
@@ -154,12 +154,14 @@ interface XRegressionCurveCalculator : com::sun::star::uno::XInterface
     string getRepresentation();
 
     /** Returns a representation using the given number format for formatting all numbers
-        contained in the formula.
+        contained in the formula. Wrap equation to fit in nFormulaLength characters
 
         @see getRepresentation
      */
     string getFormattedRepresentation( [in] com::sun::star::util::XNumberFormatsSupplier xNumFmtSupplier,
-                                       [in] long nNumberFormatKey );
+                                       [in] long nNumberFormatKey,
+                                       [in] long nFormulaLength );
+
 };
 
 } ; // chart2


More information about the Libreoffice-commits mailing list