LCOV - code coverage report
Current view: top level - chart2/source/view/charttypes - BarChart.cxx (source / functions) Hit Total Coverage
Test: commit 0e63ca4fde4e446f346e35849c756a30ca294aab Lines: 331 472 70.1 %
Date: 2014-04-11 Functions: 13 14 92.9 %
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         550 : BarChart::BarChart( const uno::Reference<XChartType>& xChartTypeModel
      43             :                     , sal_Int32 nDimensionCount )
      44             :         : VSeriesPlotter( xChartTypeModel, nDimensionCount )
      45         550 :         , m_pMainPosHelper( new BarPositionHelper() )
      46             : {
      47         550 :     PlotterBase::m_pPosHelper = m_pMainPosHelper;
      48         550 :     VSeriesPlotter::m_pMainPosHelper = m_pMainPosHelper;
      49             : 
      50             :     try
      51             :     {
      52         550 :         if( m_xChartTypeModelProps.is() )
      53             :         {
      54         550 :             m_xChartTypeModelProps->getPropertyValue( "OverlapSequence" ) >>= m_aOverlapSequence;
      55         550 :             m_xChartTypeModelProps->getPropertyValue( "GapwidthSequence" ) >>= m_aGapwidthSequence;
      56             :         }
      57             :     }
      58           0 :     catch( const uno::Exception& e )
      59             :     {
      60             :         ASSERT_EXCEPTION( e );
      61             :     }
      62         550 : }
      63             : 
      64        1650 : BarChart::~BarChart()
      65             : {
      66         550 :     delete m_pMainPosHelper;
      67        1100 : }
      68             : 
      69        6884 : PlottingPositionHelper& BarChart::getPlottingPositionHelper( sal_Int32 nAxisIndex ) const
      70             : {
      71        6884 :     PlottingPositionHelper& rPosHelper = VSeriesPlotter::getPlottingPositionHelper( nAxisIndex );
      72        6884 :     BarPositionHelper* pBarPosHelper = dynamic_cast<BarPositionHelper*>(&rPosHelper);
      73        6884 :     if( pBarPosHelper && nAxisIndex >= 0 )
      74             :     {
      75        6884 :         if( nAxisIndex < m_aOverlapSequence.getLength() )
      76        6884 :             pBarPosHelper->setInnerDistance( -m_aOverlapSequence[nAxisIndex]/100.0 );
      77        6884 :         if( nAxisIndex < m_aGapwidthSequence.getLength() )
      78        6884 :             pBarPosHelper->setOuterDistance( m_aGapwidthSequence[nAxisIndex]/100.0 );
      79             :     }
      80        6884 :     return rPosHelper;
      81             : }
      82             : 
      83         549 : drawing::Direction3D BarChart::getPreferredDiagramAspectRatio() const
      84             : {
      85         549 :     drawing::Direction3D aRet(1.0,1.0,1.0);
      86         549 :     if( m_nDimension == 3 )
      87             :     {
      88           8 :         aRet = drawing::Direction3D(1.0,-1.0,1.0);
      89           8 :         BarPositionHelper* pPosHelper = dynamic_cast<BarPositionHelper*>(&( this->getPlottingPositionHelper( MAIN_AXIS_INDEX) ) );
      90             :         assert(pPosHelper);
      91           8 :         if(pPosHelper)
      92             :         {
      93           8 :             drawing::Direction3D aScale( pPosHelper->getScaledLogicWidth() );
      94           8 :             if(aScale.DirectionX!=0.0)
      95             :             {
      96           8 :                 double fXSlotCount = 1.0;
      97           8 :                 if(!m_aZSlots.empty())
      98             :                 {
      99           8 :                     fXSlotCount = m_aZSlots.begin()->size();
     100             :                 }
     101          16 :                 aRet.DirectionZ = aScale.DirectionZ /
     102          16 :                     (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           8 :         if(aRet.DirectionZ<0.05)
     115             :         {
     116           0 :             aRet.DirectionZ=0.05;
     117             :         }
     118           8 :         else if(aRet.DirectionZ>10)
     119             :         {
     120           0 :             aRet.DirectionZ=10;
     121             :         }
     122           8 :         if( m_pMainPosHelper && m_pMainPosHelper->isSwapXAndY() )
     123             :         {
     124           2 :             double fTemp = aRet.DirectionX;
     125           2 :             aRet.DirectionX = aRet.DirectionY;
     126           2 :             aRet.DirectionY = fTemp;
     127             :         }
     128             :     }
     129             :     else
     130         541 :         aRet = drawing::Direction3D(-1,-1,-1);
     131         549 :     return aRet;
     132             : }
     133             : 
     134           0 : bool BarChart::keepAspectRatio() const
     135             : {
     136           0 :     return true;
     137             : }
     138             : 
     139         152 : 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         152 :     double fX = fScaledX;
     147         152 :     double fY = fScaledUpperYValue;
     148         152 :     double fZ = fScaledZ;
     149         152 :     bool bReverse = !pPosHelper->isMathematicalOrientationY();
     150         152 :     bool bNormalOutside = (!bReverse == !!(fBaseValue < fScaledUpperYValue));
     151         152 :     double fDepth = fScaledUpperBarDepth;
     152             : 
     153         152 :     switch(nLabelPlacement)
     154             :     {
     155             :     case ::com::sun::star::chart::DataLabelPlacement::TOP:
     156             :         {
     157         129 :             if( !pPosHelper->isSwapXAndY() )
     158             :             {
     159         129 :                 fY = bReverse ? fScaledLowerYValue : fScaledUpperYValue;
     160         129 :                 rAlignment = LABEL_ALIGN_TOP;
     161         129 :                 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         129 :         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          23 :         fY -= (fScaledUpperYValue-fScaledLowerYValue)/2.0;
     258          23 :         rAlignment = LABEL_ALIGN_CENTER;
     259          23 :         if(3==m_nDimension)
     260          23 :             fDepth = fabs(fScaledUpperBarDepth-fScaledLowerBarDepth)/2.0;
     261          23 :         break;
     262             :     default:
     263             :         OSL_FAIL("this label alignment is not implemented yet");
     264             : 
     265           0 :         break;
     266             :     }
     267         152 :     if(3==m_nDimension)
     268          23 :         fZ -= fDepth/2.0;
     269             : 
     270             :     drawing::Position3D aScenePosition3D( pPosHelper->
     271         152 :             transformScaledLogicToScene( fX, fY, fZ, true ) );
     272         152 :     return LabelPositionHelper(pPosHelper,m_nDimension,m_xLogicTarget,m_pShapeFactory)
     273         304 :         .transformSceneToScreenPosition( aScenePosition3D );
     274             : }
     275             : 
     276          81 : 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          81 :     bool bRoundedEdges = true;
     284             :     try
     285             :     {
     286          81 :         if( xObjectProperties.is() )
     287             :         {
     288          81 :             sal_Int16 nPercentDiagonal = 0;
     289          81 :             xObjectProperties->getPropertyValue( "PercentDiagonal" ) >>= nPercentDiagonal;
     290          81 :             if( nPercentDiagonal < 5 )
     291          81 :                 bRoundedEdges = false;
     292             :         }
     293             :     }
     294           0 :     catch( const uno::Exception& e )
     295             :     {
     296             :         ASSERT_EXCEPTION( e );
     297             :     }
     298             : 
     299          81 :     uno::Reference< drawing::XShape > xShape(NULL);
     300          81 :     switch( nGeometry3D )
     301             :     {
     302             :         case DataPointGeometry3D::CYLINDER:
     303          24 :             xShape = m_pShapeFactory->createCylinder( xTarget, rPosition, rSize, nRotateZAngleHundredthDegree );
     304          24 :             break;
     305             :         case DataPointGeometry3D::CONE:
     306          24 :             xShape = m_pShapeFactory->createCone( xTarget, rPosition, rSize, fTopHeight, nRotateZAngleHundredthDegree );
     307          24 :             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         132 :             xShape = m_pShapeFactory->createCube( xTarget, rPosition, rSize
     315             :                     , nRotateZAngleHundredthDegree, xObjectProperties
     316          99 :                     , PropertyMapper::getPropertyNameMapForFilledSeriesProperties(), bRoundedEdges );
     317          33 :             return xShape;
     318             :     }
     319          48 :     if( nGeometry3D != DataPointGeometry3D::PYRAMID )
     320          48 :         this->setMappedProperties( xShape, xObjectProperties, PropertyMapper::getPropertyNameMapForFilledSeriesProperties() );
     321          48 :     return xShape;
     322             : }
     323             : 
     324             : namespace
     325             : {
     326         236 : bool lcl_hasGeometry3DVariableWidth( sal_Int32 nGeometry3D )
     327             : {
     328         236 :     bool bRet = false;
     329         236 :     switch( nGeometry3D )
     330             :     {
     331             :         case DataPointGeometry3D::PYRAMID:
     332             :         case DataPointGeometry3D::CONE:
     333          36 :             bRet = true;
     334          36 :             break;
     335             :         case DataPointGeometry3D::CUBOID:
     336             :         case DataPointGeometry3D::CYLINDER:
     337             :         default:
     338         200 :             bRet = false;
     339         200 :             break;
     340             :     }
     341         236 :     return bRet;
     342             : }
     343             : }// end anonymous namespace
     344             : 
     345        1776 : void BarChart::addSeries( VDataSeries* pSeries, sal_Int32 zSlot, sal_Int32 xSlot, sal_Int32 ySlot )
     346             : {
     347        1776 :     if( !pSeries )
     348        1776 :         return;
     349        1776 :     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        1752 :         sal_Int32 nAxisIndex = pSeries->getAttachedAxisIndex();
     355        1752 :         zSlot = nAxisIndex;
     356             : 
     357        1752 :         if( !pSeries->getGroupBarsPerAxis() )
     358           0 :             zSlot = 0;
     359        1752 :         if(zSlot>=static_cast<sal_Int32>(m_aZSlots.size()))
     360         541 :             m_aZSlots.resize(zSlot+1);
     361             :     }
     362        1776 :     VSeriesPlotter::addSeries( pSeries, zSlot, xSlot, ySlot );
     363             : }
     364             : 
     365             : //better performance for big data
     366             : struct FormerBarPoint
     367             : {
     368        6835 :     FormerBarPoint( double fX, double fUpperY, double fLowerY, double fZ )
     369        6835 :         : m_fX(fX), m_fUpperY(fUpperY), m_fLowerY(fLowerY), m_fZ(fZ)
     370        6835 :         {}
     371        1761 :     FormerBarPoint()
     372             :     {
     373        1761 :         ::rtl::math::setNan( &m_fX );
     374        1761 :         ::rtl::math::setNan( &m_fUpperY );
     375        1761 :         ::rtl::math::setNan( &m_fLowerY );
     376        1761 :         ::rtl::math::setNan( &m_fZ );
     377        1761 :     }
     378             : 
     379             :     double m_fX;
     380             :     double m_fUpperY;
     381             :     double m_fLowerY;
     382             :     double m_fZ;
     383             : };
     384             : 
     385         549 : 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         549 :     VDataSeries* pFirstSeries = getFirstSeries();
     391         549 :     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         549 : }
     414             : 
     415         549 : void BarChart::createShapes()
     416             : {
     417         549 :     if( m_aZSlots.begin() == m_aZSlots.end() ) //no series
     418           0 :         return;
     419             : 
     420             :     OSL_ENSURE(m_pShapeFactory&&m_xLogicTarget.is()&&m_xFinalTarget.is(),"BarChart is not proper initialized");
     421         549 :     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         549 :         createGroupShape( m_xLogicTarget,OUString() ));
     433             :     uno::Reference< drawing::XShapes > xRegressionCurveTarget(
     434        1098 :         createGroupShape( m_xLogicTarget,OUString() ));
     435             :     uno::Reference< drawing::XShapes > xTextTarget(
     436        1098 :         m_pShapeFactory->createGroup2D( m_xFinalTarget,OUString() ));
     437             : 
     438             :     uno::Reference< drawing::XShapes > xRegressionCurveEquationTarget(
     439        1098 :         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         549 :     double fLogicZ        = 1.0;//as defined
     443             : 
     444         549 :     bool bDrawConnectionLines = false;
     445         549 :     bool bDrawConnectionLinesInited = false;
     446         549 :     bool bOnlyConnectionLinesForThisPoint = false;
     447             : 
     448         549 :     adaptOverlapAndGapwidthForGroupBarsPerAxis();
     449             : 
     450             :     //better performance for big data
     451        1098 :     std::map< VDataSeries*, FormerBarPoint > aSeriesFormerPointMap;
     452         549 :     m_bPointsWereSkipped = false;
     453         549 :     sal_Int32 nSkippedPoints = 0;
     454         549 :     sal_Int32 nCreatedPoints = 0;
     455             : 
     456             : 
     457         549 :     sal_Int32 nStartIndex = 0;
     458         549 :     sal_Int32 nEndIndex = VSeriesPlotter::getPointCount();
     459             :     //iterate through all x values per indices
     460        2737 :     for( sal_Int32 nPointIndex = nStartIndex; nPointIndex < nEndIndex; nPointIndex++ )
     461             :     {
     462        2188 :         ::std::vector< ::std::vector< VDataSeriesGroup > >::iterator             aZSlotIter = m_aZSlots.begin();
     463        2188 :         const ::std::vector< ::std::vector< VDataSeriesGroup > >::const_iterator  aZSlotEnd = m_aZSlots.end();
     464             : 
     465             :         //sum up the values for all series in a complete z zlot per attached axis
     466        2188 :         ::std::map< sal_Int32,  double > aLogicYSumMap;
     467        4376 :         for( ; aZSlotIter != aZSlotEnd; ++aZSlotIter )
     468             :         {
     469        2188 :             ::std::vector< VDataSeriesGroup >::iterator             aXSlotIter = aZSlotIter->begin();
     470        2188 :             const ::std::vector< VDataSeriesGroup >::const_iterator aXSlotEnd = aZSlotIter->end();
     471             : 
     472        9064 :             for( aXSlotIter = aZSlotIter->begin(); aXSlotIter != aXSlotEnd; ++aXSlotIter )
     473             :             {
     474        6876 :                 sal_Int32 nAttachedAxisIndex = aXSlotIter->getAttachedAxisIndexForFirstSeries();
     475        6876 :                 if( aLogicYSumMap.find(nAttachedAxisIndex)==aLogicYSumMap.end() )
     476        2188 :                     aLogicYSumMap[nAttachedAxisIndex]=0.0;
     477             : 
     478        6876 :                 double fMinimumY = 0.0, fMaximumY = 0.0;
     479             :                 aXSlotIter->calculateYMinAndMaxForCategory( nPointIndex
     480        6876 :                     , isSeparateStackingForDifferentSigns( 1 ), fMinimumY, fMaximumY, nAttachedAxisIndex );
     481             : 
     482        6876 :                 if( !::rtl::math::isNan( fMaximumY ) && fMaximumY > 0)
     483        6705 :                     aLogicYSumMap[nAttachedAxisIndex] += fMaximumY;
     484        6876 :                 if( !::rtl::math::isNan( fMinimumY ) && fMinimumY < 0)
     485         146 :                     aLogicYSumMap[nAttachedAxisIndex] += fabs(fMinimumY);
     486             :             }
     487             :         }
     488             : 
     489        2188 :         aZSlotIter = m_aZSlots.begin();
     490        4376 :         for( sal_Int32 nZ=1; aZSlotIter != aZSlotEnd; ++aZSlotIter, nZ++ )
     491             :         {
     492        2188 :             ::std::vector< VDataSeriesGroup >::iterator             aXSlotIter = aZSlotIter->begin();
     493        2188 :             const ::std::vector< VDataSeriesGroup >::const_iterator aXSlotEnd = aZSlotIter->end();
     494             : 
     495             :             //iterate through all x slots in this category
     496        2188 :             double fSlotX=0;
     497        9064 :             for( aXSlotIter = aZSlotIter->begin(); aXSlotIter != aXSlotEnd; ++aXSlotIter, fSlotX+=1.0 )
     498             :             {
     499        6876 :                 sal_Int32 nAttachedAxisIndex = 0;
     500        6876 :                 BarPositionHelper* pPosHelper = m_pMainPosHelper;
     501        6876 :                 if( aXSlotIter != aXSlotEnd )
     502             :                 {
     503        6876 :                     nAttachedAxisIndex = aXSlotIter->getAttachedAxisIndexForFirstSeries();
     504             :                     //2ND_AXIS_IN_BARS so far one can assume to have the same plotter for each z slot
     505        6876 :                     pPosHelper = dynamic_cast<BarPositionHelper*>(&( this->getPlottingPositionHelper( nAttachedAxisIndex ) ) );
     506        6876 :                     if(!pPosHelper)
     507           0 :                         pPosHelper = m_pMainPosHelper;
     508             :                 }
     509        6876 :                 PlotterBase::m_pPosHelper = pPosHelper;
     510             : 
     511             :                 //update/create information for current group
     512        6876 :                 pPosHelper->updateSeriesCount( aZSlotIter->size() );
     513        6876 :                 double fLogicBaseWidth = pPosHelper->getScaledSlotWidth();
     514             : 
     515        6876 :                 ::std::vector< VDataSeries* >* pSeriesList = &(aXSlotIter->m_aSeriesVector);
     516             : 
     517             :                 // get distance from base value to maximum and minimum
     518             : 
     519        6876 :                 double fMinimumY = 0.0, fMaximumY = 0.0;
     520             :                 aXSlotIter->calculateYMinAndMaxForCategory( nPointIndex
     521        6876 :                     , isSeparateStackingForDifferentSigns( 1 ), fMinimumY, fMaximumY, nAttachedAxisIndex );
     522             : 
     523        6876 :                 double fLogicPositiveYSum = 0.0;
     524        6876 :                 if( !::rtl::math::isNan( fMaximumY ) )
     525        6860 :                     fLogicPositiveYSum = fMaximumY;
     526             : 
     527        6876 :                 double fLogicNegativeYSum = 0.0;
     528        6876 :                 if( !::rtl::math::isNan( fMinimumY ) )
     529        6860 :                     fLogicNegativeYSum = fMinimumY;
     530             : 
     531        6876 :                 if( pPosHelper->isPercentY() )
     532             :                 {
     533             :                     /*  #i70395# fLogicPositiveYSum contains sum of all positive
     534             :                         values, if any, otherwise the highest negative value.
     535             :                         fLogicNegativeYSum contains sum of all negative values,
     536             :                         if any, otherwise the lowest positive value.
     537             :                         Afterwards, fLogicPositiveYSum will contain the maximum
     538             :                         (positive) value that is related to 100%. */
     539             : 
     540             :                     // do nothing if there are positive values only
     541           8 :                     if( fLogicNegativeYSum < 0.0 )
     542             :                     {
     543             :                         // fLogicPositiveYSum<0 => negative values only, use absolute of negative sum
     544           0 :                         if( fLogicPositiveYSum < 0.0 )
     545           0 :                             fLogicPositiveYSum = -fLogicNegativeYSum;
     546             :                         // otherwise there are positive and negative values, calculate total distance
     547             :                         else
     548           0 :                             fLogicPositiveYSum -= fLogicNegativeYSum;
     549             :                     }
     550           8 :                     fLogicNegativeYSum = 0.0;
     551             :                 }
     552             : 
     553        6876 :                 double fBaseValue = 0.0;
     554        6876 :                 if( !pPosHelper->isPercentY() && pSeriesList->size()<=1 )
     555        6860 :                     fBaseValue = pPosHelper->getBaseValueY();
     556        6876 :                 double fPositiveLogicYForNextSeries = fBaseValue;
     557        6876 :                 double fNegativeLogicYForNextSeries = fBaseValue;
     558             : 
     559        6876 :                 ::std::vector< VDataSeries* >::const_iterator       aSeriesIter = pSeriesList->begin();
     560        6876 :                 const ::std::vector< VDataSeries* >::const_iterator aSeriesEnd  = pSeriesList->end();
     561             :                 //iterate through all series in this x slot
     562       13784 :                 for( ; aSeriesIter != aSeriesEnd; ++aSeriesIter )
     563             :                 {
     564        6908 :                     VDataSeries* pSeries( *aSeriesIter );
     565        6908 :                     if(!pSeries)
     566          73 :                         continue;
     567             : 
     568        6908 :                     bool bHasFillColorMapping = pSeries->hasPropertyMapping("FillColor");
     569             : 
     570        6908 :                     bOnlyConnectionLinesForThisPoint = false;
     571             : 
     572        6908 :                     if(nPointIndex==nStartIndex)//do not create a regression line for each point
     573        1776 :                         createRegressionCurvesShapes( **aSeriesIter, xRegressionCurveTarget, xRegressionCurveEquationTarget,
     574        3552 :                                                       m_pPosHelper->maySkipPointsInRegressionCalculation());
     575             : 
     576        6908 :                     if( !bDrawConnectionLinesInited )
     577             :                     {
     578         549 :                         bDrawConnectionLines = pSeries->getConnectBars();
     579         549 :                         if( m_nDimension==3 )
     580           8 :                             bDrawConnectionLines = false;
     581         549 :                         if( bDrawConnectionLines && pSeriesList->size()==1 )
     582             :                         {
     583             :                             //detect whether we have a stacked chart or not:
     584           0 :                             StackingDirection eDirection = pSeries->getStackingDirection();
     585           0 :                             if( eDirection  != StackingDirection_Y_STACKING )
     586           0 :                                 bDrawConnectionLines = false;
     587             :                         }
     588         549 :                         bDrawConnectionLinesInited = true;
     589             :                     }
     590             : 
     591             :                     uno::Reference< drawing::XShapes > xSeriesGroupShape_Shapes(
     592        6908 :                         getSeriesGroupShape(*aSeriesIter, xSeriesTarget) );
     593             : 
     594             :                     //collect data point information (logic coordinates, style ):
     595        6908 :                     double fUnscaledLogicX = (*aSeriesIter)->getXValue( nPointIndex );
     596        6908 :                     fUnscaledLogicX = DateHelper::RasterizeDateValue( fUnscaledLogicX, m_aNullDate, m_nTimeResolution );
     597        6908 :                     if(fUnscaledLogicX<pPosHelper->getLogicMinX())
     598           0 :                         continue;//point not visible
     599        6908 :                     if(fUnscaledLogicX>pPosHelper->getLogicMaxX())
     600           0 :                         continue;//point not visible
     601        6908 :                     if(pPosHelper->isStrongLowerRequested(0) && fUnscaledLogicX==pPosHelper->getLogicMaxX())
     602           0 :                         continue;//point not visible
     603        6908 :                     double fLogicX = pPosHelper->getScaledSlotPos( fUnscaledLogicX, fSlotX );
     604             : 
     605        6908 :                     double fLogicBarHeight = (*aSeriesIter)->getYValue( nPointIndex );
     606        6908 :                     if( ::rtl::math::isNan( fLogicBarHeight )) //no value at this category
     607          16 :                         continue;
     608             : 
     609        6892 :                     double fLogicValueForLabeDisplay = fLogicBarHeight;
     610        6892 :                     fLogicBarHeight-=fBaseValue;
     611             : 
     612        6892 :                     if( pPosHelper->isPercentY() )
     613             :                     {
     614          24 :                         if(fLogicPositiveYSum!=0.0)
     615          24 :                             fLogicBarHeight = fabs( fLogicBarHeight )/fLogicPositiveYSum;
     616             :                         else
     617           0 :                             fLogicBarHeight = 0.0;
     618             :                     }
     619             : 
     620             :                     //sort negative and positive values, to display them on different sides of the x axis
     621        6892 :                     bool bPositive = fLogicBarHeight >= 0.0;
     622        6892 :                     double fLowerYValue = bPositive ? fPositiveLogicYForNextSeries : fNegativeLogicYForNextSeries;
     623        6892 :                     double fUpperYValue = fLowerYValue+fLogicBarHeight;
     624        6892 :                     if( bPositive )
     625        6746 :                         fPositiveLogicYForNextSeries += fLogicBarHeight;
     626             :                     else
     627         146 :                         fNegativeLogicYForNextSeries += fLogicBarHeight;
     628             : 
     629        6892 :                     if(m_nDimension==3)
     630          93 :                         fLogicZ = nZ+0.5;
     631             : 
     632        6892 :                     drawing::Position3D aUnscaledLogicPosition( fUnscaledLogicX, fUpperYValue, fLogicZ );
     633             : 
     634             :                     //@todo ... start an iteration over the different breaks of the axis
     635             :                     //each subsystem may add an additional shape to form the whole point
     636             :                     //create a group shape for this point and add to the series shape:
     637             :     //              uno::Reference< drawing::XShapes > xPointGroupShape_Shapes( createGroupShape(xSeriesGroupShape_Shapes) );
     638             :     //              uno::Reference<drawing::XShape> xPointGroupShape_Shape =
     639             :     //                      uno::Reference<drawing::XShape>( xPointGroupShape_Shapes, uno::UNO_QUERY );
     640             :                     //as long as we do not iterate we do not need to create an additional group for each point
     641       13727 :                     uno::Reference< drawing::XShapes > xPointGroupShape_Shapes = xSeriesGroupShape_Shapes;
     642       13727 :                     uno::Reference< beans::XPropertySet > xDataPointProperties( (*aSeriesIter)->getPropertiesOfPoint( nPointIndex ) );
     643        6892 :                     sal_Int32 nGeometry3D = DataPointGeometry3D::CUBOID;
     644        6892 :                     if(m_nDimension==3) try
     645             :                     {
     646          93 :                         xDataPointProperties->getPropertyValue( "Geometry3D") >>= nGeometry3D;
     647             :                     }
     648           0 :                     catch( const uno::Exception& e )
     649             :                     {
     650             :                         ASSERT_EXCEPTION( e );
     651             :                     }
     652             : 
     653             :                     //@todo iterate through all subsystems to create partial points
     654             :                     {
     655             :                         //@todo select a suiteable PositionHelper for this subsystem
     656        6892 :                         BarPositionHelper* pSubPosHelper = pPosHelper;
     657             : 
     658        6892 :                         double fUnclippedUpperYValue = fUpperYValue;
     659             : 
     660             :                         //apply clipping to Y
     661        6892 :                         if( !pPosHelper->clipYRange(fLowerYValue,fUpperYValue) )
     662             :                         {
     663          57 :                             if( bDrawConnectionLines )
     664           0 :                                 bOnlyConnectionLinesForThisPoint = true;
     665             :                             else
     666         114 :                                 continue;
     667             :                         }
     668             :                         //@todo clipping of X and Z is not fully integrated so far, as there is a need to create different objects
     669             : 
     670             :                         //apply scaling to Y before calculating width (necessary to maintain gradient in clipped objects)
     671        6835 :                         pSubPosHelper->doLogicScaling(NULL,&fLowerYValue,NULL);
     672        6835 :                         pSubPosHelper->doLogicScaling(NULL,&fUpperYValue,NULL);
     673             :                         //scaling of X and Z is not provided as the created objects should be symmetric in that dimensions
     674             : 
     675        6835 :                         pSubPosHelper->doLogicScaling(NULL,&fUnclippedUpperYValue,NULL);
     676             : 
     677             :                         //calculate resulting width
     678        6835 :                         double fCompleteHeight = bPositive ? fLogicPositiveYSum : fLogicNegativeYSum;
     679        6835 :                         if( pPosHelper->isPercentY() )
     680          15 :                             fCompleteHeight = 1.0;
     681        6835 :                         double fLogicBarWidth = fLogicBaseWidth;
     682        6835 :                         double fTopHeight=approxSub(fCompleteHeight,fUpperYValue);
     683        6835 :                         if(!bPositive)
     684         146 :                             fTopHeight=approxSub(fCompleteHeight,fLowerYValue);
     685        6835 :                         double fLogicYStart = bPositive ? fLowerYValue : fUpperYValue;
     686        6835 :                         double fMiddleHeight = fUpperYValue-fLowerYValue;
     687        6835 :                         if(!bPositive)
     688         146 :                             fMiddleHeight*=-1.0;
     689        6835 :                         double fLogicBarDepth = 0.5;
     690        6835 :                         if(m_nDimension==3)
     691             :                         {
     692          84 :                             if( lcl_hasGeometry3DVariableWidth(nGeometry3D) && fCompleteHeight!=0.0 )
     693             :                             {
     694          24 :                                 double fHeight = fCompleteHeight-fLowerYValue;
     695          24 :                                 if(!bPositive)
     696           0 :                                     fHeight = fCompleteHeight-fUpperYValue;
     697          24 :                                 fLogicBarWidth = fLogicBaseWidth*fHeight/(fCompleteHeight);
     698          24 :                                 if(fLogicBarWidth<=0.0)
     699           0 :                                     fLogicBarWidth=fLogicBaseWidth;
     700          24 :                                 fLogicBarDepth = fLogicBarDepth*fHeight/(fCompleteHeight);
     701          24 :                                 if(fLogicBarDepth<=0.0)
     702           0 :                                     fLogicBarDepth*=-1.0;
     703             :                             }
     704             :                         }
     705             : 
     706             :                         //better performance for big data
     707        6835 :                         FormerBarPoint aFormerPoint( aSeriesFormerPointMap[pSeries] );
     708        6835 :                         pPosHelper->setCoordinateSystemResolution( m_aCoordinateSystemResolution );
     709       13670 :                         if( !pSeries->isAttributedDataPoint(nPointIndex)
     710        6705 :                             &&
     711             :                             pPosHelper->isSameForGivenResolution( aFormerPoint.m_fX, aFormerPoint.m_fUpperY, aFormerPoint.m_fZ
     712        6705 :                                                             , fLogicX, fUpperYValue, fLogicZ )
     713        6835 :                             &&
     714             :                             pPosHelper->isSameForGivenResolution( aFormerPoint.m_fX, aFormerPoint.m_fLowerY, aFormerPoint.m_fZ
     715           0 :                                                             , fLogicX, fLowerYValue, fLogicZ )
     716             :                                                             )
     717             :                         {
     718           0 :                             nSkippedPoints++;
     719           0 :                             m_bPointsWereSkipped = true;
     720           0 :                             continue;
     721             :                         }
     722        6835 :                         aSeriesFormerPointMap[pSeries] = FormerBarPoint(fLogicX,fUpperYValue,fLowerYValue,fLogicZ);
     723             : 
     724        6835 :                         if( bDrawConnectionLines )
     725             :                         {
     726             :                             //store point information for connection lines
     727             : 
     728           0 :                             drawing::Position3D aLeftUpperPoint( fLogicX-fLogicBarWidth/2.0,fUnclippedUpperYValue,fLogicZ );
     729           0 :                             drawing::Position3D aRightUpperPoint( fLogicX+fLogicBarWidth/2.0,fUnclippedUpperYValue,fLogicZ );
     730             : 
     731           0 :                             if( isValidPosition(aLeftUpperPoint) )
     732           0 :                                 AddPointToPoly( (*aSeriesIter)->m_aPolyPolygonShape3D, aLeftUpperPoint );
     733           0 :                             if( isValidPosition(aRightUpperPoint) )
     734           0 :                                 AddPointToPoly( (*aSeriesIter)->m_aPolyPolygonShape3D, aRightUpperPoint );
     735             :                         }
     736             : 
     737        6835 :                         if( bOnlyConnectionLinesForThisPoint )
     738           0 :                             continue;
     739             : 
     740             :                         //maybe additional possibility for performance improvement
     741             :                         //bool bCreateLineInsteadOfComplexGeometryDueToMissingSpace = false;
     742             :                         //pPosHelper->isSameForGivenResolution( fLogicX-fLogicBarWidth/2.0, fLowerYValue, fLogicZ
     743             :                         //                            , fLogicX+fLogicBarWidth/2.0, fLowerYValue, fLogicZ );
     744             : 
     745        6835 :                         nCreatedPoints++;
     746             :                         //create partial point
     747        6835 :                         if( !approxEqual(fLowerYValue,fUpperYValue) )
     748             :                         {
     749        6823 :                             uno::Reference< drawing::XShape >  xShape;
     750        6823 :                             if( m_nDimension==3 )
     751             :                             {
     752          81 :                                 drawing::Position3D aLogicBottom            (fLogicX,fLogicYStart,fLogicZ);
     753          81 :                                 drawing::Position3D aLogicLeftBottomFront   (fLogicX+fLogicBarWidth/2.0,fLogicYStart,fLogicZ-fLogicBarDepth/2.0);
     754          81 :                                 drawing::Position3D aLogicRightDeepTop      (fLogicX-fLogicBarWidth/2.0,fLogicYStart+fMiddleHeight,fLogicZ+fLogicBarDepth/2.0);
     755          81 :                                 drawing::Position3D aLogicTopTop            (fLogicX,fLogicYStart+fMiddleHeight+fTopHeight,fLogicZ);
     756             : 
     757          81 :                                 uno::Reference< XTransformation > xTransformation = pSubPosHelper->getTransformationScaledLogicToScene();
     758             : 
     759             :                                 //transformation 3) -> 4)
     760          81 :                                 drawing::Position3D aTransformedBottom          ( SequenceToPosition3D( xTransformation->transform( Position3DToSequence(aLogicBottom) ) ) );
     761          81 :                                 drawing::Position3D aTransformedLeftBottomFront ( SequenceToPosition3D( xTransformation->transform( Position3DToSequence(aLogicLeftBottomFront) ) ) );
     762          81 :                                 drawing::Position3D aTransformedRightDeepTop    ( SequenceToPosition3D( xTransformation->transform( Position3DToSequence(aLogicRightDeepTop) ) ) );
     763          81 :                                 drawing::Position3D aTransformedTopTop          ( SequenceToPosition3D( xTransformation->transform( Position3DToSequence(aLogicTopTop) ) ) );
     764             : 
     765          81 :                                 drawing::Direction3D aSize = aTransformedRightDeepTop - aTransformedLeftBottomFront;
     766          81 :                                 drawing::Direction3D aTopSize( aTransformedTopTop - aTransformedRightDeepTop );
     767          81 :                                 fTopHeight = aTopSize.DirectionY;
     768             : 
     769          81 :                                 sal_Int32 nRotateZAngleHundredthDegree = 0;
     770          81 :                                 if( pPosHelper->isSwapXAndY() )
     771             :                                 {
     772          24 :                                     fTopHeight = aTopSize.DirectionX;
     773          24 :                                     nRotateZAngleHundredthDegree = 90*100;
     774          24 :                                     aSize = drawing::Direction3D(aSize.DirectionY,aSize.DirectionX,aSize.DirectionZ);
     775             :                                 }
     776             : 
     777          81 :                                 if( aSize.DirectionX < 0 )
     778          81 :                                     aSize.DirectionX *= -1.0;
     779          81 :                                 if( aSize.DirectionZ < 0 )
     780          81 :                                     aSize.DirectionZ *= -1.0;
     781          81 :                                 if( fTopHeight < 0 )
     782           0 :                                     fTopHeight *= -1.0;
     783             : 
     784         162 :                                 xShape = createDataPoint3D_Bar(
     785             :                                     xPointGroupShape_Shapes, aTransformedBottom, aSize, fTopHeight, nRotateZAngleHundredthDegree
     786         162 :                                     , xDataPointProperties, nGeometry3D );
     787             :                             }
     788             :                             else //m_nDimension!=3
     789             :                             {
     790             :                                 // performance improvement: alloc the sequence before the rendering
     791             :                                 // otherwise we have 2 realloc calls
     792        6742 :                                 drawing::PolyPolygonShape3D aPoly;
     793        6742 :                                 aPoly.SequenceX.realloc(1);
     794        6742 :                                 aPoly.SequenceY.realloc(1);
     795        6742 :                                 aPoly.SequenceZ.realloc(1);
     796        6742 :                                 drawing::Position3D aLeftUpperPoint( fLogicX-fLogicBarWidth/2.0,fUpperYValue,fLogicZ );
     797        6742 :                                 drawing::Position3D aRightUpperPoint( fLogicX+fLogicBarWidth/2.0,fUpperYValue,fLogicZ );
     798             : 
     799        6742 :                                 AddPointToPoly( aPoly, drawing::Position3D( fLogicX-fLogicBarWidth/2.0,fLowerYValue,fLogicZ) );
     800        6742 :                                 AddPointToPoly( aPoly, drawing::Position3D( fLogicX+fLogicBarWidth/2.0,fLowerYValue,fLogicZ) );
     801        6742 :                                 AddPointToPoly( aPoly, aRightUpperPoint );
     802        6742 :                                 AddPointToPoly( aPoly, aLeftUpperPoint );
     803        6742 :                                 AddPointToPoly( aPoly, drawing::Position3D( fLogicX-fLogicBarWidth/2.0,fLowerYValue,fLogicZ) );
     804        6742 :                                 pPosHelper->transformScaledLogicToScene( aPoly );
     805        6742 :                                 xShape = m_pShapeFactory->createArea2D( xPointGroupShape_Shapes, aPoly );
     806        6742 :                                 this->setMappedProperties( xShape, xDataPointProperties, PropertyMapper::getPropertyNameMapForFilledSeriesProperties() );
     807             :                             }
     808             : 
     809        6823 :                             if(bHasFillColorMapping)
     810             :                             {
     811           0 :                                 uno::Reference< beans::XPropertySet > xProps( xShape, uno::UNO_QUERY_THROW );
     812           0 :                                 xProps->setPropertyValue("FillColor", uno::makeAny(static_cast<sal_Int32>(
     813           0 :                                                 pSeries->getValueByProperty(nPointIndex, "FillColor"))));
     814             :                             }
     815             :                             //set name/classified ObjectID (CID)
     816             :                             ShapeFactory::setShapeName(xShape
     817             :                                 , ObjectIdentifier::createPointCID(
     818        6823 :                                     (*aSeriesIter)->getPointCID_Stub(),nPointIndex) );
     819             :                         }
     820             : 
     821             :                         //create error bar
     822        6835 :                         createErrorBar_Y( aUnscaledLogicPosition, **aSeriesIter, nPointIndex, m_xLogicTarget, &fLogicX );
     823             : 
     824             :                         //create data point label
     825        6835 :                         if( (**aSeriesIter).getDataPointLabelIfLabel(nPointIndex) )
     826             :                         {
     827         152 :                             double fLogicSum = aLogicYSumMap[nAttachedAxisIndex];
     828             : 
     829         152 :                             LabelAlignment eAlignment(LABEL_ALIGN_CENTER);
     830         152 :                             sal_Int32 nLabelPlacement = pSeries->getLabelPlacement( nPointIndex, m_xChartTypeModel, m_nDimension, pPosHelper->isSwapXAndY() );
     831             : 
     832         152 :                             double fLowerBarDepth = fLogicBarDepth;
     833         152 :                             double fUpperBarDepth = fLogicBarDepth;
     834             :                             {
     835         152 :                                 double fOuterBarDepth = fLogicBarDepth;
     836         152 :                                 if( lcl_hasGeometry3DVariableWidth(nGeometry3D) && fCompleteHeight!=0.0 )
     837             :                                 {
     838          12 :                                     fOuterBarDepth = fLogicBarDepth * (fTopHeight)/(fabs(fCompleteHeight));
     839          12 :                                     fLowerBarDepth = (fBaseValue < fUpperYValue) ? fabs(fLogicBarDepth) : fabs(fOuterBarDepth);
     840          12 :                                     fUpperBarDepth = (fBaseValue < fUpperYValue) ? fabs(fOuterBarDepth) : fabs(fLogicBarDepth);
     841             :                                 }
     842             :                             }
     843             : 
     844             :                             awt::Point aScreenPosition2D( this->getLabelScreenPositionAndAlignment(
     845             :                                 eAlignment, nLabelPlacement
     846             :                                 , fLogicX, fLowerYValue, fUpperYValue, fLogicZ
     847         152 :                                 , fLowerBarDepth, fUpperBarDepth, fBaseValue, pPosHelper ));
     848         152 :                             sal_Int32 nOffset = 0;
     849         152 :                             if(LABEL_ALIGN_CENTER!=eAlignment)
     850             :                             {
     851         129 :                                 nOffset = 100;//add some spacing //@todo maybe get more intelligent values
     852         129 :                                 if( m_nDimension == 3 )
     853           0 :                                     nOffset = 260;
     854             :                             }
     855         152 :                             this->createDataLabel( xTextTarget, **aSeriesIter, nPointIndex
     856         304 :                                             , fLogicValueForLabeDisplay, fLogicSum, aScreenPosition2D, eAlignment, nOffset );
     857             :                         }
     858             : 
     859             :                     }//end iteration through partial points
     860             : 
     861        6835 :                 }//next series in x slot (next y slot)
     862             :             }//next x slot
     863             :         }//next z slot
     864        2188 :     }//next category
     865         549 :     if( bDrawConnectionLines )
     866             :     {
     867           0 :         ::std::vector< ::std::vector< VDataSeriesGroup > >::iterator             aZSlotIter = m_aZSlots.begin();
     868           0 :         const ::std::vector< ::std::vector< VDataSeriesGroup > >::const_iterator  aZSlotEnd = m_aZSlots.end();
     869           0 :         for( sal_Int32 nZ=1; aZSlotIter != aZSlotEnd; ++aZSlotIter, nZ++ )
     870             :         {
     871           0 :             ::std::vector< VDataSeriesGroup >::iterator             aXSlotIter = aZSlotIter->begin();
     872           0 :             const ::std::vector< VDataSeriesGroup >::const_iterator aXSlotEnd = aZSlotIter->end();
     873             : 
     874           0 :             BarPositionHelper* pPosHelper = m_pMainPosHelper;
     875           0 :             if( aXSlotIter != aXSlotEnd )
     876             :             {
     877           0 :                 sal_Int32 nAttachedAxisIndex = aXSlotIter->getAttachedAxisIndexForFirstSeries();
     878             :                 //2ND_AXIS_IN_BARS so far one can assume to have the same plotter for each z slot
     879           0 :                 pPosHelper = dynamic_cast<BarPositionHelper*>(&( this->getPlottingPositionHelper( nAttachedAxisIndex ) ) );
     880           0 :                 if(!pPosHelper)
     881           0 :                     pPosHelper = m_pMainPosHelper;
     882             :             }
     883           0 :             PlotterBase::m_pPosHelper = pPosHelper;
     884             : 
     885             :             //iterate through all x slots in this category
     886           0 :             for( double fSlotX=0; aXSlotIter != aXSlotEnd; ++aXSlotIter, fSlotX+=1.0 )
     887             :             {
     888           0 :                 ::std::vector< VDataSeries* >* pSeriesList = &(aXSlotIter->m_aSeriesVector);
     889             : 
     890           0 :                 ::std::vector< VDataSeries* >::const_iterator       aSeriesIter = pSeriesList->begin();
     891           0 :                 const ::std::vector< VDataSeries* >::const_iterator aSeriesEnd  = pSeriesList->end();
     892             :                 //iterate through all series in this x slot
     893           0 :                 for( ; aSeriesIter != aSeriesEnd; ++aSeriesIter )
     894             :                 {
     895           0 :                     VDataSeries* pSeries( *aSeriesIter );
     896           0 :                     if(!pSeries)
     897           0 :                         continue;
     898           0 :                     drawing::PolyPolygonShape3D* pSeriesPoly = &pSeries->m_aPolyPolygonShape3D;
     899           0 :                     if(!ShapeFactory::hasPolygonAnyLines(*pSeriesPoly))
     900           0 :                         continue;
     901             : 
     902           0 :                     drawing::PolyPolygonShape3D aPoly;
     903           0 :                     Clipping::clipPolygonAtRectangle( *pSeriesPoly, pPosHelper->getScaledLogicClipDoubleRect(), aPoly );
     904             : 
     905           0 :                     if(!ShapeFactory::hasPolygonAnyLines(aPoly))
     906           0 :                         continue;
     907             : 
     908             :                     //transformation 3) -> 4)
     909           0 :                     pPosHelper->transformScaledLogicToScene( aPoly );
     910             : 
     911             :                     uno::Reference< drawing::XShapes > xSeriesGroupShape_Shapes(
     912           0 :                         getSeriesGroupShape(*aSeriesIter, xSeriesTarget) );
     913             :                     uno::Reference< drawing::XShape > xShape( m_pShapeFactory->createLine2D(
     914           0 :                         xSeriesGroupShape_Shapes, PolyToPointSequence( aPoly ) ) );
     915             :                     this->setMappedProperties( xShape, pSeries->getPropertiesOfSeries()
     916           0 :                         , PropertyMapper::getPropertyNameMapForFilledSeriesProperties() );
     917           0 :                 }
     918             :             }
     919             :         }
     920             :     }
     921             : 
     922             :     /* @todo remove series shapes if empty
     923             :     */
     924             : 
     925         549 :     OSL_TRACE( "\nPPPPPPPPP<<<<<<<<<<<< bar chart :: createShapes():: skipped points: %d created points: %d", nSkippedPoints, nCreatedPoints );
     926             : }
     927             : 
     928             : } //namespace chart
     929             : 
     930             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10