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

Generated by: LCOV version 1.10