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

Generated by: LCOV version 1.10