LCOV - code coverage report
Current view: top level - chart2/source/view/main - VDataSeries.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 423 576 73.4 %
Date: 2015-06-13 12:38:46 Functions: 64 74 86.5 %
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 "VDataSeries.hxx"
      21             : #include "ObjectIdentifier.hxx"
      22             : #include "macros.hxx"
      23             : #include "CommonConverters.hxx"
      24             : #include "LabelPositionHelper.hxx"
      25             : #include "ChartTypeHelper.hxx"
      26             : #include "ContainerHelper.hxx"
      27             : #include "DataSeriesHelper.hxx"
      28             : #include "RegressionCurveHelper.hxx"
      29             : #include <unonames.hxx>
      30             : 
      31             : #include <com/sun/star/chart/MissingValueTreatment.hpp>
      32             : #include <com/sun/star/chart2/Symbol.hpp>
      33             : 
      34             : #include <rtl/math.hxx>
      35             : #include <com/sun/star/beans/XPropertySet.hpp>
      36             : #include <com/sun/star/beans/XPropertyState.hpp>
      37             : #include <com/sun/star/drawing/LineStyle.hpp>
      38             : #include <com/sun/star/drawing/TextVerticalAdjust.hpp>
      39             : #include <com/sun/star/drawing/TextHorizontalAdjust.hpp>
      40             : #include <com/sun/star/text/WritingMode.hpp>
      41             : #include <com/sun/star/chart2/data/XDataSource.hpp>
      42             : 
      43             : namespace chart {
      44             : 
      45             : using namespace ::com::sun::star;
      46             : using namespace ::com::sun::star::chart2;
      47             : using ::com::sun::star::uno::Reference;
      48             : 
      49        3253 : void VDataSequence::init( const uno::Reference< data::XDataSequence >& xModel )
      50             : {
      51        3253 :     Model = xModel;
      52        3253 :     Doubles = DataSequenceToDoubleSequence( xModel );
      53        3253 : }
      54             : 
      55      135815 : bool VDataSequence::is() const
      56             : {
      57      135815 :     return Model.is();
      58             : }
      59        3038 : void VDataSequence::clear()
      60             : {
      61        3038 :     Model = NULL;
      62        3038 :     Doubles.realloc(0);
      63        3038 : }
      64             : 
      65         618 : double VDataSequence::getValue( sal_Int32 index ) const
      66             : {
      67         618 :     if( 0<=index && index<Doubles.getLength() )
      68         486 :         return Doubles[index];
      69             :     else
      70             :     {
      71             :         double fNan;
      72         132 :         ::rtl::math::setNan( & fNan );
      73         132 :         return fNan;
      74             :     }
      75             : }
      76             : 
      77        1104 : sal_Int32 VDataSequence::detectNumberFormatKey( sal_Int32 index ) const
      78             : {
      79        1104 :     sal_Int32 nNumberFormatKey = -1;
      80             : 
      81             :     // -1 is allowed and means a key for the whole sequence
      82        2208 :     if( -1<=index && index<Doubles.getLength() &&
      83        1104 :         Model.is())
      84             :     {
      85        1104 :         nNumberFormatKey = Model->getNumberFormatKeyByIndex( index );
      86             :     }
      87             : 
      88        1104 :     return nNumberFormatKey;
      89             : }
      90             : 
      91       63056 : sal_Int32 VDataSequence::getLength() const
      92             : {
      93       63056 :     return Doubles.getLength();
      94             : }
      95             : 
      96             : namespace
      97             : {
      98             : struct lcl_LessXOfPoint
      99             : {
     100           0 :     inline bool operator() ( const std::vector< double >& first,
     101             :                              const std::vector< double >& second )
     102             :     {
     103           0 :         if( !first.empty() && !second.empty() )
     104             :         {
     105           0 :             return first[0]<second[0];
     106             :         }
     107           0 :         return false;
     108             :     }
     109             : };
     110             : 
     111         121 : void lcl_clearIfNoValuesButTextIsContained( VDataSequence& rData, const uno::Reference<data::XDataSequence>& xDataSequence )
     112             : {
     113             :     //#i71686#, #i101968#, #i102428#
     114         121 :     sal_Int32 nCount = rData.Doubles.getLength();
     115         297 :     for( sal_Int32 i = 0; i < nCount; ++i )
     116             :     {
     117         227 :         if( !::rtl::math::isNan( rData.Doubles[i] ) )
     118         147 :             return;
     119             :     }
     120             :     //no double value is countained
     121             :     //is there any text?
     122          70 :     uno::Sequence< OUString > aStrings( DataSequenceToStringSequence( xDataSequence ) );
     123          70 :     sal_Int32 nTextCount = aStrings.getLength();
     124          70 :     for( sal_Int32 j = 0; j < nTextCount; ++j )
     125             :     {
     126          45 :         if( !aStrings[j].isEmpty() )
     127             :         {
     128          45 :             rData.clear();
     129          45 :             return;
     130             :         }
     131          25 :     }
     132             :     //no content at all
     133             : }
     134             : 
     135      110335 : void lcl_maybeReplaceNanWithZero( double& rfValue, sal_Int32 nMissingValueTreatment )
     136             : {
     137      110335 :     if( nMissingValueTreatment == ::com::sun::star::chart::MissingValueTreatment::USE_ZERO
     138      110335 :         && (::rtl::math::isNan(rfValue) || ::rtl::math::isInf(rfValue)) )
     139          12 :             rfValue = 0.0;
     140      110335 : }
     141             : 
     142             : }
     143             : 
     144        3098 : VDataSeries::VDataSeries( const uno::Reference< XDataSeries >& xDataSeries )
     145             :     : m_nPolygonIndex(0)
     146             :     , m_fLogicMinX(0.0)
     147             :     , m_fLogicMaxX(0.0)
     148             :     , m_fLogicZPos(0.0)
     149             :     , m_xGroupShape(NULL)
     150             :     , m_xLabelsGroupShape(NULL)
     151             :     , m_xErrorXBarsGroupShape(NULL)
     152             :     , m_xErrorYBarsGroupShape(NULL)
     153             :     , m_xFrontSubGroupShape(NULL)
     154             :     , m_xBackSubGroupShape(NULL)
     155             :     , m_xDataSeries(xDataSeries)
     156             :     , m_nPointCount(0)
     157             : 
     158             :     , m_pValueSequenceForDataLabelNumberFormatDetection(&m_aValues_Y)
     159             : 
     160             :     , m_fXMeanValue(1.0)
     161             :     , m_fYMeanValue(1.0)
     162             : 
     163             :     , m_aAttributedDataPointIndexList()
     164             : 
     165             :     , m_eStackingDirection(StackingDirection_NO_STACKING)
     166             :     , m_nAxisIndex(0)
     167             :     , m_bConnectBars(false)
     168             :     , m_bGroupBarsPerAxis(true)
     169             :     , m_nStartingAngle(90)
     170             : 
     171             :     , m_nGlobalSeriesIndex(0)
     172             : 
     173             :     , m_apLabel_Series(NULL)
     174             :     , m_apLabelPropNames_Series(NULL)
     175             :     , m_apLabelPropValues_Series(NULL)
     176             :     , m_apSymbolProperties_Series(NULL)
     177             : 
     178             :     , m_apLabel_AttributedPoint(NULL)
     179             :     , m_apLabelPropNames_AttributedPoint(NULL)
     180             :     , m_apLabelPropValues_AttributedPoint(NULL)
     181             :     , m_apSymbolProperties_AttributedPoint(NULL)
     182             :     , m_apSymbolProperties_InvisibleSymbolForSelection(NULL)
     183             :     , m_nCurrentAttributedPoint(-1)
     184             :     , m_nMissingValueTreatment(::com::sun::star::chart::MissingValueTreatment::LEAVE_GAP)
     185             :     , m_bAllowPercentValueInDataLabel(false)
     186             :     , mpOldSeries(NULL)
     187        3098 :     , mnPercent(0.0)
     188             : {
     189        3098 :     ::rtl::math::setNan( & m_fXMeanValue );
     190        3098 :     ::rtl::math::setNan( & m_fYMeanValue );
     191             : 
     192             :     uno::Reference<data::XDataSource> xDataSource =
     193        3098 :             uno::Reference<data::XDataSource>( xDataSeries, uno::UNO_QUERY );
     194             : 
     195             :     uno::Sequence< uno::Reference<
     196             :         chart2::data::XLabeledDataSequence > > aDataSequences =
     197        6196 :             xDataSource->getDataSequences();
     198             : 
     199        9395 :     for(sal_Int32 nN = aDataSequences.getLength();nN--;)
     200             :     {
     201        3199 :         if(!aDataSequences[nN].is())
     202           0 :             continue;
     203        3199 :         uno::Reference<data::XDataSequence>  xDataSequence( aDataSequences[nN]->getValues());
     204        6398 :         uno::Reference<beans::XPropertySet> xProp(xDataSequence, uno::UNO_QUERY );
     205        3199 :         if( xProp.is())
     206             :         {
     207             :             try
     208             :             {
     209        3199 :                 uno::Any aARole = xProp->getPropertyValue("Role");
     210        6398 :                 OUString aRole;
     211        3199 :                 aARole >>= aRole;
     212             : 
     213        3199 :                 if (aRole == "values-x")
     214             :                 {
     215          67 :                     m_aValues_X.init( xDataSequence );
     216          67 :                     lcl_clearIfNoValuesButTextIsContained( m_aValues_X, xDataSequence );
     217             :                 }
     218        3132 :                 else if (aRole =="values-y")
     219        3084 :                     m_aValues_Y.init( xDataSequence );
     220          48 :                 else if (aRole == "values-min")
     221          14 :                     m_aValues_Y_Min.init( xDataSequence );
     222          34 :                 else if (aRole == "values-max")
     223          12 :                     m_aValues_Y_Max.init( xDataSequence );
     224          22 :                 else if (aRole == "values-first")
     225           4 :                     m_aValues_Y_First.init( xDataSequence );
     226          18 :                 else if (aRole == "values-last")
     227          12 :                     m_aValues_Y_Last.init( xDataSequence );
     228           6 :                 else if (aRole == "values-size")
     229           6 :                     m_aValues_Bubble_Size.init( xDataSequence );
     230             :                 else
     231             :                 {
     232           0 :                     VDataSequence* pSequence = new VDataSequence();
     233           0 :                     pSequence->init( xDataSequence );
     234           0 :                     maPropertyMap.insert(aRole, pSequence);
     235        3199 :                 }
     236             :             }
     237           0 :             catch( const uno::Exception& e )
     238             :             {
     239             :                 ASSERT_EXCEPTION( e );
     240             :             }
     241             :         }
     242        3199 :     }
     243             : 
     244             :     //determine the point count
     245        3098 :     m_nPointCount = m_aValues_Y.getLength();
     246             :     {
     247        3098 :         if( m_nPointCount < m_aValues_Bubble_Size.getLength() )
     248           0 :             m_nPointCount = m_aValues_Bubble_Size.getLength();
     249        3098 :         if( m_nPointCount < m_aValues_Y_Min.getLength() )
     250          14 :             m_nPointCount = m_aValues_Y_Min.getLength();
     251        3098 :         if( m_nPointCount < m_aValues_Y_Max.getLength() )
     252           0 :             m_nPointCount = m_aValues_Y_Max.getLength();
     253        3098 :         if( m_nPointCount < m_aValues_Y_First.getLength() )
     254           0 :             m_nPointCount = m_aValues_Y_First.getLength();
     255        3098 :         if( m_nPointCount < m_aValues_Y_Last.getLength() )
     256           0 :             m_nPointCount = m_aValues_Y_Last.getLength();
     257             :     }
     258             : 
     259        6196 :     uno::Reference<beans::XPropertySet> xProp(xDataSeries, uno::UNO_QUERY );
     260        3098 :     if( xProp.is())
     261             :     {
     262             :         try
     263             :         {
     264             :             //get AttributedDataPoints
     265        3098 :             xProp->getPropertyValue("AttributedDataPoints") >>= m_aAttributedDataPointIndexList;
     266             : 
     267        3098 :             xProp->getPropertyValue("StackingDirection") >>= m_eStackingDirection;
     268             : 
     269        3098 :             xProp->getPropertyValue("AttachedAxisIndex") >>= m_nAxisIndex;
     270        3098 :             if(m_nAxisIndex<0)
     271           0 :                 m_nAxisIndex=0;
     272             :         }
     273           0 :         catch( const uno::Exception& e )
     274             :         {
     275             :             ASSERT_EXCEPTION( e );
     276             :         }
     277        3098 :     }
     278        3098 : }
     279             : 
     280        3098 : VDataSeries::~VDataSeries()
     281             : {
     282        3098 : }
     283             : 
     284           0 : void VDataSeries::doSortByXValues()
     285             : {
     286           0 :     if( m_aValues_X.is() && m_aValues_X.Doubles.getLength() )
     287             :     {
     288             :         //prepare a vector for sorting
     289           0 :         std::vector< ::std::vector< double > > aTmp;//outer vector are points, inner vector are the different values of athe point
     290             :         double fNan;
     291           0 :         ::rtl::math::setNan( & fNan );
     292           0 :         sal_Int32 nPointIndex = 0;
     293           0 :         for( nPointIndex=0; nPointIndex < m_nPointCount; nPointIndex++ )
     294             :         {
     295           0 :             std::vector< double > aSinglePoint;
     296           0 :             aSinglePoint.push_back( (nPointIndex < m_aValues_X.Doubles.getLength()) ? m_aValues_X.Doubles[nPointIndex] : fNan );
     297           0 :             aSinglePoint.push_back( (nPointIndex < m_aValues_Y.Doubles.getLength()) ? m_aValues_Y.Doubles[nPointIndex] : fNan );
     298           0 :             aTmp.push_back( aSinglePoint );
     299           0 :         }
     300             : 
     301             :         //do sort
     302           0 :         std::stable_sort( aTmp.begin(), aTmp.end(), lcl_LessXOfPoint() );
     303             : 
     304             :         //fill the sorted points back to the members
     305           0 :         m_aValues_X.Doubles.realloc( m_nPointCount );
     306           0 :         m_aValues_Y.Doubles.realloc( m_nPointCount );
     307             : 
     308           0 :         for( nPointIndex=0; nPointIndex < m_nPointCount; nPointIndex++ )
     309             :         {
     310           0 :             m_aValues_X.Doubles[nPointIndex]=aTmp[nPointIndex][0];
     311           0 :             m_aValues_Y.Doubles[nPointIndex]=aTmp[nPointIndex][1];
     312           0 :         }
     313             :     }
     314           0 : }
     315             : 
     316          66 : void VDataSeries::releaseShapes()
     317             : {
     318          66 :     m_xGroupShape.set(0);
     319          66 :     m_xLabelsGroupShape.set(0);
     320          66 :     m_xErrorXBarsGroupShape.set(0);
     321          66 :     m_xErrorYBarsGroupShape.set(0);
     322          66 :     m_xFrontSubGroupShape.set(0);
     323          66 :     m_xBackSubGroupShape.set(0);
     324             : 
     325          66 :     m_aPolyPolygonShape3D.SequenceX.realloc(0);
     326          66 :     m_aPolyPolygonShape3D.SequenceY.realloc(0);
     327          66 :     m_aPolyPolygonShape3D.SequenceZ.realloc(0);
     328          66 :     m_nPolygonIndex = 0;
     329          66 : }
     330             : 
     331       10414 : uno::Reference<css::chart2::XDataSeries> VDataSeries::getModel() const
     332             : {
     333       10414 :     return m_xDataSeries;
     334             : }
     335             : 
     336        2993 : void VDataSeries::setCategoryXAxis()
     337             : {
     338        2993 :     m_aValues_X.clear();
     339        2993 :     m_bAllowPercentValueInDataLabel = true;
     340        2993 : }
     341             : 
     342           0 : void VDataSeries::setXValues( const Reference< chart2::data::XDataSequence >& xValues )
     343             : {
     344           0 :     m_aValues_X.clear();
     345           0 :     m_aValues_X.init( xValues );
     346           0 :     m_bAllowPercentValueInDataLabel = true;
     347           0 : }
     348             : 
     349         105 : void VDataSeries::setXValuesIfNone( const Reference< chart2::data::XDataSequence >& xValues )
     350             : {
     351         105 :     if( m_aValues_X.is() )
     352         156 :         return;
     353             : 
     354          54 :     m_aValues_X.init( xValues );
     355          54 :     lcl_clearIfNoValuesButTextIsContained( m_aValues_X, xValues );
     356             : }
     357             : 
     358        3098 : void VDataSeries::setGlobalSeriesIndex( sal_Int32 nGlobalSeriesIndex )
     359             : {
     360        3098 :     m_nGlobalSeriesIndex = nGlobalSeriesIndex;
     361        3098 : }
     362             : 
     363        3098 : void VDataSeries::setParticle( const OUString& rSeriesParticle )
     364             : {
     365        3098 :     m_aSeriesParticle = rSeriesParticle;
     366             : 
     367             :     //get CID
     368        3098 :     m_aCID = ObjectIdentifier::createClassifiedIdentifierForParticle( m_aSeriesParticle );
     369        3098 :     m_aPointCID_Stub = ObjectIdentifier::createSeriesSubObjectStub( OBJECTTYPE_DATA_POINT, m_aSeriesParticle );
     370             : 
     371        6196 :     m_aLabelCID_Stub = ObjectIdentifier::createClassifiedIdentifierWithParent(
     372        3098 :                         OBJECTTYPE_DATA_LABEL, OUString(), getLabelsCID() );
     373        3098 : }
     374         880 : OUString VDataSeries::getErrorBarsCID(bool bYError) const
     375             : {
     376             :     OUString aChildParticle( ObjectIdentifier::getStringForType(
     377         880 :                                       bYError ? OBJECTTYPE_DATA_ERRORS_Y : OBJECTTYPE_DATA_ERRORS_X ) );
     378         880 :     aChildParticle += "=";
     379             : 
     380             :     return ObjectIdentifier::createClassifiedIdentifierForParticles(
     381         880 :             m_aSeriesParticle, aChildParticle );
     382             : }
     383        3473 : OUString VDataSeries::getLabelsCID() const
     384             : {
     385        3473 :     OUString aChildParticle( ObjectIdentifier::getStringForType( OBJECTTYPE_DATA_LABELS ) );
     386        3473 :     aChildParticle += "=";
     387             : 
     388             :     return ObjectIdentifier::createClassifiedIdentifierForParticles(
     389        3473 :             m_aSeriesParticle, aChildParticle );
     390             : }
     391          54 : OUString VDataSeries::getDataCurveCID( sal_Int32 nCurveIndex, bool bAverageLine ) const
     392             : {
     393          54 :     OUString aRet;
     394          54 :     aRet = ObjectIdentifier::createDataCurveCID( m_aSeriesParticle, nCurveIndex, bAverageLine );
     395          54 :     return aRet;
     396             : }
     397             : 
     398          60 : OUString VDataSeries::getDataCurveEquationCID( sal_Int32 nCurveIndex ) const
     399             : {
     400          60 :     OUString aRet;
     401          60 :     aRet = ObjectIdentifier::createDataCurveEquationCID( m_aSeriesParticle, nCurveIndex );
     402          60 :     return aRet;
     403             : }
     404        3098 : void VDataSeries::setPageReferenceSize( const awt::Size & rPageRefSize )
     405             : {
     406        3098 :     m_aReferenceSize = rPageRefSize;
     407        3098 : }
     408             : 
     409        3098 : void VDataSeries::setConnectBars( bool bConnectBars )
     410             : {
     411        3098 :     m_bConnectBars = bConnectBars;
     412        3098 : }
     413             : 
     414         883 : bool VDataSeries::getConnectBars() const
     415             : {
     416         883 :     return m_bConnectBars;
     417             : }
     418             : 
     419        3098 : void VDataSeries::setGroupBarsPerAxis( bool bGroupBarsPerAxis )
     420             : {
     421        3098 :     m_bGroupBarsPerAxis = bGroupBarsPerAxis;
     422        3098 : }
     423             : 
     424        3436 : bool VDataSeries::getGroupBarsPerAxis() const
     425             : {
     426        3436 :     return m_bGroupBarsPerAxis;
     427             : }
     428             : 
     429        3098 : void VDataSeries::setStartingAngle( sal_Int32 nStartingAngle )
     430             : {
     431        3098 :     m_nStartingAngle = nStartingAngle;
     432        3098 : }
     433             : 
     434          74 : sal_Int32 VDataSeries::getStartingAngle() const
     435             : {
     436          74 :     return m_nStartingAngle;
     437             : }
     438             : 
     439        5619 : chart2::StackingDirection VDataSeries::getStackingDirection() const
     440             : {
     441        5619 :     return m_eStackingDirection;
     442             : }
     443             : 
     444       45567 : sal_Int32 VDataSeries::getAttachedAxisIndex() const
     445             : {
     446       45567 :     return m_nAxisIndex;
     447             : }
     448             : 
     449           0 : void VDataSeries::setAttachedAxisIndex( sal_Int32 nAttachedAxisIndex )
     450             : {
     451           0 :     if( nAttachedAxisIndex < 0 )
     452           0 :         nAttachedAxisIndex = 0;
     453           0 :     m_nAxisIndex = nAttachedAxisIndex;
     454           0 : }
     455             : 
     456       68121 : double VDataSeries::getXValue( sal_Int32 index ) const
     457             : {
     458       68121 :     double fRet = 0.0;
     459       68121 :     if(m_aValues_X.is())
     460             :     {
     461        2166 :         if( 0<=index && index<m_aValues_X.getLength() )
     462             :         {
     463        2166 :             fRet = m_aValues_X.Doubles[index];
     464        2166 :             if(mpOldSeries && index < mpOldSeries->m_aValues_X.getLength())
     465             :             {
     466           0 :                 double nOldVal = mpOldSeries->m_aValues_X.Doubles[index];
     467           0 :                 fRet = nOldVal + (fRet - nOldVal) * mnPercent;
     468             :             }
     469             :         }
     470             :         else
     471           0 :             ::rtl::math::setNan( &fRet );
     472             :     }
     473             :     else
     474             :     {
     475             :         // #i70133# always return correct X position - needed for short data series
     476       65955 :         if( 0<=index /*&& index < m_nPointCount*/ )
     477       65955 :             fRet = index+1;//first category (index 0) matches with real number 1.0
     478             :         else
     479           0 :             ::rtl::math::setNan( &fRet );
     480             :     }
     481       68121 :     lcl_maybeReplaceNanWithZero( fRet, getMissingValueTreatment() );
     482       68121 :     return fRet;
     483             : }
     484             : 
     485       42214 : double VDataSeries::getYValue( sal_Int32 index ) const
     486             : {
     487       42214 :     double fRet = 0.0;
     488       42214 :     if(m_aValues_Y.is())
     489             :     {
     490       42214 :         if( 0<=index && index<m_aValues_Y.getLength() )
     491             :         {
     492       42214 :             fRet = m_aValues_Y.Doubles[index];
     493       42214 :             if(mpOldSeries && index < mpOldSeries->m_aValues_Y.getLength())
     494             :             {
     495           0 :                 double nOldVal = mpOldSeries->m_aValues_Y.Doubles[index];
     496           0 :                 fRet = nOldVal + (fRet - nOldVal) * mnPercent;
     497             :             }
     498             :         }
     499             :         else
     500           0 :             ::rtl::math::setNan( &fRet );
     501             :     }
     502             :     else
     503             :     {
     504             :         // #i70133# always return correct X position - needed for short data series
     505           0 :         if( 0<=index /*&& index < m_nPointCount*/ )
     506           0 :             fRet = index+1;//first category (index 0) matches with real number 1.0
     507             :         else
     508           0 :             ::rtl::math::setNan( &fRet );
     509             :     }
     510       42214 :     lcl_maybeReplaceNanWithZero( fRet, getMissingValueTreatment() );
     511       42214 :     return fRet;
     512             : }
     513             : 
     514          23 : void VDataSeries::getMinMaxXValue(double& fMin, double& fMax) const
     515             : {
     516          23 :     rtl::math::setNan( &fMax );
     517          23 :     rtl::math::setNan( &fMin );
     518             : 
     519          23 :     uno::Sequence< double > aValuesX = getAllX();
     520             : 
     521          23 :     if(aValuesX.getLength() > 0)
     522             :     {
     523          23 :         fMax = fMin = aValuesX[0];
     524             : 
     525         155 :         for (sal_Int32 i = 1; i < aValuesX.getLength(); i++)
     526             :         {
     527         132 :             const double aValue = aValuesX[i];
     528         132 :             if ( aValue > fMax)
     529             :             {
     530         132 :                 fMax = aValue;
     531             :             }
     532           0 :             else if ( aValue < fMin)
     533             :             {
     534           0 :                 fMin = aValue;
     535             :             }
     536             :         }
     537          23 :     }
     538          23 : }
     539         150 : double VDataSeries::getY_Min( sal_Int32 index ) const
     540             : {
     541         150 :     return m_aValues_Y_Min.getValue( index );
     542             : }
     543         150 : double VDataSeries::getY_Max( sal_Int32 index ) const
     544             : {
     545         150 :     return m_aValues_Y_Max.getValue( index );
     546             : }
     547         150 : double VDataSeries::getY_First( sal_Int32 index ) const
     548             : {
     549         150 :     return m_aValues_Y_First.getValue( index );
     550             : }
     551         150 : double VDataSeries::getY_Last( sal_Int32 index ) const
     552             : {
     553         150 :     return m_aValues_Y_Last.getValue( index );
     554             : }
     555          18 : double VDataSeries::getBubble_Size( sal_Int32 index ) const
     556             : {
     557          18 :     double nNewVal = m_aValues_Bubble_Size.getValue( index );
     558          18 :     if(mpOldSeries && index < mpOldSeries->m_aValues_Bubble_Size.getLength())
     559             :     {
     560           0 :         double nOldVal = mpOldSeries->m_aValues_Bubble_Size.getValue( index );
     561           0 :         nNewVal = nOldVal + (nNewVal - nOldVal) * mnPercent;
     562             :     }
     563             : 
     564          18 :     return nNewVal;
     565             : }
     566             : 
     567        1700 : bool VDataSeries::hasExplicitNumberFormat( sal_Int32 nPointIndex, bool bForPercentage ) const
     568             : {
     569        1700 :     OUString aPropName = bForPercentage ? OUString("PercentageNumberFormat") : OUString(CHART_UNONAME_NUMFMT);
     570        1700 :     bool bHasNumberFormat = false;
     571        3400 :     uno::Reference< beans::XPropertySet > xPointProp( this->getPropertiesOfPoint( nPointIndex ));
     572        1700 :     sal_Int32 nNumberFormat = -1;
     573        1700 :     if( xPointProp.is() && (xPointProp->getPropertyValue(aPropName) >>= nNumberFormat) )
     574         297 :         bHasNumberFormat = true;
     575        3400 :     return bHasNumberFormat;
     576             : }
     577         297 : sal_Int32 VDataSeries::getExplicitNumberFormat( sal_Int32 nPointIndex, bool bForPercentage ) const
     578             : {
     579         297 :     OUString aPropName = bForPercentage ? OUString("PercentageNumberFormat") : OUString(CHART_UNONAME_NUMFMT);
     580         297 :     sal_Int32 nNumberFormat = -1;
     581         594 :     uno::Reference< beans::XPropertySet > xPointProp( this->getPropertiesOfPoint( nPointIndex ));
     582         297 :     if( xPointProp.is() )
     583         297 :         xPointProp->getPropertyValue(aPropName) >>= nNumberFormat;
     584         594 :     return nNumberFormat;
     585             : }
     586        3098 : void VDataSeries::setRoleOfSequenceForDataLabelNumberFormatDetection( const OUString& rRole )
     587             : {
     588        3098 :     if (rRole == "values-y")
     589        3075 :         m_pValueSequenceForDataLabelNumberFormatDetection = &m_aValues_Y;
     590          23 :     else if (rRole == "values-size")
     591           9 :         m_pValueSequenceForDataLabelNumberFormatDetection = &m_aValues_Bubble_Size;
     592          14 :     else if (rRole == "values-min")
     593           0 :         m_pValueSequenceForDataLabelNumberFormatDetection = &m_aValues_Y_Min;
     594          14 :     else if (rRole == "values-max")
     595           0 :         m_pValueSequenceForDataLabelNumberFormatDetection = &m_aValues_Y_Max;
     596          14 :     else if (rRole == "values-first")
     597           0 :         m_pValueSequenceForDataLabelNumberFormatDetection = &m_aValues_Y_First;
     598          14 :     else if (rRole == "values-last")
     599          14 :         m_pValueSequenceForDataLabelNumberFormatDetection = &m_aValues_Y_Last;
     600           0 :     else if (rRole == "values-x")
     601           0 :         m_pValueSequenceForDataLabelNumberFormatDetection = &m_aValues_X;
     602        3098 : }
     603        1260 : bool VDataSeries::shouldLabelNumberFormatKeyBeDetectedFromYAxis() const
     604             : {
     605        1260 :     if( m_pValueSequenceForDataLabelNumberFormatDetection == &m_aValues_Bubble_Size )
     606           0 :         return false;
     607        1260 :     else if( m_pValueSequenceForDataLabelNumberFormatDetection == &m_aValues_X )
     608           0 :         return false;
     609        1260 :     return true;
     610             : }
     611        1104 : sal_Int32 VDataSeries::detectNumberFormatKey( sal_Int32 index ) const
     612             : {
     613        1104 :     sal_Int32 nRet = 0;
     614        1104 :     if( m_pValueSequenceForDataLabelNumberFormatDetection )
     615        1104 :         nRet = m_pValueSequenceForDataLabelNumberFormatDetection->detectNumberFormatKey( index );
     616        1104 :     return nRet;
     617             : }
     618             : 
     619        1674 : sal_Int32 VDataSeries::getLabelPlacement( sal_Int32 nPointIndex, const uno::Reference< chart2::XChartType >& xChartType, sal_Int32 nDimensionCount, bool bSwapXAndY ) const
     620             : {
     621        1674 :     sal_Int32 nLabelPlacement=0;
     622             :     try
     623             :     {
     624        1674 :         uno::Reference< beans::XPropertySet > xPointProps( this->getPropertiesOfPoint( nPointIndex ) );
     625        1674 :         if( xPointProps.is() )
     626        1674 :             xPointProps->getPropertyValue("LabelPlacement") >>= nLabelPlacement;
     627             : 
     628             :         //ensure that the set label placement is supported by this charttype
     629             : 
     630             :         uno::Sequence < sal_Int32 > aAvailablePlacements( ChartTypeHelper::getSupportedLabelPlacements(
     631        1674 :                 xChartType, nDimensionCount, bSwapXAndY, m_xDataSeries ) );
     632             : 
     633        9195 :         for( sal_Int32 nN = 0; nN < aAvailablePlacements.getLength(); nN++ )
     634        7700 :             if( aAvailablePlacements[nN] == nLabelPlacement )
     635         179 :                 return nLabelPlacement; //ok
     636             : 
     637             :         //otherwise use the first supported one
     638        1495 :         if( aAvailablePlacements.getLength() )
     639             :         {
     640        1495 :             nLabelPlacement = aAvailablePlacements[0];
     641        1495 :             return nLabelPlacement;
     642             :         }
     643             : 
     644           0 :         OSL_FAIL("no label placement supported");
     645             :     }
     646           0 :     catch( const uno::Exception& e )
     647             :     {
     648             :         ASSERT_EXCEPTION( e );
     649             :     }
     650           0 :     return nLabelPlacement;
     651             : }
     652             : 
     653       12434 : double VDataSeries::getMinimumofAllDifferentYValues( sal_Int32 index ) const
     654             : {
     655       12434 :     double fMin=0.0;
     656       12434 :     ::rtl::math::setInf(&fMin, false);
     657             : 
     658       12534 :     if( !m_aValues_Y.is() &&
     659          50 :         (m_aValues_Y_Min.is() || m_aValues_Y_Max.is()
     660           0 :         || m_aValues_Y_First.is() || m_aValues_Y_Last.is() ) )
     661             :     {
     662          50 :         double fY_Min = getY_Min( index );
     663          50 :         double fY_Max = getY_Max( index );
     664          50 :         double fY_First = getY_First( index );
     665          50 :         double fY_Last = getY_Last( index );
     666             : 
     667          50 :         if(fMin>fY_First)
     668          20 :             fMin=fY_First;
     669          50 :         if(fMin>fY_Last)
     670          32 :             fMin=fY_Last;
     671          50 :         if(fMin>fY_Min)
     672          30 :             fMin=fY_Min;
     673          50 :         if(fMin>fY_Max)
     674          18 :             fMin=fY_Max;
     675             :     }
     676             :     else
     677             :     {
     678       12384 :         double fY = getYValue( index );
     679       12384 :         if(fMin>fY)
     680       12353 :             fMin=fY;
     681             :     }
     682             : 
     683       12434 :     if( ::rtl::math::isInf(fMin) )
     684          31 :         ::rtl::math::setNan(&fMin);
     685             : 
     686       12434 :     return fMin;
     687             : }
     688             : 
     689       12434 : double VDataSeries::getMaximumofAllDifferentYValues( sal_Int32 index ) const
     690             : {
     691       12434 :     double fMax=0.0;
     692       12434 :     ::rtl::math::setInf(&fMax, true);
     693             : 
     694       12534 :     if( !m_aValues_Y.is() &&
     695          50 :         (m_aValues_Y_Min.is() || m_aValues_Y_Max.is()
     696           0 :         || m_aValues_Y_First.is() || m_aValues_Y_Last.is() ) )
     697             :     {
     698          50 :         double fY_Min = getY_Min( index );
     699          50 :         double fY_Max = getY_Max( index );
     700          50 :         double fY_First = getY_First( index );
     701          50 :         double fY_Last = getY_Last( index );
     702             : 
     703          50 :         if(fMax<fY_First)
     704          20 :             fMax=fY_First;
     705          50 :         if(fMax<fY_Last)
     706          36 :             fMax=fY_Last;
     707          50 :         if(fMax<fY_Min)
     708          26 :             fMax=fY_Min;
     709          50 :         if(fMax<fY_Max)
     710          18 :             fMax=fY_Max;
     711             :     }
     712             :     else
     713             :     {
     714       12384 :         double fY = getYValue( index );
     715       12384 :         if(fMax<fY)
     716       12353 :             fMax=fY;
     717             :     }
     718             : 
     719       12434 :     if( ::rtl::math::isInf(fMax) )
     720          31 :         ::rtl::math::setNan(&fMax);
     721             : 
     722       12434 :     return fMax;
     723             : }
     724             : 
     725          83 : uno::Sequence< double > VDataSeries::getAllX() const
     726             : {
     727          83 :     if(!m_aValues_X.is() && !m_aValues_X.getLength() && m_nPointCount)
     728             :     {
     729             :         //init x values from category indexes
     730             :         //first category (index 0) matches with real number 1.0
     731          37 :         m_aValues_X.Doubles.realloc( m_nPointCount );
     732         501 :         for(sal_Int32 nN=m_aValues_X.getLength();nN--;)
     733         427 :             m_aValues_X.Doubles[nN] = nN+1;
     734             :     }
     735          83 :     return m_aValues_X.Doubles;
     736             : }
     737             : 
     738         309 : uno::Sequence< double > VDataSeries::getAllY() const
     739             : {
     740         309 :     if(!m_aValues_Y.is() && !m_aValues_Y.getLength() && m_nPointCount)
     741             :     {
     742             :         //init y values from indexes
     743             :         //first y-value (index 0) matches with real number 1.0
     744           0 :         m_aValues_Y.Doubles.realloc( m_nPointCount );
     745           0 :         for(sal_Int32 nN=m_aValues_Y.getLength();nN--;)
     746           0 :             m_aValues_Y.Doubles[nN] = nN+1;
     747             :     }
     748         309 :     return m_aValues_Y.Doubles;
     749             : }
     750             : 
     751           0 : double VDataSeries::getXMeanValue() const
     752             : {
     753           0 :     if( ::rtl::math::isNan( m_fXMeanValue ) )
     754             :     {
     755           0 :         uno::Reference< XRegressionCurveCalculator > xCalculator( RegressionCurveHelper::createRegressionCurveCalculatorByServiceName( "com.sun.star.chart2.MeanValueRegressionCurve" ) );
     756           0 :         uno::Sequence< double > aXValuesDummy;
     757           0 :         xCalculator->recalculateRegression( aXValuesDummy, getAllX() );
     758           0 :         double fXDummy = 1.0;
     759           0 :         m_fXMeanValue = xCalculator->getCurveValue( fXDummy );
     760             :     }
     761           0 :     return m_fXMeanValue;
     762             : }
     763             : 
     764           0 : double VDataSeries::getYMeanValue() const
     765             : {
     766           0 :     if( ::rtl::math::isNan( m_fYMeanValue ) )
     767             :     {
     768             :         uno::Reference< XRegressionCurveCalculator > xCalculator(
     769           0 :             RegressionCurveHelper::createRegressionCurveCalculatorByServiceName("com.sun.star.chart2.MeanValueRegressionCurve"));
     770           0 :         uno::Sequence< double > aXValuesDummy;
     771           0 :         xCalculator->recalculateRegression( aXValuesDummy, getAllY() );
     772           0 :         double fXDummy = 1.0;
     773           0 :         m_fYMeanValue = xCalculator->getCurveValue( fXDummy );
     774             :     }
     775           0 :     return m_fYMeanValue;
     776             : }
     777             : 
     778         305 : Symbol* getSymbolPropertiesFromPropertySet( const uno::Reference< beans::XPropertySet >& xProp )
     779             : {
     780         305 :     ::std::unique_ptr< Symbol > apSymbolProps( new Symbol() );
     781             :     try
     782             :     {
     783         305 :         if( xProp->getPropertyValue("Symbol") >>= *apSymbolProps )
     784             :         {
     785             :             //use main color to fill symbols
     786         305 :             xProp->getPropertyValue("Color") >>= apSymbolProps->FillColor;
     787             :             // border of symbols always same as fill color
     788         305 :             apSymbolProps->BorderColor = apSymbolProps->FillColor;
     789             :         }
     790             :         else
     791           0 :             apSymbolProps.reset();
     792             :     }
     793           0 :     catch(const uno::Exception &e)
     794             :     {
     795             :         ASSERT_EXCEPTION( e );
     796             :     }
     797         305 :     return apSymbolProps.release();
     798             : }
     799             : 
     800        1959 : Symbol* VDataSeries::getSymbolProperties( sal_Int32 index ) const
     801             : {
     802        1959 :     Symbol* pRet=NULL;
     803        1959 :     if( isAttributedDataPoint( index ) )
     804             :     {
     805           0 :         adaptPointCache( index );
     806           0 :         if (!m_apSymbolProperties_AttributedPoint)
     807             :             m_apSymbolProperties_AttributedPoint.reset(
     808           0 :                 getSymbolPropertiesFromPropertySet(this->getPropertiesOfPoint(index)));
     809           0 :         pRet = m_apSymbolProperties_AttributedPoint.get();
     810             :         //if a single data point does not have symbols but the dataseries itself has symbols
     811             :         //we create an invisible symbol shape to enable selection of that point
     812           0 :         if( !pRet || pRet->Style == SymbolStyle_NONE )
     813             :         {
     814           0 :             if (!m_apSymbolProperties_Series)
     815             :                 m_apSymbolProperties_Series.reset(
     816           0 :                     getSymbolPropertiesFromPropertySet(this->getPropertiesOfSeries()));
     817           0 :             if( m_apSymbolProperties_Series.get() && m_apSymbolProperties_Series->Style != SymbolStyle_NONE )
     818             :             {
     819           0 :                 if (!m_apSymbolProperties_InvisibleSymbolForSelection)
     820             :                 {
     821           0 :                     m_apSymbolProperties_InvisibleSymbolForSelection.reset(new Symbol);
     822           0 :                     m_apSymbolProperties_InvisibleSymbolForSelection->Style = SymbolStyle_STANDARD;
     823           0 :                     m_apSymbolProperties_InvisibleSymbolForSelection->StandardSymbol = 0;//square
     824           0 :                     m_apSymbolProperties_InvisibleSymbolForSelection->Size = m_apSymbolProperties_Series->Size;
     825           0 :                     m_apSymbolProperties_InvisibleSymbolForSelection->BorderColor = 0xff000000;//invisible
     826           0 :                     m_apSymbolProperties_InvisibleSymbolForSelection->FillColor = 0xff000000;//invisible
     827             :                 }
     828           0 :                 pRet = m_apSymbolProperties_InvisibleSymbolForSelection.get();
     829             :             }
     830             :         }
     831             :     }
     832             :     else
     833             :     {
     834        1959 :         if (!m_apSymbolProperties_Series)
     835             :             m_apSymbolProperties_Series.reset(
     836         305 :                 getSymbolPropertiesFromPropertySet(this->getPropertiesOfSeries()));
     837        1959 :         pRet = m_apSymbolProperties_Series.get();
     838             :     }
     839             : 
     840        1959 :     if( pRet && pRet->Style == SymbolStyle_AUTO )
     841             :     {
     842          15 :         pRet->Style = SymbolStyle_STANDARD;
     843             : 
     844          15 :         sal_Int32 nIndex = m_nGlobalSeriesIndex;
     845          15 :         if(m_aValues_X.is())
     846           3 :             nIndex++;
     847          15 :         pRet->StandardSymbol = nIndex;
     848             :     }
     849             : 
     850        1959 :     return pRet;
     851             : }
     852             : 
     853        2084 : uno::Reference< beans::XPropertySet > VDataSeries::getXErrorBarProperties( sal_Int32 index ) const
     854             : {
     855        2084 :     uno::Reference< beans::XPropertySet > xErrorBarProp;
     856             : 
     857        4168 :     uno::Reference< beans::XPropertySet > xPointProp( this->getPropertiesOfPoint( index ));
     858        2084 :     if( xPointProp.is() )
     859        2084 :         xPointProp->getPropertyValue(CHART_UNONAME_ERRORBAR_X) >>= xErrorBarProp;
     860        4168 :     return xErrorBarProp;
     861             : }
     862             : 
     863       12311 : uno::Reference< beans::XPropertySet > VDataSeries::getYErrorBarProperties( sal_Int32 index ) const
     864             : {
     865       12311 :     uno::Reference< beans::XPropertySet > xErrorBarProp;
     866             : 
     867       24622 :     uno::Reference< beans::XPropertySet > xPointProp( this->getPropertiesOfPoint( index ));
     868       12311 :     if( xPointProp.is() )
     869       12311 :         xPointProp->getPropertyValue(CHART_UNONAME_ERRORBAR_Y) >>= xErrorBarProp;
     870       24622 :     return xErrorBarProp;
     871             : }
     872             : 
     873         460 : bool VDataSeries::hasPointOwnColor( sal_Int32 index ) const
     874             : {
     875         460 :     if( !isAttributedDataPoint(index) )
     876         140 :         return false;
     877             : 
     878             :     try
     879             :     {
     880         320 :         uno::Reference< beans::XPropertyState > xPointState( this->getPropertiesOfPoint(index), uno::UNO_QUERY_THROW );
     881         320 :         return (xPointState->getPropertyState("Color") != beans::PropertyState_DEFAULT_VALUE );
     882             :     }
     883           0 :     catch(const uno::Exception& e)
     884             :     {
     885             :         ASSERT_EXCEPTION( e );
     886             :     }
     887           0 :     return false;
     888             : }
     889             : 
     890       69632 : bool VDataSeries::isAttributedDataPoint( sal_Int32 index ) const
     891             : {
     892             :     //returns true if the data point assigned by the given index has set it's own properties
     893       69632 :     if( index>=m_nPointCount || m_nPointCount==0)
     894           0 :         return false;
     895      151187 :     for(sal_Int32 nN=m_aAttributedDataPointIndexList.getLength();nN--;)
     896             :     {
     897       17815 :         if(index==m_aAttributedDataPointIndexList[nN])
     898        5892 :             return true;
     899             :     }
     900       63740 :     return false;
     901             : }
     902             : 
     903        3563 : bool VDataSeries::isVaryColorsByPoint() const
     904             : {
     905        3563 :     bool bVaryColorsByPoint = false;
     906        3563 :     Reference< beans::XPropertySet > xSeriesProp( this->getPropertiesOfSeries() );
     907        3563 :     if( xSeriesProp.is() )
     908        3563 :         xSeriesProp->getPropertyValue("VaryColorsByPoint") >>= bVaryColorsByPoint;
     909        3563 :     return bVaryColorsByPoint;
     910             : }
     911             : 
     912       37161 : uno::Reference< beans::XPropertySet > VDataSeries::getPropertiesOfPoint( sal_Int32 index ) const
     913             : {
     914       37161 :     if( isAttributedDataPoint( index ) )
     915        3974 :         return m_xDataSeries->getDataPointByIndex(index);
     916       33187 :     return this->getPropertiesOfSeries();
     917             : }
     918             : 
     919       40572 : uno::Reference<beans::XPropertySet> VDataSeries::getPropertiesOfSeries() const
     920             : {
     921       40572 :     return uno::Reference<css::beans::XPropertySet>(m_xDataSeries, css::uno::UNO_QUERY);
     922             : }
     923             : 
     924        3518 : DataPointLabel* getDataPointLabelFromPropertySet( const uno::Reference< beans::XPropertySet >& xProp )
     925             : {
     926        3518 :     ::std::unique_ptr< DataPointLabel > apLabel( new DataPointLabel() );
     927             :     try
     928             :     {
     929        3518 :         if( !(xProp->getPropertyValue(CHART_UNONAME_LABEL) >>= *apLabel) )
     930           0 :             apLabel.reset();
     931             :     }
     932           0 :     catch(const uno::Exception &e)
     933             :     {
     934             :         ASSERT_EXCEPTION( e );
     935             :     }
     936        3518 :     return apLabel.release();
     937             : }
     938             : 
     939        1224 : void VDataSeries::adaptPointCache( sal_Int32 nNewPointIndex ) const
     940             : {
     941        1224 :     if( m_nCurrentAttributedPoint != nNewPointIndex )
     942             :     {
     943         502 :         m_apLabel_AttributedPoint.reset();
     944         502 :         m_apLabelPropNames_AttributedPoint.reset();
     945         502 :         m_apLabelPropValues_AttributedPoint.reset();
     946         502 :         m_apSymbolProperties_AttributedPoint.reset();
     947         502 :         m_nCurrentAttributedPoint = nNewPointIndex;
     948             :     }
     949        1224 : }
     950             : 
     951       15628 : DataPointLabel* VDataSeries::getDataPointLabel( sal_Int32 index ) const
     952             : {
     953       15628 :     DataPointLabel* pRet = NULL;
     954       15628 :     if( isAttributedDataPoint( index ) )
     955             :     {
     956         863 :         adaptPointCache( index );
     957         863 :         if( !m_apLabel_AttributedPoint.get() )
     958             :             m_apLabel_AttributedPoint.reset(
     959         502 :                 getDataPointLabelFromPropertySet(this->getPropertiesOfPoint(index)));
     960         863 :         pRet = m_apLabel_AttributedPoint.get();
     961             :     }
     962             :     else
     963             :     {
     964       14765 :         if (!m_apLabel_Series)
     965             :             m_apLabel_Series.reset(
     966        3016 :                 getDataPointLabelFromPropertySet(this->getPropertiesOfPoint(index)));
     967       14765 :         pRet = m_apLabel_Series.get();
     968             :     }
     969       15628 :     if( !m_bAllowPercentValueInDataLabel )
     970             :     {
     971         360 :         if( pRet )
     972         360 :             pRet->ShowNumberInPercent = false;
     973             :     }
     974       15628 :     return pRet;
     975             : }
     976             : 
     977       15628 : DataPointLabel* VDataSeries::getDataPointLabelIfLabel( sal_Int32 index ) const
     978             : {
     979       15628 :     DataPointLabel* pLabel = this->getDataPointLabel( index );
     980       15628 :     if( !pLabel || (!pLabel->ShowNumber && !pLabel->ShowNumberInPercent
     981       11406 :         && !pLabel->ShowCategoryName ) )
     982       11320 :         return 0;
     983        4308 :     return pLabel;
     984             : }
     985             : 
     986        1674 : bool VDataSeries::getTextLabelMultiPropertyLists( sal_Int32 index
     987             :     , tNameSequence*& pPropNames
     988             :     , tAnySequence*& pPropValues ) const
     989             : {
     990        1674 :     pPropNames = NULL; pPropValues = NULL;
     991        1674 :     uno::Reference< beans::XPropertySet > xTextProp;
     992        1674 :     bool bDoDynamicFontResize = false;
     993        1674 :     if( isAttributedDataPoint( index ) )
     994             :     {
     995         361 :         adaptPointCache( index );
     996         361 :         if (!m_apLabelPropValues_AttributedPoint)
     997             :         {
     998             :             // Cache these properties for this point.
     999         361 :             m_apLabelPropNames_AttributedPoint.reset(new tNameSequence);
    1000         361 :             m_apLabelPropValues_AttributedPoint.reset(new tAnySequence);
    1001         361 :             xTextProp.set( this->getPropertiesOfPoint( index ));
    1002             :             PropertyMapper::getTextLabelMultiPropertyLists(
    1003         361 :                 xTextProp, *m_apLabelPropNames_AttributedPoint, *m_apLabelPropValues_AttributedPoint);
    1004         361 :             bDoDynamicFontResize = true;
    1005             :         }
    1006         361 :         pPropNames = m_apLabelPropNames_AttributedPoint.get();
    1007         361 :         pPropValues = m_apLabelPropValues_AttributedPoint.get();
    1008             :     }
    1009             :     else
    1010             :     {
    1011        1313 :         if (!m_apLabelPropValues_Series)
    1012             :         {
    1013             :             // Cache these properties for the whole series.
    1014         139 :             m_apLabelPropNames_Series.reset(new tNameSequence);
    1015         139 :             m_apLabelPropValues_Series.reset(new tAnySequence);
    1016         139 :             xTextProp.set( this->getPropertiesOfPoint( index ));
    1017             :             PropertyMapper::getTextLabelMultiPropertyLists(
    1018         139 :                 xTextProp, *m_apLabelPropNames_Series, *m_apLabelPropValues_Series);
    1019         139 :             bDoDynamicFontResize = true;
    1020             :         }
    1021        1313 :         pPropNames = m_apLabelPropNames_Series.get();
    1022        1313 :         pPropValues = m_apLabelPropValues_Series.get();
    1023             :     }
    1024             : 
    1025        2174 :     if( bDoDynamicFontResize &&
    1026        2674 :         pPropNames && pPropValues &&
    1027         500 :         xTextProp.is())
    1028             :     {
    1029         500 :         LabelPositionHelper::doDynamicFontResize( *pPropValues, *pPropNames, xTextProp, m_aReferenceSize );
    1030             :     }
    1031             : 
    1032        1674 :     return (pPropNames && pPropValues);
    1033             : }
    1034             : 
    1035        3098 : void VDataSeries::setMissingValueTreatment( sal_Int32 nMissingValueTreatment )
    1036             : {
    1037        3098 :     m_nMissingValueTreatment = nMissingValueTreatment;
    1038        3098 : }
    1039             : 
    1040      110404 : sal_Int32 VDataSeries::getMissingValueTreatment() const
    1041             : {
    1042      110404 :     return m_nMissingValueTreatment;
    1043             : }
    1044             : 
    1045           0 : VDataSeries::VDataSeries()
    1046             :     : m_nPolygonIndex(0)
    1047             :     , m_fLogicMinX(0)
    1048             :     , m_fLogicMaxX(0)
    1049             :     , m_fLogicZPos(0)
    1050             :     , m_nPointCount(0)
    1051             :     , m_pValueSequenceForDataLabelNumberFormatDetection(NULL)
    1052             :     , m_fXMeanValue(0)
    1053             :     , m_fYMeanValue(0)
    1054             :     , m_eStackingDirection(chart2::StackingDirection_NO_STACKING)
    1055             :     , m_nAxisIndex(0)
    1056             :     , m_bConnectBars(false)
    1057             :     , m_bGroupBarsPerAxis(false)
    1058             :     , m_nStartingAngle(0)
    1059             :     , m_nGlobalSeriesIndex(0)
    1060             :     , m_nCurrentAttributedPoint(0)
    1061             :     , m_nMissingValueTreatment(0)
    1062             :     , m_bAllowPercentValueInDataLabel(false)
    1063             :     , mpOldSeries(NULL)
    1064           0 :     , mnPercent(0)
    1065             : {
    1066           0 : }
    1067             : 
    1068           0 : void VDataSeries::setOldTimeBased( VDataSeries* pOldSeries, double nPercent )
    1069             : {
    1070           0 :     mnPercent = nPercent;
    1071           0 :     mpOldSeries = pOldSeries;
    1072           0 :     mpOldSeries->mpOldSeries = NULL;
    1073           0 : }
    1074             : 
    1075           0 : VDataSeries* VDataSeries::createCopyForTimeBased() const
    1076             : {
    1077           0 :     VDataSeries* pNew = new VDataSeries();
    1078           0 :     pNew->m_aValues_X = m_aValues_X;
    1079           0 :     pNew->m_aValues_Y = m_aValues_Y;
    1080           0 :     pNew->m_aValues_Z = m_aValues_Z;
    1081           0 :     pNew->m_aValues_Y_Min = m_aValues_Y_Min;
    1082           0 :     pNew->m_aValues_Y_Max = m_aValues_Y_Max;
    1083           0 :     pNew->m_aValues_Y_First = m_aValues_Y_First;
    1084           0 :     pNew->m_aValues_Y_Last = m_aValues_Y_Last;
    1085           0 :     pNew->m_aValues_Bubble_Size = m_aValues_Bubble_Size;
    1086           0 :     pNew->maPropertyMap = maPropertyMap;
    1087             : 
    1088           0 :     pNew->m_nPointCount = m_nPointCount;
    1089             : 
    1090           0 :     return pNew;
    1091             : }
    1092             : 
    1093           0 : double VDataSeries::getValueByProperty( sal_Int32 nIndex, const OUString& rPropName ) const
    1094             : {
    1095             :     boost::ptr_map<OUString, VDataSequence>::const_iterator itr =
    1096           0 :         maPropertyMap.find(rPropName);
    1097           0 :     if(itr == maPropertyMap.end())
    1098             :     {
    1099             :         double fNan;
    1100           0 :         ::rtl::math::setNan( &fNan );
    1101           0 :         return fNan;
    1102             :     }
    1103             : 
    1104           0 :     const VDataSequence* pData = itr->second;
    1105           0 :     double fValue = pData->getValue(nIndex);
    1106           0 :     if(mpOldSeries && mpOldSeries->hasPropertyMapping(rPropName))
    1107             :     {
    1108           0 :         double fOldValue = mpOldSeries->getValueByProperty( nIndex, rPropName );
    1109           0 :         if(rPropName.endsWith("Color"))
    1110             :         {
    1111             :             //optimized interpolation for color values
    1112           0 :             Color aColor(static_cast<sal_uInt32>(fValue));
    1113           0 :             Color aOldColor(static_cast<sal_uInt32>(fOldValue));
    1114           0 :             sal_uInt8 r = aOldColor.GetRed() + (aColor.GetRed() - aOldColor.GetRed()) * mnPercent;
    1115           0 :             sal_uInt8 g = aOldColor.GetGreen() + (aColor.GetGreen() - aOldColor.GetGreen()) * mnPercent;
    1116           0 :             sal_uInt8 b = aOldColor.GetBlue() + (aColor.GetBlue() - aOldColor.GetBlue()) * mnPercent;
    1117           0 :             sal_uInt8 t = aOldColor.GetTransparency() + (aColor.GetTransparency() - aOldColor.GetTransparency()) * mnPercent;
    1118           0 :             Color aRet(t, r, g, b);
    1119           0 :             return aRet.GetColor();
    1120             :         }
    1121           0 :         return fOldValue + (fValue - fOldValue) * mnPercent;
    1122             :     }
    1123           0 :     return fValue;
    1124             : }
    1125             : 
    1126       10705 : bool VDataSeries::hasPropertyMapping(const OUString& rPropName ) const
    1127             : {
    1128       10705 :     return maPropertyMap.find(rPropName) != maPropertyMap.end();
    1129             : }
    1130             : 
    1131             : } //namespace chart
    1132             : 
    1133             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11