summaryrefslogtreecommitdiff
path: root/chart2
diff options
context:
space:
mode:
authorLaurent Balland-Poirier <laurent.balland-poirier@laposte.net>2016-03-11 23:28:35 +0100
committerMarkus Mohrhard <markus.mohrhard@googlemail.com>2016-05-22 19:12:07 +0000
commit033b2ae8775d1dcf49f798e267761000cc51627c (patch)
tree83e276940761096572bc75875a381ffe4d88b13c /chart2
parentbeeb71085036d09494e44f43670d6d26f30c6277 (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')
-rw-r--r--chart2/inc/SpecialUnicodes.hxx2
-rw-r--r--chart2/source/inc/ExponentialRegressionCurveCalculator.hxx2
-rw-r--r--chart2/source/inc/LogarithmicRegressionCurveCalculator.hxx2
-rw-r--r--chart2/source/inc/MeanValueRegressionCurveCalculator.hxx2
-rw-r--r--chart2/source/inc/MovingAverageRegressionCurveCalculator.hxx2
-rw-r--r--chart2/source/inc/PolynomialRegressionCurveCalculator.hxx2
-rw-r--r--chart2/source/inc/PotentialRegressionCurveCalculator.hxx2
-rw-r--r--chart2/source/inc/RegressionCurveCalculator.hxx10
-rw-r--r--chart2/source/tools/ExponentialRegressionCurveCalculator.cxx2
-rw-r--r--chart2/source/tools/LogarithmicRegressionCurveCalculator.cxx2
-rw-r--r--chart2/source/tools/MeanValueRegressionCurveCalculator.cxx15
-rw-r--r--chart2/source/tools/MovingAverageRegressionCurveCalculator.cxx2
-rw-r--r--chart2/source/tools/PolynomialRegressionCurveCalculator.cxx61
-rw-r--r--chart2/source/tools/PotentialRegressionCurveCalculator.cxx2
-rw-r--r--chart2/source/tools/RegressionCurveCalculator.cxx60
-rw-r--r--chart2/source/view/charttypes/VSeriesPlotter.cxx189
16 files changed, 248 insertions, 109 deletions
diff --git a/chart2/inc/SpecialUnicodes.hxx b/chart2/inc/SpecialUnicodes.hxx
index 6b3398daf840..db6e3b65fdb5 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 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
+ }
}
}
}