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:
committed by
Markus Mohrhard
parent
beeb710850
commit
033b2ae877
@@ -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
|
||||
|
@@ -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 ____
|
||||
|
@@ -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 ____
|
||||
|
@@ -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 ____
|
||||
|
@@ -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 ____
|
||||
|
@@ -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,
|
||||
|
@@ -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 ____
|
||||
|
@@ -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;
|
||||
};
|
||||
|
||||
|
@@ -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 );
|
||||
|
@@ -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) = ");
|
||||
|
||||
|
@@ -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
|
||||
|
@@ -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 );
|
||||
}
|
||||
|
@@ -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" );
|
||||
|
@@ -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) = ");
|
||||
|
||||
|
@@ -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: */
|
||||
|
@@ -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())
|
||||
bResizeEquation = false;
|
||||
if( bShowEquation )
|
||||
{
|
||||
aFormula = xRegressionCurveCalculator->getFormattedRepresentation(
|
||||
m_apNumberFormatterWrapper->getNumberFormatsSupplier(),
|
||||
nNumberFormatKey );
|
||||
}
|
||||
else
|
||||
{
|
||||
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
|
||||
aScreenPosition2D = aDefaultPos;
|
||||
|
||||
if( !aFormula.isEmpty())
|
||||
{
|
||||
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 ));
|
||||
}
|
||||
}
|
||||
// set fill and line properties on creation
|
||||
tNameSequence aNames;
|
||||
tAnySequence aValues;
|
||||
PropertyMapper::getPreparedTextShapePropertyLists( xEquationProperties, aNames, aValues );
|
||||
|
||||
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;
|
||||
uno::Reference< drawing::XShape > xTextShape = m_pShapeFactory->createText(
|
||||
xEquationTarget, aFormula.makeStringAndClear(),
|
||||
aNames, aValues, AbstractShapeFactory::makeTransformation( aScreenPosition2D ));
|
||||
|
||||
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 ));
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -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
|
||||
|
Reference in New Issue
Block a user