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>
This commit is contained in:
Laurent Balland-Poirier
2016-03-11 23:28:35 +01:00
committed by Markus Mohrhard
parent beeb710850
commit 033b2ae877
17 changed files with 252 additions and 111 deletions

View File

@@ -11,6 +11,8 @@
#define INCLUDED_CHART2_INC_SPECIALUNICODES_HXX #define INCLUDED_CHART2_INC_SPECIALUNICODES_HXX
const OUString aMinusSign ( sal_Unicode (0x2212) ); 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 }; const sal_Unicode aSuperscriptFigures[10]={ 0x2070, 0x00B9, 0x00B2, 0x00B3, 0x2074, 0x2075, 0x2076, 0x2077, 0x2078, 0x2079 };
#endif #endif

View File

@@ -33,7 +33,7 @@ public:
protected: protected:
virtual OUString ImplGetRepresentation( virtual OUString ImplGetRepresentation(
const css::uno::Reference<css::util::XNumberFormatter>& xNumFormatter, const css::uno::Reference<css::util::XNumberFormatter>& xNumFormatter,
sal_Int32 nNumberFormatKey ) const override; sal_Int32 nNumberFormatKey, sal_Int32* pFormulaLength = nullptr ) const override;
private: private:
// ____ XRegressionCurveCalculator ____ // ____ XRegressionCurveCalculator ____

View File

@@ -33,7 +33,7 @@ public:
protected: protected:
virtual OUString ImplGetRepresentation( virtual OUString ImplGetRepresentation(
const css::uno::Reference<css::util::XNumberFormatter>& xNumFormatter, const css::uno::Reference<css::util::XNumberFormatter>& xNumFormatter,
sal_Int32 nNumberFormatKey ) const override; sal_Int32 nNumberFormatKey, sal_Int32* pFormulaLength = nullptr ) const override;
private: private:
// ____ XRegressionCurveCalculator ____ // ____ XRegressionCurveCalculator ____

View File

@@ -33,7 +33,7 @@ public:
protected: protected:
virtual OUString ImplGetRepresentation( virtual OUString ImplGetRepresentation(
const css::uno::Reference<css::util::XNumberFormatter>& xNumFormatter, const css::uno::Reference<css::util::XNumberFormatter>& xNumFormatter,
sal_Int32 nNumberFormatKey ) const override; sal_Int32 nNumberFormatKey, sal_Int32* pFormulaLength = nullptr ) const override;
private: private:
// ____ XRegressionCurveCalculator ____ // ____ XRegressionCurveCalculator ____

View File

@@ -34,7 +34,7 @@ public:
protected: protected:
virtual OUString ImplGetRepresentation( virtual OUString ImplGetRepresentation(
const css::uno::Reference<css::util::XNumberFormatter>& xNumFormatter, const css::uno::Reference<css::util::XNumberFormatter>& xNumFormatter,
sal_Int32 nNumberFormatKey ) const override; sal_Int32 nNumberFormatKey, sal_Int32* pFormulaLength = nullptr ) const override;
private: private:
// ____ XRegressionCurveCalculator ____ // ____ XRegressionCurveCalculator ____

View File

@@ -34,7 +34,7 @@ public:
protected: protected:
virtual OUString ImplGetRepresentation( virtual OUString ImplGetRepresentation(
const css::uno::Reference<css::util::XNumberFormatter>& xNumFormatter, 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 ) virtual double SAL_CALL getCurveValue( double x )
throw (css::lang::IllegalArgumentException, throw (css::lang::IllegalArgumentException,

View File

@@ -34,7 +34,7 @@ public:
protected: protected:
virtual OUString ImplGetRepresentation( virtual OUString ImplGetRepresentation(
const css::uno::Reference<css::util::XNumberFormatter>& xNumFormatter, const css::uno::Reference<css::util::XNumberFormatter>& xNumFormatter,
sal_Int32 nNumberFormatKey ) const override; sal_Int32 nNumberFormatKey, sal_Int32* pFormulaLength = nullptr ) const override;
private: private:
// ____ XRegressionCurveCalculator ____ // ____ XRegressionCurveCalculator ____

View File

@@ -20,6 +20,7 @@
#define INCLUDED_CHART2_SOURCE_INC_REGRESSIONCURVECALCULATOR_HXX #define INCLUDED_CHART2_SOURCE_INC_REGRESSIONCURVECALCULATOR_HXX
#include <cppuhelper/implbase.hxx> #include <cppuhelper/implbase.hxx>
#include <rtl/ustrbuf.hxx>
#include <com/sun/star/chart2/XRegressionCurveCalculator.hpp> #include <com/sun/star/chart2/XRegressionCurveCalculator.hpp>
#include <com/sun/star/util/XNumberFormatter.hpp> #include <com/sun/star/util/XNumberFormatter.hpp>
@@ -43,12 +44,15 @@ public:
protected: protected:
virtual OUString ImplGetRepresentation( virtual OUString ImplGetRepresentation(
const css::uno::Reference< css::util::XNumberFormatter >& xNumFormatter, 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( static OUString getFormattedString(
const css::uno::Reference< css::util::XNumberFormatter >& xNumFormatter, const css::uno::Reference< css::util::XNumberFormatter >& xNumFormatter,
sal_Int32 nNumberFormatKey, 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; double m_fCorrelationCoeffitient;
@@ -92,7 +96,7 @@ protected:
virtual OUString SAL_CALL getFormattedRepresentation( virtual OUString SAL_CALL getFormattedRepresentation(
const css::uno::Reference< css::util::XNumberFormatsSupplier >& xNumFmtSupplier, const css::uno::Reference< css::util::XNumberFormatsSupplier >& xNumFmtSupplier,
sal_Int32 nNumberFormatKey ) sal_Int32 nNumberFormatKey, sal_Int32 nFormulaLength )
throw (css::uno::RuntimeException, std::exception) override; throw (css::uno::RuntimeException, std::exception) override;
}; };

View File

@@ -154,7 +154,7 @@ uno::Sequence< geometry::RealPoint2D > SAL_CALL ExponentialRegressionCurveCalcul
OUString ExponentialRegressionCurveCalculator::ImplGetRepresentation( OUString ExponentialRegressionCurveCalculator::ImplGetRepresentation(
const uno::Reference< util::XNumberFormatter >& xNumFormatter, 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); double fIntercept = m_fSign * exp(m_fLogIntercept);
bool bHasSlope = !rtl::math::approxEqual( exp(m_fLogSlope), 1.0 ); bool bHasSlope = !rtl::math::approxEqual( exp(m_fLogSlope), 1.0 );

View File

@@ -130,7 +130,7 @@ uno::Sequence< geometry::RealPoint2D > SAL_CALL LogarithmicRegressionCurveCalcul
OUString LogarithmicRegressionCurveCalculator::ImplGetRepresentation( OUString LogarithmicRegressionCurveCalculator::ImplGetRepresentation(
const uno::Reference< util::XNumberFormatter >& xNumFormatter, const uno::Reference< util::XNumberFormatter >& xNumFormatter,
::sal_Int32 nNumberFormatKey ) const sal_Int32 nNumberFormatKey, sal_Int32* /* pFormulaLength = nullptr */ ) const
{ {
OUStringBuffer aBuf( "f(x) = "); OUStringBuffer aBuf( "f(x) = ");

View File

@@ -23,6 +23,7 @@
#include <osl/diagnose.h> #include <osl/diagnose.h>
#include <rtl/math.hxx> #include <rtl/math.hxx>
#include <rtl/ustrbuf.hxx> #include <rtl/ustrbuf.hxx>
#include <SpecialUnicodes.hxx>
using namespace ::com::sun::star; using namespace ::com::sun::star;
@@ -118,12 +119,16 @@ uno::Sequence< geometry::RealPoint2D > SAL_CALL MeanValueRegressionCurveCalculat
OUString MeanValueRegressionCurveCalculator::ImplGetRepresentation( OUString MeanValueRegressionCurveCalculator::ImplGetRepresentation(
const uno::Reference< util::XNumberFormatter >& xNumFormatter, const uno::Reference< util::XNumberFormatter >& xNumFormatter,
::sal_Int32 nNumberFormatKey ) const sal_Int32 nNumberFormatKey, sal_Int32* pFormulaLength /* = nullptr */ ) const
{ {
OUString aBuf = "f(x) = " + OUString aBuf = "f(x) = ";
getFormattedString( xNumFormatter, nNumberFormatKey, m_fMeanValue ); if ( pFormulaLength )
{
return aBuf; *pFormulaLength -= aBuf.getLength();
if ( *pFormulaLength <= 0 )
return aHashString;
}
return ( aBuf + getFormattedString( xNumFormatter, nNumberFormatKey, m_fMeanValue, pFormulaLength ) );
} }
} // namespace chart } // namespace chart

View File

@@ -101,7 +101,7 @@ uno::Sequence< geometry::RealPoint2D > SAL_CALL MovingAverageRegressionCurveCalc
OUString MovingAverageRegressionCurveCalculator::ImplGetRepresentation( OUString MovingAverageRegressionCurveCalculator::ImplGetRepresentation(
const uno::Reference< util::XNumberFormatter >& /*xNumFormatter*/, 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 ); return SCH_RESSTR( STR_OBJECT_MOVING_AVERAGE_WITH_PARAMETERS );
} }

View File

@@ -27,7 +27,6 @@
#include <SpecialUnicodes.hxx> #include <SpecialUnicodes.hxx>
using namespace com::sun::star; using namespace com::sun::star;
namespace chart namespace chart
@@ -236,15 +235,53 @@ uno::Sequence< geometry::RealPoint2D > SAL_CALL PolynomialRegressionCurveCalcula
OUString PolynomialRegressionCurveCalculator::ImplGetRepresentation( OUString PolynomialRegressionCurveCalculator::ImplGetRepresentation(
const uno::Reference< util::XNumberFormatter >& xNumFormatter, const uno::Reference< util::XNumberFormatter >& xNumFormatter,
sal_Int32 nNumberFormatKey ) const sal_Int32 nNumberFormatKey, sal_Int32* pFormulaMaxWidth /* = nullptr */ ) const
{ {
OUStringBuffer aBuf( "f(x) = " ); OUStringBuffer aBuf( "f(x) = " );
sal_Int32 nValueLength=0;
sal_Int32 aLastIndex = mCoefficients.size() - 1; sal_Int32 aLastIndex = mCoefficients.size() - 1;
bool bFindValue = false;
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--) for (sal_Int32 i = aLastIndex; i >= 0; i--)
{ {
double aValue = mCoefficients[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) if (aValue == 0.0)
{ {
continue; continue;
@@ -252,38 +289,42 @@ OUString PolynomialRegressionCurveCalculator::ImplGetRepresentation(
else if (aValue < 0.0) else if (aValue < 0.0)
{ {
if ( bFindValue ) // if it is not the first aValue if ( bFindValue ) // if it is not the first aValue
aBuf.append( " " ); aTmpBuf.append( " " );
aBuf.append( aMinusSign + " "); aTmpBuf.append( aMinusSign + " ");
aValue = - aValue; aValue = - aValue;
} }
else else
{ {
if ( bFindValue ) // if it is not the first aValue if ( bFindValue ) // if it is not the first aValue
aBuf.append( " + " ); aTmpBuf.append( " + " );
} }
bFindValue = true; bFindValue = true;
if ( i == 0 || !rtl::math::approxEqual( aValue , 1.0 ) ) // if nValueLength not calculated then nullptr
aBuf.append( getFormattedString( xNumFormatter, nNumberFormatKey, aValue ) ); 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) if(i > 0)
{ {
aBuf.append( "x" ); aTmpBuf.append( "x" );
if (i > 1) if (i > 1)
{ {
if (i < 10) // simple case if only one digit if (i < 10) // simple case if only one digit
aBuf.append( aSuperscriptFigures[ i ] ); aTmpBuf.append( aSuperscriptFigures[ i ] );
else else
{ {
OUString aValueOfi = OUString::number( i ); OUString aValueOfi = OUString::number( i );
for ( sal_Int32 n = 0; n < aValueOfi.getLength() ; n++ ) for ( sal_Int32 n = 0; n < aValueOfi.getLength() ; n++ )
{ {
sal_Int32 nIndex = aValueOfi[n] - sal_Unicode ( '0' ); 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) = " ) if ( aBuf.toString() == "f(x) = " )
aBuf.append( "0" ); aBuf.append( "0" );

View File

@@ -142,7 +142,7 @@ uno::Sequence< geometry::RealPoint2D > SAL_CALL PotentialRegressionCurveCalculat
OUString PotentialRegressionCurveCalculator::ImplGetRepresentation( OUString PotentialRegressionCurveCalculator::ImplGetRepresentation(
const uno::Reference< util::XNumberFormatter >& xNumFormatter, const uno::Reference< util::XNumberFormatter >& xNumFormatter,
::sal_Int32 nNumberFormatKey ) const sal_Int32 nNumberFormatKey, sal_Int32* /* pFormulaLength = nullptr */ ) const
{ {
OUStringBuffer aBuf( "f(x) = "); OUStringBuffer aBuf( "f(x) = ");

View File

@@ -27,6 +27,11 @@
#include <com/sun/star/lang/XServiceName.hpp> #include <com/sun/star/lang/XServiceName.hpp>
#include <com/sun/star/util/NumberFormatter.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 namespace ::com::sun::star;
using ::com::sun::star::uno::Reference; using ::com::sun::star::uno::Reference;
@@ -82,17 +87,46 @@ void RegressionCurveCalculator::setRegressionProperties(
OUString RegressionCurveCalculator::getFormattedString( OUString RegressionCurveCalculator::getFormattedString(
const Reference< util::XNumberFormatter >& xNumFormatter, const Reference< util::XNumberFormatter >& xNumFormatter,
sal_Int32 nNumberFormatKey, sal_Int32 nNumberFormatKey,
double fNumber ) double fNumber, sal_Int32* pStringLength /* = nullptr */ )
{ {
if ( pStringLength && *pStringLength <= 0 )
return aHashString;
OUString aResult; OUString aResult;
if( xNumFormatter.is()) if( xNumFormatter.is() )
aResult = xNumFormatter->convertNumberToString( nNumberFormatKey, fNumber ); {
else 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( aResult = OStringToOUString(
::rtl::math::doubleToString( fNumber, rtl_math_StringFormat_G1, 4, '.', true ), ::rtl::math::doubleToString( fNumber, rtl_math_StringFormat_G1, nSignificantDigit, '.', true ),
RTL_TEXTENCODING_ASCII_US ); 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, nStringLength, '.', true ),
RTL_TEXTENCODING_ASCII_US );
}
return aResult; return aResult;
} }
@@ -150,8 +184,8 @@ OUString SAL_CALL RegressionCurveCalculator::getRepresentation()
OUString SAL_CALL RegressionCurveCalculator::getFormattedRepresentation( OUString SAL_CALL RegressionCurveCalculator::getFormattedRepresentation(
const Reference< util::XNumberFormatsSupplier > & xNumFmtSupplier, const Reference< util::XNumberFormatsSupplier > & xNumFmtSupplier,
sal_Int32 nNumberFormatKey ) sal_Int32 nNumberFormatKey, sal_Int32 nFormulaLength )
throw (uno::RuntimeException, std::exception) throw (uno::RuntimeException, std::exception)
{ {
// create and prepare a number formatter // create and prepare a number formatter
if( !xNumFmtSupplier.is()) if( !xNumFmtSupplier.is())
@@ -160,9 +194,23 @@ OUString SAL_CALL RegressionCurveCalculator::getFormattedRepresentation(
Reference< util::XNumberFormatter > xNumFormatter( util::NumberFormatter::create(xContext), uno::UNO_QUERY_THROW ); Reference< util::XNumberFormatter > xNumFormatter( util::NumberFormatter::create(xContext), uno::UNO_QUERY_THROW );
xNumFormatter->attachNumberFormatsSupplier( xNumFmtSupplier ); xNumFormatter->attachNumberFormatsSupplier( xNumFmtSupplier );
if ( nFormulaLength > 0 )
return ImplGetRepresentation( xNumFormatter, nNumberFormatKey, &nFormulaLength );
return ImplGetRepresentation( xNumFormatter, nNumberFormatKey ); 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 } // namespace chart
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

View File

@@ -20,6 +20,7 @@
#include "VSeriesPlotter.hxx" #include "VSeriesPlotter.hxx"
#include "AbstractShapeFactory.hxx" #include "AbstractShapeFactory.hxx"
#include "chartview/ExplicitValueProvider.hxx" #include "chartview/ExplicitValueProvider.hxx"
#include <svl/zformat.hxx>
#include "CommonConverters.hxx" #include "CommonConverters.hxx"
#include "macros.hxx" #include "macros.hxx"
@@ -52,6 +53,7 @@
#include "BubbleChart.hxx" #include "BubbleChart.hxx"
#include "NetChart.hxx" #include "NetChart.hxx"
#include <unonames.hxx> #include <unonames.hxx>
#include <SpecialUnicodes.hxx>
#include <com/sun/star/chart/ErrorBarStyle.hpp> #include <com/sun/star/chart/ErrorBarStyle.hpp>
#include <com/sun/star/chart/TimeUnit.hpp> #include <com/sun/star/chart/TimeUnit.hpp>
@@ -407,7 +409,6 @@ OUString VSeriesPlotter::getLabelTextForValue( VDataSeries& rDataSeries
} }
else else
{ {
const LocaleDataWrapper& rLocaleDataWrapper = Application::GetSettings().GetLocaleDataWrapper(); const LocaleDataWrapper& rLocaleDataWrapper = Application::GetSettings().GetLocaleDataWrapper();
const OUString& aNumDecimalSep = rLocaleDataWrapper.getNumDecimalSep(); const OUString& aNumDecimalSep = rLocaleDataWrapper.getNumDecimalSep();
assert(aNumDecimalSep.getLength() > 0); 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( void VSeriesPlotter::createRegressionCurveEquationShapes(
const OUString & rEquationCID, const OUString & rEquationCID,
const uno::Reference< beans::XPropertySet > & xEquationProperties, const uno::Reference< beans::XPropertySet > & xEquationProperties,
@@ -1220,7 +1240,6 @@ void VSeriesPlotter::createRegressionCurveEquationShapes(
bool bShowEquation = false; bool bShowEquation = false;
bool bShowCorrCoeff = false; bool bShowCorrCoeff = false;
OUString aSep( "\n" );
if(( xEquationProperties->getPropertyValue( "ShowEquation") >>= bShowEquation ) && if(( xEquationProperties->getPropertyValue( "ShowEquation") >>= bShowEquation ) &&
( xEquationProperties->getPropertyValue( "ShowCorrelationCoefficient") >>= bShowCorrCoeff )) ( xEquationProperties->getPropertyValue( "ShowCorrelationCoefficient") >>= bShowCorrCoeff ))
{ {
@@ -1229,15 +1248,23 @@ void VSeriesPlotter::createRegressionCurveEquationShapes(
OUStringBuffer aFormula; OUStringBuffer aFormula;
sal_Int32 nNumberFormatKey = 0; sal_Int32 nNumberFormatKey = 0;
sal_Int32 nFormulaWidth = 0;
xEquationProperties->getPropertyValue(CHART_UNONAME_NUMFMT) >>= nNumberFormatKey; xEquationProperties->getPropertyValue(CHART_UNONAME_NUMFMT) >>= nNumberFormatKey;
bool bResizeEquation = true;
sal_Int32 nMaxIteration = 2;
for ( sal_Int32 nCountIteration = 0; bResizeEquation && nCountIteration < nMaxIteration ; nCountIteration++ )
{
bResizeEquation = false;
if( bShowEquation ) if( bShowEquation )
{ {
if( m_apNumberFormatterWrapper.get()) if( m_apNumberFormatterWrapper.get())
{ { // iteration 0: default representation (no wrap)
// iteration 1: expected width (nFormulaWidth) is calculated
aFormula = xRegressionCurveCalculator->getFormattedRepresentation( aFormula = xRegressionCurveCalculator->getFormattedRepresentation(
m_apNumberFormatterWrapper->getNumberFormatsSupplier(), m_apNumberFormatterWrapper->getNumberFormatsSupplier(),
nNumberFormatKey ); nNumberFormatKey, nFormulaWidth );
nFormulaWidth = lcl_getOUStringMaxLineLength( aFormula );
} }
else else
{ {
@@ -1246,14 +1273,12 @@ void VSeriesPlotter::createRegressionCurveEquationShapes(
if( bShowCorrCoeff ) if( bShowCorrCoeff )
{ {
aFormula.append( aSep ); aFormula.append( aNewLine );
} }
} }
if( bShowCorrCoeff ) if( bShowCorrCoeff )
{ {
aFormula.append( "R" ); aFormula.append( "R" + OUString( aSuperscriptFigures[2] ) + " = " );
aFormula.append( sal_Unicode( 0x00b2 ));
aFormula.append( " = ");
double fR( xRegressionCurveCalculator->getCorrelationCoefficient()); double fR( xRegressionCurveCalculator->getCorrelationCoefficient());
if( m_apNumberFormatterWrapper.get()) if( m_apNumberFormatterWrapper.get())
{ {
@@ -1310,12 +1335,26 @@ void VSeriesPlotter::createRegressionCurveEquationShapes(
if( (aPos.X + aSize.Width) > m_aPageReferenceSize.Width ) if( (aPos.X + aSize.Width) > m_aPageReferenceSize.Width )
aPos.X = m_aPageReferenceSize.Width - aSize.Width; aPos.X = m_aPageReferenceSize.Width - aSize.Width;
if( aPos.X < 0 ) if( aPos.X < 0 )
{
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 ) if( (aPos.Y + aSize.Height) > m_aPageReferenceSize.Height )
aPos.Y = m_aPageReferenceSize.Height - aSize.Height; aPos.Y = m_aPageReferenceSize.Height - aSize.Height;
if( aPos.Y < 0 ) if( aPos.Y < 0 )
aPos.Y = 0; aPos.Y = 0;
xTextShape->setPosition(aPos); if ( !bResizeEquation || nCountIteration == nMaxIteration-1 )
xTextShape->setPosition(aPos); // if equation was not removed
}
} }
} }
} }

View File

@@ -154,12 +154,14 @@ interface XRegressionCurveCalculator : com::sun::star::uno::XInterface
string getRepresentation(); string getRepresentation();
/** Returns a representation using the given number format for formatting all numbers /** 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 @see getRepresentation
*/ */
string getFormattedRepresentation( [in] com::sun::star::util::XNumberFormatsSupplier xNumFmtSupplier, string getFormattedRepresentation( [in] com::sun::star::util::XNumberFormatsSupplier xNumFmtSupplier,
[in] long nNumberFormatKey ); [in] long nNumberFormatKey,
[in] long nFormulaLength );
}; };
} ; // chart2 } ; // chart2