LCOV - code coverage report
Current view: top level - chart2/source/view/charttypes - BarChart.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 287 458 62.7 %
Date: 2012-08-25 Functions: 13 14 92.9 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 293 749 39.1 %

           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 "BarChart.hxx"
      21                 :            : #include "ShapeFactory.hxx"
      22                 :            : #include "CommonConverters.hxx"
      23                 :            : #include "ObjectIdentifier.hxx"
      24                 :            : #include "LabelPositionHelper.hxx"
      25                 :            : #include "BarPositionHelper.hxx"
      26                 :            : #include "macros.hxx"
      27                 :            : #include "AxisIndexDefines.hxx"
      28                 :            : #include "Clipping.hxx"
      29                 :            : #include "DateHelper.hxx"
      30                 :            : 
      31                 :            : #include <com/sun/star/chart/DataLabelPlacement.hpp>
      32                 :            : 
      33                 :            : #include <com/sun/star/chart2/DataPointGeometry3D.hpp>
      34                 :            : #include <rtl/math.hxx>
      35                 :            : 
      36                 :            : //.............................................................................
      37                 :            : namespace chart
      38                 :            : {
      39                 :            : //.............................................................................
      40                 :            : using namespace ::com::sun::star;
      41                 :            : using namespace ::rtl::math;
      42                 :            : using namespace ::com::sun::star::chart2;
      43                 :            : 
      44                 :        886 : BarChart::BarChart( const uno::Reference<XChartType>& xChartTypeModel
      45                 :            :                     , sal_Int32 nDimensionCount )
      46                 :            :         : VSeriesPlotter( xChartTypeModel, nDimensionCount )
      47 [ +  - ][ +  - ]:        886 :         , m_pMainPosHelper( new BarPositionHelper() )
         [ +  - ][ +  - ]
      48                 :            : {
      49         [ +  - ]:        886 :     PlotterBase::m_pPosHelper = m_pMainPosHelper;
      50         [ +  - ]:        886 :     VSeriesPlotter::m_pMainPosHelper = m_pMainPosHelper;
      51                 :            : 
      52                 :            :     try
      53                 :            :     {
      54         [ +  - ]:        886 :         if( m_xChartTypeModelProps.is() )
      55                 :            :         {
      56 [ +  - ][ +  - ]:        886 :             m_xChartTypeModelProps->getPropertyValue( C2U( "OverlapSequence" ) ) >>= m_aOverlapSequence;
         [ +  - ][ +  - ]
      57 [ +  - ][ +  - ]:        886 :             m_xChartTypeModelProps->getPropertyValue( C2U( "GapwidthSequence" ) ) >>= m_aGapwidthSequence;
         [ +  - ][ #  # ]
                 [ +  - ]
      58                 :            :         }
      59                 :            :     }
      60         [ #  # ]:          0 :     catch( const uno::Exception& e )
      61                 :            :     {
      62                 :            :         ASSERT_EXCEPTION( e );
      63                 :            :     }
      64                 :        886 : }
      65                 :            : 
      66 [ +  - ][ +  - ]:        886 : BarChart::~BarChart()
      67                 :            : {
      68 [ +  - ][ +  - ]:        886 :     delete m_pMainPosHelper;
      69         [ -  + ]:       1772 : }
      70                 :            : 
      71                 :            : //-------------------------------------------------------------------------
      72                 :            : 
      73                 :      11108 : PlottingPositionHelper& BarChart::getPlottingPositionHelper( sal_Int32 nAxisIndex ) const
      74                 :            : {
      75                 :      11108 :     PlottingPositionHelper& rPosHelper = VSeriesPlotter::getPlottingPositionHelper( nAxisIndex );
      76         [ -  + ]:      11108 :     BarPositionHelper* pBarPosHelper = dynamic_cast<BarPositionHelper*>(&rPosHelper);
      77 [ +  - ][ +  - ]:      11108 :     if( pBarPosHelper && nAxisIndex >= 0 )
      78                 :            :     {
      79         [ +  - ]:      11108 :         if( nAxisIndex < m_aOverlapSequence.getLength() )
      80                 :      11108 :             pBarPosHelper->setInnerDistance( -m_aOverlapSequence[nAxisIndex]/100.0 );
      81         [ +  - ]:      11108 :         if( nAxisIndex < m_aGapwidthSequence.getLength() )
      82                 :      11108 :             pBarPosHelper->setOuterDistance( m_aGapwidthSequence[nAxisIndex]/100.0 );
      83                 :            :     }
      84                 :      11108 :     return rPosHelper;
      85                 :            : }
      86                 :            : 
      87                 :        886 : drawing::Direction3D BarChart::getPreferredDiagramAspectRatio() const
      88                 :            : {
      89                 :        886 :     drawing::Direction3D aRet(1.0,1.0,1.0);
      90         [ +  + ]:        886 :     if( m_nDimension == 3 )
      91                 :            :     {
      92                 :          3 :         aRet = drawing::Direction3D(1.0,-1.0,1.0);
      93 [ -  + ][ +  - ]:          3 :                 BarPositionHelper* pPosHelper = dynamic_cast<BarPositionHelper*>(&( this->getPlottingPositionHelper( MAIN_AXIS_INDEX) ) );
      94         [ +  - ]:          3 :         drawing::Direction3D aScale( pPosHelper->getScaledLogicWidth() );
      95         [ +  - ]:          3 :         if(aScale.DirectionX!=0.0)
      96                 :            :         {
      97                 :          3 :             double fXSlotCount = 1.0;
      98         [ +  - ]:          3 :             if(!m_aZSlots.empty())
      99                 :          3 :                 fXSlotCount = m_aZSlots.begin()->size();
     100                 :            : 
     101         [ +  - ]:          3 :             aRet.DirectionZ = aScale.DirectionZ/(aScale.DirectionX + aScale.DirectionX*(fXSlotCount-1.0)*pPosHelper->getScaledSlotWidth());
     102                 :            :         }
     103                 :            :         else
     104         [ #  # ]:          0 :             return VSeriesPlotter::getPreferredDiagramAspectRatio();
     105         [ -  + ]:          3 :         if(aRet.DirectionZ<0.05)
     106                 :          0 :             aRet.DirectionZ=0.05;
     107         [ -  + ]:          3 :         if(aRet.DirectionZ>10)
     108                 :          0 :             aRet.DirectionZ=10;
     109                 :            : 
     110 [ +  - ][ -  + ]:          3 :         if( m_pMainPosHelper && m_pMainPosHelper->isSwapXAndY() )
                 [ -  + ]
     111                 :            :         {
     112                 :          0 :             double fTemp = aRet.DirectionX;
     113                 :          0 :             aRet.DirectionX = aRet.DirectionY;
     114                 :          3 :             aRet.DirectionY = fTemp;
     115                 :            :         }
     116                 :            :     }
     117                 :            :     else
     118                 :        883 :         aRet = drawing::Direction3D(-1,-1,-1);
     119                 :        886 :     return aRet;
     120                 :            : }
     121                 :            : 
     122                 :          0 : bool BarChart::keepAspectRatio() const
     123                 :            : {
     124         [ #  # ]:          0 :     if( m_nDimension == 3 )
     125                 :          0 :         return true;
     126                 :          0 :     return true;
     127                 :            : }
     128                 :            : 
     129                 :        244 : awt::Point BarChart::getLabelScreenPositionAndAlignment(
     130                 :            :                      LabelAlignment& rAlignment, sal_Int32 nLabelPlacement
     131                 :            :                      , double fScaledX, double fScaledLowerYValue, double fScaledUpperYValue, double fScaledZ
     132                 :            :                      , double fScaledLowerBarDepth, double fScaledUpperBarDepth, double fBaseValue
     133                 :            :                      , BarPositionHelper* pPosHelper
     134                 :            :                      ) const
     135                 :            : {
     136                 :        244 :     double fX = fScaledX;
     137                 :        244 :     double fY = fScaledUpperYValue;
     138                 :        244 :     double fZ = fScaledZ;
     139         [ +  - ]:        244 :     bool bReverse = !pPosHelper->isMathematicalOrientationY();
     140                 :        244 :     bool bNormalOutside = (!bReverse == !!(fBaseValue < fScaledUpperYValue));
     141                 :        244 :     double fDepth = fScaledUpperBarDepth;
     142                 :            : 
     143   [ +  -  -  -  :        244 :     switch(nLabelPlacement)
             -  -  -  -  
                      - ]
     144                 :            :     {
     145                 :            :     case ::com::sun::star::chart::DataLabelPlacement::TOP:
     146                 :            :         {
     147         [ +  - ]:        244 :             if( !pPosHelper->isSwapXAndY() )
     148                 :            :             {
     149         [ -  + ]:        244 :                 fY = bReverse ? fScaledLowerYValue : fScaledUpperYValue;
     150                 :        244 :                 rAlignment = LABEL_ALIGN_TOP;
     151         [ -  + ]:        244 :                 if(3==m_nDimension)
     152         [ #  # ]:          0 :                     fDepth = bReverse ? fabs(fScaledLowerBarDepth) : fabs(fScaledUpperBarDepth);
     153                 :            :             }
     154                 :            :             else
     155                 :            :             {
     156                 :          0 :                 fY -= (fScaledUpperYValue-fScaledLowerYValue)/2.0;
     157                 :          0 :                 rAlignment = LABEL_ALIGN_CENTER;
     158                 :            :                 OSL_FAIL( "top label placement is not really supported by horizontal bar charts" );
     159                 :            :             }
     160                 :            :         }
     161                 :        244 :         break;
     162                 :            :     case ::com::sun::star::chart::DataLabelPlacement::BOTTOM:
     163                 :            :         {
     164         [ #  # ]:          0 :             if(!pPosHelper->isSwapXAndY())
     165                 :            :             {
     166         [ #  # ]:          0 :                 fY = bReverse ? fScaledUpperYValue : fScaledLowerYValue;
     167                 :          0 :                 rAlignment = LABEL_ALIGN_BOTTOM;
     168         [ #  # ]:          0 :                 if(3==m_nDimension)
     169         [ #  # ]:          0 :                     fDepth = bReverse ? fabs(fScaledUpperBarDepth) : fabs(fScaledLowerBarDepth);
     170                 :            :             }
     171                 :            :             else
     172                 :            :             {
     173                 :          0 :                 fY -= (fScaledUpperYValue-fScaledLowerYValue)/2.0;
     174                 :          0 :                 rAlignment = LABEL_ALIGN_CENTER;
     175                 :            :                 OSL_FAIL( "bottom label placement is not supported by horizontal bar charts" );
     176                 :            :             }
     177                 :            :         }
     178                 :          0 :         break;
     179                 :            :     case ::com::sun::star::chart::DataLabelPlacement::LEFT:
     180                 :            :         {
     181         [ #  # ]:          0 :             if( pPosHelper->isSwapXAndY() )
     182                 :            :             {
     183         [ #  # ]:          0 :                 fY = bReverse ? fScaledUpperYValue : fScaledLowerYValue;
     184                 :          0 :                 rAlignment = LABEL_ALIGN_LEFT;
     185         [ #  # ]:          0 :                 if(3==m_nDimension)
     186         [ #  # ]:          0 :                     fDepth = bReverse ? fabs(fScaledUpperBarDepth) : fabs(fScaledLowerBarDepth);
     187                 :            :             }
     188                 :            :             else
     189                 :            :             {
     190                 :          0 :                 fY -= (fScaledUpperYValue-fScaledLowerYValue)/2.0;
     191                 :          0 :                 rAlignment = LABEL_ALIGN_CENTER;
     192                 :            :                 OSL_FAIL( "left label placement is not supported by column charts" );
     193                 :            :             }
     194                 :            :         }
     195                 :          0 :         break;
     196                 :            :     case ::com::sun::star::chart::DataLabelPlacement::RIGHT:
     197                 :            :         {
     198         [ #  # ]:          0 :             if( pPosHelper->isSwapXAndY() )
     199                 :            :             {
     200         [ #  # ]:          0 :                 fY = bReverse ? fScaledLowerYValue : fScaledUpperYValue;
     201                 :          0 :                 rAlignment = LABEL_ALIGN_RIGHT;
     202         [ #  # ]:          0 :                 if(3==m_nDimension)
     203         [ #  # ]:          0 :                     fDepth = bReverse ? fabs(fScaledLowerBarDepth) : fabs(fScaledUpperBarDepth);
     204                 :            :             }
     205                 :            :             else
     206                 :            :             {
     207                 :          0 :                 fY -= (fScaledUpperYValue-fScaledLowerYValue)/2.0;
     208                 :          0 :                 rAlignment = LABEL_ALIGN_CENTER;
     209                 :            :                 OSL_FAIL( "right label placement is not supported by column charts" );
     210                 :            :             }
     211                 :            :         }
     212                 :          0 :         break;
     213                 :            :     case ::com::sun::star::chart::DataLabelPlacement::OUTSIDE:
     214                 :            :         {
     215         [ #  # ]:          0 :         fY = (fBaseValue < fScaledUpperYValue) ? fScaledUpperYValue : fScaledLowerYValue;
     216         [ #  # ]:          0 :         if( pPosHelper->isSwapXAndY() )
     217         [ #  # ]:          0 :             rAlignment = bNormalOutside ? LABEL_ALIGN_RIGHT : LABEL_ALIGN_LEFT;
     218                 :            :         else
     219         [ #  # ]:          0 :             rAlignment = bNormalOutside ? LABEL_ALIGN_TOP : LABEL_ALIGN_BOTTOM;
     220         [ #  # ]:          0 :         if(3==m_nDimension)
     221         [ #  # ]:          0 :             fDepth = (fBaseValue < fScaledUpperYValue) ? fabs(fScaledUpperBarDepth) : fabs(fScaledLowerBarDepth);
     222                 :            :         }
     223                 :          0 :         break;
     224                 :            :     case ::com::sun::star::chart::DataLabelPlacement::INSIDE:
     225                 :            :         {
     226         [ #  # ]:          0 :         fY = (fBaseValue < fScaledUpperYValue) ? fScaledUpperYValue : fScaledLowerYValue;
     227         [ #  # ]:          0 :         if( pPosHelper->isSwapXAndY() )
     228         [ #  # ]:          0 :             rAlignment = bNormalOutside ? LABEL_ALIGN_LEFT : LABEL_ALIGN_RIGHT;
     229                 :            :         else
     230         [ #  # ]:          0 :             rAlignment = bNormalOutside ? LABEL_ALIGN_BOTTOM : LABEL_ALIGN_TOP;
     231         [ #  # ]:          0 :         if(3==m_nDimension)
     232         [ #  # ]:          0 :             fDepth = (fBaseValue < fScaledUpperYValue) ? fabs(fScaledUpperBarDepth) : fabs(fScaledLowerBarDepth);
     233                 :            :         }
     234                 :          0 :         break;
     235                 :            :     case ::com::sun::star::chart::DataLabelPlacement::NEAR_ORIGIN:
     236                 :            :         {
     237         [ #  # ]:          0 :         fY = (fBaseValue < fScaledUpperYValue) ? fScaledLowerYValue : fScaledUpperYValue;
     238         [ #  # ]:          0 :         if( pPosHelper->isSwapXAndY() )
     239         [ #  # ]:          0 :             rAlignment = bNormalOutside ? LABEL_ALIGN_RIGHT : LABEL_ALIGN_LEFT;
     240                 :            :         else
     241         [ #  # ]:          0 :             rAlignment = bNormalOutside ? LABEL_ALIGN_TOP : LABEL_ALIGN_BOTTOM;
     242         [ #  # ]:          0 :         if(3==m_nDimension)
     243         [ #  # ]:          0 :             fDepth = (fBaseValue < fScaledUpperYValue) ? fabs(fScaledLowerBarDepth) : fabs(fScaledUpperBarDepth);
     244                 :            :         }
     245                 :          0 :         break;
     246                 :            :     case ::com::sun::star::chart::DataLabelPlacement::CENTER:
     247                 :          0 :         fY -= (fScaledUpperYValue-fScaledLowerYValue)/2.0;
     248                 :          0 :         rAlignment = LABEL_ALIGN_CENTER;
     249         [ #  # ]:          0 :         if(3==m_nDimension)
     250                 :          0 :             fDepth = fabs(fScaledUpperBarDepth-fScaledLowerBarDepth)/2.0;
     251                 :          0 :         break;
     252                 :            :     default:
     253                 :            :         OSL_FAIL("this label alignment is not implemented yet");
     254                 :            : 
     255                 :          0 :         break;
     256                 :            :     }
     257         [ -  + ]:        244 :     if(3==m_nDimension)
     258                 :          0 :         fZ -= fDepth/2.0;
     259                 :            : 
     260                 :            :     drawing::Position3D aScenePosition3D( pPosHelper->
     261         [ +  - ]:        244 :             transformScaledLogicToScene( fX, fY, fZ, true ) );
     262         [ +  - ]:        244 :     return LabelPositionHelper(pPosHelper,m_nDimension,m_xLogicTarget,m_pShapeFactory)
     263 [ +  - ][ +  - ]:        244 :         .transformSceneToScreenPosition( aScenePosition3D );
                 [ +  - ]
     264                 :            : }
     265                 :            : 
     266                 :         36 : uno::Reference< drawing::XShape > BarChart::createDataPoint3D_Bar(
     267                 :            :           const uno::Reference< drawing::XShapes >& xTarget
     268                 :            :         , const drawing::Position3D& rPosition, const drawing::Direction3D& rSize
     269                 :            :         , double fTopHeight, sal_Int32 nRotateZAngleHundredthDegree
     270                 :            :         , const uno::Reference< beans::XPropertySet >& xObjectProperties
     271                 :            :         , sal_Int32 nGeometry3D )
     272                 :            : {
     273                 :         36 :     bool bRoundedEdges = true;
     274                 :            :     try
     275                 :            :     {
     276         [ +  - ]:         36 :         if( xObjectProperties.is() )
     277                 :            :         {
     278                 :         36 :             sal_Int16 nPercentDiagonal = 0;
     279 [ +  - ][ +  - ]:         36 :             xObjectProperties->getPropertyValue( C2U( "PercentDiagonal" ) ) >>= nPercentDiagonal;
         [ +  - ][ #  # ]
     280         [ +  - ]:         36 :             if( nPercentDiagonal < 5 )
     281                 :         36 :                 bRoundedEdges = false;
     282                 :            :         }
     283                 :            :     }
     284                 :          0 :     catch( const uno::Exception& e )
     285                 :            :     {
     286                 :            :         ASSERT_EXCEPTION( e );
     287                 :            :     }
     288                 :            : 
     289                 :         36 :     uno::Reference< drawing::XShape > xShape(NULL);
     290   [ -  -  -  + ]:         36 :     switch( nGeometry3D )
     291                 :            :     {
     292                 :            :         case DataPointGeometry3D::CYLINDER:
     293 [ #  # ][ #  # ]:          0 :             xShape = m_pShapeFactory->createCylinder( xTarget, rPosition, rSize, nRotateZAngleHundredthDegree );
     294                 :          0 :             break;
     295                 :            :         case DataPointGeometry3D::CONE:
     296 [ #  # ][ #  # ]:          0 :             xShape = m_pShapeFactory->createCone( xTarget, rPosition, rSize, fTopHeight, nRotateZAngleHundredthDegree );
     297                 :          0 :             break;
     298                 :            :         case DataPointGeometry3D::PYRAMID:
     299                 :            :             xShape = m_pShapeFactory->createPyramid( xTarget, rPosition, rSize, fTopHeight, nRotateZAngleHundredthDegree>0
     300 [ #  # ][ #  # ]:          0 :                 , xObjectProperties, PropertyMapper::getPropertyNameMapForFilledSeriesProperties() );
                 [ #  # ]
     301                 :          0 :             break;
     302                 :            :         case DataPointGeometry3D::CUBOID:
     303                 :            :         default:
     304                 :            :             xShape = m_pShapeFactory->createCube( xTarget, rPosition, rSize
     305                 :            :                     , nRotateZAngleHundredthDegree, xObjectProperties
     306 [ +  - ][ +  - ]:         36 :                     , PropertyMapper::getPropertyNameMapForFilledSeriesProperties(), bRoundedEdges );
                 [ +  - ]
     307                 :         36 :             return xShape;
     308                 :            :     }
     309         [ #  # ]:          0 :     if( nGeometry3D != DataPointGeometry3D::PYRAMID )
     310 [ #  # ][ #  # ]:          0 :         this->setMappedProperties( xShape, xObjectProperties, PropertyMapper::getPropertyNameMapForFilledSeriesProperties() );
     311                 :         36 :     return xShape;
     312                 :            : }
     313                 :            : 
     314                 :            : namespace
     315                 :            : {
     316                 :        280 : bool lcl_hasGeometry3DVariableWidth( sal_Int32 nGeometry3D )
     317                 :            : {
     318                 :        280 :     bool bRet = false;
     319         [ -  + ]:        280 :     switch( nGeometry3D )
     320                 :            :     {
     321                 :            :         case DataPointGeometry3D::PYRAMID:
     322                 :            :         case DataPointGeometry3D::CONE:
     323                 :          0 :             bRet = true;
     324                 :          0 :             break;
     325                 :            :         case DataPointGeometry3D::CUBOID:
     326                 :            :         case DataPointGeometry3D::CYLINDER:
     327                 :            :         default:
     328                 :        280 :             bRet = false;
     329                 :        280 :             break;
     330                 :            :     }
     331                 :        280 :     return bRet;
     332                 :            : }
     333                 :            : }// end anonymous namespace
     334                 :            : 
     335                 :       2833 : void BarChart::addSeries( VDataSeries* pSeries, sal_Int32 zSlot, sal_Int32 xSlot, sal_Int32 ySlot )
     336                 :            : {
     337         [ -  + ]:       2833 :     if( !pSeries )
     338                 :       2833 :         return;
     339         [ +  + ]:       2833 :     if(m_nDimension==2)
     340                 :            :     {
     341                 :            :         //2ND_AXIS_IN_BARS put series on second scales to different z slot as temporary workaround
     342                 :            :         //this needs to be redesigned if 3d bars are also able to display secondary axes
     343                 :            : 
     344                 :       2824 :         sal_Int32 nAxisIndex = pSeries->getAttachedAxisIndex();
     345                 :       2824 :         zSlot = nAxisIndex;
     346                 :            : 
     347         [ -  + ]:       2824 :         if( !pSeries->getGroupBarsPerAxis() )
     348                 :          0 :             zSlot = 0;
     349         [ +  + ]:       2824 :         if(zSlot>=static_cast<sal_Int32>(m_aZSlots.size()))
     350                 :        883 :             m_aZSlots.resize(zSlot+1);
     351                 :            :     }
     352                 :       2833 :     VSeriesPlotter::addSeries( pSeries, zSlot, xSlot, ySlot );
     353                 :            : }
     354                 :            : 
     355                 :            : //better performance for big data
     356                 :            : struct FormerBarPoint
     357                 :            : {
     358                 :      10969 :     FormerBarPoint( double fX, double fUpperY, double fLowerY, double fZ )
     359                 :      10969 :         : m_fX(fX), m_fUpperY(fUpperY), m_fLowerY(fLowerY), m_fZ(fZ)
     360                 :      10969 :         {}
     361                 :       2802 :     FormerBarPoint()
     362                 :            :     {
     363                 :       2802 :         ::rtl::math::setNan( &m_fX );
     364                 :       2802 :         ::rtl::math::setNan( &m_fUpperY );
     365                 :       2802 :         ::rtl::math::setNan( &m_fLowerY );
     366                 :       2802 :         ::rtl::math::setNan( &m_fZ );
     367                 :       2802 :     }
     368                 :            : 
     369                 :            :     double m_fX;
     370                 :            :     double m_fUpperY;
     371                 :            :     double m_fLowerY;
     372                 :            :     double m_fZ;
     373                 :            : };
     374                 :            : 
     375                 :        886 : void BarChart::adaptOverlapAndGapwidthForGroupBarsPerAxis()
     376                 :            : {
     377                 :            :     //adapt m_aOverlapSequence and m_aGapwidthSequence for the groupBarsPerAxis feature
     378                 :            :     //thus the different series use the same settings
     379                 :            : 
     380                 :        886 :     VDataSeries* pFirstSeries = getFirstSeries();
     381 [ -  + ][ -  + ]:        886 :     if(pFirstSeries && !pFirstSeries->getGroupBarsPerAxis() )
                 [ +  - ]
     382                 :            :     {
     383                 :          0 :         sal_Int32 nAxisIndex = pFirstSeries->getAttachedAxisIndex();
     384                 :          0 :         sal_Int32 nN = 0;
     385                 :          0 :         sal_Int32 nUseThisIndex = nAxisIndex;
     386 [ #  # ][ #  # ]:          0 :         if( nUseThisIndex < 0 || nUseThisIndex >= m_aOverlapSequence.getLength() )
                 [ #  # ]
     387                 :          0 :             nUseThisIndex = 0;
     388         [ #  # ]:          0 :         for( nN = 0; nN < m_aOverlapSequence.getLength(); nN++ )
     389                 :            :         {
     390         [ #  # ]:          0 :             if(nN!=nUseThisIndex)
     391                 :          0 :                 m_aOverlapSequence[nN] = m_aOverlapSequence[nUseThisIndex];
     392                 :            :         }
     393                 :            : 
     394                 :          0 :         nUseThisIndex = nAxisIndex;
     395 [ #  # ][ #  # ]:          0 :         if( nUseThisIndex < 0 || nUseThisIndex >= m_aGapwidthSequence.getLength() )
                 [ #  # ]
     396                 :          0 :             nUseThisIndex = 0;
     397         [ #  # ]:          0 :         for( nN = 0; nN < m_aGapwidthSequence.getLength(); nN++ )
     398                 :            :         {
     399         [ #  # ]:          0 :             if(nN!=nUseThisIndex)
     400                 :          0 :                 m_aGapwidthSequence[nN] = m_aGapwidthSequence[nUseThisIndex];
     401                 :            :         }
     402                 :            :     }
     403                 :        886 : }
     404                 :            : 
     405                 :        886 : void BarChart::createShapes()
     406                 :            : {
     407 [ +  - ][ +  - ]:        886 :     if( m_aZSlots.begin() == m_aZSlots.end() ) //no series
     408                 :            :         return;
     409                 :            : 
     410                 :            :     OSL_ENSURE(m_pShapeFactory&&m_xLogicTarget.is()&&m_xFinalTarget.is(),"BarChart is not proper initialized");
     411 [ +  - ][ +  - ]:        886 :     if(!(m_pShapeFactory&&m_xLogicTarget.is()&&m_xFinalTarget.is()))
         [ -  + ][ +  - ]
     412                 :            :         return;
     413                 :            : 
     414                 :            :     //the text labels should be always on top of the other series shapes
     415                 :            :     //therefore create an own group for the texts to move them to front
     416                 :            :     //(because the text group is created after the series group the texts are displayed on top)
     417                 :            : 
     418                 :            :     //the regression curves should always be on top of the bars but beneath the text labels
     419                 :            :     //to achieve this the regression curve target is created after the series target and before the text target
     420                 :            : 
     421                 :            :     uno::Reference< drawing::XShapes > xSeriesTarget(
     422         [ +  - ]:        886 :         createGroupShape( m_xLogicTarget,rtl::OUString() ));
     423                 :            :     uno::Reference< drawing::XShapes > xRegressionCurveTarget(
     424         [ +  - ]:        886 :         createGroupShape( m_xLogicTarget,rtl::OUString() ));
     425                 :            :     uno::Reference< drawing::XShapes > xTextTarget(
     426         [ +  - ]:        886 :         m_pShapeFactory->createGroup2D( m_xFinalTarget,rtl::OUString() ));
     427                 :            : 
     428                 :            : 
     429                 :            :     //---------------------------------------------
     430                 :            :     uno::Reference< drawing::XShapes > xRegressionCurveEquationTarget(
     431         [ +  - ]:        886 :         m_pShapeFactory->createGroup2D( m_xFinalTarget,rtl::OUString() ));
     432                 :            :     //check necessary here that different Y axis can not be stacked in the same group? ... hm?
     433                 :            : 
     434                 :        886 :     double fLogicZ        = 1.0;//as defined
     435                 :            : 
     436                 :        886 :     bool bDrawConnectionLines = false;
     437                 :        886 :     bool bDrawConnectionLinesInited = false;
     438                 :        886 :     bool bOnlyConnectionLinesForThisPoint = false;
     439                 :            : 
     440         [ +  - ]:        886 :     adaptOverlapAndGapwidthForGroupBarsPerAxis();
     441                 :            : 
     442                 :            :     //better performance for big data
     443         [ +  - ]:        886 :     std::map< VDataSeries*, FormerBarPoint > aSeriesFormerPointMap;
     444                 :        886 :     m_bPointsWereSkipped = false;
     445                 :        886 :     sal_Int32 nSkippedPoints = 0;
     446                 :        886 :     sal_Int32 nCreatedPoints = 0;
     447                 :            :     //
     448                 :            : 
     449                 :        886 :     sal_Int32 nStartIndex = 0;
     450         [ +  - ]:        886 :     sal_Int32 nEndIndex = VSeriesPlotter::getPointCount();
     451                 :            : //=============================================================================
     452                 :            :     //iterate through all x values per indices
     453         [ +  + ]:       4432 :     for( sal_Int32 nPointIndex = nStartIndex; nPointIndex < nEndIndex; nPointIndex++ )
     454                 :            :     {
     455                 :       3546 :         ::std::vector< ::std::vector< VDataSeriesGroup > >::iterator             aZSlotIter = m_aZSlots.begin();
     456         [ +  - ]:       3546 :         const ::std::vector< ::std::vector< VDataSeriesGroup > >::const_iterator  aZSlotEnd = m_aZSlots.end();
     457                 :            : 
     458                 :            :         //sum up the values for all series in a complete z zlot per attached axis
     459         [ +  - ]:       3546 :         ::std::map< sal_Int32,  double > aLogicYSumMap;
     460 [ +  - ][ +  + ]:       7092 :         for( ; aZSlotIter != aZSlotEnd; ++aZSlotIter )
     461                 :            :         {
     462                 :       3546 :             ::std::vector< VDataSeriesGroup >::iterator             aXSlotIter = aZSlotIter->begin();
     463         [ +  - ]:       3546 :             const ::std::vector< VDataSeriesGroup >::const_iterator aXSlotEnd = aZSlotIter->end();
     464                 :            : 
     465 [ +  - ][ +  + ]:      14651 :             for( aXSlotIter = aZSlotIter->begin(); aXSlotIter != aXSlotEnd; ++aXSlotIter )
     466                 :            :             {
     467         [ +  - ]:      11105 :                 sal_Int32 nAttachedAxisIndex = aXSlotIter->getAttachedAxisIndexForFirstSeries();
     468 [ +  - ][ +  - ]:      11105 :                 if( aLogicYSumMap.find(nAttachedAxisIndex)==aLogicYSumMap.end() )
                 [ +  + ]
     469         [ +  - ]:       3546 :                     aLogicYSumMap[nAttachedAxisIndex]=0.0;
     470                 :            : 
     471                 :      11105 :                 double fMinimumY = 0.0, fMaximumY = 0.0;
     472                 :            :                 aXSlotIter->calculateYMinAndMaxForCategory( nPointIndex
     473 [ +  - ][ +  - ]:      11105 :                     , isSeperateStackingForDifferentSigns( 1 ), fMinimumY, fMaximumY, nAttachedAxisIndex );
     474                 :            : 
     475 [ +  + ][ +  + ]:      11105 :                 if( !::rtl::math::isNan( fMaximumY ) && fMaximumY > 0)
                 [ +  + ]
     476         [ +  - ]:      10881 :                     aLogicYSumMap[nAttachedAxisIndex] += fMaximumY;
     477 [ +  + ][ +  + ]:      11105 :                 if( !::rtl::math::isNan( fMinimumY ) && fMinimumY < 0)
                 [ +  + ]
     478         [ +  - ]:        190 :                     aLogicYSumMap[nAttachedAxisIndex] += fabs(fMinimumY);
     479                 :            :             }
     480                 :            :         }
     481                 :            : 
     482                 :            : //=============================================================================
     483                 :       3546 :         aZSlotIter = m_aZSlots.begin();
     484 [ +  - ][ +  + ]:       7092 :         for( sal_Int32 nZ=1; aZSlotIter != aZSlotEnd; ++aZSlotIter, nZ++ )
     485                 :            :         {
     486                 :       3546 :             ::std::vector< VDataSeriesGroup >::iterator             aXSlotIter = aZSlotIter->begin();
     487         [ +  - ]:       3546 :             const ::std::vector< VDataSeriesGroup >::const_iterator aXSlotEnd = aZSlotIter->end();
     488                 :            : 
     489                 :            : //=============================================================================
     490                 :            :             //iterate through all x slots in this category
     491                 :       3546 :             double fSlotX=0;
     492 [ +  - ][ +  + ]:      14651 :             for( aXSlotIter = aZSlotIter->begin(); aXSlotIter != aXSlotEnd; ++aXSlotIter, fSlotX+=1.0 )
     493                 :            :             {
     494                 :      11105 :                 sal_Int32 nAttachedAxisIndex = 0;
     495                 :      11105 :                 BarPositionHelper* pPosHelper = m_pMainPosHelper;
     496 [ +  - ][ +  - ]:      11105 :                 if( aXSlotIter != aXSlotEnd )
     497                 :            :                 {
     498         [ +  - ]:      11105 :                     nAttachedAxisIndex = aXSlotIter->getAttachedAxisIndexForFirstSeries();
     499                 :            :                     //2ND_AXIS_IN_BARS so far one can assume to have the same plotter for each z slot
     500 [ +  - ][ -  + ]:      11105 :                     pPosHelper = dynamic_cast<BarPositionHelper*>(&( this->getPlottingPositionHelper( nAttachedAxisIndex ) ) );
     501         [ -  + ]:      11105 :                     if(!pPosHelper)
     502                 :          0 :                         pPosHelper = m_pMainPosHelper;
     503                 :            :                 }
     504         [ +  - ]:      11105 :                 PlotterBase::m_pPosHelper = pPosHelper;
     505                 :            : 
     506                 :            :                 //update/create information for current group
     507         [ +  - ]:      11105 :                 pPosHelper->updateSeriesCount( aZSlotIter->size() );
     508         [ +  - ]:      11105 :                 double fLogicBaseWidth = pPosHelper->getScaledSlotWidth();
     509                 :            : 
     510                 :      11105 :                 ::std::vector< VDataSeries* >* pSeriesList = &(aXSlotIter->m_aSeriesVector);
     511                 :            : 
     512                 :            :                 // get distance from base value to maximum and minimum
     513                 :            : 
     514                 :      11105 :                 double fMinimumY = 0.0, fMaximumY = 0.0;
     515                 :            :                 aXSlotIter->calculateYMinAndMaxForCategory( nPointIndex
     516 [ +  - ][ +  - ]:      11105 :                     , isSeperateStackingForDifferentSigns( 1 ), fMinimumY, fMaximumY, nAttachedAxisIndex );
     517                 :            : 
     518                 :      11105 :                 double fLogicPositiveYSum = 0.0;
     519         [ +  + ]:      11105 :                 if( !::rtl::math::isNan( fMaximumY ) )
     520                 :      11089 :                     fLogicPositiveYSum = fMaximumY;
     521                 :            : 
     522                 :      11105 :                 double fLogicNegativeYSum = 0.0;
     523         [ +  + ]:      11105 :                 if( !::rtl::math::isNan( fMinimumY ) )
     524                 :      11089 :                     fLogicNegativeYSum = fMinimumY;
     525                 :            : 
     526 [ +  - ][ -  + ]:      11105 :                 if( pPosHelper->isPercentY() )
     527                 :            :                 {
     528                 :            :                     /*  #i70395# fLogicPositiveYSum contains sum of all positive
     529                 :            :                         values, if any, otherwise the highest negative value.
     530                 :            :                         fLogicNegativeYSum contains sum of all negative values,
     531                 :            :                         if any, otherwise the lowest positive value.
     532                 :            :                         Afterwards, fLogicPositiveYSum will contain the maximum
     533                 :            :                         (positive) value that is related to 100%. */
     534                 :            : 
     535                 :            :                     // do nothing if there are positive values only
     536         [ #  # ]:          0 :                     if( fLogicNegativeYSum < 0.0 )
     537                 :            :                     {
     538                 :            :                         // fLogicPositiveYSum<0 => negative values only, use absolute of negative sum
     539         [ #  # ]:          0 :                         if( fLogicPositiveYSum < 0.0 )
     540                 :          0 :                             fLogicPositiveYSum = -fLogicNegativeYSum;
     541                 :            :                         // otherwise there are positive and negative values, calculate total distance
     542                 :            :                         else
     543                 :          0 :                             fLogicPositiveYSum -= fLogicNegativeYSum;
     544                 :            :                     }
     545                 :          0 :                     fLogicNegativeYSum = 0.0;
     546                 :            :                 }
     547                 :            : 
     548                 :      11105 :                 double fBaseValue = 0.0;
     549 [ +  - ][ +  - ]:      11105 :                 if( !pPosHelper->isPercentY() && pSeriesList->size()<=1 )
         [ +  - ][ +  - ]
     550         [ +  - ]:      11105 :                     fBaseValue = pPosHelper->getBaseValueY();
     551                 :      11105 :                 double fPositiveLogicYForNextSeries = fBaseValue;
     552                 :      11105 :                 double fNegativeLogicYForNextSeries = fBaseValue;
     553                 :            : 
     554         [ +  - ]:      11105 :                 ::std::vector< VDataSeries* >::const_iterator       aSeriesIter = pSeriesList->begin();
     555         [ +  - ]:      11105 :                 const ::std::vector< VDataSeries* >::const_iterator aSeriesEnd  = pSeriesList->end();
     556         [ +  - ]:      11105 :                 aSeriesIter = pSeriesList->begin();
     557                 :            :     //=============================================================================
     558                 :            :                 //iterate through all series in this x slot
     559 [ +  - ][ +  + ]:      22210 :                 for( ; aSeriesIter != aSeriesEnd; ++aSeriesIter )
     560                 :            :                 {
     561                 :      11105 :                     VDataSeries* pSeries( *aSeriesIter );
     562         [ -  + ]:      11105 :                     if(!pSeries)
     563                 :          0 :                         continue;
     564                 :            : 
     565                 :      11105 :                     bOnlyConnectionLinesForThisPoint = false;
     566                 :            : 
     567         [ +  + ]:      11105 :                     if(nPointIndex==nStartIndex)//do not create a regression line for each point
     568                 :       2833 :                         createRegressionCurvesShapes( **aSeriesIter, xRegressionCurveTarget, xRegressionCurveEquationTarget,
     569         [ +  - ]:       5666 :                                                       m_pPosHelper->maySkipPointsInRegressionCalculation());
     570                 :            : 
     571         [ +  + ]:      11105 :                     if( !bDrawConnectionLinesInited )
     572                 :            :                     {
     573         [ +  - ]:        886 :                         bDrawConnectionLines = pSeries->getConnectBars();
     574         [ +  + ]:        886 :                         if( m_nDimension==3 )
     575                 :          3 :                             bDrawConnectionLines = false;
     576 [ -  + ][ #  # ]:        886 :                         if( bDrawConnectionLines && pSeriesList->size()==1 )
                 [ -  + ]
     577                 :            :                         {
     578                 :            :                             //detect whether we have a stacked chart or not:
     579         [ #  # ]:          0 :                             StackingDirection eDirection = pSeries->getStackingDirection();
     580         [ #  # ]:          0 :                             if( eDirection  != StackingDirection_Y_STACKING )
     581                 :          0 :                                 bDrawConnectionLines = false;
     582                 :            :                         }
     583                 :        886 :                         bDrawConnectionLinesInited = true;
     584                 :            :                     }
     585                 :            : 
     586                 :            :                     //------------
     587                 :            : 
     588                 :            :                     uno::Reference< drawing::XShapes > xSeriesGroupShape_Shapes(
     589         [ +  - ]:      11105 :                         getSeriesGroupShape(*aSeriesIter, xSeriesTarget) );
     590                 :            : 
     591                 :            :                     //collect data point information (logic coordinates, style ):
     592         [ +  - ]:      11105 :                     double fUnscaledLogicX = (*aSeriesIter)->getXValue( nPointIndex );
     593         [ +  - ]:      11105 :                     fUnscaledLogicX = DateHelper::RasterizeDateValue( fUnscaledLogicX, m_aNullDate, m_nTimeResolution );
     594 [ +  - ][ -  + ]:      11105 :                     if(fUnscaledLogicX<pPosHelper->getLogicMinX())
     595                 :          0 :                         continue;//point not visible
     596 [ +  - ][ -  + ]:      11105 :                     if(fUnscaledLogicX>pPosHelper->getLogicMaxX())
     597                 :          0 :                         continue;//point not visible
     598 [ +  - ][ +  - ]:      11105 :                     if(pPosHelper->isStrongLowerRequested(0) && fUnscaledLogicX==pPosHelper->getLogicMaxX())
         [ +  - ][ -  + ]
                 [ -  + ]
     599                 :          0 :                         continue;//point not visible
     600         [ +  - ]:      11105 :                     double fLogicX = pPosHelper->getScaledSlotPos( fUnscaledLogicX, fSlotX );
     601                 :            : 
     602         [ +  - ]:      11105 :                     double fLogicBarHeight = (*aSeriesIter)->getYValue( nPointIndex );
     603         [ +  + ]:      11105 :                     if( ::rtl::math::isNan( fLogicBarHeight )) //no value at this category
     604                 :         16 :                         continue;
     605                 :            : 
     606                 :      11089 :                     double fLogicValueForLabeDisplay = fLogicBarHeight;
     607                 :      11089 :                     fLogicBarHeight-=fBaseValue;
     608                 :            : 
     609 [ +  - ][ -  + ]:      11089 :                     if( pPosHelper->isPercentY() )
     610                 :            :                     {
     611         [ #  # ]:          0 :                         if(fLogicPositiveYSum!=0.0)
     612                 :          0 :                             fLogicBarHeight = fabs( fLogicBarHeight )/fLogicPositiveYSum;
     613                 :            :                         else
     614                 :          0 :                             fLogicBarHeight = 0.0;
     615                 :            :                     }
     616                 :            : 
     617                 :            :                     //sort negative and positive values, to display them on different sides of the x axis
     618                 :      11089 :                     bool bPositive = fLogicBarHeight >= 0.0;
     619         [ +  + ]:      11089 :                     double fLowerYValue = bPositive ? fPositiveLogicYForNextSeries : fNegativeLogicYForNextSeries;
     620                 :      11089 :                     double fUpperYValue = fLowerYValue+fLogicBarHeight;
     621         [ +  + ]:      11089 :                     if( bPositive )
     622                 :      10899 :                         fPositiveLogicYForNextSeries += fLogicBarHeight;
     623                 :            :                     else
     624                 :        190 :                         fNegativeLogicYForNextSeries += fLogicBarHeight;
     625                 :            : 
     626         [ +  + ]:      11089 :                     if(m_nDimension==3)
     627                 :         36 :                         fLogicZ = nZ+0.5;
     628                 :            : 
     629                 :      11089 :                     drawing::Position3D aUnscaledLogicPosition( fUnscaledLogicX, fUpperYValue, fLogicZ );
     630                 :            : 
     631                 :            :                     //@todo ... start an iteration over the different breaks of the axis
     632                 :            :                     //each subsystem may add an additional shape to form the whole point
     633                 :            :                     //create a group shape for this point and add to the series shape:
     634                 :            :     //              uno::Reference< drawing::XShapes > xPointGroupShape_Shapes( createGroupShape(xSeriesGroupShape_Shapes) );
     635                 :            :     //              uno::Reference<drawing::XShape> xPointGroupShape_Shape =
     636                 :            :     //                      uno::Reference<drawing::XShape>( xPointGroupShape_Shapes, uno::UNO_QUERY );
     637                 :            :                     //as long as we do not iterate we do not need to create an additional group for each point
     638                 :      11089 :                     uno::Reference< drawing::XShapes > xPointGroupShape_Shapes = xSeriesGroupShape_Shapes;
     639         [ +  - ]:      11089 :                     uno::Reference< beans::XPropertySet > xDataPointProperties( (*aSeriesIter)->getPropertiesOfPoint( nPointIndex ) );
     640                 :      11089 :                     sal_Int32 nGeometry3D = DataPointGeometry3D::CUBOID;
     641         [ +  + ]:      11089 :                     if(m_nDimension==3) try
     642                 :            :                     {
     643 [ +  - ][ +  - ]:         36 :                         xDataPointProperties->getPropertyValue( C2U( "Geometry3D" )) >>= nGeometry3D;
         [ +  - ][ #  # ]
     644                 :            :                     }
     645         [ #  # ]:          0 :                     catch( const uno::Exception& e )
     646                 :            :                     {
     647                 :            :                         ASSERT_EXCEPTION( e );
     648                 :            :                     }
     649                 :            : 
     650                 :            :                     //@todo iterate through all subsystems to create partial points
     651                 :            :                     {
     652                 :            :                         //@todo select a suiteable PositionHelper for this subsystem
     653                 :      11089 :                         BarPositionHelper* pSubPosHelper = pPosHelper;
     654                 :            : 
     655                 :      11089 :                         double fUnclippedUpperYValue = fUpperYValue;
     656                 :            : 
     657                 :            :                         //apply clipping to Y
     658 [ +  - ][ +  + ]:      11089 :                         if( !pPosHelper->clipYRange(fLowerYValue,fUpperYValue) )
     659                 :            :                         {
     660         [ -  + ]:        120 :                             if( bDrawConnectionLines )
     661                 :          0 :                                 bOnlyConnectionLinesForThisPoint = true;
     662                 :            :                             else
     663                 :        120 :                                 continue;
     664                 :            :                         }
     665                 :            :                         //@todo clipping of X and Z is not fully integrated so far, as there is a need to create different objects
     666                 :            : 
     667                 :            :                         //apply scaling to Y before calculating width (necessary to maintain gradient in clipped objects)
     668         [ +  - ]:      10969 :                         pSubPosHelper->doLogicScaling(NULL,&fLowerYValue,NULL);
     669         [ +  - ]:      10969 :                         pSubPosHelper->doLogicScaling(NULL,&fUpperYValue,NULL);
     670                 :            :                         //scaling of X and Z is not provided as the created objects should be symmetric in that dimensions
     671                 :            : 
     672         [ +  - ]:      10969 :                         pSubPosHelper->doLogicScaling(NULL,&fUnclippedUpperYValue,NULL);
     673                 :            : 
     674                 :            :                         //calculate resulting width
     675         [ +  + ]:      10969 :                         double fCompleteHeight = bPositive ? fLogicPositiveYSum : fLogicNegativeYSum;
     676 [ +  - ][ -  + ]:      10969 :                         if( pPosHelper->isPercentY() )
     677                 :          0 :                             fCompleteHeight = 1.0;
     678                 :      10969 :                         double fLogicBarWidth = fLogicBaseWidth;
     679                 :      10969 :                         double fTopHeight=approxSub(fCompleteHeight,fUpperYValue);
     680         [ +  + ]:      10969 :                         if(!bPositive)
     681                 :        190 :                             fTopHeight=approxSub(fCompleteHeight,fLowerYValue);
     682         [ +  + ]:      10969 :                         double fLogicYStart = bPositive ? fLowerYValue : fUpperYValue;
     683                 :      10969 :                         double fMiddleHeight = fUpperYValue-fLowerYValue;
     684         [ +  + ]:      10969 :                         if(!bPositive)
     685                 :        190 :                             fMiddleHeight*=-1.0;
     686                 :      10969 :                         double fLogicBarDepth = 0.5;
     687         [ +  + ]:      10969 :                         if(m_nDimension==3)
     688                 :            :                         {
     689 [ -  + ][ #  # ]:         36 :                             if( lcl_hasGeometry3DVariableWidth(nGeometry3D) && fCompleteHeight!=0.0 )
                 [ -  + ]
     690                 :            :                             {
     691                 :          0 :                                 double fHeight = fCompleteHeight-fLowerYValue;
     692         [ #  # ]:          0 :                                 if(!bPositive)
     693                 :          0 :                                     fHeight = fCompleteHeight-fUpperYValue;
     694                 :          0 :                                 fLogicBarWidth = fLogicBaseWidth*fHeight/(fCompleteHeight);
     695         [ #  # ]:          0 :                                 if(fLogicBarWidth<=0.0)
     696                 :          0 :                                     fLogicBarWidth=fLogicBaseWidth;
     697                 :          0 :                                 fLogicBarDepth = fLogicBarDepth*fHeight/(fCompleteHeight);
     698         [ #  # ]:          0 :                                 if(fLogicBarDepth<=0.0)
     699                 :          0 :                                     fLogicBarDepth*=-1.0;
     700                 :            :                             }
     701                 :            :                         }
     702                 :            : 
     703                 :            :                         //better performance for big data
     704         [ +  - ]:      10969 :                         FormerBarPoint aFormerPoint( aSeriesFormerPointMap[pSeries] );
     705         [ +  - ]:      10969 :                         pPosHelper->setCoordinateSystemResolution( m_aCoordinateSystemResolution );
     706 [ +  - ][ +  + ]:      21694 :                         if( !pSeries->isAttributedDataPoint(nPointIndex)
         [ -  + ][ #  # ]
                 [ -  + ]
     707                 :            :                             &&
     708                 :            :                             pPosHelper->isSameForGivenResolution( aFormerPoint.m_fX, aFormerPoint.m_fUpperY, aFormerPoint.m_fZ
     709         [ +  - ]:      10725 :                                                             , fLogicX, fUpperYValue, fLogicZ )
     710                 :            :                             &&
     711                 :            :                             pPosHelper->isSameForGivenResolution( aFormerPoint.m_fX, aFormerPoint.m_fLowerY, aFormerPoint.m_fZ
     712         [ #  # ]:          0 :                                                             , fLogicX, fLowerYValue, fLogicZ )
     713                 :            :                                                             )
     714                 :            :                         {
     715                 :          0 :                             nSkippedPoints++;
     716                 :          0 :                             m_bPointsWereSkipped = true;
     717                 :          0 :                             continue;
     718                 :            :                         }
     719         [ +  - ]:      10969 :                         aSeriesFormerPointMap[pSeries] = FormerBarPoint(fLogicX,fUpperYValue,fLowerYValue,fLogicZ);
     720                 :            :                         //
     721                 :            : 
     722                 :            :                         //
     723         [ -  + ]:      10969 :                         if( bDrawConnectionLines )
     724                 :            :                         {
     725                 :            :                             //store point information for connection lines
     726                 :            : 
     727                 :          0 :                             drawing::Position3D aLeftUpperPoint( fLogicX-fLogicBarWidth/2.0,fUnclippedUpperYValue,fLogicZ );
     728                 :          0 :                             drawing::Position3D aRightUpperPoint( fLogicX+fLogicBarWidth/2.0,fUnclippedUpperYValue,fLogicZ );
     729                 :            : 
     730 [ #  # ][ #  # ]:          0 :                             if( isValidPosition(aLeftUpperPoint) )
     731         [ #  # ]:          0 :                                 AddPointToPoly( (*aSeriesIter)->m_aPolyPolygonShape3D, aLeftUpperPoint );
     732 [ #  # ][ #  # ]:          0 :                             if( isValidPosition(aRightUpperPoint) )
     733         [ #  # ]:          0 :                                 AddPointToPoly( (*aSeriesIter)->m_aPolyPolygonShape3D, aRightUpperPoint );
     734                 :            :                         }
     735                 :            : 
     736         [ -  + ]:      10969 :                         if( bOnlyConnectionLinesForThisPoint )
     737                 :          0 :                             continue;
     738                 :            : 
     739                 :            :                         //maybe additional possibility for performance improvement
     740                 :            :                         //bool bCreateLineInsteadOfComplexGeometryDueToMissingSpace = false;
     741                 :            :                         //pPosHelper->isSameForGivenResolution( fLogicX-fLogicBarWidth/2.0, fLowerYValue, fLogicZ
     742                 :            :                         //                            , fLogicX+fLogicBarWidth/2.0, fLowerYValue, fLogicZ );
     743                 :            : 
     744                 :      10969 :                         nCreatedPoints++;
     745                 :            :                         //create partial point
     746         [ +  + ]:      10969 :                         if( !approxEqual(fLowerYValue,fUpperYValue) )
     747                 :            :                         {
     748                 :      10951 :                             uno::Reference< drawing::XShape >  xShape;
     749         [ +  + ]:      10951 :                             if( m_nDimension==3 )
     750                 :            :                             {
     751                 :         36 :                                 drawing::Position3D aLogicBottom            (fLogicX,fLogicYStart,fLogicZ);
     752                 :         36 :                                 drawing::Position3D aLogicLeftBottomFront   (fLogicX+fLogicBarWidth/2.0,fLogicYStart,fLogicZ-fLogicBarDepth/2.0);
     753                 :         36 :                                 drawing::Position3D aLogicRightDeepTop      (fLogicX-fLogicBarWidth/2.0,fLogicYStart+fMiddleHeight,fLogicZ+fLogicBarDepth/2.0);
     754                 :         36 :                                 drawing::Position3D aLogicTopTop            (fLogicX,fLogicYStart+fMiddleHeight+fTopHeight,fLogicZ);
     755                 :            : 
     756         [ +  - ]:         36 :                                 uno::Reference< XTransformation > xTransformation = pSubPosHelper->getTransformationScaledLogicToScene();
     757                 :            : 
     758                 :            :                                 //transformation 3) -> 4)
     759 [ +  - ][ +  - ]:         36 :                                 drawing::Position3D aTransformedBottom          ( SequenceToPosition3D( xTransformation->transform( Position3DToSequence(aLogicBottom) ) ) );
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
     760 [ +  - ][ +  - ]:         36 :                                 drawing::Position3D aTransformedLeftBottomFront ( SequenceToPosition3D( xTransformation->transform( Position3DToSequence(aLogicLeftBottomFront) ) ) );
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
     761 [ +  - ][ +  - ]:         36 :                                 drawing::Position3D aTransformedRightDeepTop    ( SequenceToPosition3D( xTransformation->transform( Position3DToSequence(aLogicRightDeepTop) ) ) );
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
     762 [ +  - ][ +  - ]:         36 :                                 drawing::Position3D aTransformedTopTop          ( SequenceToPosition3D( xTransformation->transform( Position3DToSequence(aLogicTopTop) ) ) );
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
     763                 :            : 
     764         [ +  - ]:         36 :                                 drawing::Direction3D aSize = aTransformedRightDeepTop - aTransformedLeftBottomFront;
     765         [ +  - ]:         36 :                                 drawing::Direction3D aTopSize( aTransformedTopTop - aTransformedRightDeepTop );
     766                 :         36 :                                 fTopHeight = aTopSize.DirectionY;
     767                 :            : 
     768                 :         36 :                                 sal_Int32 nRotateZAngleHundredthDegree = 0;
     769         [ -  + ]:         36 :                                 if( pPosHelper->isSwapXAndY() )
     770                 :            :                                 {
     771                 :          0 :                                     fTopHeight = aTopSize.DirectionX;
     772                 :          0 :                                     nRotateZAngleHundredthDegree = 90*100;
     773                 :          0 :                                     aSize = drawing::Direction3D(aSize.DirectionY,aSize.DirectionX,aSize.DirectionZ);
     774                 :            :                                 }
     775                 :            : 
     776         [ +  - ]:         36 :                                 if( aSize.DirectionX < 0 )
     777                 :         36 :                                     aSize.DirectionX *= -1.0;
     778         [ +  - ]:         36 :                                 if( aSize.DirectionZ < 0 )
     779                 :         36 :                                     aSize.DirectionZ *= -1.0;
     780         [ -  + ]:         36 :                                 if( fTopHeight < 0 )
     781                 :          0 :                                     fTopHeight *= -1.0;
     782                 :            : 
     783                 :            :                                 xShape = createDataPoint3D_Bar(
     784                 :            :                                     xPointGroupShape_Shapes, aTransformedBottom, aSize, fTopHeight, nRotateZAngleHundredthDegree
     785 [ +  - ][ +  - ]:         36 :                                     , xDataPointProperties, nGeometry3D );
     786                 :            :                             }
     787                 :            :                             else //m_nDimension!=3
     788                 :            :                             {
     789         [ +  - ]:      10915 :                                 drawing::PolyPolygonShape3D aPoly;
     790                 :      10915 :                                 drawing::Position3D aLeftUpperPoint( fLogicX-fLogicBarWidth/2.0,fUpperYValue,fLogicZ );
     791                 :      10915 :                                 drawing::Position3D aRightUpperPoint( fLogicX+fLogicBarWidth/2.0,fUpperYValue,fLogicZ );
     792                 :            : 
     793         [ +  - ]:      10915 :                                 AddPointToPoly( aPoly, drawing::Position3D( fLogicX-fLogicBarWidth/2.0,fLowerYValue,fLogicZ) );
     794         [ +  - ]:      10915 :                                 AddPointToPoly( aPoly, drawing::Position3D( fLogicX+fLogicBarWidth/2.0,fLowerYValue,fLogicZ) );
     795         [ +  - ]:      10915 :                                 AddPointToPoly( aPoly, aRightUpperPoint );
     796         [ +  - ]:      10915 :                                 AddPointToPoly( aPoly, aLeftUpperPoint );
     797         [ +  - ]:      10915 :                                 AddPointToPoly( aPoly, drawing::Position3D( fLogicX-fLogicBarWidth/2.0,fLowerYValue,fLogicZ) );
     798         [ +  - ]:      10915 :                                 pPosHelper->transformScaledLogicToScene( aPoly );
     799 [ +  - ][ +  - ]:      10915 :                                 xShape = m_pShapeFactory->createArea2D( xPointGroupShape_Shapes, aPoly );
     800 [ +  - ][ +  - ]:      10915 :                                 this->setMappedProperties( xShape, xDataPointProperties, PropertyMapper::getPropertyNameMapForFilledSeriesProperties() );
                 [ +  - ]
     801                 :            :                             }
     802                 :            :                             //set name/classified ObjectID (CID)
     803                 :            :                             ShapeFactory::setShapeName(xShape
     804                 :            :                                 , ObjectIdentifier::createPointCID(
     805 [ +  - ][ +  - ]:      10951 :                                     (*aSeriesIter)->getPointCID_Stub(),nPointIndex) );
                 [ +  - ]
     806                 :            :                         }
     807                 :            : 
     808                 :            :                         //create error bar
     809         [ +  - ]:      10969 :                         createErrorBar_Y( aUnscaledLogicPosition, **aSeriesIter, nPointIndex, m_xLogicTarget, &fLogicX );
     810                 :            : 
     811                 :            :                         //------------
     812                 :            :                         //create data point label
     813 [ +  - ][ +  + ]:      10969 :                         if( (**aSeriesIter).getDataPointLabelIfLabel(nPointIndex) )
     814                 :            :                         {
     815         [ +  - ]:        244 :                             double fLogicSum = aLogicYSumMap[nAttachedAxisIndex];
     816                 :            : 
     817                 :        244 :                             LabelAlignment eAlignment(LABEL_ALIGN_CENTER);
     818         [ +  - ]:        244 :                             sal_Int32 nLabelPlacement = pSeries->getLabelPlacement( nPointIndex, m_xChartTypeModel, m_nDimension, pPosHelper->isSwapXAndY() );
     819                 :            : 
     820                 :        244 :                             double fLowerBarDepth = fLogicBarDepth;
     821                 :        244 :                             double fUpperBarDepth = fLogicBarDepth;
     822                 :            :                             {
     823                 :        244 :                                 double fOuterBarDepth = fLogicBarDepth;
     824 [ -  + ][ #  # ]:        244 :                                 if( lcl_hasGeometry3DVariableWidth(nGeometry3D) && fCompleteHeight!=0.0 )
                 [ -  + ]
     825                 :            :                                 {
     826                 :          0 :                                     fOuterBarDepth = fLogicBarDepth * (fTopHeight)/(fabs(fCompleteHeight));
     827         [ #  # ]:          0 :                                     fLowerBarDepth = (fBaseValue < fUpperYValue) ? fabs(fLogicBarDepth) : fabs(fOuterBarDepth);
     828         [ #  # ]:          0 :                                     fUpperBarDepth = (fBaseValue < fUpperYValue) ? fabs(fOuterBarDepth) : fabs(fLogicBarDepth);
     829                 :            :                                 }
     830                 :            :                             }
     831                 :            : 
     832                 :            :                             awt::Point aScreenPosition2D( this->getLabelScreenPositionAndAlignment(
     833                 :            :                                 eAlignment, nLabelPlacement
     834                 :            :                                 , fLogicX, fLowerYValue, fUpperYValue, fLogicZ
     835         [ +  - ]:        244 :                                 , fLowerBarDepth, fUpperBarDepth, fBaseValue, pPosHelper ));
     836                 :        244 :                             sal_Int32 nOffset = 0;
     837         [ +  - ]:        244 :                             if(LABEL_ALIGN_CENTER!=eAlignment)
     838                 :            :                             {
     839                 :        244 :                                 nOffset = 100;//add some spacing //@todo maybe get more intelligent values
     840         [ -  + ]:        244 :                                 if( m_nDimension == 3 )
     841                 :          0 :                                     nOffset = 260;
     842                 :            :                             }
     843                 :        244 :                             this->createDataLabel( xTextTarget, **aSeriesIter, nPointIndex
     844         [ +  - ]:      11089 :                                             , fLogicValueForLabeDisplay, fLogicSum, aScreenPosition2D, eAlignment, nOffset );
     845                 :            :                         }
     846                 :            : 
     847                 :            :                     }//end iteration through partial points
     848                 :            : 
     849 [ +  + ][ +  + ]:      11105 :                 }//next series in x slot (next y slot)
                 [ +  + ]
     850                 :            :             }//next x slot
     851                 :            :         }//next z slot
     852                 :       3546 :     }//next category
     853                 :            : //=============================================================================
     854                 :            : //=============================================================================
     855                 :            : //=============================================================================
     856         [ -  + ]:        886 :     if( bDrawConnectionLines )
     857                 :            :     {
     858                 :          0 :         ::std::vector< ::std::vector< VDataSeriesGroup > >::iterator             aZSlotIter = m_aZSlots.begin();
     859         [ #  # ]:          0 :         const ::std::vector< ::std::vector< VDataSeriesGroup > >::const_iterator  aZSlotEnd = m_aZSlots.end();
     860                 :            : //=============================================================================
     861 [ #  # ][ #  # ]:          0 :         for( sal_Int32 nZ=1; aZSlotIter != aZSlotEnd; ++aZSlotIter, nZ++ )
     862                 :            :         {
     863                 :          0 :             ::std::vector< VDataSeriesGroup >::iterator             aXSlotIter = aZSlotIter->begin();
     864         [ #  # ]:          0 :             const ::std::vector< VDataSeriesGroup >::const_iterator aXSlotEnd = aZSlotIter->end();
     865                 :            : 
     866                 :          0 :             BarPositionHelper* pPosHelper = m_pMainPosHelper;
     867 [ #  # ][ #  # ]:          0 :             if( aXSlotIter != aXSlotEnd )
     868                 :            :             {
     869         [ #  # ]:          0 :                 sal_Int32 nAttachedAxisIndex = aXSlotIter->getAttachedAxisIndexForFirstSeries();
     870                 :            :                 //2ND_AXIS_IN_BARS so far one can assume to have the same plotter for each z slot
     871 [ #  # ][ #  # ]:          0 :                 pPosHelper = dynamic_cast<BarPositionHelper*>(&( this->getPlottingPositionHelper( nAttachedAxisIndex ) ) );
     872         [ #  # ]:          0 :                 if(!pPosHelper)
     873                 :          0 :                     pPosHelper = m_pMainPosHelper;
     874                 :            :             }
     875         [ #  # ]:          0 :             PlotterBase::m_pPosHelper = pPosHelper;
     876                 :            : 
     877                 :            : //=============================================================================
     878                 :            :             //iterate through all x slots in this category
     879 [ #  # ][ #  # ]:          0 :             for( double fSlotX=0; aXSlotIter != aXSlotEnd; ++aXSlotIter, fSlotX+=1.0 )
     880                 :            :             {
     881                 :          0 :                 ::std::vector< VDataSeries* >* pSeriesList = &(aXSlotIter->m_aSeriesVector);
     882                 :            : 
     883         [ #  # ]:          0 :                 ::std::vector< VDataSeries* >::const_iterator       aSeriesIter = pSeriesList->begin();
     884         [ #  # ]:          0 :                 const ::std::vector< VDataSeries* >::const_iterator aSeriesEnd  = pSeriesList->end();
     885         [ #  # ]:          0 :                 aSeriesIter = pSeriesList->begin();
     886                 :            : //=============================================================================
     887                 :            :                 //iterate through all series in this x slot
     888 [ #  # ][ #  # ]:          0 :                 for( ; aSeriesIter != aSeriesEnd; ++aSeriesIter )
     889                 :            :                 {
     890                 :          0 :                     VDataSeries* pSeries( *aSeriesIter );
     891         [ #  # ]:          0 :                     if(!pSeries)
     892                 :          0 :                         continue;
     893                 :          0 :                     drawing::PolyPolygonShape3D* pSeriesPoly = &pSeries->m_aPolyPolygonShape3D;
     894 [ #  # ][ #  # ]:          0 :                     if(!ShapeFactory::hasPolygonAnyLines(*pSeriesPoly))
     895                 :          0 :                         continue;
     896                 :            : 
     897         [ #  # ]:          0 :                     drawing::PolyPolygonShape3D aPoly;
     898 [ #  # ][ #  # ]:          0 :                     Clipping::clipPolygonAtRectangle( *pSeriesPoly, pPosHelper->getScaledLogicClipDoubleRect(), aPoly );
     899                 :            : 
     900 [ #  # ][ #  # ]:          0 :                     if(!ShapeFactory::hasPolygonAnyLines(aPoly))
     901                 :          0 :                         continue;
     902                 :            : 
     903                 :            :                     //transformation 3) -> 4)
     904         [ #  # ]:          0 :                     pPosHelper->transformScaledLogicToScene( aPoly );
     905                 :            : 
     906                 :            :                     uno::Reference< drawing::XShapes > xSeriesGroupShape_Shapes(
     907         [ #  # ]:          0 :                         getSeriesGroupShape(*aSeriesIter, xSeriesTarget) );
     908                 :            :                     uno::Reference< drawing::XShape > xShape( m_pShapeFactory->createLine2D(
     909 [ #  # ][ #  # ]:          0 :                         xSeriesGroupShape_Shapes, PolyToPointSequence( aPoly ) ) );
                 [ #  # ]
     910                 :            :                     this->setMappedProperties( xShape, pSeries->getPropertiesOfSeries()
     911 [ #  # ][ #  # ]:          0 :                         , PropertyMapper::getPropertyNameMapForFilledSeriesProperties() );
                 [ #  # ]
     912 [ #  # ][ #  # ]:          0 :                 }
     913                 :            :             }
     914                 :            :         }
     915                 :            :     }
     916                 :            : 
     917                 :            :     /* @todo remove series shapes if empty
     918                 :            :     */
     919                 :            : 
     920                 :        886 :     OSL_TRACE( "\nPPPPPPPPP<<<<<<<<<<<< bar chart :: createShapes():: skipped points: %d created points: %d", nSkippedPoints, nCreatedPoints );
     921                 :            : }
     922                 :            : 
     923                 :            : //.............................................................................
     924                 :            : } //namespace chart
     925                 :            : //.............................................................................
     926                 :            : 
     927                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10