LCOV - code coverage report
Current view: top level - chart2/source/tools - StatisticsHelper.cxx (source / functions) Hit Total Coverage
Test: commit e02a6cb2c3e2b23b203b422e4e0680877f232636 Lines: 0 158 0.0 %
Date: 2014-04-14 Functions: 0 17 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include "StatisticsHelper.hxx"
      21             : #include "DataSeriesHelper.hxx"
      22             : #include "ErrorBar.hxx"
      23             : #include "macros.hxx"
      24             : 
      25             : #include <rtl/math.hxx>
      26             : #include <rtl/ustrbuf.hxx>
      27             : #include <comphelper/processfactory.hxx>
      28             : 
      29             : #include <com/sun/star/chart2/data/LabeledDataSequence.hpp>
      30             : #include <com/sun/star/chart2/data/XNumericalDataSequence.hpp>
      31             : #include <com/sun/star/chart2/data/XDataSink.hpp>
      32             : #include <com/sun/star/chart/ErrorBarStyle.hpp>
      33             : 
      34             : using ::com::sun::star::uno::Sequence;
      35             : using ::com::sun::star::uno::Reference;
      36             : using namespace ::com::sun::star;
      37             : 
      38             : namespace
      39             : {
      40             : 
      41           0 : double lcl_getVariance( const Sequence< double > & rData, sal_Int32 & rOutValidCount,
      42             :         bool bUnbiasedEstimator )
      43             : {
      44           0 :     const sal_Int32 nCount = rData.getLength();
      45           0 :     rOutValidCount = nCount;
      46             : 
      47           0 :     double fSum = 0.0;
      48           0 :     double fQuadSum = 0.0;
      49             : 
      50           0 :     for( sal_Int32 i = 0; i < nCount; ++i )
      51             :     {
      52           0 :         const double fData = rData[i];
      53           0 :         if( ::rtl::math::isNan( fData ))
      54           0 :             --rOutValidCount;
      55             :         else
      56             :         {
      57           0 :             fSum     += fData;
      58           0 :             fQuadSum += fData * fData;
      59             :         }
      60             :     }
      61             : 
      62             :     double fResult;
      63           0 :     if( rOutValidCount == 0 )
      64           0 :         ::rtl::math::setNan( & fResult );
      65             :     else
      66             :     {
      67           0 :         const double fN = static_cast< double >( rOutValidCount );
      68           0 :         if( bUnbiasedEstimator )
      69           0 :             fResult = (fQuadSum - fSum*fSum/fN) / (fN - 1);
      70             :         else
      71           0 :             fResult = (fQuadSum - fSum*fSum/fN) / fN;
      72             :     }
      73             : 
      74           0 :     return fResult;
      75             : }
      76             : 
      77           0 : Reference< chart2::data::XLabeledDataSequence > lcl_getErrorBarLabeledSequence(
      78             :     const Reference< chart2::data::XDataSource > & xDataSource,
      79             :     bool bPositiveValue, bool bYError,
      80             :     OUString & rOutRoleNameUsed )
      81             : {
      82           0 :     OUStringBuffer aRole( "error-bars-");
      83           0 :     if( bYError )
      84           0 :         aRole.append( 'y');
      85             :     else
      86           0 :         aRole.append( 'x');
      87             : 
      88           0 :     OUString aPlainRole = aRole.makeStringAndClear();
      89           0 :     aRole.append( aPlainRole );
      90           0 :     aRole.append( '-' );
      91             : 
      92           0 :     if( bPositiveValue )
      93           0 :         aRole = aRole.appendAscii( "positive" );
      94             :     else
      95           0 :         aRole = aRole.appendAscii( "negative" );
      96             : 
      97           0 :     OUString aLongRole = aRole.makeStringAndClear();
      98             :     Reference< chart2::data::XLabeledDataSequence > xLSeq(
      99           0 :         ::chart::DataSeriesHelper::getDataSequenceByRole( xDataSource, aLongRole ));
     100             :     // try role without "-negative" or "-positive" postfix
     101           0 :     if( xLSeq.is())
     102           0 :         rOutRoleNameUsed = aLongRole;
     103             :     else
     104             :     {
     105           0 :         xLSeq.set( ::chart::DataSeriesHelper::getDataSequenceByRole( xDataSource, aPlainRole ));
     106           0 :         if( xLSeq.is())
     107           0 :             rOutRoleNameUsed = aPlainRole;
     108             :         else
     109           0 :             rOutRoleNameUsed = aLongRole;
     110             :     }
     111             : 
     112           0 :     return xLSeq;
     113             : }
     114             : 
     115           0 : void lcl_setRole(
     116             :     const Reference< chart2::data::XDataSequence > & xNewSequence,
     117             :     const OUString & rRole )
     118             : {
     119           0 :     Reference< beans::XPropertySet > xSeqProp( xNewSequence, uno::UNO_QUERY );
     120           0 :     if( xSeqProp.is())
     121           0 :         xSeqProp->setPropertyValue( "Role", uno::makeAny( rRole ));
     122           0 : }
     123             : 
     124           0 : void lcl_addSequenceToDataSource(
     125             :     const Reference< chart2::data::XDataSource > & xDataSource,
     126             :     const Reference< chart2::data::XDataSequence > & xNewSequence,
     127             :     const OUString & rRole )
     128             : {
     129           0 :     Reference< chart2::data::XDataSink > xSink( xDataSource, uno::UNO_QUERY );
     130           0 :     Reference< uno::XComponentContext > xContext( comphelper::getProcessComponentContext() );
     131           0 :     if( ! xSink.is() )
     132           0 :         return;
     133             : 
     134           0 :     Reference< chart2::data::XLabeledDataSequence > xLSeq( chart2::data::LabeledDataSequence::create(xContext), uno::UNO_QUERY_THROW );
     135             : 
     136           0 :     lcl_setRole( xNewSequence, rRole );
     137           0 :     xLSeq->setValues( xNewSequence );
     138             :     Sequence< Reference< chart2::data::XLabeledDataSequence > > aSequences(
     139           0 :         xDataSource->getDataSequences());
     140           0 :     aSequences.realloc( aSequences.getLength() + 1 );
     141           0 :     aSequences[ aSequences.getLength() - 1 ] = xLSeq;
     142           0 :     xSink->setData( aSequences );
     143             : }
     144             : 
     145           0 : void lcl_setXMLRangePropertyAtDataSequence(
     146             :     const Reference< chart2::data::XDataSequence > & xDataSequence,
     147             :     const OUString & rXMLRange )
     148             : {
     149             :     try
     150             :     {
     151           0 :         const OUString aXMLRangePropName( "CachedXMLRange");
     152           0 :         Reference< beans::XPropertySet > xProp( xDataSequence, uno::UNO_QUERY_THROW );
     153           0 :         Reference< beans::XPropertySetInfo > xInfo( xProp->getPropertySetInfo());
     154           0 :         if( xInfo.is() && xInfo->hasPropertyByName( aXMLRangePropName ))
     155           0 :             xProp->setPropertyValue( aXMLRangePropName, uno::makeAny( rXMLRange ));
     156             :     }
     157           0 :     catch( const uno::Exception & ex )
     158             :     {
     159             :         ASSERT_EXCEPTION( ex );
     160             :     }
     161           0 : }
     162             : 
     163             : } // anonymous namespace
     164             : 
     165             : namespace chart
     166             : {
     167             : 
     168           0 : double StatisticsHelper::getVariance(
     169             :     const Sequence< double > & rData,
     170             :     bool bUnbiasedEstimator /* = false */ )
     171             : {
     172             :     sal_Int32 nValCount;
     173           0 :     return lcl_getVariance( rData, nValCount, bUnbiasedEstimator );
     174             : }
     175             : 
     176           0 : double StatisticsHelper::getStandardDeviation( const Sequence< double > & rData )
     177             : {
     178           0 :     double fResult = getVariance( rData );
     179           0 :     if( ! ::rtl::math::isNan( fResult ))
     180           0 :         fResult = sqrt( fResult );
     181             : 
     182           0 :     return fResult;
     183             : }
     184             : 
     185           0 : double StatisticsHelper::getStandardError( const Sequence< double > & rData )
     186             : {
     187             :     sal_Int32 nValCount;
     188           0 :     double fVar = lcl_getVariance( rData, nValCount, false );
     189             :     double fResult;
     190             : 
     191           0 :     if( nValCount == 0 ||
     192           0 :         ::rtl::math::isNan( fVar ))
     193             :     {
     194           0 :         ::rtl::math::setNan( & fResult );
     195             :     }
     196             :     else
     197             :     {
     198             :         // standard-deviation / sqrt(n)
     199           0 :         fResult = sqrt( fVar ) / sqrt( double(nValCount) );
     200             :     }
     201             : 
     202           0 :     return fResult;
     203             : }
     204             : 
     205           0 : Reference< chart2::data::XLabeledDataSequence > StatisticsHelper::getErrorLabeledDataSequenceFromDataSource(
     206             :     const Reference< chart2::data::XDataSource > & xDataSource,
     207             :     bool bPositiveValue,
     208             :     bool bYError /* = true */ )
     209             : {
     210           0 :     Reference< chart2::data::XLabeledDataSequence > xResult;
     211           0 :     if( !xDataSource.is())
     212           0 :         return xResult;
     213             : 
     214           0 :     OUString aRole;
     215             :     Reference< chart2::data::XLabeledDataSequence > xLSeq(
     216           0 :         lcl_getErrorBarLabeledSequence( xDataSource, bPositiveValue, bYError, aRole ));
     217           0 :     if( xLSeq.is())
     218           0 :         xResult.set( xLSeq );
     219             : 
     220           0 :     return xResult;
     221             : }
     222             : 
     223           0 : Reference< chart2::data::XDataSequence > StatisticsHelper::getErrorDataSequenceFromDataSource(
     224             :     const Reference< chart2::data::XDataSource > & xDataSource,
     225             :     bool bPositiveValue,
     226             :     bool bYError /* = true */ )
     227             : {
     228             :     Reference< chart2::data::XLabeledDataSequence > xLSeq(
     229             :         StatisticsHelper::getErrorLabeledDataSequenceFromDataSource(
     230             :             xDataSource, bPositiveValue,
     231           0 :             bYError ));
     232           0 :     if( !xLSeq.is())
     233           0 :         return Reference< chart2::data::XDataSequence >();
     234             : 
     235           0 :     return xLSeq->getValues();
     236             : }
     237             : 
     238           0 : double StatisticsHelper::getErrorFromDataSource(
     239             :     const Reference< chart2::data::XDataSource > & xDataSource,
     240             :     sal_Int32 nIndex,
     241             :     bool bPositiveValue,
     242             :     bool bYError /* = true */ )
     243             : {
     244           0 :     double fResult = 0.0;
     245           0 :     ::rtl::math::setNan( & fResult );
     246             : 
     247             :     Reference< chart2::data::XDataSequence > xValues(
     248           0 :         StatisticsHelper::getErrorDataSequenceFromDataSource( xDataSource, bPositiveValue, bYError ));
     249             : 
     250           0 :     Reference< chart2::data::XNumericalDataSequence > xNumValues( xValues, uno::UNO_QUERY );
     251           0 :     if( xNumValues.is())
     252             :     {
     253           0 :         Sequence< double > aData( xNumValues->getNumericalData());
     254           0 :         if( nIndex < aData.getLength())
     255           0 :             fResult = aData[nIndex];
     256             :     }
     257           0 :     else if( xValues.is())
     258             :     {
     259           0 :         Sequence< uno::Any > aData( xValues->getData());
     260           0 :         if( nIndex < aData.getLength())
     261           0 :             aData[nIndex] >>= fResult;
     262             :     }
     263             : 
     264           0 :     return fResult;
     265             : }
     266             : 
     267           0 : void StatisticsHelper::setErrorDataSequence(
     268             :     const Reference< chart2::data::XDataSource > & xDataSource,
     269             :     const Reference< chart2::data::XDataProvider > & xDataProvider,
     270             :     const OUString & rNewRange,
     271             :     bool bPositiveValue,
     272             :     bool bYError /* = true */,
     273             :     OUString * pXMLRange /* = 0 */ )
     274             : {
     275           0 :     Reference< chart2::data::XDataSink > xDataSink( xDataSource, uno::UNO_QUERY );
     276           0 :     if( ! ( xDataSink.is() && xDataProvider.is()))
     277           0 :         return;
     278             : 
     279           0 :     OUString aRole;
     280             :     Reference< chart2::data::XLabeledDataSequence > xLSeq(
     281           0 :         lcl_getErrorBarLabeledSequence( xDataSource, bPositiveValue, bYError, aRole ));
     282             :     Reference< chart2::data::XDataSequence > xNewSequence(
     283           0 :         xDataProvider->createDataSequenceByRangeRepresentation( rNewRange ));
     284           0 :     if( xNewSequence.is())
     285             :     {
     286           0 :         if( pXMLRange )
     287           0 :             lcl_setXMLRangePropertyAtDataSequence( xNewSequence, *pXMLRange );
     288           0 :         if( xLSeq.is())
     289             :         {
     290           0 :             lcl_setRole( xNewSequence, aRole );
     291           0 :             xLSeq->setValues( xNewSequence );
     292             :         }
     293             :         else
     294           0 :             lcl_addSequenceToDataSource( xDataSource, xNewSequence, aRole );
     295           0 :     }
     296             : }
     297             : 
     298           0 : Reference< beans::XPropertySet > StatisticsHelper::addErrorBars(
     299             :     const Reference< chart2::XDataSeries > & xDataSeries,
     300             :     const Reference< uno::XComponentContext > & xContext,
     301             :     sal_Int32 nStyle,
     302             :     bool bYError /* = true */ )
     303             : {
     304           0 :     Reference< beans::XPropertySet > xErrorBar;
     305           0 :     Reference< beans::XPropertySet > xSeriesProp( xDataSeries, uno::UNO_QUERY );
     306           0 :     if( !xSeriesProp.is())
     307           0 :         return xErrorBar;
     308             : 
     309             :     const OUString aPropName(
     310           0 :             (bYError) ? OUString("ErrorBarY") : OUString("ErrorBarX"));
     311           0 :     if( !( xSeriesProp->getPropertyValue( aPropName ) >>= xErrorBar ) ||
     312           0 :         !xErrorBar.is())
     313             :     {
     314           0 :         xErrorBar.set( createErrorBar( xContext ));
     315             :     }
     316             : 
     317             :     OSL_ASSERT( xErrorBar.is());
     318           0 :     if( xErrorBar.is())
     319             :     {
     320           0 :         xErrorBar->setPropertyValue( "ErrorBarStyle", uno::makeAny( nStyle ));
     321             :     }
     322             : 
     323           0 :     xSeriesProp->setPropertyValue( aPropName, uno::makeAny( xErrorBar ));
     324             : 
     325           0 :     return xErrorBar;
     326             : }
     327             : 
     328           0 : Reference< beans::XPropertySet > StatisticsHelper::getErrorBars(
     329             :     const Reference< chart2::XDataSeries > & xDataSeries,
     330             :     bool bYError /* = true */ )
     331             : {
     332           0 :     Reference< beans::XPropertySet > xSeriesProp( xDataSeries, uno::UNO_QUERY );
     333           0 :     Reference< beans::XPropertySet > xErrorBar;
     334             :     const OUString aPropName(
     335           0 :             (bYError) ? OUString("ErrorBarY") : OUString("ErrorBarX"));
     336             : 
     337           0 :     if ( xSeriesProp.is())
     338           0 :         xSeriesProp->getPropertyValue( aPropName ) >>= xErrorBar;
     339             : 
     340           0 :     return xErrorBar;
     341             : }
     342             : 
     343           0 : bool StatisticsHelper::hasErrorBars(
     344             :     const Reference< chart2::XDataSeries > & xDataSeries,
     345             :     bool bYError /* = true */ )
     346             : {
     347           0 :     Reference< beans::XPropertySet > xErrorBar( getErrorBars( xDataSeries, bYError ));
     348           0 :     sal_Int32 nStyle = ::com::sun::star::chart::ErrorBarStyle::NONE;
     349             : 
     350           0 :     return ( xErrorBar.is() &&
     351           0 :              ( xErrorBar->getPropertyValue( "ErrorBarStyle") >>= nStyle ) &&
     352           0 :              nStyle != ::com::sun::star::chart::ErrorBarStyle::NONE );
     353             : }
     354             : 
     355           0 : void StatisticsHelper::removeErrorBars(
     356             :     const Reference< chart2::XDataSeries > & xDataSeries,
     357             :     bool bYError /* = true  */ )
     358             : {
     359           0 :     Reference< beans::XPropertySet > xErrorBar( getErrorBars( xDataSeries, bYError ));
     360           0 :     if ( xErrorBar.is())
     361           0 :         xErrorBar->setPropertyValue( "ErrorBarStyle", uno::makeAny(
     362           0 :                                          ::com::sun::star::chart::ErrorBarStyle::NONE ));
     363           0 : }
     364             : 
     365           0 : bool StatisticsHelper::usesErrorBarRanges(
     366             :     const Reference< chart2::XDataSeries > & xDataSeries,
     367             :     bool bYError /* = true */ )
     368             : {
     369           0 :     Reference< beans::XPropertySet > xErrorBar( getErrorBars( xDataSeries, bYError ));
     370           0 :     sal_Int32 nStyle = ::com::sun::star::chart::ErrorBarStyle::NONE;
     371             : 
     372           0 :     return ( xErrorBar.is() &&
     373           0 :              ( xErrorBar->getPropertyValue( "ErrorBarStyle") >>= nStyle ) &&
     374           0 :              nStyle == ::com::sun::star::chart::ErrorBarStyle::FROM_DATA );
     375             : }
     376             : 
     377             : } //  namespace chart
     378             : 
     379             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10