LCOV - code coverage report
Current view: top level - chart2/source/view/charttypes - BarChart.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 333 474 70.3 %
Date: 2014-11-03 Functions: 15 16 93.8 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10