LCOV - code coverage report
Current view: top level - chart2/source/model/template - ChartTypeTemplate.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 356 426 83.6 %
Date: 2015-06-13 12:38:46 Functions: 27 29 93.1 %
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 "ChartTypeTemplate.hxx"
      21             : #include "PropertyHelper.hxx"
      22             : #include "macros.hxx"
      23             : #include "DataSeriesHelper.hxx"
      24             : #include "DataInterpreter.hxx"
      25             : #include "CommonConverters.hxx"
      26             : #include "ContainerHelper.hxx"
      27             : #include "ChartTypeHelper.hxx"
      28             : 
      29             : #include "CartesianCoordinateSystem.hxx"
      30             : #include "AxisHelper.hxx"
      31             : #include "LegendHelper.hxx"
      32             : #include "DiagramHelper.hxx"
      33             : #include "AxisIndexDefines.hxx"
      34             : #include <unonames.hxx>
      35             : 
      36             : #include <cppuhelper/component_context.hxx>
      37             : #include <com/sun/star/chart/ChartSolidType.hpp>
      38             : #include <com/sun/star/chart2/AxisType.hpp>
      39             : #include <com/sun/star/chart2/XDataSeriesContainer.hpp>
      40             : #include <com/sun/star/chart2/XChartTypeContainer.hpp>
      41             : 
      42             : #include <algorithm>
      43             : #include <iterator>
      44             : 
      45             : using namespace ::com::sun::star;
      46             : using namespace ::com::sun::star::chart2;
      47             : 
      48             : using ::com::sun::star::uno::Sequence;
      49             : using ::com::sun::star::uno::Reference;
      50             : using ::com::sun::star::uno::Any;
      51             : 
      52             : namespace
      53             : {
      54             : 
      55         137 : void lcl_applyDefaultStyle(
      56             :     const Reference< XDataSeries > & xSeries,
      57             :     sal_Int32 nIndex,
      58             :     const Reference< XDiagram > & xDiagram )
      59             : {
      60             :     // @deprecated: correct default color should be found by view without
      61             :     // setting color as hard attribute
      62         137 :     if( xSeries.is() && xDiagram.is())
      63             :     {
      64         137 :         Reference< beans::XPropertySet > xSeriesProp( xSeries, uno::UNO_QUERY );
      65         274 :         Reference< chart2::XColorScheme > xColorScheme( xDiagram->getDefaultColorScheme());
      66         137 :         if( xSeriesProp.is() && xColorScheme.is() )
      67         137 :             xSeriesProp->setPropertyValue(
      68             :                 "Color",
      69         274 :                 uno::makeAny( xColorScheme->getColorByIndex( nIndex )));
      70             :     }
      71         137 : }
      72             : 
      73         224 : void lcl_ensureCorrectLabelPlacement( const Reference< beans::XPropertySet >& xProp, const uno::Sequence < sal_Int32 >& rAvailablePlacements )
      74             : {
      75         224 :     sal_Int32 nLabelPlacement=0;
      76         224 :     if( xProp.is() && (xProp->getPropertyValue( "LabelPlacement" ) >>= nLabelPlacement) )
      77             :     {
      78           0 :         bool bValid = false;
      79           0 :         for( sal_Int32 nN = 0; nN < rAvailablePlacements.getLength(); nN++ )
      80             :         {
      81           0 :             if( rAvailablePlacements[nN] == nLabelPlacement )
      82             :             {
      83           0 :                 bValid = true;
      84           0 :                 break;
      85             :             }
      86             :         }
      87           0 :         if( !bValid )
      88             :         {
      89           0 :             uno::Any aNewValue;
      90             :             //otherwise use the first supported one
      91           0 :             if( rAvailablePlacements.getLength() )
      92           0 :                 aNewValue <<=rAvailablePlacements[0];
      93           0 :             xProp->setPropertyValue( "LabelPlacement", aNewValue );
      94             :         }
      95             :     }
      96         224 : }
      97             : 
      98         103 : void lcl_resetLabelPlacementIfDefault( const Reference< beans::XPropertySet >& xProp, sal_Int32 nDefaultPlacement )
      99             : {
     100             : 
     101         103 :     sal_Int32 nLabelPlacement=0;
     102         103 :     if( xProp.is() && (xProp->getPropertyValue( "LabelPlacement" ) >>= nLabelPlacement) )
     103             :     {
     104           0 :         if( nDefaultPlacement == nLabelPlacement )
     105           0 :             xProp->setPropertyValue( "LabelPlacement", uno::Any() );
     106             :     }
     107         103 : }
     108             : 
     109         121 : void lcl_ensureCorrectMissingValueTreatment( const Reference< chart2::XDiagram >& xDiagram, const Reference< XChartType >& xChartType )
     110             : {
     111         121 :     Reference< beans::XPropertySet > xDiaProp( xDiagram, uno::UNO_QUERY );
     112         121 :     if( xDiaProp.is() )
     113             :     {
     114             :         uno::Sequence < sal_Int32 > aAvailableMissingValueTreatment(
     115         121 :             ::chart::ChartTypeHelper::getSupportedMissingValueTreatments( xChartType ) );
     116             : 
     117         121 :         if( aAvailableMissingValueTreatment.getLength() )
     118         109 :             xDiaProp->setPropertyValue( "MissingValueTreatment", uno::makeAny( aAvailableMissingValueTreatment[0] ) );
     119             :         else
     120          12 :             xDiaProp->setPropertyValue( "MissingValueTreatment", uno::Any() );
     121         121 :     }
     122         121 : }
     123             : 
     124             : } // anonymous namespace
     125             : 
     126             : namespace chart
     127             : {
     128             : 
     129       79641 : ChartTypeTemplate::ChartTypeTemplate(
     130             :     Reference< uno::XComponentContext > const & xContext,
     131             :     const OUString & rServiceName ) :
     132             :         m_xContext( xContext ),
     133       79641 :         m_aServiceName( rServiceName )
     134             : {
     135       79641 : }
     136             : 
     137       79641 : ChartTypeTemplate::~ChartTypeTemplate()
     138       79641 : {}
     139             : 
     140             : // ____ XChartTypeTemplate ____
     141         107 : uno::Reference< XDiagram > SAL_CALL ChartTypeTemplate::createDiagramByDataSource(
     142             :     const uno::Reference< data::XDataSource >& xDataSource,
     143             :     const uno::Sequence< beans::PropertyValue >& aArguments )
     144             :     throw (uno::RuntimeException, std::exception)
     145             : {
     146         107 :     Reference< XDiagram > xDia;
     147             : 
     148             :     try
     149             :     {
     150             :         // create diagram
     151             :         xDia.set(
     152         214 :             GetComponentContext()->getServiceManager()->createInstanceWithContext(
     153             :                 "com.sun.star.chart2.Diagram",
     154         107 :                 GetComponentContext() ),
     155         107 :             uno::UNO_QUERY_THROW );
     156             : 
     157             :         // modify diagram
     158         107 :         Reference< chart2::XDataInterpreter > xInterpreter( getDataInterpreter());
     159             :         chart2::InterpretedData aData(
     160         107 :             xInterpreter->interpretDataSource(
     161         214 :                 xDataSource, aArguments, Sequence< Reference< XDataSeries > >() ));
     162             : 
     163         214 :         Sequence< Sequence< Reference< XDataSeries > > > aSeries( aData.Series );
     164         107 :         sal_Int32 i, j, nCount = 0;
     165         128 :         for( i=0; i<aSeries.getLength(); ++i )
     166             :         {
     167         141 :             for( j=0; j<aSeries[i].getLength(); ++j, ++nCount )
     168         120 :                 lcl_applyDefaultStyle( aSeries[i][j], nCount, xDia );
     169             :         }
     170             : 
     171         214 :         Sequence< Reference< XChartType > > aOldChartTypesSeq;
     172         214 :         FillDiagram( xDia, aData.Series, aData.Categories, aOldChartTypesSeq, true );
     173             :     }
     174           0 :     catch( const uno::Exception & ex )
     175             :     {
     176             :         ASSERT_EXCEPTION( ex );
     177             :     }
     178             : 
     179         107 :     return xDia;
     180             : }
     181             : 
     182         125 : sal_Bool SAL_CALL ChartTypeTemplate::supportsCategories()
     183             :     throw (css::uno::RuntimeException, ::std::exception)
     184             : {
     185         125 :     return sal_True;
     186             : }
     187             : 
     188          14 : void SAL_CALL ChartTypeTemplate::changeDiagram( const uno::Reference< XDiagram >& xDiagram )
     189             :     throw (uno::RuntimeException, std::exception)
     190             : {
     191          14 :     if( ! xDiagram.is())
     192          14 :         return;
     193             : 
     194             :     try
     195             :     {
     196             :         Sequence< Sequence< Reference< XDataSeries > > > aSeriesSeq(
     197          14 :             DiagramHelper::getDataSeriesGroups( xDiagram ));
     198          28 :         Sequence< Reference< XDataSeries > > aFlatSeriesSeq( FlattenSequence( aSeriesSeq ));
     199          14 :         const sal_Int32 nFormerSeriesCount = aFlatSeriesSeq.getLength();
     200             : 
     201             :         // chart-type specific interpretation of existing data series
     202          28 :         Reference< chart2::XDataInterpreter > xInterpreter( getDataInterpreter());
     203          28 :         chart2::InterpretedData aData;
     204          14 :         aData.Series = aSeriesSeq;
     205          14 :         aData.Categories = DiagramHelper::getCategoriesFromDiagram( xDiagram );
     206             : 
     207          14 :         if( xInterpreter->isDataCompatible( aData ) )
     208             :         {
     209           6 :             aData = xInterpreter->reinterpretDataSeries( aData );
     210             :         }
     211             :         else
     212             :         {
     213           8 :             Reference< data::XDataSource > xSource( xInterpreter->mergeInterpretedData( aData ));
     214             :             // todo: get a "range-union" from the data provider by calling
     215             :             // OUString aRange = getRangeRepresentationByData( xSource );
     216             :             // xSource.set( getDataByRangeRepresentation( aRange, aParam ));
     217             :             // where aParam == ??
     218          16 :             Sequence< beans::PropertyValue > aParam;
     219           8 :             if( aData.Categories.is())
     220             :             {
     221           7 :                 aParam.realloc( 1 );
     222          14 :                 aParam[0] = beans::PropertyValue( "HasCategories", -1, uno::makeAny( true ),
     223           7 :                                                   beans::PropertyState_DIRECT_VALUE );
     224             :             }
     225          16 :             aData = xInterpreter->interpretDataSource( xSource, aParam, aFlatSeriesSeq );
     226             :         }
     227          14 :         aSeriesSeq = aData.Series;
     228             : 
     229          14 :         sal_Int32 i, j, nIndex = 0;
     230          28 :         for( i=0; i<aSeriesSeq.getLength(); ++i )
     231         117 :             for( j=0; j<aSeriesSeq[i].getLength(); ++j, ++nIndex )
     232             :             {
     233         103 :                 if( nIndex >= nFormerSeriesCount )
     234          16 :                     lcl_applyDefaultStyle( aSeriesSeq[i][j], nIndex, xDiagram );
     235             :             }
     236             : 
     237             :         // remove charttype groups from all coordinate systems
     238             :         Sequence< Reference< XChartType > > aOldChartTypesSeq(
     239          28 :             DiagramHelper::getChartTypesFromDiagram(xDiagram) );
     240             : 
     241          28 :         Reference< XCoordinateSystemContainer > xCoordSysCnt( xDiagram, uno::UNO_QUERY );
     242             :         OSL_ASSERT( xCoordSysCnt.is());
     243          14 :         if( xCoordSysCnt.is())
     244             :         {
     245             :             Sequence< Reference< XCoordinateSystem > > aCooSysSeq(
     246          14 :                 xCoordSysCnt->getCoordinateSystems());
     247          28 :             for( sal_Int32 nCooSysIdx = 0; nCooSysIdx < aCooSysSeq.getLength(); ++nCooSysIdx )
     248             :             {
     249          14 :                 Reference< XChartTypeContainer > xContainer( aCooSysSeq[nCooSysIdx], uno::UNO_QUERY );
     250          14 :                 if( xContainer.is() )
     251          14 :                     xContainer->setChartTypes( Sequence< Reference< XChartType > >() );
     252          28 :             }
     253             :         }
     254             : 
     255          28 :         FillDiagram( xDiagram, aSeriesSeq, aData.Categories, aOldChartTypesSeq, false );
     256             :     }
     257           0 :     catch( const uno::Exception & ex )
     258             :     {
     259             :         ASSERT_EXCEPTION( ex );
     260             :     }
     261             : }
     262             : 
     263          19 : void SAL_CALL ChartTypeTemplate::changeDiagramData(
     264             :     const Reference< chart2::XDiagram >& xDiagram,
     265             :     const Reference< chart2::data::XDataSource >& xDataSource,
     266             :     const Sequence< beans::PropertyValue >& aArguments )
     267             :     throw (uno::RuntimeException, std::exception)
     268             : {
     269          38 :     if( ! (xDiagram.is() &&
     270          19 :            xDataSource.is()) )
     271          19 :         return;
     272             : 
     273             :     try
     274             :     {
     275             :         // interpret new data and re-use existing series
     276             :         Sequence< Reference< XDataSeries > > aFlatSeriesSeq(
     277          19 :             ::chart::ContainerHelper::ContainerToSequence( DiagramHelper::getDataSeriesFromDiagram( xDiagram )));
     278          19 :         const sal_Int32 nFormerSeriesCount = aFlatSeriesSeq.getLength();
     279          38 :         Reference< chart2::XDataInterpreter > xInterpreter( getDataInterpreter());
     280             :         chart2::InterpretedData aData =
     281          38 :             xInterpreter->interpretDataSource( xDataSource, aArguments, aFlatSeriesSeq );
     282             : 
     283             :         // data series
     284          38 :         Sequence< Sequence< Reference< XDataSeries > > > aSeriesSeq( aData.Series );
     285             : 
     286          19 :         sal_Int32 i, j, nIndex = 0;
     287          39 :         for( i=0; i<aSeriesSeq.getLength(); ++i )
     288         134 :             for( j=0; j<aSeriesSeq[i].getLength(); ++j, ++nIndex )
     289             :             {
     290         114 :                 if( nIndex >= nFormerSeriesCount )
     291             :                 {
     292           1 :                     lcl_applyDefaultStyle( aSeriesSeq[i][j], nIndex, xDiagram );
     293           1 :                     applyStyle( aSeriesSeq[i][j], i, j, aSeriesSeq[i].getLength() );
     294             :                 }
     295             :             }
     296             : 
     297             :         // categories
     298          19 :         DiagramHelper::setCategoriesToDiagram( aData.Categories, xDiagram, true, supportsCategories() );
     299             : 
     300             :         Sequence< Reference< XChartType > > aChartTypes(
     301          38 :             DiagramHelper::getChartTypesFromDiagram( xDiagram ));
     302          19 :         sal_Int32 nMax = ::std::min( aChartTypes.getLength(), aSeriesSeq.getLength());
     303          39 :         for( i=0; i<nMax; ++i )
     304             :         {
     305          20 :             Reference< XDataSeriesContainer > xDSCnt( aChartTypes[i], uno::UNO_QUERY_THROW );
     306          20 :             xDSCnt->setDataSeries( aSeriesSeq[i] );
     307          39 :         }
     308             :     }
     309           0 :     catch( const uno::Exception & ex )
     310             :     {
     311             :         ASSERT_EXCEPTION( ex );
     312             :     }
     313             : }
     314             : 
     315       73431 : sal_Bool SAL_CALL ChartTypeTemplate::matchesTemplate(
     316             :     const Reference< chart2::XDiagram >& xDiagram,
     317             :     sal_Bool /* bAdaptProperties */ )
     318             :     throw (uno::RuntimeException, std::exception)
     319             : {
     320       73431 :     bool bResult = false;
     321             : 
     322       73431 :     if( ! xDiagram.is())
     323           0 :         return bResult;
     324             : 
     325             :     try
     326             :     {
     327             :         Reference< XCoordinateSystemContainer > xCooSysCnt(
     328       73431 :             xDiagram, uno::UNO_QUERY_THROW );
     329             :         Sequence< Reference< XCoordinateSystem > > aCooSysSeq(
     330      146862 :             xCooSysCnt->getCoordinateSystems());
     331             : 
     332             :         // need to have at least one coordinate system
     333       73431 :         bResult = (aCooSysSeq.getLength() > 0);
     334       73431 :         if( bResult )
     335             :         {
     336       73431 :             Sequence< Reference< XChartType > > aFormerlyUsedChartTypes;
     337      146862 :             Reference<XChartType> xOldCT = getChartTypeForNewSeries(aFormerlyUsedChartTypes);
     338       73431 :             if (!xOldCT.is())
     339           0 :                 return false;
     340             : 
     341      146862 :             const OUString aChartTypeToMatch = xOldCT->getChartType();
     342       73431 :             const sal_Int32 nDimensionToMatch = getDimension();
     343      146862 :             for( sal_Int32 nCooSysIdx=0; bResult && (nCooSysIdx < aCooSysSeq.getLength()); ++nCooSysIdx )
     344             :             {
     345             :                 // match dimension
     346       73431 :                 bResult = bResult && (aCooSysSeq[nCooSysIdx]->getDimension() == nDimensionToMatch);
     347             : 
     348       73431 :                 Reference< XChartTypeContainer > xCTCnt( aCooSysSeq[nCooSysIdx], uno::UNO_QUERY_THROW );
     349      146862 :                 Sequence< Reference< XChartType > > aChartTypeSeq( xCTCnt->getChartTypes());
     350      108307 :                 for( sal_Int32 nCTIdx=0; bResult && (nCTIdx < aChartTypeSeq.getLength()); ++nCTIdx )
     351             :                 {
     352       34876 :                     if (!aChartTypeSeq[nCTIdx].is())
     353           0 :                         return false;
     354             : 
     355             :                     // match chart type
     356       34876 :                     bResult = bResult && aChartTypeSeq[nCTIdx]->getChartType().equals( aChartTypeToMatch );
     357       34876 :                     bool bFound=false;
     358       34876 :                     bool bAmbiguous=false;
     359             :                     // match stacking mode
     360       43647 :                     bResult = bResult &&
     361             :                         ( DiagramHelper::getStackModeFromChartType(
     362        8771 :                             aChartTypeSeq[nCTIdx], bFound, bAmbiguous,
     363       17542 :                             aCooSysSeq[nCooSysIdx] )
     364       43647 :                           == getStackMode( nCTIdx ) );
     365             :                 }
     366      146862 :             }
     367       73431 :         }
     368             :     }
     369           0 :     catch( const uno::Exception & ex )
     370             :     {
     371             :         ASSERT_EXCEPTION( ex );
     372             :     }
     373             : 
     374       73431 :     return bResult;
     375             : }
     376             : 
     377         106 : Reference< chart2::XDataInterpreter > SAL_CALL ChartTypeTemplate::getDataInterpreter()
     378             :     throw (uno::RuntimeException, std::exception)
     379             : {
     380         106 :     if( ! m_xDataInterpreter.is())
     381         106 :         m_xDataInterpreter.set( new DataInterpreter( GetComponentContext() ) );
     382             : 
     383         106 :     return m_xDataInterpreter;
     384             : }
     385             : 
     386         224 : void SAL_CALL ChartTypeTemplate::applyStyle(
     387             :     const Reference< chart2::XDataSeries >& xSeries,
     388             :     ::sal_Int32 nChartTypeIndex,
     389             :     ::sal_Int32 /* nSeriesIndex */,
     390             :     ::sal_Int32 /* nSeriesCount */ )
     391             :     throw (uno::RuntimeException, std::exception)
     392             : {
     393             :     // sset stacking mode
     394         224 :     Reference< beans::XPropertySet > xSeriesProp( xSeries, uno::UNO_QUERY );
     395         224 :     if( xSeriesProp.is())
     396             :     {
     397             :         try
     398             :         {
     399         224 :             StackMode eStackMode = getStackMode( nChartTypeIndex );
     400             :             const uno::Any aPropValue = uno::makeAny(
     401         224 :                 ( (eStackMode == StackMode_Y_STACKED) ||
     402             :                   (eStackMode == StackMode_Y_STACKED_PERCENT) )
     403             :                 ? chart2::StackingDirection_Y_STACKING
     404             :                 : (eStackMode == StackMode_Z_STACKED )
     405             :                 ? chart2::StackingDirection_Z_STACKING
     406         448 :                 : chart2::StackingDirection_NO_STACKING );
     407         224 :             xSeriesProp->setPropertyValue( "StackingDirection", aPropValue );
     408             : 
     409             :             //ensure valid label placement
     410             :             {
     411             :                 uno::Sequence < sal_Int32 > aAvailablePlacements( ChartTypeHelper::getSupportedLabelPlacements(
     412         224 :                             getChartTypeForIndex( nChartTypeIndex ), getDimension(), isSwapXAndY(), xSeries ) );
     413         224 :                 lcl_ensureCorrectLabelPlacement( xSeriesProp, aAvailablePlacements );
     414             : 
     415         448 :                 uno::Sequence< sal_Int32 > aAttributedDataPointIndexList;
     416         224 :                 if( xSeriesProp->getPropertyValue( "AttributedDataPoints" ) >>= aAttributedDataPointIndexList )
     417         448 :                     for(sal_Int32 nN=aAttributedDataPointIndexList.getLength();nN--;)
     418         224 :                         lcl_ensureCorrectLabelPlacement( xSeries->getDataPointByIndex(aAttributedDataPointIndexList[nN]), aAvailablePlacements );
     419         224 :             }
     420             :         }
     421           0 :         catch( const uno::Exception & ex )
     422             :         {
     423             :             ASSERT_EXCEPTION( ex );
     424             :         }
     425         224 :     }
     426         224 : }
     427             : 
     428         121 : void SAL_CALL ChartTypeTemplate::applyStyles( const Reference< chart2::XDiagram >& xDiagram )
     429             :     throw (uno::RuntimeException)
     430             : {
     431             :     // apply chart-type specific styles, like "symbols on" for example
     432             :     Sequence< Sequence< Reference< XDataSeries > > > aNewSeriesSeq(
     433         121 :         DiagramHelper::getDataSeriesGroups( xDiagram ));
     434         242 :     for( sal_Int32 i=0; i<aNewSeriesSeq.getLength(); ++i )
     435             :     {
     436         121 :         const sal_Int32 nNumSeries = aNewSeriesSeq[i].getLength();
     437         344 :         for( sal_Int32 j=0; j<nNumSeries; ++j )
     438         223 :             applyStyle( aNewSeriesSeq[i][j], i, j, nNumSeries );
     439             :     }
     440             : 
     441             :     //ensure valid empty cell handling (for first chart type...)
     442         121 :     lcl_ensureCorrectMissingValueTreatment( xDiagram, getChartTypeForIndex( 0 ) );
     443         121 : }
     444             : 
     445          13 : void SAL_CALL ChartTypeTemplate::resetStyles( const Reference< chart2::XDiagram >& xDiagram )
     446             :     throw (uno::RuntimeException, std::exception)
     447             : {
     448             :     // reset number format if we had percent stacking on
     449          13 :     bool bPercent = (getStackMode(0) == StackMode_Y_STACKED_PERCENT);
     450          13 :     if( bPercent )
     451             :     {
     452           0 :         Sequence< Reference< chart2::XAxis > > aAxisSeq( AxisHelper::getAllAxesOfDiagram( xDiagram ) );
     453           0 :         for( sal_Int32 i=0; i<aAxisSeq.getLength(); ++i )
     454             :         {
     455           0 :             if( 1== AxisHelper::getDimensionIndexOfAxis( aAxisSeq[i], xDiagram ) )
     456             :             {
     457           0 :                 Reference< beans::XPropertySet > xAxisProp( aAxisSeq[i], uno::UNO_QUERY );
     458           0 :                 if( xAxisProp.is())
     459             :                 {
     460             :                     // set number format to source format
     461           0 :                     xAxisProp->setPropertyValue(CHART_UNONAME_LINK_TO_SRC_NUMFMT, uno::makeAny(true));
     462           0 :                     xAxisProp->setPropertyValue(CHART_UNONAME_NUMFMT, uno::Any());
     463           0 :                 }
     464             :             }
     465           0 :         }
     466             :     }
     467             : 
     468             :     //reset label placement if default
     469             :     {
     470          13 :         uno::Reference< XCoordinateSystemContainer > xCooSysContainer( xDiagram, uno::UNO_QUERY );
     471          13 :         if( xCooSysContainer.is() )
     472             :         {
     473          13 :             uno::Sequence< uno::Reference< XCoordinateSystem > > aCooSysList( xCooSysContainer->getCoordinateSystems() );
     474          26 :             for( sal_Int32 nCS = 0; nCS < aCooSysList.getLength(); ++nCS )
     475             :             {
     476          13 :                 uno::Reference< XCoordinateSystem > xCooSys( aCooSysList[nCS] );
     477             : 
     478             :                 //iterate through all chart types in the current coordinate system
     479          26 :                 uno::Reference< XChartTypeContainer > xChartTypeContainer( xCooSys, uno::UNO_QUERY );
     480             :                 OSL_ASSERT( xChartTypeContainer.is());
     481          13 :                 if( !xChartTypeContainer.is() )
     482           0 :                     continue;
     483          26 :                 uno::Sequence< uno::Reference< XChartType > > aChartTypeList( xChartTypeContainer->getChartTypes() );
     484          26 :                 for( sal_Int32 nT = 0; nT < aChartTypeList.getLength(); ++nT )
     485             :                 {
     486          13 :                     uno::Reference< XChartType > xChartType( aChartTypeList[nT] );
     487             : 
     488             :                     //iterate through all series in this chart type
     489          26 :                     uno::Reference< XDataSeriesContainer > xDataSeriesContainer( xChartType, uno::UNO_QUERY );
     490             :                     OSL_ASSERT( xDataSeriesContainer.is());
     491          13 :                     if( !xDataSeriesContainer.is() )
     492           0 :                         continue;
     493             : 
     494          26 :                     uno::Sequence< uno::Reference< XDataSeries > > aSeriesList( xDataSeriesContainer->getDataSeries() );
     495         116 :                     for( sal_Int32 nS = 0; nS < aSeriesList.getLength(); ++nS )
     496             :                     {
     497         103 :                         Reference< XDataSeries > xSeries(aSeriesList[nS]);
     498         206 :                         Reference< beans::XPropertySet > xSeriesProp( xSeries, uno::UNO_QUERY );
     499         103 :                         if(!xSeries.is() || !xSeriesProp.is() )
     500           0 :                             continue;
     501             : 
     502             :                         uno::Sequence < sal_Int32 > aAvailablePlacements( ChartTypeHelper::getSupportedLabelPlacements(
     503         206 :                             xChartType, getDimension(), isSwapXAndY(), xSeries ) );
     504         103 :                         if(!aAvailablePlacements.getLength())
     505           0 :                             continue;
     506             : 
     507         103 :                         sal_Int32 nDefaultPlacement = aAvailablePlacements[0];
     508             : 
     509         103 :                         lcl_resetLabelPlacementIfDefault( xSeriesProp, nDefaultPlacement );
     510             : 
     511         206 :                         uno::Sequence< sal_Int32 > aAttributedDataPointIndexList;
     512         103 :                         if( xSeriesProp->getPropertyValue( "AttributedDataPoints" ) >>= aAttributedDataPointIndexList )
     513         206 :                             for(sal_Int32 nN=aAttributedDataPointIndexList.getLength();nN--;)
     514           0 :                                 lcl_resetLabelPlacementIfDefault( xSeries->getDataPointByIndex(aAttributedDataPointIndexList[nN]), nDefaultPlacement );
     515         103 :                     }
     516          13 :                 }
     517          26 :             }
     518          13 :         }
     519             :     }
     520             : 
     521          13 :     return;
     522             : }
     523             : 
     524             : // ____ XServiceName ____
     525           0 :     OUString SAL_CALL ChartTypeTemplate::getServiceName()
     526             :     throw (uno::RuntimeException, std::exception)
     527             : {
     528           0 :     return m_aServiceName;
     529             : }
     530             : 
     531       20583 : sal_Int32 ChartTypeTemplate::getDimension() const
     532             : {
     533       20583 :     return 2;
     534             : }
     535             : 
     536        1375 : StackMode ChartTypeTemplate::getStackMode( sal_Int32 /* nChartTypeIndex */ ) const
     537             : {
     538        1375 :     return StackMode_NONE;
     539             : }
     540             : 
     541         113 : bool ChartTypeTemplate::isSwapXAndY() const
     542             : {
     543         113 :     return false;
     544             : }
     545             : 
     546         121 : void ChartTypeTemplate::createCoordinateSystems(
     547             :     const Reference< chart2::XCoordinateSystemContainer > & xOutCooSysCnt )
     548             : {
     549         121 :     if( ! xOutCooSysCnt.is())
     550          12 :         return;
     551         121 :     Sequence< Reference< XChartType > > aFormerlyUsedChartTypes;
     552         230 :     Reference< XChartType > xChartType( getChartTypeForNewSeries(aFormerlyUsedChartTypes));
     553         121 :     if( ! xChartType.is())
     554           0 :         return;
     555         230 :     Reference< XCoordinateSystem > xCooSys( xChartType->createCoordinateSystem( getDimension()));
     556         121 :     if( ! xCooSys.is())
     557             :     {
     558             :         // chart type wants no coordinate systems
     559           0 :         xOutCooSysCnt->setCoordinateSystems( Sequence< Reference< XCoordinateSystem > >());
     560           0 :         return;
     561             :     }
     562             :     // #i69680# make grid of first y-axis visible (was in the CooSys CTOR before)
     563         121 :     if( xCooSys->getDimension() >= 2 )
     564             :     {
     565         121 :         Reference< chart2::XAxis > xAxis( xCooSys->getAxisByDimension( 1, 0 ));
     566         121 :         if( xAxis.is())
     567         121 :             AxisHelper::makeGridVisible( xAxis->getGridProperties() );
     568             :     }
     569             : 
     570             :     Sequence< Reference< XCoordinateSystem > > aCoordinateSystems(
     571         230 :         xOutCooSysCnt->getCoordinateSystems());
     572             : 
     573         121 :     if( aCoordinateSystems.getLength())
     574             :     {
     575          14 :         bool bOk = true;
     576          28 :         for( sal_Int32 i=0; bOk && i<aCoordinateSystems.getLength(); ++i )
     577          54 :             bOk = bOk && ( xCooSys->getCoordinateSystemType().equals( aCoordinateSystems[i]->getCoordinateSystemType()) &&
     578          26 :                            (xCooSys->getDimension() == aCoordinateSystems[i]->getDimension()) );
     579             :         // coordinate systems are ok
     580          14 :         if( bOk )
     581          12 :             return;
     582             :         // there are coordinate systems but they do not fit.  So overwrite them.
     583             :     }
     584             : 
     585             :     //copy as much info from former coordinate system as possible:
     586         109 :     if( aCoordinateSystems.getLength() )
     587             :     {
     588           2 :         Reference< XCoordinateSystem > xOldCooSys( aCoordinateSystems[0] );
     589           2 :         sal_Int32 nMaxDimensionCount = std::min( xCooSys->getDimension(), xOldCooSys->getDimension() );
     590             : 
     591           6 :         for(sal_Int32 nDimensionIndex=0; nDimensionIndex<nMaxDimensionCount; nDimensionIndex++)
     592             :         {
     593           4 :             const sal_Int32 nMaximumAxisIndex = xOldCooSys->getMaximumAxisIndexByDimension(nDimensionIndex);
     594           8 :             for(sal_Int32 nAxisIndex=0; nAxisIndex<=nMaximumAxisIndex; ++nAxisIndex)
     595             :             {
     596           4 :                 uno::Reference< XAxis > xAxis( xOldCooSys->getAxisByDimension( nDimensionIndex, nAxisIndex ) );
     597           4 :                 if( xAxis.is())
     598             :                 {
     599           4 :                     xCooSys->setAxisByDimension( nDimensionIndex, xAxis, nAxisIndex );
     600             :                 }
     601           4 :             }
     602           2 :         }
     603             :     }
     604             : 
     605             :     // set new coordinate systems
     606         109 :     aCoordinateSystems.realloc( 1 );
     607         109 :     aCoordinateSystems[0] = xCooSys;
     608             : 
     609         218 :     xOutCooSysCnt->setCoordinateSystems( aCoordinateSystems );
     610             : }
     611             : 
     612         121 : void ChartTypeTemplate::adaptScales(
     613             :     const Sequence< Reference< chart2::XCoordinateSystem > > & aCooSysSeq,
     614             :     const Reference< data::XLabeledDataSequence > & xCategories //@todo: in future there may be more than one sequence of categories (e.g. charttype with categories at x and y axis )
     615             :     )
     616             : {
     617         121 :     bool bSupportsCategories( supportsCategories() );
     618         242 :     for( sal_Int32 nCooSysIdx=0; nCooSysIdx<aCooSysSeq.getLength(); ++nCooSysIdx )
     619             :     {
     620             :         try
     621             :         {
     622         121 :             Reference< XCoordinateSystem > xCooSys( aCooSysSeq[nCooSysIdx] );
     623         121 :             if( !xCooSys.is() )
     624           0 :                 continue;
     625             : 
     626             :             // attach categories to first axis
     627         121 :             sal_Int32 nDim( xCooSys->getDimension());
     628         121 :             if( nDim > 0 )
     629             :             {
     630         121 :                 const sal_Int32 nDimensionX = 0;
     631         121 :                 const sal_Int32 nMaxIndex = xCooSys->getMaximumAxisIndexByDimension(nDimensionX);
     632         242 :                 for(sal_Int32 nI=0; nI<=nMaxIndex; ++nI)
     633             :                 {
     634         121 :                     Reference< XAxis > xAxis( xCooSys->getAxisByDimension(nDimensionX,nI) );
     635         121 :                     if( xAxis.is())
     636             :                     {
     637         121 :                         ScaleData aData( xAxis->getScaleData() );
     638         121 :                         aData.Categories = xCategories;
     639         121 :                         if(bSupportsCategories)
     640             :                         {
     641             : 
     642          92 :                             Reference< XChartType > xChartType( getChartTypeForNewSeries(Sequence< Reference< XChartType > >() ));
     643          92 :                             bool bSupportsDates = ::chart::ChartTypeHelper::isSupportingDateAxis( xChartType, 2, nDimensionX );
     644          92 :                             if( aData.AxisType != AxisType::CATEGORY && ( aData.AxisType != AxisType::DATE || !bSupportsDates) )
     645             :                             {
     646           9 :                                 aData.AxisType = AxisType::CATEGORY;
     647           9 :                                 aData.AutoDateAxis = true;
     648           9 :                                 AxisHelper::removeExplicitScaling( aData );
     649          92 :                             }
     650             :                         }
     651             :                         else
     652          29 :                             aData.AxisType = AxisType::REALNUMBER;
     653             : 
     654         121 :                         xAxis->setScaleData( aData );
     655             :                     }
     656         121 :                 }
     657             :             }
     658             :             // set percent stacking mode at second axis
     659         121 :             if( nDim > 1 )
     660             :             {
     661         121 :                 const sal_Int32 nMaxIndex = xCooSys->getMaximumAxisIndexByDimension(1);
     662         242 :                 for(sal_Int32 nI=0; nI<=nMaxIndex; ++nI)
     663             :                 {
     664         121 :                     Reference< chart2::XAxis > xAxis( xCooSys->getAxisByDimension( 1,nI ));
     665         121 :                     if( xAxis.is())
     666             :                     {
     667         121 :                         bool bPercent = (getStackMode(0) == StackMode_Y_STACKED_PERCENT);
     668         121 :                         chart2::ScaleData aScaleData = xAxis->getScaleData();
     669             : 
     670         121 :                         if( bPercent != (aScaleData.AxisType==AxisType::PERCENT) )
     671             :                         {
     672           0 :                             if( bPercent )
     673           0 :                                 aScaleData.AxisType = AxisType::PERCENT;
     674             :                             else
     675           0 :                                 aScaleData.AxisType = AxisType::REALNUMBER;
     676           0 :                             xAxis->setScaleData( aScaleData );
     677         121 :                         }
     678             :                     }
     679         121 :                 }
     680         121 :             }
     681             :         }
     682           0 :         catch( const uno::Exception & ex )
     683             :         {
     684             :             ASSERT_EXCEPTION( ex );
     685             :         }
     686             :     }
     687         121 : }
     688             : 
     689         113 : void ChartTypeTemplate::adaptDiagram( const Reference< XDiagram > & /* xDiagram */ )
     690             : {
     691         113 :     return;
     692             : }
     693             : 
     694         121 : void ChartTypeTemplate::createAxes(
     695             :     const Sequence< Reference< XCoordinateSystem > > & rCoordSys )
     696             : {
     697             :     //create missing axes
     698         121 :     if( rCoordSys.getLength() > 0 )
     699             :     {
     700         121 :         sal_Int32 nCooSysIdx = 0;
     701         121 :         Reference< XCoordinateSystem > xCooSys( rCoordSys[nCooSysIdx] );
     702         121 :         if(!xCooSys.is())
     703         121 :             return;
     704             : 
     705             :         //create main axis in first coordinate system
     706         121 :         sal_Int32 nDimCount = xCooSys->getDimension();
     707         121 :         sal_Int32 nDim=0;
     708         363 :         for( nDim=0; nDim<nDimCount; ++nDim )
     709             :         {
     710         242 :             sal_Int32 nAxisCount = getAxisCountByDimension( nDim );
     711         363 :             if( nDim == 1 &&
     712         363 :                 nAxisCount < 2 && AxisHelper::isSecondaryYAxisNeeded( xCooSys ))
     713           0 :                 nAxisCount = 2;
     714         468 :             for( sal_Int32 nAxisIndex = 0; nAxisIndex < nAxisCount; ++nAxisIndex )
     715             :             {
     716         226 :                 Reference< XAxis > xAxis = AxisHelper::getAxis( nDim, nAxisIndex, xCooSys );
     717         226 :                 if( !xAxis.is())
     718             :                 {
     719             :                     // create and add axis
     720             :                     xAxis.set( AxisHelper::createAxis(
     721           0 :                                    nDim, nAxisIndex, xCooSys, GetComponentContext() ));
     722             :                 }
     723         226 :             }
     724         121 :         }
     725             :     }
     726             : }
     727             : 
     728         113 : void ChartTypeTemplate::adaptAxes(
     729             :     const Sequence< Reference< XCoordinateSystem > > & rCoordSys )
     730             : {
     731             :     //adapt properties of exsisting axes and remove superfluous axes
     732             : 
     733         113 :     if( rCoordSys.getLength() > 0 )
     734             :     {
     735         226 :         for( sal_Int32 nCooSysIdx=0; nCooSysIdx < rCoordSys.getLength(); ++nCooSysIdx )
     736             :         {
     737         113 :             Reference< XCoordinateSystem > xCooSys( rCoordSys[nCooSysIdx] );
     738         113 :             if( !xCooSys.is() )
     739           0 :                 continue;
     740         113 :             sal_Int32 nDimCount = xCooSys->getDimension();
     741         339 :             for( sal_Int32 nDim=0; nDim<nDimCount; ++nDim )
     742             :             {
     743         226 :                 sal_Int32 nMaxAxisIndex = xCooSys->getMaximumAxisIndexByDimension( nDim );
     744         452 :                 for( sal_Int32 nAxisIndex=0; nAxisIndex<=nMaxAxisIndex; nAxisIndex++ )
     745             :                 {
     746         226 :                     Reference< XAxis > xAxis( AxisHelper::getAxis( nDim, nAxisIndex, xCooSys ) );
     747         226 :                     if( !xAxis.is() )
     748           0 :                         continue;
     749             : 
     750         226 :                     if( nAxisIndex == MAIN_AXIS_INDEX || nAxisIndex == SECONDARY_AXIS_INDEX )
     751             :                     {
     752             :                         // adapt scales
     753         226 :                         bool bPercent = (getStackMode(0) == StackMode_Y_STACKED_PERCENT);
     754         226 :                         if( bPercent && nDim == 1 )
     755             :                         {
     756           0 :                             Reference< beans::XPropertySet > xAxisProp( xAxis, uno::UNO_QUERY );
     757           0 :                             if( xAxisProp.is())
     758             :                             {
     759             :                                 // set number format to source format
     760           0 :                                 xAxisProp->setPropertyValue(CHART_UNONAME_LINK_TO_SRC_NUMFMT, uno::makeAny(true));
     761           0 :                                 xAxisProp->setPropertyValue(CHART_UNONAME_NUMFMT, uno::Any());
     762           0 :                             }
     763             :                         }
     764             :                     }
     765         226 :                 }
     766             :             }
     767         113 :         }
     768             :     }
     769         113 : }
     770             : 
     771         218 : sal_Int32 ChartTypeTemplate::getAxisCountByDimension( sal_Int32 nDimension )
     772             : {
     773         218 :     return (nDimension < getDimension()) ? 1 : 0;
     774             : }
     775             : 
     776         121 : void ChartTypeTemplate::FillDiagram(
     777             :     const Reference< XDiagram >& xDiagram,
     778             :     const Sequence< Sequence< Reference< XDataSeries > > >& aSeriesSeq,
     779             :     Reference< data::XLabeledDataSequence > xCategories,
     780             :     const Sequence< Reference< XChartType > >& aOldChartTypesSeq,
     781             :     bool /* bCreate */ )
     782             : {
     783         121 :     adaptDiagram( xDiagram );
     784             : 
     785             :     try
     786             :     {
     787             :         // create coordinate systems and scales
     788         121 :         Reference< XCoordinateSystemContainer > xCoordSysCnt( xDiagram, uno::UNO_QUERY_THROW );
     789         121 :         createCoordinateSystems( xCoordSysCnt );
     790         242 :         Sequence< Reference< XCoordinateSystem > > aCoordinateSystems( xCoordSysCnt->getCoordinateSystems());
     791         121 :         createAxes( aCoordinateSystems );
     792         121 :         adaptAxes( aCoordinateSystems );
     793         121 :         adaptScales( aCoordinateSystems, xCategories );
     794             : 
     795             :         // chart types
     796         121 :         createChartTypes( aSeriesSeq, aCoordinateSystems, aOldChartTypesSeq );
     797         242 :         applyStyles( xDiagram );
     798             :     }
     799           0 :     catch( const uno::Exception & ex )
     800             :     {
     801             :         ASSERT_EXCEPTION( ex );
     802             :     }
     803         121 : }
     804             : 
     805         109 : void ChartTypeTemplate::createChartTypes(
     806             :     const Sequence< Sequence< Reference< XDataSeries > > > & aSeriesSeq,
     807             :     const Sequence< Reference< XCoordinateSystem > > & rCoordSys,
     808             :     const Sequence< Reference< XChartType > >& aOldChartTypesSeq )
     809             : {
     810         218 :     if( rCoordSys.getLength() == 0 ||
     811         109 :         ! rCoordSys[0].is() )
     812         109 :         return;
     813             : 
     814             :     try
     815             :     {
     816         109 :         sal_Int32 nCooSysIdx=0;
     817         109 :         Reference< XChartType > xCT;
     818         109 :         if( aSeriesSeq.getLength() == 0 )
     819             :         {
     820             :             // we need a new chart type
     821          79 :             xCT.set( getChartTypeForNewSeries( aOldChartTypesSeq ));
     822          79 :             Reference< XChartTypeContainer > xCTCnt( rCoordSys[nCooSysIdx], uno::UNO_QUERY_THROW );
     823         158 :             Sequence< Reference< XChartType > > aCTSeq( xCTCnt->getChartTypes());
     824          79 :             aCTSeq.realloc( 1 );
     825          79 :             aCTSeq[0] = xCT;
     826         158 :             xCTCnt->setChartTypes( aCTSeq );
     827             :         }
     828             :         else
     829             :         {
     830          60 :             for( sal_Int32 nSeriesIdx=0; nSeriesIdx<aSeriesSeq.getLength(); ++nSeriesIdx )
     831             :             {
     832          30 :                 if( nSeriesIdx == nCooSysIdx )
     833             :                 {
     834             :                     // we need a new chart type
     835          30 :                     xCT.set( getChartTypeForNewSeries( aOldChartTypesSeq ));
     836          30 :                     Reference< XChartTypeContainer > xCTCnt( rCoordSys[nCooSysIdx], uno::UNO_QUERY_THROW );
     837          60 :                     Sequence< Reference< XChartType > > aCTSeq( xCTCnt->getChartTypes());
     838          30 :                     if( aCTSeq.getLength())
     839             :                     {
     840           0 :                         aCTSeq[0] = xCT;
     841           0 :                         xCTCnt->setChartTypes( aCTSeq );
     842             :                     }
     843             :                     else
     844          30 :                         xCTCnt->addChartType( xCT );
     845             : 
     846          60 :                     Reference< chart2::XDataSeriesContainer > xDSCnt( xCT, uno::UNO_QUERY_THROW );
     847          60 :                     xDSCnt->setDataSeries( aSeriesSeq[nSeriesIdx] );
     848             :                 }
     849             :                 else
     850             :                 {
     851             :                     // reuse existing chart type
     852             :                     OSL_ASSERT( xCT.is());
     853           0 :                     Reference< chart2::XDataSeriesContainer > xDSCnt( xCT, uno::UNO_QUERY_THROW );
     854           0 :                     Sequence< Reference< XDataSeries > > aNewSeriesSeq( xDSCnt->getDataSeries());
     855           0 :                     sal_Int32 nNewStartIndex = aNewSeriesSeq.getLength();
     856           0 :                     aNewSeriesSeq.realloc( nNewStartIndex + aSeriesSeq[nSeriesIdx].getLength() );
     857           0 :                     ::std::copy( aSeriesSeq[nSeriesIdx].begin(),
     858           0 :                                  aSeriesSeq[nSeriesIdx].end(),
     859           0 :                                  aNewSeriesSeq.getArray() + nNewStartIndex );
     860           0 :                     xDSCnt->setDataSeries( aNewSeriesSeq );
     861             :                 }
     862             : 
     863             :                 // spread the series over the available coordinate systems
     864          30 :                 if( rCoordSys.getLength() > (nCooSysIdx + 1) )
     865           0 :                     ++nCooSysIdx;
     866             :             }
     867         109 :         }
     868             :     }
     869           0 :     catch( const uno::Exception & ex )
     870             :     {
     871             :         ASSERT_EXCEPTION( ex );
     872             :     }
     873             : }
     874             : 
     875       70173 : void ChartTypeTemplate::copyPropertiesFromOldToNewCoordianteSystem(
     876             :                     const Sequence< Reference< XChartType > > & rOldChartTypesSeq,
     877             :                     const Reference< XChartType > & xNewChartType )
     878             : {
     879       70173 :     Reference< beans::XPropertySet > xDestination( xNewChartType, uno::UNO_QUERY );
     880       70173 :     if( !xDestination.is() )
     881       70173 :         return;
     882             : 
     883      140346 :     OUString aNewChartType( xNewChartType->getChartType() );
     884             : 
     885      140346 :     Reference< beans::XPropertySet > xSource;
     886       70173 :     sal_Int32 nN=0;
     887       70182 :     for( nN=0; nN<rOldChartTypesSeq.getLength();++nN)
     888             :     {
     889           9 :         Reference< XChartType > xOldType( rOldChartTypesSeq[nN] );
     890           9 :         if( xOldType.is() && xOldType->getChartType().equals( aNewChartType ) )
     891             :         {
     892           0 :             xSource.set( Reference< beans::XPropertySet >(xOldType, uno::UNO_QUERY ) );
     893           0 :             if( xSource.is() )
     894           0 :                 break;
     895             :         }
     896           9 :     }
     897       70173 :     if( xSource.is() )
     898       70173 :         comphelper::copyProperties( xSource, xDestination );
     899             : }
     900             : 
     901             : } //  namespace chart
     902             : 
     903             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11