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

Generated by: LCOV version 1.10