office-gobmx/chart2/source/tools/StatisticsHelper.cxx
Kurt Zenker a3acf41195 CWS-TOOLING: integrate CWS chart37
2009-05-22 09:10:36 +0200 iha  r272170 : #i102130# color of pies is not loaded correctly
2009-04-27 17:16:20 +0200 iha  r271294 : #i24203# compiler problem
2009-04-27 16:43:21 +0200 iha  r271292 : #i101281# missing API documentation for secondary axis title properties
2009-04-27 15:26:05 +0200 hde  r271276 : #i100987
2009-04-27 15:24:42 +0200 hde  r271273 : #i100987
2009-04-24 15:08:33 +0200 iha  r271214 : #i100995# crash with some logarithmic scalings
2009-04-22 18:50:56 +0200 dr  r271134 : #i82177# write out deleted point labels
2009-04-22 18:40:48 +0200 iha  r271133 : #i101281# missing API documentation for secondary axis title properties
2009-04-22 16:39:42 +0200 dr  r271128 : #i82177# extensions for bubble charts
2009-04-22 14:37:00 +0200 dr  r271114 : #i82177# import/export data label type and separator
2009-04-22 14:36:24 +0200 dr  r271113 : #i82177# import/export data label type and separator
2009-04-21 15:25:26 +0200 dr  r271038 : #i82177# import data label type and separator from BIFF8 CHFR records
2009-04-21 14:37:16 +0200 dr  r271037 : #i82177# dump BIFF8 chart future records
2009-04-20 17:44:27 +0200 iha  r271002 : #i96898# reduce library exports
2009-04-20 13:01:13 +0200 iha  r270975 : #i24203# rotate data labels - help ids
2009-04-20 11:40:33 +0200 dr  r270969 : #i96600# export of axis scaling/positioning properties
2009-04-16 16:02:31 +0200 dr  r270892 : #i69599# keep Y axis left in 3d charts
2009-04-15 18:16:46 +0200 dr  r270859 : #i69599# import of axis position settings
2009-04-15 18:16:01 +0200 dr  r270858 : #i69599# correct handling of logarithmic crossing axes
2009-04-14 16:27:48 +0200 dr  r270794 : #i96599# handle auto axis position on logarithmic axes
2009-04-09 19:59:51 +0200 dr  r270722 : #i96599# import axis crossing settings, fix import of logarithmic scaling settings
2009-04-09 18:26:00 +0200 iha  r270720 : #i96898# reduce library exports
2009-04-09 15:17:04 +0200 iha  r270710 : #i96898# reduce library exports
2009-04-09 10:50:14 +0200 dr  r270682 : #i24203# import/export of data label rotation, fixed some other broken stuff too
2009-04-08 16:54:54 +0200 dr  r270657 : #i24203# import rotation for data point labels
2009-04-06 18:19:17 +0200 iha  r270571 : #i100876# Axis scaling settings dialog wrong after API usage (anys different from double type)
2009-04-06 15:57:05 +0200 iha  r270567 : #i100105# #i58585# leftover  -> 
2009-04-06 15:55:48 +0200 iha  r270564 : #i58585# leftover  -> 
2009-04-02 16:41:07 +0200 iha  r270422 : #i99721# remove unused code
2009-04-02 14:29:03 +0200 iha  r270407 : #i99721# remove unused code
2009-03-26 10:58:23 +0100 iha  r270059 : #i96898# reduce library exports
2009-03-26 10:13:49 +0100 iha  r270055 : #i96898# reduce library exports
2009-03-25 09:39:13 +0100 iha  r269998 : CWS-TOOLING: rebase CWS chart37 to trunk@269781 (milestone: DEV300:m44)
2009-03-24 17:56:56 +0100 iha  r269986 : #i96898# reduce library exports
2009-03-24 16:56:44 +0100 iha  r269974 : #i99721# remove unused code
2009-03-24 16:48:48 +0100 iha  r269970 : #i89731# remove unused string
2009-03-24 15:44:04 +0100 iha  r269961 : remove unused code
2009-03-24 15:22:45 +0100 iha  r269959 : remove unused code
2009-03-24 15:17:17 +0100 iha  r269957 : remove unused code
2009-03-24 11:14:53 +0100 iha  r269923 : #i24203# rotate data labels
2009-03-09 12:10:25 +0100 hde  r269076 : #i99300#
2009-03-06 15:56:26 +0100 iha  r269011 : #i93953# Source Format for secondary axis without data
2009-02-17 15:59:05 +0100 iha  r268177 : avoid warning during build
2009-02-17 15:01:59 +0100 iha  r268173 : avoid warning during build
2009-02-13 09:39:03 +0100 ufi  r267693 : i96999
2009-02-11 15:12:35 +0100 iha  r267604 : removed unused string
2009-02-11 14:00:29 +0100 iha  r267600 : #i96999# Corrected wording from 'correlation coefficient' to 'coefficient of determination'
2009-02-11 10:56:45 +0100 iha  r267584 : #i89731# typo in resource string
2009-02-11 10:01:29 +0100 iha  r267582 : #i89031# compile error on asian windows systems
2009-02-10 16:15:16 +0100 iha  r267552 : #i24203# rotate data labels
2009-02-04 18:00:33 +0100 iha  r267395 : #i98893# don't export defaults to file
2009-02-04 15:48:15 +0100 iha  r267390 : #i92128# asian typography for chart elements
2009-02-04 15:17:41 +0100 iha  r267386 : #i92128# asian typography for chart elements
2009-01-30 14:41:10 +0100 iha  r267197 : CWS-TOOLING: rebase CWS chart37 to trunk@267171 (milestone: DEV300:m41)
2009-06-04 09:41:18 +00:00

406 lines
13 KiB
C++

/*************************************************************************
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright 2008 by Sun Microsystems, Inc.
*
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: StatisticsHelper.cxx,v $
* $Revision: 1.6 $
*
* This file is part of OpenOffice.org.
*
* OpenOffice.org is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 3
* only, as published by the Free Software Foundation.
*
* OpenOffice.org is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License version 3 for more details
* (a copy is included in the LICENSE file that accompanied this code).
*
* You should have received a copy of the GNU Lesser General Public License
* version 3 along with OpenOffice.org. If not, see
* <http://www.openoffice.org/license.html>
* for a copy of the LGPLv3 License.
*
************************************************************************/
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_chart2.hxx"
#include "StatisticsHelper.hxx"
#include "DataSeriesHelper.hxx"
#include "ErrorBar.hxx"
#include "macros.hxx"
#include <rtl/math.hxx>
#include <rtl/ustrbuf.hxx>
#include <comphelper/processfactory.hxx>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/chart2/data/XLabeledDataSequence.hpp>
#include <com/sun/star/chart2/data/XNumericalDataSequence.hpp>
#include <com/sun/star/chart2/data/XDataSink.hpp>
#include <com/sun/star/chart/ErrorBarStyle.hpp>
using ::com::sun::star::uno::Sequence;
using ::com::sun::star::uno::Reference;
using ::rtl::OUString;
using ::rtl::OUStringBuffer;
using namespace ::com::sun::star;
namespace
{
double lcl_getVariance( const Sequence< double > & rData, sal_Int32 & rOutValidCount,
bool bUnbiasedEstimator )
{
const sal_Int32 nCount = rData.getLength();
rOutValidCount = nCount;
double fSum = 0.0;
double fQuadSum = 0.0;
for( sal_Int32 i = 0; i < nCount; ++i )
{
const double fData = rData[i];
if( ::rtl::math::isNan( fData ))
--rOutValidCount;
else
{
fSum += fData;
fQuadSum += fData * fData;
}
}
double fResult;
if( rOutValidCount == 0 )
::rtl::math::setNan( & fResult );
else
{
const double fN = static_cast< double >( rOutValidCount );
if( bUnbiasedEstimator )
fResult = (fQuadSum - fSum*fSum/fN) / (fN - 1);
else
fResult = (fQuadSum - fSum*fSum/fN) / fN;
}
return fResult;
}
Reference< chart2::data::XLabeledDataSequence > lcl_getErrorBarLabeledSequence(
const Reference< chart2::data::XDataSource > & xDataSource,
bool bPositiveValue, bool bYError,
OUString & rOutRoleNameUsed )
{
OUStringBuffer aRole( C2U("error-bars-"));
if( bYError )
aRole.append( sal_Unicode( 'y' ));
else
aRole.append( sal_Unicode( 'x' ));
OUString aPlainRole = aRole.makeStringAndClear();
aRole.append( aPlainRole );
aRole.append( sal_Unicode( '-' ));
if( bPositiveValue )
aRole = aRole.appendAscii( "positive" );
else
aRole = aRole.appendAscii( "negative" );
OUString aLongRole = aRole.makeStringAndClear();
Reference< chart2::data::XLabeledDataSequence > xLSeq(
::chart::DataSeriesHelper::getDataSequenceByRole( xDataSource, aLongRole ));
// try role without "-negative" or "-positive" postfix
if( xLSeq.is())
rOutRoleNameUsed = aLongRole;
else
{
xLSeq.set( ::chart::DataSeriesHelper::getDataSequenceByRole( xDataSource, aPlainRole ));
if( xLSeq.is())
rOutRoleNameUsed = aPlainRole;
else
rOutRoleNameUsed = aLongRole;
}
return xLSeq;
}
void lcl_setRole(
const Reference< chart2::data::XDataSequence > & xNewSequence,
const OUString & rRole )
{
Reference< beans::XPropertySet > xSeqProp( xNewSequence, uno::UNO_QUERY );
if( xSeqProp.is())
xSeqProp->setPropertyValue( C2U("Role"), uno::makeAny( rRole ));
}
void lcl_addSequenceToDataSource(
const Reference< chart2::data::XDataSource > & xDataSource,
const Reference< chart2::data::XDataSequence > & xNewSequence,
const OUString & rRole )
{
Reference< chart2::data::XDataSink > xSink( xDataSource, uno::UNO_QUERY );
Reference< lang::XMultiServiceFactory > xFact( comphelper::getProcessServiceFactory(), uno::UNO_QUERY_THROW );
if( ! ( xFact.is() && xSink.is() ))
return;
Reference< chart2::data::XLabeledDataSequence > xLSeq(
xFact->createInstance( C2U("com.sun.star.chart2.data.LabeledDataSequence")), uno::UNO_QUERY );
if( xLSeq.is())
{
lcl_setRole( xNewSequence, rRole );
xLSeq->setValues( xNewSequence );
Sequence< Reference< chart2::data::XLabeledDataSequence > > aSequences(
xDataSource->getDataSequences());
aSequences.realloc( aSequences.getLength() + 1 );
aSequences[ aSequences.getLength() - 1 ] = xLSeq;
xSink->setData( aSequences );
}
}
void lcl_setXMLRangePropertyAtDataSequence(
const Reference< chart2::data::XDataSequence > & xDataSequence,
const OUString & rXMLRange )
{
try
{
const OUString aXMLRangePropName( C2U( "CachedXMLRange" ));
Reference< beans::XPropertySet > xProp( xDataSequence, uno::UNO_QUERY_THROW );
Reference< beans::XPropertySetInfo > xInfo( xProp->getPropertySetInfo());
if( xInfo.is() && xInfo->hasPropertyByName( aXMLRangePropName ))
xProp->setPropertyValue( aXMLRangePropName, uno::makeAny( rXMLRange ));
}
catch( const uno::Exception & ex )
{
ASSERT_EXCEPTION( ex );
}
}
} // anonymous namespace
namespace chart
{
// static
double StatisticsHelper::getVariance(
const Sequence< double > & rData,
bool bUnbiasedEstimator /* = false */ )
{
sal_Int32 nValCount;
return lcl_getVariance( rData, nValCount, bUnbiasedEstimator );
}
// static
double StatisticsHelper::getStandardDeviation( const Sequence< double > & rData )
{
double fResult = getVariance( rData );
if( ! ::rtl::math::isNan( fResult ))
fResult = sqrt( fResult );
return fResult;
}
// static
double StatisticsHelper::getStandardError( const Sequence< double > & rData )
{
sal_Int32 nValCount;
double fVar = lcl_getVariance( rData, nValCount, false );
double fResult;
if( nValCount == 0 ||
::rtl::math::isNan( fVar ))
{
::rtl::math::setNan( & fResult );
}
else
{
// standard-deviation / sqrt(n)
fResult = sqrt( fVar ) / sqrt( double(nValCount) );
}
return fResult;
}
// static
Reference< chart2::data::XLabeledDataSequence > StatisticsHelper::getErrorLabeledDataSequenceFromDataSource(
const Reference< chart2::data::XDataSource > & xDataSource,
bool bPositiveValue,
bool bYError /* = true */ )
{
Reference< chart2::data::XLabeledDataSequence > xResult;
if( !xDataSource.is())
return xResult;
OUString aRole;
Reference< chart2::data::XLabeledDataSequence > xLSeq(
lcl_getErrorBarLabeledSequence( xDataSource, bPositiveValue, bYError, aRole ));
if( xLSeq.is())
xResult.set( xLSeq );
return xResult;
}
// static
Reference< chart2::data::XDataSequence > StatisticsHelper::getErrorDataSequenceFromDataSource(
const Reference< chart2::data::XDataSource > & xDataSource,
bool bPositiveValue,
bool bYError /* = true */ )
{
Reference< chart2::data::XLabeledDataSequence > xLSeq(
StatisticsHelper::getErrorLabeledDataSequenceFromDataSource(
xDataSource, bPositiveValue,
bYError ));
if( !xLSeq.is())
return Reference< chart2::data::XDataSequence >();
return xLSeq->getValues();
}
// static
double StatisticsHelper::getErrorFromDataSource(
const Reference< chart2::data::XDataSource > & xDataSource,
sal_Int32 nIndex,
bool bPositiveValue,
bool bYError /* = true */ )
{
double fResult = 0.0;
::rtl::math::setNan( & fResult );
Reference< chart2::data::XDataSequence > xValues(
StatisticsHelper::getErrorDataSequenceFromDataSource( xDataSource, bPositiveValue, bYError ));
Reference< chart2::data::XNumericalDataSequence > xNumValues( xValues, uno::UNO_QUERY );
if( xNumValues.is())
{
Sequence< double > aData( xNumValues->getNumericalData());
if( nIndex < aData.getLength())
fResult = aData[nIndex];
}
else if( xValues.is())
{
Sequence< uno::Any > aData( xValues->getData());
if( nIndex < aData.getLength())
aData[nIndex] >>= fResult;
}
return fResult;
}
// static
void StatisticsHelper::setErrorDataSequence(
const Reference< chart2::data::XDataSource > & xDataSource,
const Reference< chart2::data::XDataProvider > & xDataProvider,
const OUString & rNewRange,
bool bPositiveValue,
bool bYError /* = true */,
OUString * pXMLRange /* = 0 */ )
{
Reference< chart2::data::XDataSink > xDataSink( xDataSource, uno::UNO_QUERY );
if( ! ( xDataSink.is() && xDataProvider.is()))
return;
OUString aRole;
Reference< chart2::data::XLabeledDataSequence > xLSeq(
lcl_getErrorBarLabeledSequence( xDataSource, bPositiveValue, bYError, aRole ));
Reference< chart2::data::XDataSequence > xNewSequence(
xDataProvider->createDataSequenceByRangeRepresentation( rNewRange ));
if( xNewSequence.is())
{
if( pXMLRange )
lcl_setXMLRangePropertyAtDataSequence( xNewSequence, *pXMLRange );
if( xLSeq.is())
{
lcl_setRole( xNewSequence, aRole );
xLSeq->setValues( xNewSequence );
}
else
lcl_addSequenceToDataSource( xDataSource, xNewSequence, aRole );
}
}
// static
Reference< beans::XPropertySet > StatisticsHelper::addErrorBars(
const Reference< chart2::XDataSeries > & xDataSeries,
const Reference< uno::XComponentContext > & xContext,
sal_Int32 nStyle,
bool bYError /* = true */ )
{
Reference< beans::XPropertySet > xErrorBar;
Reference< beans::XPropertySet > xSeriesProp( xDataSeries, uno::UNO_QUERY );
if( !xSeriesProp.is())
return xErrorBar;
const OUString aPropName( bYError ? C2U("ErrorBarY") : C2U("ErrorBarX"));
if( !( xSeriesProp->getPropertyValue( aPropName ) >>= xErrorBar ) ||
!xErrorBar.is())
{
xErrorBar.set( createErrorBar( xContext ));
}
OSL_ASSERT( xErrorBar.is());
if( xErrorBar.is())
{
xErrorBar->setPropertyValue( C2U("ErrorBarStyle"), uno::makeAny( nStyle ));
}
xSeriesProp->setPropertyValue( aPropName, uno::makeAny( xErrorBar ));
return xErrorBar;
}
// static
Reference< beans::XPropertySet > StatisticsHelper::getErrorBars(
const Reference< chart2::XDataSeries > & xDataSeries,
bool bYError /* = true */ )
{
Reference< beans::XPropertySet > xSeriesProp( xDataSeries, uno::UNO_QUERY );
Reference< beans::XPropertySet > xErrorBar;
const OUString aPropName( bYError ? C2U("ErrorBarY") : C2U("ErrorBarX"));
if ( xSeriesProp.is())
xSeriesProp->getPropertyValue( aPropName ) >>= xErrorBar;
return xErrorBar;
}
// static
bool StatisticsHelper::hasErrorBars(
const Reference< chart2::XDataSeries > & xDataSeries,
bool bYError /* = true */ )
{
Reference< beans::XPropertySet > xErrorBar( getErrorBars( xDataSeries, bYError ));
sal_Int32 nStyle = ::com::sun::star::chart::ErrorBarStyle::NONE;
return ( xErrorBar.is() &&
( xErrorBar->getPropertyValue( C2U("ErrorBarStyle")) >>= nStyle ) &&
nStyle != ::com::sun::star::chart::ErrorBarStyle::NONE );
}
// static
void StatisticsHelper::removeErrorBars(
const Reference< chart2::XDataSeries > & xDataSeries,
bool bYError /* = true */ )
{
Reference< beans::XPropertySet > xErrorBar( getErrorBars( xDataSeries, bYError ));
if ( xErrorBar.is())
xErrorBar->setPropertyValue( C2U("ErrorBarStyle"), uno::makeAny(
::com::sun::star::chart::ErrorBarStyle::NONE ));
}
// static
bool StatisticsHelper::usesErrorBarRanges(
const Reference< chart2::XDataSeries > & xDataSeries,
bool bYError /* = true */ )
{
Reference< beans::XPropertySet > xErrorBar( getErrorBars( xDataSeries, bYError ));
sal_Int32 nStyle = ::com::sun::star::chart::ErrorBarStyle::NONE;
return ( xErrorBar.is() &&
( xErrorBar->getPropertyValue( C2U("ErrorBarStyle")) >>= nStyle ) &&
nStyle == ::com::sun::star::chart::ErrorBarStyle::FROM_DATA );
}
} // namespace chart