LCOV - code coverage report
Current view: top level - chart2/source/view/charttypes - AreaChart.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 265 480 55.2 %
Date: 2012-08-25 Functions: 15 19 78.9 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 306 944 32.4 %

           Branch data     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 "AreaChart.hxx"
      21                 :            : #include "PlottingPositionHelper.hxx"
      22                 :            : #include "ShapeFactory.hxx"
      23                 :            : #include "CommonConverters.hxx"
      24                 :            : #include "macros.hxx"
      25                 :            : #include "ViewDefines.hxx"
      26                 :            : #include "ObjectIdentifier.hxx"
      27                 :            : #include "Splines.hxx"
      28                 :            : #include "ChartTypeHelper.hxx"
      29                 :            : #include "LabelPositionHelper.hxx"
      30                 :            : #include "Clipping.hxx"
      31                 :            : #include "Stripe.hxx"
      32                 :            : #include "PolarLabelPositionHelper.hxx"
      33                 :            : #include "DateHelper.hxx"
      34                 :            : 
      35                 :            : #include <com/sun/star/chart2/Symbol.hpp>
      36                 :            : #include <com/sun/star/chart/DataLabelPlacement.hpp>
      37                 :            : #include <com/sun/star/chart/MissingValueTreatment.hpp>
      38                 :            : 
      39                 :            : #include <editeng/unoprnms.hxx>
      40                 :            : #include <rtl/math.hxx>
      41                 :            : 
      42                 :            : #include <com/sun/star/drawing/DoubleSequence.hpp>
      43                 :            : #include <com/sun/star/drawing/NormalsKind.hpp>
      44                 :            : #include <com/sun/star/lang/XServiceName.hpp>
      45                 :            : 
      46                 :            : //.............................................................................
      47                 :            : namespace chart
      48                 :            : {
      49                 :            : //.............................................................................
      50                 :            : using namespace ::com::sun::star;
      51                 :            : using namespace ::rtl::math;
      52                 :            : using namespace ::com::sun::star::chart2;
      53                 :            : 
      54                 :            : //-----------------------------------------------------------------------------
      55                 :            : //-----------------------------------------------------------------------------
      56                 :            : //-----------------------------------------------------------------------------
      57                 :            : 
      58                 :         72 : AreaChart::AreaChart( const uno::Reference<XChartType>& xChartTypeModel
      59                 :            :                      , sal_Int32 nDimensionCount
      60                 :            :                      , bool bCategoryXAxis
      61                 :            :                      , bool bNoArea
      62                 :            :                      , PlottingPositionHelper* pPlottingPositionHelper
      63                 :            :                      , bool bConnectLastToFirstPoint
      64                 :            :                      , bool bExpandIfValuesCloseToBorder
      65                 :            :                      , sal_Int32 nKeepAspectRatio
      66                 :            :                      , const drawing::Direction3D& rAspectRatio
      67                 :            :                      )
      68                 :            :         : VSeriesPlotter( xChartTypeModel, nDimensionCount, bCategoryXAxis )
      69                 :            :         , m_pMainPosHelper(pPlottingPositionHelper)
      70                 :         72 :         , m_bArea(!bNoArea)
      71                 :            :         , m_bLine(bNoArea)
      72         [ +  - ]:         72 :         , m_bSymbol( ChartTypeHelper::isSupportingSymbolProperties(xChartTypeModel,nDimensionCount) )
      73                 :            :         , m_bIsPolarCooSys( bConnectLastToFirstPoint )
      74                 :            :         , m_bConnectLastToFirstPoint( bConnectLastToFirstPoint )
      75                 :            :         , m_bExpandIfValuesCloseToBorder( bExpandIfValuesCloseToBorder )
      76                 :            :         , m_nKeepAspectRatio(nKeepAspectRatio)
      77                 :            :         , m_aGivenAspectRatio(rAspectRatio)
      78                 :            :         , m_eCurveStyle(CurveStyle_LINES)
      79                 :            :         , m_nCurveResolution(20)
      80                 :            :         , m_nSplineOrder(3)
      81                 :            :         , m_xSeriesTarget(0)
      82                 :            :         , m_xErrorBarTarget(0)
      83                 :            :         , m_xTextTarget(0)
      84 [ +  - ][ +  - ]:        144 :         , m_xRegressionCurveEquationTarget(0)
         [ +  - ][ +  - ]
      85                 :            : {
      86         [ +  - ]:         72 :     if( !m_pMainPosHelper )
      87 [ +  - ][ +  - ]:         72 :         m_pMainPosHelper = new PlottingPositionHelper();
      88         [ +  - ]:         72 :     if( m_pMainPosHelper )
      89                 :            :     {
      90         [ +  - ]:         72 :         m_pMainPosHelper->AllowShiftXAxisPos(true);
      91         [ +  - ]:         72 :         m_pMainPosHelper->AllowShiftZAxisPos(true);
      92                 :            :     }
      93                 :         72 :     PlotterBase::m_pPosHelper = m_pMainPosHelper;
      94                 :         72 :     VSeriesPlotter::m_pMainPosHelper = m_pMainPosHelper;
      95                 :            : 
      96                 :            :     try
      97                 :            :     {
      98         [ +  - ]:         72 :         if( m_xChartTypeModelProps.is() )
      99                 :            :         {
     100 [ +  - ][ +  - ]:         72 :             m_xChartTypeModelProps->getPropertyValue( C2U( "CurveStyle" ) ) >>= m_eCurveStyle;
         [ +  - ][ +  - ]
     101 [ +  - ][ +  - ]:         72 :             m_xChartTypeModelProps->getPropertyValue( C2U( "CurveResolution" ) ) >>= m_nCurveResolution;
                 [ +  - ]
     102 [ +  - ][ +  - ]:         72 :             m_xChartTypeModelProps->getPropertyValue( C2U( "SplineOrder" ) ) >>= m_nSplineOrder;
         [ #  # ][ +  - ]
     103                 :            :         }
     104                 :            :     }
     105         [ #  # ]:          0 :     catch( uno::Exception& e )
     106                 :            :     {
     107                 :            :         //the above properties are not supported by all charttypes supported by this class (e.g. area or net chart)
     108                 :            :         //in that cases this exception is ok
     109                 :          0 :         e.Context.is();//to have debug information without compilation warnings
     110                 :            :     }
     111                 :         72 : }
     112                 :            : 
     113                 :         72 : AreaChart::~AreaChart()
     114                 :            : {
     115 [ +  - ][ +  - ]:         72 :     delete m_pMainPosHelper;
     116         [ -  + ]:        144 : }
     117                 :            : 
     118                 :        158 : double AreaChart::getMaximumX()
     119                 :            : {
     120                 :        158 :     double fMax = VSeriesPlotter::getMaximumX();
     121 [ -  + ][ +  - ]:        158 :     if( m_bCategoryXAxis && m_bIsPolarCooSys )//the angle axis in net charts needs a different autoscaling
     122                 :          0 :         fMax += 1.0;
     123                 :        158 :     return fMax;
     124                 :            : }
     125                 :            : 
     126                 :        352 : bool AreaChart::isExpandIfValuesCloseToBorder( sal_Int32 nDimensionIndex )
     127                 :            : {
     128                 :            :     return m_bExpandIfValuesCloseToBorder &&
     129 [ +  - ][ +  + ]:        352 :         VSeriesPlotter::isExpandIfValuesCloseToBorder( nDimensionIndex );
     130                 :            : }
     131                 :            : 
     132                 :       1304 : bool AreaChart::isSeperateStackingForDifferentSigns( sal_Int32 /*nDimensionIndex*/ )
     133                 :            : {
     134                 :            :     // no separate stacking in all types of line/area charts
     135                 :       1304 :     return false;
     136                 :            : }
     137                 :            : 
     138                 :            : //-----------------------------------------------------------------
     139                 :            : 
     140                 :        357 : LegendSymbolStyle AreaChart::getLegendSymbolStyle()
     141                 :            : {
     142 [ +  - ][ +  + ]:        357 :     if( m_bArea || m_nDimension == 3 )
     143                 :         33 :         return LegendSymbolStyle_BOX;
     144                 :        357 :     return LegendSymbolStyle_LINE;
     145                 :            : }
     146                 :            : 
     147                 :        296 : uno::Any AreaChart::getExplicitSymbol( const VDataSeries& rSeries, sal_Int32 nPointIndex )
     148                 :            : {
     149                 :        296 :     uno::Any aRet;
     150                 :            : 
     151         [ +  - ]:        296 :     Symbol* pSymbolProperties = rSeries.getSymbolProperties( nPointIndex );
     152         [ +  - ]:        296 :     if( pSymbolProperties )
     153                 :            :     {
     154         [ +  - ]:        296 :         aRet = uno::makeAny(*pSymbolProperties);
     155                 :            :     }
     156                 :            : 
     157                 :        296 :     return aRet;
     158                 :            : }
     159                 :            : 
     160                 :         72 : drawing::Direction3D AreaChart::getPreferredDiagramAspectRatio() const
     161                 :            : {
     162         [ -  + ]:         72 :     if( m_nKeepAspectRatio == 1 )
     163                 :          0 :         return m_aGivenAspectRatio;
     164                 :         72 :     drawing::Direction3D aRet(1,-1,1);
     165         [ +  + ]:         72 :     if( m_nDimension == 2 )
     166                 :         61 :         aRet = drawing::Direction3D(-1,-1,-1);
     167                 :            :     else
     168                 :            :     {
     169         [ +  - ]:         11 :         drawing::Direction3D aScale( m_pPosHelper->getScaledLogicWidth() );
     170                 :         11 :         aRet.DirectionZ = aScale.DirectionZ*0.2;
     171         [ -  + ]:         11 :         if(aRet.DirectionZ>1.0)
     172                 :          0 :             aRet.DirectionZ=1.0;
     173         [ -  + ]:         11 :         if(aRet.DirectionZ>10)
     174                 :         11 :             aRet.DirectionZ=10;
     175                 :            :     }
     176                 :         72 :     return aRet;
     177                 :            : }
     178                 :            : 
     179                 :          0 : bool AreaChart::keepAspectRatio() const
     180                 :            : {
     181         [ #  # ]:          0 :     if( m_nKeepAspectRatio == 0 )
     182                 :          0 :         return false;
     183         [ #  # ]:          0 :     if( m_nKeepAspectRatio == 1 )
     184                 :          0 :         return true;
     185         [ #  # ]:          0 :     if( m_nDimension == 2 )
     186                 :            :     {
     187         [ #  # ]:          0 :         if( !m_bSymbol )
     188                 :          0 :             return false;
     189                 :            :     }
     190                 :          0 :     return true;
     191                 :            : }
     192                 :            : 
     193                 :        296 : void AreaChart::addSeries( VDataSeries* pSeries, sal_Int32 zSlot, sal_Int32 xSlot, sal_Int32 ySlot )
     194                 :            : {
     195 [ -  + ][ #  # ]:        296 :     if( m_bArea && !m_bIsPolarCooSys && pSeries )
                 [ #  # ]
     196                 :            :     {
     197                 :          0 :         sal_Int32 nMissingValueTreatment = pSeries->getMissingValueTreatment();
     198         [ #  # ]:          0 :         if( nMissingValueTreatment == ::com::sun::star::chart::MissingValueTreatment::LEAVE_GAP  )
     199                 :          0 :             pSeries->setMissingValueTreatment( ::com::sun::star::chart::MissingValueTreatment::USE_ZERO );
     200                 :            :     }
     201 [ +  + ][ -  + ]:        296 :     if( m_nDimension == 3 && !m_bCategoryXAxis )
     202                 :            :     {
     203                 :            :         //3D xy always deep
     204                 :            :         OSL_ENSURE( zSlot==-1,"3D xy charts should be deep stacked in model also" );
     205                 :          0 :         zSlot=-1;
     206                 :          0 :         xSlot=0;
     207                 :          0 :         ySlot=0;
     208                 :            :     }
     209                 :        296 :     VSeriesPlotter::addSeries( pSeries, zSlot, xSlot, ySlot );
     210                 :        296 : }
     211                 :            : 
     212                 :          0 : void lcl_removeDuplicatePoints( drawing::PolyPolygonShape3D& rPolyPoly, PlottingPositionHelper& rPosHelper )
     213                 :            : {
     214                 :          0 :     sal_Int32 nPolyCount = rPolyPoly.SequenceX.getLength();
     215         [ #  # ]:          0 :     if(!nPolyCount)
     216                 :          0 :         return;
     217                 :            : 
     218         [ #  # ]:          0 :     drawing::PolyPolygonShape3D aTmp;
     219         [ #  # ]:          0 :     aTmp.SequenceX.realloc(nPolyCount);
     220         [ #  # ]:          0 :     aTmp.SequenceY.realloc(nPolyCount);
     221         [ #  # ]:          0 :     aTmp.SequenceZ.realloc(nPolyCount);
     222                 :            : 
     223         [ #  # ]:          0 :     for( sal_Int32 nPolygonIndex = 0; nPolygonIndex<nPolyCount; nPolygonIndex++ )
     224                 :            :     {
     225         [ #  # ]:          0 :         drawing::DoubleSequence* pOuterSourceX = &rPolyPoly.SequenceX.getArray()[nPolygonIndex];
     226         [ #  # ]:          0 :         drawing::DoubleSequence* pOuterSourceY = &rPolyPoly.SequenceY.getArray()[nPolygonIndex];
     227         [ #  # ]:          0 :         drawing::DoubleSequence* pOuterSourceZ = &rPolyPoly.SequenceZ.getArray()[nPolygonIndex];
     228                 :            : 
     229         [ #  # ]:          0 :         drawing::DoubleSequence* pOuterTargetX = &aTmp.SequenceX.getArray()[nPolygonIndex];
     230         [ #  # ]:          0 :         drawing::DoubleSequence* pOuterTargetY = &aTmp.SequenceY.getArray()[nPolygonIndex];
     231         [ #  # ]:          0 :         drawing::DoubleSequence* pOuterTargetZ = &aTmp.SequenceZ.getArray()[nPolygonIndex];
     232                 :            : 
     233                 :          0 :         sal_Int32 nPointCount = pOuterSourceX->getLength();
     234         [ #  # ]:          0 :         if( !nPointCount )
     235                 :          0 :             continue;
     236                 :            : 
     237         [ #  # ]:          0 :         pOuterTargetX->realloc(nPointCount);
     238         [ #  # ]:          0 :         pOuterTargetY->realloc(nPointCount);
     239         [ #  # ]:          0 :         pOuterTargetZ->realloc(nPointCount);
     240                 :            : 
     241         [ #  # ]:          0 :         double* pSourceX = pOuterSourceX->getArray();
     242         [ #  # ]:          0 :         double* pSourceY = pOuterSourceY->getArray();
     243         [ #  # ]:          0 :         double* pSourceZ = pOuterSourceZ->getArray();
     244                 :            : 
     245         [ #  # ]:          0 :         double* pTargetX = pOuterTargetX->getArray();
     246         [ #  # ]:          0 :         double* pTargetY = pOuterTargetY->getArray();
     247         [ #  # ]:          0 :         double* pTargetZ = pOuterTargetZ->getArray();
     248                 :            : 
     249                 :            :         //copy first point
     250                 :          0 :         *pTargetX=*pSourceX++;
     251                 :          0 :         *pTargetY=*pSourceY++;
     252                 :          0 :         *pTargetZ=*pSourceZ++;
     253                 :          0 :         sal_Int32 nTargetPointCount=1;
     254                 :            : 
     255         [ #  # ]:          0 :         for( sal_Int32 nSource=1; nSource<nPointCount; nSource++ )
     256                 :            :         {
     257         [ #  # ]:          0 :             if( !rPosHelper.isSameForGivenResolution( *pTargetX, *pTargetY, *pTargetZ
     258         [ #  # ]:          0 :                                                    , *pSourceX, *pSourceY, *pSourceZ ) )
     259                 :            :             {
     260                 :          0 :                 pTargetX++; pTargetY++; pTargetZ++;
     261                 :          0 :                 *pTargetX=*pSourceX;
     262                 :          0 :                 *pTargetY=*pSourceY;
     263                 :          0 :                 *pTargetZ=*pSourceZ;
     264                 :          0 :                 nTargetPointCount++;
     265                 :            :             }
     266                 :          0 :             pSourceX++; pSourceY++; pSourceZ++;
     267                 :            :         }
     268                 :            : 
     269                 :            :         //free unused space
     270         [ #  # ]:          0 :         if( nTargetPointCount<nPointCount )
     271                 :            :         {
     272         [ #  # ]:          0 :             pOuterTargetX->realloc(nTargetPointCount);
     273         [ #  # ]:          0 :             pOuterTargetY->realloc(nTargetPointCount);
     274         [ #  # ]:          0 :             pOuterTargetZ->realloc(nTargetPointCount);
     275                 :            :         }
     276                 :            : 
     277         [ #  # ]:          0 :         pOuterSourceX->realloc(0);
     278         [ #  # ]:          0 :         pOuterSourceY->realloc(0);
     279         [ #  # ]:          0 :         pOuterSourceZ->realloc(0);
     280                 :            :     }
     281                 :            : 
     282                 :            :     //free space
     283         [ #  # ]:          0 :     rPolyPoly.SequenceX.realloc(nPolyCount);
     284         [ #  # ]:          0 :     rPolyPoly.SequenceY.realloc(nPolyCount);
     285         [ #  # ]:          0 :     rPolyPoly.SequenceZ.realloc(nPolyCount);
     286                 :            : 
     287 [ #  # ][ #  # ]:          0 :     rPolyPoly=aTmp;
     288                 :            : }
     289                 :            : 
     290                 :        296 : bool AreaChart::impl_createLine( VDataSeries* pSeries
     291                 :            :                 , drawing::PolyPolygonShape3D* pSeriesPoly
     292                 :            :                 , PlottingPositionHelper* pPosHelper )
     293                 :            : {
     294                 :            :     //return true if a line was created successfully
     295         [ +  - ]:        296 :     uno::Reference< drawing::XShapes > xSeriesGroupShape_Shapes = getSeriesGroupShapeBackChild(pSeries, m_xSeriesTarget);
     296                 :            : 
     297         [ +  - ]:        296 :     drawing::PolyPolygonShape3D aPoly;
     298         [ -  + ]:        296 :     if(CurveStyle_CUBIC_SPLINES==m_eCurveStyle)
     299                 :            :     {
     300         [ #  # ]:          0 :         drawing::PolyPolygonShape3D aSplinePoly;
     301         [ #  # ]:          0 :         SplineCalculater::CalculateCubicSplines( *pSeriesPoly, aSplinePoly, m_nCurveResolution );
     302         [ #  # ]:          0 :         lcl_removeDuplicatePoints( aSplinePoly, *pPosHelper );
     303 [ #  # ][ #  # ]:          0 :         Clipping::clipPolygonAtRectangle( aSplinePoly, pPosHelper->getScaledLogicClipDoubleRect(), aPoly );
                 [ #  # ]
     304                 :            :     }
     305         [ -  + ]:        296 :     else if(CurveStyle_B_SPLINES==m_eCurveStyle)
     306                 :            :     {
     307         [ #  # ]:          0 :         drawing::PolyPolygonShape3D aSplinePoly;
     308         [ #  # ]:          0 :         SplineCalculater::CalculateBSplines( *pSeriesPoly, aSplinePoly, m_nCurveResolution, m_nSplineOrder );
     309         [ #  # ]:          0 :         lcl_removeDuplicatePoints( aSplinePoly, *pPosHelper );
     310 [ #  # ][ #  # ]:          0 :         Clipping::clipPolygonAtRectangle( aSplinePoly, pPosHelper->getScaledLogicClipDoubleRect(), aPoly );
                 [ #  # ]
     311                 :            :     }
     312                 :            :     else
     313                 :            :     {
     314                 :        296 :         bool bIsClipped = false;
     315 [ -  + ][ #  # ]:        296 :         if( m_bConnectLastToFirstPoint && !ShapeFactory::isPolygonEmptyOrSinglePoint(*pSeriesPoly) )
         [ #  # ][ -  + ]
     316                 :            :         {
     317                 :            :             // do NOT connect last and first point, if one is NAN, and NAN handling is NAN_AS_GAP
     318         [ #  # ]:          0 :             double fFirstY = pSeries->getYValue( 0 );
     319 [ #  # ][ #  # ]:          0 :             double fLastY = pSeries->getYValue( VSeriesPlotter::getPointCount() - 1 );
     320 [ #  # ][ #  #  :          0 :             if( (pSeries->getMissingValueTreatment() != ::com::sun::star::chart::MissingValueTreatment::LEAVE_GAP)
             #  #  #  # ]
                 [ #  # ]
     321                 :          0 :                 || (::rtl::math::isFinite( fFirstY ) && ::rtl::math::isFinite( fLastY )) )
     322                 :            :             {
     323                 :            :                 // connect last point in last polygon with first point in first polygon
     324         [ #  # ]:          0 :                 ::basegfx::B2DRectangle aScaledLogicClipDoubleRect( pPosHelper->getScaledLogicClipDoubleRect() );
     325         [ #  # ]:          0 :                 drawing::PolyPolygonShape3D aTmpPoly(*pSeriesPoly);
     326 [ #  # ][ #  # ]:          0 :                 drawing::Position3D aLast(aScaledLogicClipDoubleRect.getMaxX(),aTmpPoly.SequenceY[0][0],aTmpPoly.SequenceZ[0][0]);
         [ #  # ][ #  # ]
                 [ #  # ]
     327                 :            :                 // add connector line to last polygon
     328         [ #  # ]:          0 :                 AddPointToPoly( aTmpPoly, aLast, pSeriesPoly->SequenceX.getLength() - 1 );
     329         [ #  # ]:          0 :                 Clipping::clipPolygonAtRectangle( aTmpPoly, aScaledLogicClipDoubleRect, aPoly );
     330         [ #  # ]:          0 :                 bIsClipped = true;
     331                 :            :             }
     332                 :            :         }
     333                 :            : 
     334         [ +  - ]:        296 :         if( !bIsClipped )
     335 [ +  - ][ +  - ]:        296 :             Clipping::clipPolygonAtRectangle( *pSeriesPoly, pPosHelper->getScaledLogicClipDoubleRect(), aPoly );
     336                 :            :     }
     337                 :            : 
     338 [ +  - ][ -  + ]:        296 :     if(!ShapeFactory::hasPolygonAnyLines(aPoly))
     339                 :          0 :         return false;
     340                 :            : 
     341                 :            :     //transformation 3) -> 4)
     342         [ +  - ]:        296 :     pPosHelper->transformScaledLogicToScene( aPoly );
     343                 :            : 
     344                 :            :     //create line:
     345         [ +  - ]:        296 :     uno::Reference< drawing::XShape > xShape(NULL);
     346         [ +  + ]:        296 :     if(m_nDimension==3)
     347                 :            :     {
     348         [ +  - ]:         33 :         double fDepth = this->getTransformedDepth();
     349                 :         33 :         sal_Int32 nPolyCount = aPoly.SequenceX.getLength();
     350         [ +  + ]:         66 :         for(sal_Int32 nPoly=0;nPoly<nPolyCount;nPoly++)
     351                 :            :         {
     352         [ +  - ]:         33 :             sal_Int32 nPointCount = aPoly.SequenceX[nPoly].getLength();
     353         [ +  + ]:        429 :             for(sal_Int32 nPoint=0;nPoint<nPointCount-1;nPoint++)
     354                 :            :             {
     355                 :        396 :                 drawing::Position3D aPoint1, aPoint2;
     356 [ +  - ][ +  - ]:        396 :                 aPoint1.PositionX = aPoly.SequenceX[nPoly][nPoint+1];
     357 [ +  - ][ +  - ]:        396 :                 aPoint1.PositionY = aPoly.SequenceY[nPoly][nPoint+1];
     358 [ +  - ][ +  - ]:        396 :                 aPoint1.PositionZ = aPoly.SequenceZ[nPoly][nPoint+1];
     359                 :            : 
     360 [ +  - ][ +  - ]:        396 :                 aPoint2.PositionX = aPoly.SequenceX[nPoly][nPoint];
     361 [ +  - ][ +  - ]:        396 :                 aPoint2.PositionY = aPoly.SequenceY[nPoly][nPoint];
     362 [ +  - ][ +  - ]:        396 :                 aPoint2.PositionZ = aPoly.SequenceZ[nPoly][nPoint];
     363                 :            : 
     364         [ +  - ]:        396 :                 Stripe aStripe( aPoint1, aPoint2, fDepth );
     365                 :            : 
     366                 :            :                 m_pShapeFactory->createStripe(xSeriesGroupShape_Shapes
     367                 :            :                     , Stripe( aPoint1, aPoint2, fDepth )
     368 [ +  - ][ +  - ]:        396 :                     , pSeries->getPropertiesOfSeries(), PropertyMapper::getPropertyNameMapForFilledSeriesProperties(), true, 1 );
         [ +  - ][ +  - ]
     369                 :            :             }
     370                 :            :         }
     371                 :            :     }
     372                 :            :     else //m_nDimension!=3
     373                 :            :     {
     374                 :            :         xShape = m_pShapeFactory->createLine2D( xSeriesGroupShape_Shapes
     375 [ +  - ][ +  - ]:        263 :                 , PolyToPointSequence( aPoly ) );
         [ +  - ][ +  - ]
     376                 :            :         this->setMappedProperties( xShape
     377                 :            :                 , pSeries->getPropertiesOfSeries()
     378 [ +  - ][ +  - ]:        263 :                 , PropertyMapper::getPropertyNameMapForLineSeriesProperties() );
                 [ +  - ]
     379                 :            :         //because of this name this line will be used for marking
     380 [ +  - ][ +  - ]:        263 :         m_pShapeFactory->setShapeName( xShape, C2U("MarkHandles") );
     381                 :            :     }
     382         [ +  - ]:        296 :     return true;
     383                 :            : }
     384                 :            : 
     385                 :          0 : bool AreaChart::impl_createArea( VDataSeries* pSeries
     386                 :            :                 , drawing::PolyPolygonShape3D* pSeriesPoly
     387                 :            :                 , drawing::PolyPolygonShape3D* pPreviousSeriesPoly
     388                 :            :                 , PlottingPositionHelper* pPosHelper )
     389                 :            : {
     390                 :            :     //return true if an area was created successfully
     391                 :            : 
     392         [ #  # ]:          0 :     uno::Reference< drawing::XShapes > xSeriesGroupShape_Shapes = getSeriesGroupShapeBackChild(pSeries, m_xSeriesTarget);
     393                 :          0 :     double zValue = pSeries->m_fLogicZPos;
     394                 :            : 
     395         [ #  # ]:          0 :     drawing::PolyPolygonShape3D aPoly( *pSeriesPoly );
     396                 :            :     //add second part to the polygon (grounding points or previous series points)
     397 [ #  # ][ #  # ]:          0 :     if( m_bConnectLastToFirstPoint && !ShapeFactory::isPolygonEmptyOrSinglePoint(*pSeriesPoly) )
         [ #  # ][ #  # ]
     398                 :            :     {
     399         [ #  # ]:          0 :         if( pPreviousSeriesPoly )
     400         [ #  # ]:          0 :             addPolygon( aPoly, *pPreviousSeriesPoly );
     401                 :            :     }
     402         [ #  # ]:          0 :     else if(!pPreviousSeriesPoly)
     403                 :            :     {
     404                 :          0 :         double fMinX = pSeries->m_fLogicMinX;
     405                 :          0 :         double fMaxX = pSeries->m_fLogicMaxX;
     406         [ #  # ]:          0 :         double fY = pPosHelper->getBaseValueY();//logic grounding
     407         [ #  # ]:          0 :         if( m_nDimension==3 )
     408         [ #  # ]:          0 :             fY = pPosHelper->getLogicMinY();
     409                 :            : 
     410                 :            :         //clip to scale
     411 [ #  # ][ #  # ]:          0 :         if(fMaxX<pPosHelper->getLogicMinX() || fMinX>pPosHelper->getLogicMaxX())
         [ #  # ][ #  # ]
                 [ #  # ]
     412                 :          0 :             return false;//no visible shape needed
     413         [ #  # ]:          0 :         pPosHelper->clipLogicValues( &fMinX, &fY, 0 );
     414         [ #  # ]:          0 :         pPosHelper->clipLogicValues( &fMaxX, 0, 0 );
     415                 :            : 
     416                 :            :         //apply scaling
     417                 :            :         {
     418         [ #  # ]:          0 :             pPosHelper->doLogicScaling( &fMinX, &fY, &zValue );
     419         [ #  # ]:          0 :             pPosHelper->doLogicScaling( &fMaxX, 0, 0 );
     420                 :            :         }
     421                 :            : 
     422         [ #  # ]:          0 :         AddPointToPoly( aPoly, drawing::Position3D( fMaxX,fY,zValue) );
     423         [ #  # ]:          0 :         AddPointToPoly( aPoly, drawing::Position3D( fMinX,fY,zValue) );
     424                 :            :     }
     425                 :            :     else
     426                 :            :     {
     427         [ #  # ]:          0 :         appendPoly( aPoly, *pPreviousSeriesPoly );
     428                 :            :     }
     429         [ #  # ]:          0 :     ShapeFactory::closePolygon(aPoly);
     430                 :            : 
     431                 :            :     //apply clipping
     432                 :            :     {
     433         [ #  # ]:          0 :         drawing::PolyPolygonShape3D aClippedPoly;
     434 [ #  # ][ #  # ]:          0 :         Clipping::clipPolygonAtRectangle( aPoly, pPosHelper->getScaledLogicClipDoubleRect(), aClippedPoly, false );
     435         [ #  # ]:          0 :         ShapeFactory::closePolygon(aClippedPoly); //again necessary after clipping
     436 [ #  # ][ #  # ]:          0 :         aPoly = aClippedPoly;
     437                 :            :     }
     438                 :            : 
     439 [ #  # ][ #  # ]:          0 :     if(!ShapeFactory::hasPolygonAnyLines(aPoly))
     440                 :          0 :         return false;
     441                 :            : 
     442                 :            :     //transformation 3) -> 4)
     443         [ #  # ]:          0 :     pPosHelper->transformScaledLogicToScene( aPoly );
     444                 :            : 
     445                 :            :     //create area:
     446         [ #  # ]:          0 :     uno::Reference< drawing::XShape > xShape(NULL);
     447         [ #  # ]:          0 :     if(m_nDimension==3)
     448                 :            :     {
     449                 :            :         xShape = m_pShapeFactory->createArea3D( xSeriesGroupShape_Shapes
     450 [ #  # ][ #  # ]:          0 :                 , aPoly, this->getTransformedDepth() );
                 [ #  # ]
     451                 :            :     }
     452                 :            :     else //m_nDimension!=3
     453                 :            :     {
     454                 :            :         xShape = m_pShapeFactory->createArea2D( xSeriesGroupShape_Shapes
     455 [ #  # ][ #  # ]:          0 :                 , aPoly );
     456                 :            :     }
     457                 :            :     this->setMappedProperties( xShape
     458                 :            :                 , pSeries->getPropertiesOfSeries()
     459 [ #  # ][ #  # ]:          0 :                 , PropertyMapper::getPropertyNameMapForFilledSeriesProperties() );
                 [ #  # ]
     460                 :            :     //because of this name this line will be used for marking
     461 [ #  # ][ #  # ]:          0 :     m_pShapeFactory->setShapeName( xShape, C2U("MarkHandles") );
     462         [ #  # ]:          0 :     return true;
     463                 :            : }
     464                 :            : 
     465                 :         72 : void AreaChart::impl_createSeriesShapes()
     466                 :            : {
     467                 :            :     //the polygon shapes for each series need to be created before
     468                 :            : 
     469                 :            :     //iterate through all series again to create the series shapes
     470                 :         72 :     ::std::vector< ::std::vector< VDataSeriesGroup > >::iterator            aZSlotIter = m_aZSlots.begin();
     471         [ +  - ]:         72 :     const ::std::vector< ::std::vector< VDataSeriesGroup > >::const_iterator aZSlotEnd = m_aZSlots.end();
     472                 :            : //=============================================================================
     473 [ +  - ][ +  + ]:        162 :     for( sal_Int32 nZ=1; aZSlotIter != aZSlotEnd; ++aZSlotIter, ++nZ )
     474                 :            :     {
     475                 :         90 :         ::std::vector< VDataSeriesGroup >::iterator             aXSlotIter = aZSlotIter->begin();
     476         [ +  - ]:         90 :         const ::std::vector< VDataSeriesGroup >::const_iterator aXSlotEnd = aZSlotIter->end();
     477                 :            : 
     478                 :            :     //=============================================================================
     479 [ +  - ][ +  + ]:        374 :         for( ; aXSlotIter != aXSlotEnd; ++aXSlotIter )
     480                 :            :         {
     481                 :        284 :             ::std::vector< VDataSeries* >* pSeriesList = &(aXSlotIter->m_aSeriesVector);
     482                 :            : 
     483         [ +  - ]:        284 :             ::std::vector< VDataSeries* >::const_iterator       aSeriesIter = pSeriesList->begin();
     484         [ +  - ]:        284 :             const ::std::vector< VDataSeries* >::const_iterator aSeriesEnd  = pSeriesList->end();
     485                 :            :     //=============================================================================
     486                 :            : 
     487         [ +  - ]:        284 :             std::map< sal_Int32, drawing::PolyPolygonShape3D* > aPreviousSeriesPolyMap;//a PreviousSeriesPoly for each different nAttachedAxisIndex
     488                 :        284 :             drawing::PolyPolygonShape3D* pSeriesPoly = NULL;
     489                 :            : 
     490                 :            :             //iterate through all series
     491 [ +  - ][ +  + ]:        580 :             for( ; aSeriesIter != aSeriesEnd; ++aSeriesIter )
     492                 :            :             {
     493         [ +  - ]:        296 :                 sal_Int32 nAttachedAxisIndex = (*aSeriesIter)->getAttachedAxisIndex();
     494         [ +  - ]:        296 :                 PlottingPositionHelper* pPosHelper = &(this->getPlottingPositionHelper( nAttachedAxisIndex ));
     495         [ -  + ]:        296 :                 if(!pPosHelper)
     496                 :          0 :                     pPosHelper = m_pMainPosHelper;
     497                 :        296 :                 PlotterBase::m_pPosHelper = pPosHelper;
     498                 :            : 
     499                 :        296 :                 createRegressionCurvesShapes( **aSeriesIter, m_xErrorBarTarget, m_xRegressionCurveEquationTarget,
     500         [ +  - ]:        592 :                                               m_pPosHelper->maySkipPointsInRegressionCalculation());
     501                 :            : 
     502                 :        296 :                 pSeriesPoly = &(*aSeriesIter)->m_aPolyPolygonShape3D;
     503         [ -  + ]:        296 :                 if( m_bArea )
     504                 :            :                 {
     505 [ #  # ][ #  # ]:          0 :                     if( !impl_createArea( *aSeriesIter, pSeriesPoly, aPreviousSeriesPolyMap[nAttachedAxisIndex], pPosHelper ) )
                 [ #  # ]
     506                 :          0 :                         continue;
     507                 :            :                 }
     508         [ +  - ]:        296 :                 if( m_bLine )
     509                 :            :                 {
     510 [ +  - ][ -  + ]:        296 :                     if( !impl_createLine( *aSeriesIter, pSeriesPoly, pPosHelper ) )
     511                 :          0 :                         continue;
     512                 :            :                 }
     513         [ +  - ]:        296 :                 aPreviousSeriesPolyMap[nAttachedAxisIndex] = pSeriesPoly;
     514                 :            :             }//next series in x slot (next y slot)
     515                 :        284 :         }//next x slot
     516                 :            :     }//next z slot
     517                 :         72 : }
     518                 :            : 
     519                 :            : namespace
     520                 :            : {
     521                 :            : 
     522                 :          0 : void lcl_reorderSeries( ::std::vector< ::std::vector< VDataSeriesGroup > >&  rZSlots )
     523                 :            : {
     524         [ #  # ]:          0 :     ::std::vector< ::std::vector< VDataSeriesGroup > >  aRet( rZSlots.size() );
     525                 :            : 
     526                 :          0 :     ::std::vector< ::std::vector< VDataSeriesGroup > >::reverse_iterator aZIt( rZSlots.rbegin() );
     527                 :          0 :     ::std::vector< ::std::vector< VDataSeriesGroup > >::reverse_iterator aZEnd( rZSlots.rend() );
     528 [ #  # ][ #  # ]:          0 :     for( ; aZIt != aZEnd; ++aZIt )
                 [ #  # ]
     529                 :            :     {
     530 [ #  # ][ #  # ]:          0 :         ::std::vector< VDataSeriesGroup > aXSlot( aZIt->size() );
     531                 :            : 
     532         [ #  # ]:          0 :         ::std::vector< VDataSeriesGroup >::reverse_iterator aXIt( aZIt->rbegin() );
     533         [ #  # ]:          0 :         ::std::vector< VDataSeriesGroup >::reverse_iterator aXEnd( aZIt->rend() );
     534 [ #  # ][ #  # ]:          0 :         for( ; aXIt != aXEnd; ++aXIt )
                 [ #  # ]
     535 [ #  # ][ #  # ]:          0 :             aXSlot.push_back(*aXIt);
     536                 :            : 
     537         [ #  # ]:          0 :         aRet.push_back(aXSlot);
     538                 :          0 :     }
     539                 :            : 
     540                 :          0 :     rZSlots.clear();
     541         [ #  # ]:          0 :     rZSlots = aRet;
     542                 :          0 : }
     543                 :            : 
     544                 :            : }//anonymous namespace
     545                 :            : 
     546                 :            : //better performance for big data
     547                 :            : struct FormerPoint
     548                 :            : {
     549                 :       2538 :     FormerPoint( double fX, double fY, double fZ )
     550                 :       2538 :         : m_fX(fX), m_fY(fY), m_fZ(fZ)
     551                 :       2538 :         {}
     552                 :        296 :     FormerPoint()
     553                 :            :     {
     554                 :        296 :         ::rtl::math::setNan( &m_fX );
     555                 :        296 :         ::rtl::math::setNan( &m_fY );
     556                 :        296 :         ::rtl::math::setNan( &m_fZ );
     557                 :        296 :     }
     558                 :            : 
     559                 :            :     double m_fX;
     560                 :            :     double m_fY;
     561                 :            :     double m_fZ;
     562                 :            : };
     563                 :            : 
     564                 :         72 : void AreaChart::createShapes()
     565                 :            : {
     566 [ +  - ][ +  - ]:         72 :     if( m_aZSlots.begin() == m_aZSlots.end() ) //no series
     567                 :            :         return;
     568                 :            : 
     569 [ +  + ][ +  - ]:         72 :     if( m_nDimension == 2 && ( m_bArea || !m_bCategoryXAxis ) )
                 [ -  + ]
     570         [ #  # ]:          0 :         lcl_reorderSeries( m_aZSlots );
     571                 :            : 
     572                 :            :     OSL_ENSURE(m_pShapeFactory&&m_xLogicTarget.is()&&m_xFinalTarget.is(),"AreaChart is not proper initialized");
     573 [ +  - ][ +  - ]:         72 :     if(!(m_pShapeFactory&&m_xLogicTarget.is()&&m_xFinalTarget.is()))
         [ -  + ][ +  - ]
     574                 :            :         return;
     575                 :            : 
     576                 :            :     //the text labels should be always on top of the other series shapes
     577                 :            :     //for area chart the error bars should be always on top of the other series shapes
     578                 :            : 
     579                 :            :     //therefore create an own group for the texts and the error bars to move them to front
     580                 :            :     //(because the text group is created after the series group the texts are displayed on top)
     581 [ +  - ][ +  - ]:         72 :     m_xSeriesTarget   = createGroupShape( m_xLogicTarget,rtl::OUString() );
     582         [ -  + ]:         72 :     if( m_bArea )
     583 [ #  # ][ #  # ]:          0 :         m_xErrorBarTarget = createGroupShape( m_xLogicTarget,rtl::OUString() );
     584                 :            :     else
     585         [ +  - ]:         72 :         m_xErrorBarTarget = m_xSeriesTarget;
     586 [ +  - ][ +  - ]:         72 :     m_xTextTarget     = m_pShapeFactory->createGroup2D( m_xFinalTarget,rtl::OUString() );
     587 [ +  - ][ +  - ]:         72 :     m_xRegressionCurveEquationTarget = m_pShapeFactory->createGroup2D( m_xFinalTarget,rtl::OUString() );
     588                 :            : 
     589                 :            :     //---------------------------------------------
     590                 :            :     //check necessary here that different Y axis can not be stacked in the same group? ... hm?
     591                 :            : 
     592                 :            :     //update/create information for current group
     593                 :         72 :     double fLogicZ        = 1.0;//as defined
     594                 :            : 
     595                 :         72 :     sal_Int32 nStartIndex = 0; // inclusive       ;..todo get somehow from x scale
     596         [ +  - ]:         72 :     sal_Int32 nEndIndex = VSeriesPlotter::getPointCount();
     597         [ -  + ]:         72 :     if(nEndIndex<=0)
     598                 :          0 :         nEndIndex=1;
     599                 :            : 
     600                 :            :     //better performance for big data
     601         [ +  - ]:         72 :     std::map< VDataSeries*, FormerPoint > aSeriesFormerPointMap;
     602                 :         72 :     m_bPointsWereSkipped = false;
     603                 :         72 :     sal_Int32 nSkippedPoints = 0;
     604                 :         72 :     sal_Int32 nCreatedPoints = 0;
     605                 :            :     //
     606                 :            : 
     607 [ +  - ][ +  - ]:         72 :     bool bDateCategory = (m_pExplicitCategoriesProvider && m_pExplicitCategoriesProvider->isDateAxis());
                 [ -  + ]
     608                 :            : 
     609                 :            : //=============================================================================
     610                 :            :     //iterate through all x values per indices
     611         [ +  + ]:        838 :     for( sal_Int32 nIndex = nStartIndex; nIndex < nEndIndex; nIndex++ )
     612                 :            :     {
     613                 :        766 :         ::std::vector< ::std::vector< VDataSeriesGroup > >::iterator             aZSlotIter = m_aZSlots.begin();
     614         [ +  - ]:        766 :         const ::std::vector< ::std::vector< VDataSeriesGroup > >::const_iterator  aZSlotEnd = m_aZSlots.end();
     615                 :            : 
     616         [ +  - ]:        766 :         std::map< sal_Int32, double > aLogicYSumMap;//one for each different nAttachedAxisIndex
     617 [ +  - ][ +  + ]:       1766 :         for( ; aZSlotIter != aZSlotEnd; ++aZSlotIter )
     618                 :            :         {
     619                 :       1000 :             ::std::vector< VDataSeriesGroup >::iterator             aXSlotIter = aZSlotIter->begin();
     620         [ +  - ]:       1000 :             const ::std::vector< VDataSeriesGroup >::const_iterator aXSlotEnd = aZSlotIter->end();
     621                 :            : 
     622                 :            :             //iterate through all x slots in this category to get 100percent sum
     623 [ +  - ][ +  + ]:       3382 :             for( ; aXSlotIter != aXSlotEnd; ++aXSlotIter )
     624                 :            :             {
     625                 :       2382 :                 std::vector<VDataSeries*>& rSeriesList = aXSlotIter->m_aSeriesVector;
     626                 :       2382 :                 std::vector<VDataSeries*>::iterator       aSeriesIter = rSeriesList.begin();
     627                 :       2382 :                 const std::vector<VDataSeries*>::iterator aSeriesEnd  = rSeriesList.end();
     628                 :            : 
     629 [ +  - ][ +  + ]:       4920 :                 for( ; aSeriesIter != aSeriesEnd; ++aSeriesIter )
     630                 :            :                 {
     631                 :       2538 :                     VDataSeries* pSeries( *aSeriesIter );
     632         [ -  + ]:       2538 :                     if(!pSeries)
     633                 :          0 :                         continue;
     634                 :            : 
     635         [ -  + ]:       2538 :                     if (bDateCategory)
     636         [ #  # ]:          0 :                         pSeries->doSortByXValues();
     637                 :            : 
     638         [ +  - ]:       2538 :                     sal_Int32 nAttachedAxisIndex = pSeries->getAttachedAxisIndex();
     639 [ +  - ][ +  - ]:       2538 :                     if( aLogicYSumMap.find(nAttachedAxisIndex)==aLogicYSumMap.end() )
                 [ +  + ]
     640         [ +  - ]:        766 :                         aLogicYSumMap[nAttachedAxisIndex]=0.0;
     641                 :            : 
     642         [ +  - ]:       2538 :                     PlottingPositionHelper* pPosHelper = &(this->getPlottingPositionHelper( nAttachedAxisIndex ));
     643         [ -  + ]:       2538 :                     if(!pPosHelper)
     644                 :          0 :                         pPosHelper = m_pMainPosHelper;
     645                 :       2538 :                     PlotterBase::m_pPosHelper = pPosHelper;
     646                 :            : 
     647         [ +  - ]:       2538 :                     double fAdd = pSeries->getYValue( nIndex );
     648 [ +  - ][ +  - ]:       2538 :                     if( !::rtl::math::isNan(fAdd) && !::rtl::math::isInf(fAdd) )
                 [ +  - ]
     649         [ +  - ]:       2538 :                         aLogicYSumMap[nAttachedAxisIndex] += fabs( fAdd );
     650                 :            :                 }
     651                 :            :             }
     652                 :            :         }
     653                 :            : 
     654                 :            : //=============================================================================
     655                 :        766 :         aZSlotIter = m_aZSlots.begin();
     656 [ +  - ][ +  + ]:       1766 :         for( sal_Int32 nZ=1; aZSlotIter != aZSlotEnd; ++aZSlotIter, ++nZ )
     657                 :            :         {
     658                 :       1000 :             ::std::vector< VDataSeriesGroup >::iterator             aXSlotIter = aZSlotIter->begin();
     659         [ +  - ]:       1000 :             const ::std::vector< VDataSeriesGroup >::const_iterator aXSlotEnd = aZSlotIter->end();
     660                 :            : 
     661                 :            :             //for the area chart there should be at most one x slot (no side by side stacking available)
     662                 :            :             //attention different: xSlots are always interpreted as independent areas one behind the other: @todo this doesn't work why not???
     663                 :       1000 :             aXSlotIter = aZSlotIter->begin();
     664 [ +  - ][ +  + ]:       3382 :             for( sal_Int32 nX=0; aXSlotIter != aXSlotEnd; ++aXSlotIter, ++nX )
     665                 :            :             {
     666                 :       2382 :                 std::vector<VDataSeries*>& rSeriesList = aXSlotIter->m_aSeriesVector;
     667         [ +  - ]:       2382 :                 std::vector<VDataSeries*>::const_iterator       aSeriesIter = rSeriesList.begin();
     668         [ +  - ]:       2382 :                 const std::vector<VDataSeries*>::const_iterator aSeriesEnd  = rSeriesList.end();
     669                 :            : 
     670         [ +  - ]:       2382 :                 std::map< sal_Int32, double > aLogicYForNextSeriesMap;//one for each different nAttachedAxisIndex
     671                 :            :     //=============================================================================
     672                 :            :                 //iterate through all series
     673 [ +  - ][ +  + ]:       4920 :                 for( sal_Int32 nSeriesIndex = 0; aSeriesIter != aSeriesEnd; ++aSeriesIter, ++nSeriesIndex )
     674                 :            :                 {
     675                 :       2538 :                     VDataSeries* pSeries( *aSeriesIter );
     676         [ -  + ]:       2538 :                     if(!pSeries)
     677                 :          0 :                         continue;
     678                 :            : 
     679                 :            :                     /*  #i70133# ignore points outside of series length in standard area
     680                 :            :                         charts. Stacked area charts will use missing points as zeros. In
     681                 :            :                         standard charts, pSeriesList contains only one series. */
     682 [ -  + ][ #  # ]:       2538 :                     if( m_bArea && (rSeriesList.size() == 1) && (nIndex >= (*aSeriesIter)->getTotalPointCount()) )
         [ #  # ][ #  # ]
                 [ -  + ]
     683                 :          0 :                         continue;
     684                 :            : 
     685         [ +  - ]:       2538 :                     uno::Reference< drawing::XShapes > xSeriesGroupShape_Shapes = getSeriesGroupShapeFrontChild(*aSeriesIter, m_xSeriesTarget);
     686                 :            : 
     687         [ +  - ]:       2538 :                     sal_Int32 nAttachedAxisIndex = (*aSeriesIter)->getAttachedAxisIndex();
     688         [ +  - ]:       2538 :                     PlottingPositionHelper* pPosHelper = &(this->getPlottingPositionHelper( nAttachedAxisIndex ));
     689         [ -  + ]:       2538 :                     if(!pPosHelper)
     690                 :          0 :                         pPosHelper = m_pMainPosHelper;
     691                 :       2538 :                     PlotterBase::m_pPosHelper = pPosHelper;
     692                 :            : 
     693         [ +  + ]:       2538 :                     if(m_nDimension==3)
     694                 :        429 :                         fLogicZ = nZ+0.5;
     695                 :       2538 :                     (*aSeriesIter)->m_fLogicZPos = fLogicZ;
     696                 :            : 
     697                 :            :                     //collect data point information (logic coordinates, style ):
     698         [ +  - ]:       2538 :                     double fLogicX = (*aSeriesIter)->getXValue(nIndex);
     699         [ -  + ]:       2538 :                     if (bDateCategory)
     700         [ #  # ]:          0 :                         fLogicX = DateHelper::RasterizeDateValue( fLogicX, m_aNullDate, m_nTimeResolution );
     701         [ +  - ]:       2538 :                     double fLogicY = (*aSeriesIter)->getYValue(nIndex);
     702                 :            : 
     703 [ -  + ][ #  #  :       2538 :                     if( m_bIsPolarCooSys && m_bArea &&
             #  #  #  # ]
                 [ -  + ]
     704                 :          0 :                         ( ::rtl::math::isNan(fLogicY) || ::rtl::math::isInf(fLogicY) ) )
     705                 :            :                     {
     706 [ #  # ][ #  # ]:          0 :                         if( (*aSeriesIter)->getMissingValueTreatment() == ::com::sun::star::chart::MissingValueTreatment::LEAVE_GAP )
     707                 :            :                         {
     708 [ #  # ][ #  # ]:          0 :                             if( rSeriesList.size() == 1 || nSeriesIndex == 0 )
                 [ #  # ]
     709                 :            :                             {
     710         [ #  # ]:          0 :                                 fLogicY = pPosHelper->getLogicMinY();
     711 [ #  # ][ #  # ]:          0 :                                 if( !pPosHelper->isMathematicalOrientationY() )
     712         [ #  # ]:          0 :                                     fLogicY = pPosHelper->getLogicMaxY();
     713                 :            :                             }
     714                 :            :                             else
     715                 :          0 :                                 fLogicY = 0.0;
     716                 :            :                         }
     717                 :            :                     }
     718                 :            : 
     719 [ +  + ][ -  + ]:       2538 :                     if( m_nDimension==3 && m_bArea && rSeriesList.size()!=1 )
         [ #  # ][ -  + ]
     720                 :          0 :                         fLogicY = fabs( fLogicY );
     721                 :            : 
     722 [ +  - ][ +  + ]:       2538 :                     if( pPosHelper->isPercentY() && !::rtl::math::approxEqual( aLogicYSumMap[nAttachedAxisIndex], 0.0 ) )
         [ +  - ][ +  - ]
                 [ +  + ]
     723                 :            :                     {
     724         [ +  - ]:        156 :                         fLogicY = fabs( fLogicY )/aLogicYSumMap[nAttachedAxisIndex];
     725                 :            :                     }
     726                 :            : 
     727 [ +  - ][ +  -  :      12690 :                     if(    ::rtl::math::isNan(fLogicX) || ::rtl::math::isInf(fLogicX)
          +  -  +  -  +  
                -  -  + ]
                 [ -  + ]
     728                 :       5076 :                         || ::rtl::math::isNan(fLogicY) || ::rtl::math::isInf(fLogicY)
     729                 :       5076 :                         || ::rtl::math::isNan(fLogicZ) || ::rtl::math::isInf(fLogicZ) )
     730                 :            :                     {
     731 [ #  # ][ #  # ]:          0 :                         if( (*aSeriesIter)->getMissingValueTreatment() == ::com::sun::star::chart::MissingValueTreatment::LEAVE_GAP )
     732                 :            :                         {
     733                 :          0 :                             drawing::PolyPolygonShape3D& rPolygon = (*aSeriesIter)->m_aPolyPolygonShape3D;
     734                 :          0 :                             sal_Int32& rIndex = (*aSeriesIter)->m_nPolygonIndex;
     735 [ #  # ][ #  # ]:          0 :                             if( 0<= rIndex && rIndex < rPolygon.SequenceX.getLength() )
                 [ #  # ]
     736                 :            :                             {
     737 [ #  # ][ #  # ]:          0 :                                 if( rPolygon.SequenceX[ rIndex ].getLength() )
     738                 :          0 :                                     rIndex++; //start a new polygon for the next point if the current poly is not empty
     739                 :            :                             }
     740                 :            :                         }
     741                 :          0 :                         continue;
     742                 :            :                     }
     743                 :            : 
     744 [ +  - ][ +  - ]:       2538 :                     if( aLogicYForNextSeriesMap.find(nAttachedAxisIndex) == aLogicYForNextSeriesMap.end() )
                 [ +  + ]
     745         [ +  - ]:       2382 :                         aLogicYForNextSeriesMap[nAttachedAxisIndex] = 0.0;
     746                 :            : 
     747                 :       2538 :                     double fLogicValueForLabeDisplay = fLogicY;
     748                 :            : 
     749         [ +  - ]:       2538 :                     fLogicY += aLogicYForNextSeriesMap[nAttachedAxisIndex];
     750         [ +  - ]:       2538 :                     aLogicYForNextSeriesMap[nAttachedAxisIndex] = fLogicY;
     751                 :            : 
     752         [ +  - ]:       2538 :                     bool bIsVisible = pPosHelper->isLogicVisible( fLogicX, fLogicY, fLogicZ );
     753                 :            : 
     754                 :            :                     //remind minimal and maximal x values for area 'grounding' points
     755                 :            :                     //only for filled area
     756                 :            :                     {
     757                 :       2538 :                         double& rfMinX = (*aSeriesIter)->m_fLogicMinX;
     758 [ -  + ][ +  + ]:       2538 :                         if(!nIndex||fLogicX<rfMinX)
     759                 :        296 :                             rfMinX=fLogicX;
     760                 :       2538 :                         double& rfMaxX = (*aSeriesIter)->m_fLogicMaxX;
     761 [ +  - ][ +  + ]:       2538 :                         if(!nIndex||fLogicX>rfMaxX)
     762                 :       2538 :                             rfMaxX=fLogicX;
     763                 :            :                     }
     764                 :            : 
     765                 :       2538 :                     drawing::Position3D aUnscaledLogicPosition( fLogicX, fLogicY, fLogicZ );
     766                 :       2538 :                     drawing::Position3D aScaledLogicPosition(aUnscaledLogicPosition);
     767         [ +  - ]:       2538 :                     pPosHelper->doLogicScaling( aScaledLogicPosition );
     768                 :            : 
     769                 :            :                     //transformation 3) -> 4)
     770         [ +  - ]:       2538 :                     drawing::Position3D aScenePosition( pPosHelper->transformLogicToScene( fLogicX,fLogicY,fLogicZ, false ) );
     771                 :            : 
     772                 :            :                     //better performance for big data
     773         [ +  - ]:       2538 :                     FormerPoint aFormerPoint( aSeriesFormerPointMap[pSeries] );
     774         [ +  - ]:       2538 :                     pPosHelper->setCoordinateSystemResolution( m_aCoordinateSystemResolution );
     775 [ +  - ][ +  - ]:       5076 :                     if( !pSeries->isAttributedDataPoint(nIndex)
         [ -  + ][ -  + ]
     776                 :            :                             &&
     777                 :            :                         pPosHelper->isSameForGivenResolution( aFormerPoint.m_fX, aFormerPoint.m_fY, aFormerPoint.m_fZ
     778         [ +  - ]:       2538 :                                                             , aScaledLogicPosition.PositionX, aScaledLogicPosition.PositionY, aScaledLogicPosition.PositionZ ) )
     779                 :            :                     {
     780                 :          0 :                         ++nSkippedPoints;
     781                 :          0 :                         m_bPointsWereSkipped = true;
     782                 :          0 :                         continue;
     783                 :            :                     }
     784         [ +  - ]:       2538 :                     aSeriesFormerPointMap[pSeries] = FormerPoint(aScaledLogicPosition.PositionX, aScaledLogicPosition.PositionY, aScaledLogicPosition.PositionZ);
     785                 :            :                     //
     786                 :            : 
     787                 :            :                     //store point information for series polygon
     788                 :            :                     //for area and/or line (symbols only do not need this)
     789 [ +  - ][ +  - ]:       2538 :                     if( isValidPosition(aScaledLogicPosition) )
     790                 :            :                     {
     791         [ +  - ]:       2538 :                         AddPointToPoly( (*aSeriesIter)->m_aPolyPolygonShape3D, aScaledLogicPosition, (*aSeriesIter)->m_nPolygonIndex );
     792                 :            : 
     793                 :            :                         //prepare clipping for filled net charts
     794 [ -  + ][ #  # ]:       2538 :                         if( !bIsVisible && m_bIsPolarCooSys && m_bArea )
                 [ #  # ]
     795                 :            :                         {
     796                 :          0 :                             drawing::Position3D aClippedPos(aScaledLogicPosition);
     797         [ #  # ]:          0 :                             pPosHelper->clipScaledLogicValues( 0, &aClippedPos.PositionY, 0 );
     798 [ #  # ][ #  # ]:          0 :                             if( pPosHelper->isLogicVisible( aClippedPos.PositionX, aClippedPos.PositionY, aClippedPos.PositionZ ) )
     799                 :            :                             {
     800         [ #  # ]:          0 :                                 AddPointToPoly( (*aSeriesIter)->m_aPolyPolygonShape3D, aClippedPos, (*aSeriesIter)->m_nPolygonIndex );
     801         [ #  # ]:          0 :                                 AddPointToPoly( (*aSeriesIter)->m_aPolyPolygonShape3D, aScaledLogicPosition, (*aSeriesIter)->m_nPolygonIndex );
     802                 :            :                             }
     803                 :            :                         }
     804                 :            :                     }
     805                 :            : 
     806                 :            :                     //create a single datapoint if point is visible
     807                 :            :                     //apply clipping:
     808         [ -  + ]:       2538 :                     if( !bIsVisible )
     809                 :          0 :                         continue;
     810                 :            : 
     811                 :       2538 :                     bool bCreateYErrorBar = false, bCreateXErrorBar = false;
     812                 :            :                     {
     813         [ +  - ]:       2538 :                         uno::Reference< beans::XPropertySet > xErrorBarProp(pSeries->getYErrorBarProperties(nIndex));
     814         [ +  + ]:       2538 :                         if( xErrorBarProp.is() )
     815                 :            :                         {
     816                 :       1014 :                             bool bShowPositive = false;
     817                 :       1014 :                             bool bShowNegative = false;
     818 [ +  - ][ +  - ]:       1014 :                             xErrorBarProp->getPropertyValue( C2U( "ShowPositiveError" )) >>= bShowPositive;
                 [ +  - ]
     819 [ +  - ][ +  - ]:       1014 :                             xErrorBarProp->getPropertyValue( C2U( "ShowNegativeError" )) >>= bShowNegative;
                 [ +  - ]
     820 [ -  + ][ +  + ]:       1014 :                             bCreateYErrorBar = bShowPositive || bShowNegative;
     821                 :            :                         }
     822                 :            : 
     823 [ +  - ][ +  - ]:       2538 :                         xErrorBarProp = pSeries->getXErrorBarProperties(nIndex);
     824         [ -  + ]:       2538 :                         if ( xErrorBarProp.is() )
     825                 :            :                         {
     826                 :          0 :                             bool bShowPositive = false;
     827                 :          0 :                             bool bShowNegative = false;
     828 [ #  # ][ #  # ]:          0 :                             xErrorBarProp->getPropertyValue( C2U( "ShowPositiveError" )) >>= bShowPositive;
                 [ #  # ]
     829 [ #  # ][ #  # ]:          0 :                             xErrorBarProp->getPropertyValue( C2U( "ShowNegativeError" )) >>= bShowNegative;
                 [ #  # ]
     830 [ #  # ][ #  # ]:          0 :                             bCreateXErrorBar = bShowPositive || bShowNegative;
     831                 :       2538 :                         }
     832                 :            :                     }
     833                 :            : 
     834 [ +  - ][ +  + ]:       2538 :                     Symbol* pSymbolProperties = m_bSymbol ? (*aSeriesIter)->getSymbolProperties( nIndex ) : 0;
     835 [ +  + ][ -  + ]:       2538 :                     bool bCreateSymbol = pSymbolProperties && (pSymbolProperties->Style != SymbolStyle_NONE);
     836                 :            : 
     837 [ +  - ][ +  + ]:       4569 :                     if( !bCreateSymbol && !bCreateYErrorBar &&
         [ +  - ][ +  + ]
                 [ +  + ]
     838         [ +  - ]:       2031 :                             !bCreateXErrorBar && !pSeries->getDataPointLabelIfLabel(nIndex) )
     839                 :        510 :                         continue;
     840                 :            : 
     841                 :            :                     //create a group shape for this point and add to the series shape:
     842                 :            :                     rtl::OUString aPointCID = ObjectIdentifier::createPointCID(
     843 [ +  - ][ +  - ]:       2028 :                         (*aSeriesIter)->getPointCID_Stub(), nIndex );
     844                 :            :                     uno::Reference< drawing::XShapes > xPointGroupShape_Shapes(
     845         [ +  - ]:       2028 :                         createGroupShape(xSeriesGroupShape_Shapes,aPointCID) );
     846                 :            :                     uno::Reference<drawing::XShape> xPointGroupShape_Shape =
     847         [ +  - ]:       2028 :                             uno::Reference<drawing::XShape>( xPointGroupShape_Shapes, uno::UNO_QUERY );
     848                 :            : 
     849                 :            :                     {
     850                 :       2028 :                         nCreatedPoints++;
     851                 :            : 
     852                 :            :                         //create data point
     853                 :       2028 :                         drawing::Direction3D aSymbolSize(0,0,0);
     854         [ -  + ]:       2028 :                         if( bCreateSymbol )
     855                 :            :                         {
     856         [ #  # ]:          0 :                             if(m_nDimension!=3)
     857                 :            :                             {
     858         [ #  # ]:          0 :                                 if( pSymbolProperties )
     859                 :            :                                 {
     860         [ #  # ]:          0 :                                     if( pSymbolProperties->Style != SymbolStyle_NONE )
     861                 :            :                                     {
     862                 :          0 :                                         aSymbolSize.DirectionX = pSymbolProperties->Size.Width;
     863                 :          0 :                                         aSymbolSize.DirectionY = pSymbolProperties->Size.Height;
     864                 :            :                                     }
     865                 :            : 
     866         [ #  # ]:          0 :                                     if( pSymbolProperties->Style == SymbolStyle_STANDARD )
     867                 :            :                                     {
     868                 :          0 :                                         sal_Int32 nSymbol = pSymbolProperties->StandardSymbol;
     869                 :            :                                         m_pShapeFactory->createSymbol2D( xPointGroupShape_Shapes
     870                 :            :                                                 , aScenePosition, aSymbolSize
     871                 :            :                                                 , nSymbol
     872                 :            :                                                 , pSymbolProperties->BorderColor
     873         [ #  # ]:          0 :                                                 , pSymbolProperties->FillColor );
     874                 :            :                                     }
     875         [ #  # ]:          0 :                                     else if( pSymbolProperties->Style == SymbolStyle_GRAPHIC )
     876                 :            :                                     {
     877                 :            :                                         m_pShapeFactory->createGraphic2D( xPointGroupShape_Shapes
     878                 :            :                                                 , aScenePosition , aSymbolSize
     879         [ #  # ]:          0 :                                                 , pSymbolProperties->Graphic );
     880                 :            :                                     }
     881                 :            :                                     //@todo other symbol styles
     882                 :            :                                 }
     883                 :            :                             }
     884                 :            :                         }
     885                 :            :                         //create error bars
     886         [ -  + ]:       2028 :                         if (bCreateXErrorBar)
     887         [ #  # ]:          0 :                             createErrorBar_X( aUnscaledLogicPosition, **aSeriesIter, nIndex, m_xErrorBarTarget );
     888                 :            : 
     889         [ +  + ]:       2028 :                         if (bCreateYErrorBar)
     890         [ +  - ]:        507 :                             createErrorBar_Y( aUnscaledLogicPosition, **aSeriesIter, nIndex, m_xErrorBarTarget );
     891                 :            : 
     892                 :            :                         //create data point label
     893 [ +  - ][ +  - ]:       2028 :                         if( (**aSeriesIter).getDataPointLabelIfLabel(nIndex) )
     894                 :            :                         {
     895                 :       2028 :                             LabelAlignment eAlignment = LABEL_ALIGN_TOP;
     896                 :            :                             drawing::Position3D aScenePosition3D( aScenePosition.PositionX
     897                 :            :                                         , aScenePosition.PositionY
     898         [ +  - ]:       2028 :                                         , aScenePosition.PositionZ+this->getTransformedDepth() );
     899                 :            : 
     900         [ +  - ]:       2028 :                             sal_Int32 nLabelPlacement = pSeries->getLabelPlacement( nIndex, m_xChartTypeModel, m_nDimension, pPosHelper->isSwapXAndY() );
     901                 :            : 
     902   [ +  -  -  -  :       2028 :                             switch(nLabelPlacement)
                   -  - ]
     903                 :            :                             {
     904                 :            :                             case ::com::sun::star::chart::DataLabelPlacement::TOP:
     905                 :       2028 :                                 aScenePosition3D.PositionY -= (aSymbolSize.DirectionY/2+1);
     906                 :       2028 :                                 eAlignment = LABEL_ALIGN_TOP;
     907                 :       2028 :                                 break;
     908                 :            :                             case ::com::sun::star::chart::DataLabelPlacement::BOTTOM:
     909                 :          0 :                                 aScenePosition3D.PositionY += (aSymbolSize.DirectionY/2+1);
     910                 :          0 :                                 eAlignment = LABEL_ALIGN_BOTTOM;
     911                 :          0 :                                 break;
     912                 :            :                             case ::com::sun::star::chart::DataLabelPlacement::LEFT:
     913                 :          0 :                                 aScenePosition3D.PositionX -= (aSymbolSize.DirectionX/2+1);
     914                 :          0 :                                 eAlignment = LABEL_ALIGN_LEFT;
     915                 :          0 :                                 break;
     916                 :            :                             case ::com::sun::star::chart::DataLabelPlacement::RIGHT:
     917                 :          0 :                                 aScenePosition3D.PositionX += (aSymbolSize.DirectionX/2+1);
     918                 :          0 :                                 eAlignment = LABEL_ALIGN_RIGHT;
     919                 :          0 :                                 break;
     920                 :            :                             case ::com::sun::star::chart::DataLabelPlacement::CENTER:
     921                 :          0 :                                 eAlignment = LABEL_ALIGN_CENTER;
     922                 :            :                                 //todo implement this different for area charts
     923                 :          0 :                                 break;
     924                 :            :                             default:
     925                 :            :                                 OSL_FAIL("this label alignment is not implemented yet");
     926                 :          0 :                                 aScenePosition3D.PositionY -= (aSymbolSize.DirectionY/2+1);
     927                 :          0 :                                 eAlignment = LABEL_ALIGN_TOP;
     928                 :          0 :                                 break;
     929                 :            :                             }
     930                 :            : 
     931                 :       2028 :                             awt::Point aScreenPosition2D;//get the screen position for the labels
     932                 :       2028 :                             sal_Int32 nOffset = 100; //todo maybe calculate this font height dependent
     933 [ #  # ][ -  + ]:       2028 :                             if( m_bIsPolarCooSys && nLabelPlacement == ::com::sun::star::chart::DataLabelPlacement::OUTSIDE )
     934                 :            :                             {
     935         [ #  # ]:          0 :                                 PolarPlottingPositionHelper* pPolarPosHelper = dynamic_cast<PolarPlottingPositionHelper*>(pPosHelper);
     936         [ #  # ]:          0 :                                 if( pPolarPosHelper )
     937                 :            :                                 {
     938         [ #  # ]:          0 :                                     PolarLabelPositionHelper aPolarLabelPositionHelper(pPolarPosHelper,m_nDimension,m_xLogicTarget,m_pShapeFactory);
     939                 :            :                                     aScreenPosition2D = awt::Point( aPolarLabelPositionHelper.getLabelScreenPositionAndAlignmentForLogicValues(
     940 [ #  # ][ #  # ]:          0 :                                         eAlignment, fLogicX, fLogicY, fLogicZ, nOffset ));
     941                 :          0 :                                 }
     942                 :            :                             }
     943                 :            :                             else
     944                 :            :                             {
     945 [ +  - ][ +  + ]:       2028 :                                 if(LABEL_ALIGN_CENTER==eAlignment || m_nDimension == 3 )
     946                 :        429 :                                     nOffset = 0;
     947                 :            :                                 aScreenPosition2D = awt::Point( LabelPositionHelper(pPosHelper,m_nDimension,m_xLogicTarget,m_pShapeFactory)
     948 [ +  - ][ +  - ]:       2028 :                                     .transformSceneToScreenPosition( aScenePosition3D ) );
                 [ +  - ]
     949                 :            :                             }
     950                 :            : 
     951                 :       2028 :                             this->createDataLabel( m_xTextTarget, **aSeriesIter, nIndex
     952                 :            :                                             , fLogicValueForLabeDisplay
     953   [ +  -  +  - ]:       4056 :                                             , aLogicYSumMap[nAttachedAxisIndex], aScreenPosition2D, eAlignment, nOffset );
     954                 :            :                         }
     955                 :            :                     }
     956                 :            : 
     957                 :            :                     //remove PointGroupShape if empty
     958 [ +  - ][ +  - ]:       2028 :                     if(!xPointGroupShape_Shapes->getCount())
                 [ +  - ]
     959 [ +  - ][ +  - ]:       2028 :                         xSeriesGroupShape_Shapes->remove(xPointGroupShape_Shape);
     960                 :            : 
     961         [ +  + ]:       2538 :                 }//next series in x slot (next y slot)
     962                 :       2382 :             }//next x slot
     963                 :            :         }//next z slot
     964                 :        766 :     }//next category
     965                 :            : //=============================================================================
     966                 :            : //=============================================================================
     967                 :            : //=============================================================================
     968                 :            : 
     969         [ +  - ]:         72 :     impl_createSeriesShapes();
     970                 :            : 
     971                 :            :     /* @todo remove series shapes if empty
     972                 :            :     //remove and delete point-group-shape if empty
     973                 :            :     if(!xSeriesGroupShape_Shapes->getCount())
     974                 :            :     {
     975                 :            :         (*aSeriesIter)->m_xShape.set(NULL);
     976                 :            :         m_xLogicTarget->remove(xSeriesGroupShape_Shape);
     977                 :            :     }
     978                 :            :     */
     979                 :            : 
     980                 :            :     //remove and delete series-group-shape if empty
     981                 :            : 
     982                 :            :     //... todo
     983                 :            : 
     984                 :         72 :     OSL_TRACE( "\nPPPPPPPPP<<<<<<<<<<<< area chart :: createShapes():: skipped points: %d created points: %d", nSkippedPoints, nCreatedPoints );
     985                 :            : }
     986                 :            : 
     987                 :            : //.............................................................................
     988                 :            : } //namespace chart
     989                 :            : //.............................................................................
     990                 :            : 
     991                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10