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

Generated by: LCOV version 1.11