LCOV - code coverage report
Current view: top level - chart2/source/model/template - ChartTypeTemplate.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 357 427 83.6 %
Date: 2014-11-03 Functions: 29 31 93.5 %
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         274 : 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         274 :     if( xSeries.is() && xDiagram.is())
      63             :     {
      64         274 :         Reference< beans::XPropertySet > xSeriesProp( xSeries, uno::UNO_QUERY );
      65         548 :         Reference< chart2::XColorScheme > xColorScheme( xDiagram->getDefaultColorScheme());
      66         274 :         if( xSeriesProp.is() && xColorScheme.is() )
      67         274 :             xSeriesProp->setPropertyValue(
      68             :                 "Color",
      69         548 :                 uno::makeAny( xColorScheme->getColorByIndex( nIndex )));
      70             :     }
      71         274 : }
      72             : 
      73         448 : void lcl_ensureCorrectLabelPlacement( const Reference< beans::XPropertySet >& xProp, const uno::Sequence < sal_Int32 >& rAvailablePlacements )
      74             : {
      75         448 :     sal_Int32 nLabelPlacement=0;
      76         448 :     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         448 : }
      97             : 
      98         206 : void lcl_resetLabelPlacementIfDefault( const Reference< beans::XPropertySet >& xProp, sal_Int32 nDefaultPlacement )
      99             : {
     100             : 
     101         206 :     sal_Int32 nLabelPlacement=0;
     102         206 :     if( xProp.is() && (xProp->getPropertyValue( "LabelPlacement" ) >>= nLabelPlacement) )
     103             :     {
     104           0 :         if( nDefaultPlacement == nLabelPlacement )
     105           0 :             xProp->setPropertyValue( "LabelPlacement", uno::Any() );
     106             :     }
     107         206 : }
     108             : 
     109         316 : void lcl_ensureCorrectMissingValueTreatment( const Reference< chart2::XDiagram >& xDiagram, const Reference< XChartType >& xChartType )
     110             : {
     111         316 :     Reference< beans::XPropertySet > xDiaProp( xDiagram, uno::UNO_QUERY );
     112         316 :     if( xDiaProp.is() )
     113             :     {
     114             :         uno::Sequence < sal_Int32 > aAvailableMissingValueTreatment(
     115         316 :             ::chart::ChartTypeHelper::getSupportedMissingValueTreatments( xChartType ) );
     116             : 
     117         316 :         if( aAvailableMissingValueTreatment.getLength() )
     118         272 :             xDiaProp->setPropertyValue( "MissingValueTreatment", uno::makeAny( aAvailableMissingValueTreatment[0] ) );
     119             :         else
     120          44 :             xDiaProp->setPropertyValue( "MissingValueTreatment", uno::Any() );
     121         316 :     }
     122         316 : }
     123             : 
     124             : } // anonymous namespace
     125             : 
     126             : namespace chart
     127             : {
     128             : 
     129      167946 : ChartTypeTemplate::ChartTypeTemplate(
     130             :     Reference< uno::XComponentContext > const & xContext,
     131             :     const OUString & rServiceName ) :
     132             :         m_xContext( xContext ),
     133      167946 :         m_aServiceName( rServiceName )
     134             : {
     135      167946 : }
     136             : 
     137      167946 : ChartTypeTemplate::~ChartTypeTemplate()
     138      167946 : {}
     139             : 
     140             : // ____ XChartTypeTemplate ____
     141         286 : 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         286 :     Reference< XDiagram > xDia;
     147             : 
     148             :     try
     149             :     {
     150             :         // create diagram
     151             :         xDia.set(
     152         572 :             GetComponentContext()->getServiceManager()->createInstanceWithContext(
     153             :                 "com.sun.star.chart2.Diagram",
     154         286 :                 GetComponentContext() ),
     155         286 :             uno::UNO_QUERY_THROW );
     156             : 
     157             :         // modify diagram
     158         286 :         Reference< chart2::XDataInterpreter > xInterpreter( getDataInterpreter());
     159             :         chart2::InterpretedData aData(
     160         286 :             xInterpreter->interpretDataSource(
     161         572 :                 xDataSource, aArguments, Sequence< Reference< XDataSeries > >() ));
     162             : 
     163         572 :         Sequence< Sequence< Reference< XDataSeries > > > aSeries( aData.Series );
     164         286 :         sal_Int32 i, j, nCount = 0;
     165         328 :         for( i=0; i<aSeries.getLength(); ++i )
     166             :         {
     167         282 :             for( j=0; j<aSeries[i].getLength(); ++j, ++nCount )
     168         240 :                 lcl_applyDefaultStyle( aSeries[i][j], nCount, xDia );
     169             :         }
     170             : 
     171         572 :         Sequence< Reference< XChartType > > aOldChartTypesSeq;
     172         572 :         FillDiagram( xDia, aData.Series, aData.Categories, aOldChartTypesSeq, true );
     173             :     }
     174           0 :     catch( const uno::Exception & ex )
     175             :     {
     176             :         ASSERT_EXCEPTION( ex );
     177             :     }
     178             : 
     179         286 :     return xDia;
     180             : }
     181             : 
     182         326 : sal_Bool SAL_CALL ChartTypeTemplate::supportsCategories()
     183             :     throw (css::uno::RuntimeException, ::std::exception)
     184             : {
     185         326 :     return sal_True;
     186             : }
     187             : 
     188          30 : void SAL_CALL ChartTypeTemplate::changeDiagram( const uno::Reference< XDiagram >& xDiagram )
     189             :     throw (uno::RuntimeException, std::exception)
     190             : {
     191          30 :     if( ! xDiagram.is())
     192          30 :         return;
     193             : 
     194             :     try
     195             :     {
     196             :         Sequence< Sequence< Reference< XDataSeries > > > aSeriesSeq(
     197          30 :             DiagramHelper::getDataSeriesGroups( xDiagram ));
     198          60 :         Sequence< Reference< XDataSeries > > aFlatSeriesSeq( FlattenSequence( aSeriesSeq ));
     199          30 :         const sal_Int32 nFormerSeriesCount = aFlatSeriesSeq.getLength();
     200             : 
     201             :         // chart-type specific interpretation of existing data series
     202          60 :         Reference< chart2::XDataInterpreter > xInterpreter( getDataInterpreter());
     203          60 :         chart2::InterpretedData aData;
     204          30 :         aData.Series = aSeriesSeq;
     205          30 :         aData.Categories = DiagramHelper::getCategoriesFromDiagram( xDiagram );
     206             : 
     207          30 :         if( xInterpreter->isDataCompatible( aData ) )
     208             :         {
     209          12 :             aData = xInterpreter->reinterpretDataSeries( aData );
     210             :         }
     211             :         else
     212             :         {
     213          18 :             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          36 :             Sequence< beans::PropertyValue > aParam;
     219          18 :             if( aData.Categories.is())
     220             :             {
     221          14 :                 aParam.realloc( 1 );
     222          28 :                 aParam[0] = beans::PropertyValue( "HasCategories", -1, uno::makeAny( true ),
     223          14 :                                                   beans::PropertyState_DIRECT_VALUE );
     224             :             }
     225          36 :             aData = xInterpreter->interpretDataSource( xSource, aParam, aFlatSeriesSeq );
     226             :         }
     227          30 :         aSeriesSeq = aData.Series;
     228             : 
     229          30 :         sal_Int32 i, j, nIndex = 0;
     230          60 :         for( i=0; i<aSeriesSeq.getLength(); ++i )
     231         236 :             for( j=0; j<aSeriesSeq[i].getLength(); ++j, ++nIndex )
     232             :             {
     233         206 :                 if( nIndex >= nFormerSeriesCount )
     234          32 :                     lcl_applyDefaultStyle( aSeriesSeq[i][j], nIndex, xDiagram );
     235             :             }
     236             : 
     237             :         // remove charttype groups from all coordinate systems
     238             :         Sequence< Reference< XChartType > > aOldChartTypesSeq(
     239          60 :             DiagramHelper::getChartTypesFromDiagram(xDiagram) );
     240             : 
     241          60 :         Reference< XCoordinateSystemContainer > xCoordSysCnt( xDiagram, uno::UNO_QUERY );
     242             :         OSL_ASSERT( xCoordSysCnt.is());
     243          30 :         if( xCoordSysCnt.is())
     244             :         {
     245             :             Sequence< Reference< XCoordinateSystem > > aCooSysSeq(
     246          30 :                 xCoordSysCnt->getCoordinateSystems());
     247          60 :             for( sal_Int32 nCooSysIdx = 0; nCooSysIdx < aCooSysSeq.getLength(); ++nCooSysIdx )
     248             :             {
     249          30 :                 Reference< XChartTypeContainer > xContainer( aCooSysSeq[nCooSysIdx], uno::UNO_QUERY );
     250          30 :                 if( xContainer.is() )
     251          30 :                     xContainer->setChartTypes( Sequence< Reference< XChartType > >() );
     252          60 :             }
     253             :         }
     254             : 
     255          60 :         FillDiagram( xDiagram, aSeriesSeq, aData.Categories, aOldChartTypesSeq, false );
     256             :     }
     257           0 :     catch( const uno::Exception & ex )
     258             :     {
     259             :         ASSERT_EXCEPTION( ex );
     260             :     }
     261             : }
     262             : 
     263          40 : 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          80 :     if( ! (xDiagram.is() &&
     270          40 :            xDataSource.is()) )
     271          40 :         return;
     272             : 
     273             :     try
     274             :     {
     275             :         // interpret new data and re-use existing series
     276             :         Sequence< Reference< XDataSeries > > aFlatSeriesSeq(
     277          40 :             ::chart::ContainerHelper::ContainerToSequence( DiagramHelper::getDataSeriesFromDiagram( xDiagram )));
     278          40 :         const sal_Int32 nFormerSeriesCount = aFlatSeriesSeq.getLength();
     279          80 :         Reference< chart2::XDataInterpreter > xInterpreter( getDataInterpreter());
     280             :         chart2::InterpretedData aData =
     281          80 :             xInterpreter->interpretDataSource( xDataSource, aArguments, aFlatSeriesSeq );
     282             : 
     283             :         // data series
     284          80 :         Sequence< Sequence< Reference< XDataSeries > > > aSeriesSeq( aData.Series );
     285             : 
     286          40 :         sal_Int32 i, j, nIndex = 0;
     287          84 :         for( i=0; i<aSeriesSeq.getLength(); ++i )
     288         276 :             for( j=0; j<aSeriesSeq[i].getLength(); ++j, ++nIndex )
     289             :             {
     290         232 :                 if( nIndex >= nFormerSeriesCount )
     291             :                 {
     292           2 :                     lcl_applyDefaultStyle( aSeriesSeq[i][j], nIndex, xDiagram );
     293           2 :                     applyStyle( aSeriesSeq[i][j], i, j, aSeriesSeq[i].getLength() );
     294             :                 }
     295             :             }
     296             : 
     297             :         // categories
     298          40 :         DiagramHelper::setCategoriesToDiagram( aData.Categories, xDiagram, true, supportsCategories() );
     299             : 
     300             :         Sequence< Reference< XChartType > > aChartTypes(
     301          80 :             DiagramHelper::getChartTypesFromDiagram( xDiagram ));
     302          40 :         sal_Int32 nMax = ::std::min( aChartTypes.getLength(), aSeriesSeq.getLength());
     303          84 :         for( i=0; i<nMax; ++i )
     304             :         {
     305          44 :             Reference< XDataSeriesContainer > xDSCnt( aChartTypes[i], uno::UNO_QUERY_THROW );
     306          44 :             xDSCnt->setDataSeries( aSeriesSeq[i] );
     307          84 :         }
     308             :     }
     309           0 :     catch( const uno::Exception & ex )
     310             :     {
     311             :         ASSERT_EXCEPTION( ex );
     312             :     }
     313             : }
     314             : 
     315      154764 : sal_Bool SAL_CALL ChartTypeTemplate::matchesTemplate(
     316             :     const Reference< chart2::XDiagram >& xDiagram,
     317             :     sal_Bool /* bAdaptProperties */ )
     318             :     throw (uno::RuntimeException, std::exception)
     319             : {
     320      154764 :     bool bResult = false;
     321             : 
     322      154764 :     if( ! xDiagram.is())
     323           0 :         return bResult;
     324             : 
     325             :     try
     326             :     {
     327             :         Reference< XCoordinateSystemContainer > xCooSysCnt(
     328      154764 :             xDiagram, uno::UNO_QUERY_THROW );
     329             :         Sequence< Reference< XCoordinateSystem > > aCooSysSeq(
     330      309528 :             xCooSysCnt->getCoordinateSystems());
     331             : 
     332             :         // need to have at least one coordinate system
     333      154764 :         bResult = (aCooSysSeq.getLength() > 0);
     334      154764 :         if( bResult )
     335             :         {
     336      154764 :             Sequence< Reference< XChartType > > aFormerlyUsedChartTypes;
     337      309528 :             Reference<XChartType> xOldCT = getChartTypeForNewSeries(aFormerlyUsedChartTypes);
     338      154764 :             if (!xOldCT.is())
     339           0 :                 return false;
     340             : 
     341      309528 :             const OUString aChartTypeToMatch = xOldCT->getChartType();
     342      154764 :             const sal_Int32 nDimensionToMatch = getDimension();
     343      309528 :             for( sal_Int32 nCooSysIdx=0; bResult && (nCooSysIdx < aCooSysSeq.getLength()); ++nCooSysIdx )
     344             :             {
     345             :                 // match dimension
     346      154764 :                 bResult = bResult && (aCooSysSeq[nCooSysIdx]->getDimension() == nDimensionToMatch);
     347             : 
     348      154764 :                 Reference< XChartTypeContainer > xCTCnt( aCooSysSeq[nCooSysIdx], uno::UNO_QUERY_THROW );
     349      309528 :                 Sequence< Reference< XChartType > > aChartTypeSeq( xCTCnt->getChartTypes());
     350      228476 :                 for( sal_Int32 nCTIdx=0; bResult && (nCTIdx < aChartTypeSeq.getLength()); ++nCTIdx )
     351             :                 {
     352       73712 :                     if (!aChartTypeSeq[nCTIdx].is())
     353           0 :                         return false;
     354             : 
     355             :                     // match chart type
     356       73712 :                     bResult = bResult && aChartTypeSeq[nCTIdx]->getChartType().equals( aChartTypeToMatch );
     357       73712 :                     bool bFound=false;
     358       73712 :                     bool bAmbiguous=false;
     359             :                     // match stacking mode
     360       92364 :                     bResult = bResult &&
     361             :                         ( DiagramHelper::getStackModeFromChartType(
     362       18652 :                             aChartTypeSeq[nCTIdx], bFound, bAmbiguous,
     363       37304 :                             aCooSysSeq[nCooSysIdx] )
     364       92364 :                           == getStackMode( nCTIdx ) );
     365             :                 }
     366      309528 :             }
     367      154764 :         }
     368             :     }
     369           0 :     catch( const uno::Exception & ex )
     370             :     {
     371             :         ASSERT_EXCEPTION( ex );
     372             :     }
     373             : 
     374      154764 :     return bResult;
     375             : }
     376             : 
     377         282 : Reference< chart2::XDataInterpreter > SAL_CALL ChartTypeTemplate::getDataInterpreter()
     378             :     throw (uno::RuntimeException, std::exception)
     379             : {
     380         282 :     if( ! m_xDataInterpreter.is())
     381         282 :         m_xDataInterpreter.set( new DataInterpreter( GetComponentContext() ) );
     382             : 
     383         282 :     return m_xDataInterpreter;
     384             : }
     385             : 
     386         448 : 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         448 :     Reference< beans::XPropertySet > xSeriesProp( xSeries, uno::UNO_QUERY );
     395         448 :     if( xSeriesProp.is())
     396             :     {
     397             :         try
     398             :         {
     399         448 :             StackMode eStackMode = getStackMode( nChartTypeIndex );
     400             :             const uno::Any aPropValue = uno::makeAny(
     401         448 :                 ( (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         896 :                 : chart2::StackingDirection_NO_STACKING );
     407         448 :             xSeriesProp->setPropertyValue( "StackingDirection", aPropValue );
     408             : 
     409             :             //ensure valid label placement
     410             :             {
     411             :                 uno::Sequence < sal_Int32 > aAvailablePlacements( ChartTypeHelper::getSupportedLabelPlacements(
     412         448 :                             getChartTypeForIndex( nChartTypeIndex ), getDimension(), isSwapXAndY(), xSeries ) );
     413         448 :                 lcl_ensureCorrectLabelPlacement( xSeriesProp, aAvailablePlacements );
     414             : 
     415         896 :                 uno::Sequence< sal_Int32 > aAttributedDataPointIndexList;
     416         448 :                 if( xSeriesProp->getPropertyValue( "AttributedDataPoints" ) >>= aAttributedDataPointIndexList )
     417         896 :                     for(sal_Int32 nN=aAttributedDataPointIndexList.getLength();nN--;)
     418         448 :                         lcl_ensureCorrectLabelPlacement( xSeries->getDataPointByIndex(aAttributedDataPointIndexList[nN]), aAvailablePlacements );
     419         448 :             }
     420             :         }
     421           0 :         catch( const uno::Exception & ex )
     422             :         {
     423             :             ASSERT_EXCEPTION( ex );
     424             :         }
     425         448 :     }
     426         448 : }
     427             : 
     428         316 : 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         316 :         DiagramHelper::getDataSeriesGroups( xDiagram ));
     434         632 :     for( sal_Int32 i=0; i<aNewSeriesSeq.getLength(); ++i )
     435             :     {
     436         316 :         const sal_Int32 nNumSeries = aNewSeriesSeq[i].getLength();
     437         762 :         for( sal_Int32 j=0; j<nNumSeries; ++j )
     438         446 :             applyStyle( aNewSeriesSeq[i][j], i, j, nNumSeries );
     439             :     }
     440             : 
     441             :     //ensure valid empty cell handling (for first chart type...)
     442         316 :     lcl_ensureCorrectMissingValueTreatment( xDiagram, getChartTypeForIndex( 0 ) );
     443         316 : }
     444             : 
     445          26 : 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          26 :     bool bPercent = (getStackMode(0) == StackMode_Y_STACKED_PERCENT);
     450          26 :     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          26 :         uno::Reference< XCoordinateSystemContainer > xCooSysContainer( xDiagram, uno::UNO_QUERY );
     471          26 :         if( xCooSysContainer.is() )
     472             :         {
     473          26 :             uno::Sequence< uno::Reference< XCoordinateSystem > > aCooSysList( xCooSysContainer->getCoordinateSystems() );
     474          52 :             for( sal_Int32 nCS = 0; nCS < aCooSysList.getLength(); ++nCS )
     475             :             {
     476          26 :                 uno::Reference< XCoordinateSystem > xCooSys( aCooSysList[nCS] );
     477             : 
     478             :                 //iterate through all chart types in the current coordinate system
     479          52 :                 uno::Reference< XChartTypeContainer > xChartTypeContainer( xCooSys, uno::UNO_QUERY );
     480             :                 OSL_ASSERT( xChartTypeContainer.is());
     481          26 :                 if( !xChartTypeContainer.is() )
     482           0 :                     continue;
     483          52 :                 uno::Sequence< uno::Reference< XChartType > > aChartTypeList( xChartTypeContainer->getChartTypes() );
     484          52 :                 for( sal_Int32 nT = 0; nT < aChartTypeList.getLength(); ++nT )
     485             :                 {
     486          26 :                     uno::Reference< XChartType > xChartType( aChartTypeList[nT] );
     487             : 
     488             :                     //iterate through all series in this chart type
     489          52 :                     uno::Reference< XDataSeriesContainer > xDataSeriesContainer( xChartType, uno::UNO_QUERY );
     490             :                     OSL_ASSERT( xDataSeriesContainer.is());
     491          26 :                     if( !xDataSeriesContainer.is() )
     492           0 :                         continue;
     493             : 
     494          52 :                     uno::Sequence< uno::Reference< XDataSeries > > aSeriesList( xDataSeriesContainer->getDataSeries() );
     495         232 :                     for( sal_Int32 nS = 0; nS < aSeriesList.getLength(); ++nS )
     496             :                     {
     497         206 :                         Reference< XDataSeries > xSeries(aSeriesList[nS]);
     498         412 :                         Reference< beans::XPropertySet > xSeriesProp( xSeries, uno::UNO_QUERY );
     499         206 :                         if(!xSeries.is() || !xSeriesProp.is() )
     500           0 :                             continue;
     501             : 
     502             :                         uno::Sequence < sal_Int32 > aAvailablePlacements( ChartTypeHelper::getSupportedLabelPlacements(
     503         412 :                             xChartType, getDimension(), isSwapXAndY(), xSeries ) );
     504         206 :                         if(!aAvailablePlacements.getLength())
     505           0 :                             continue;
     506             : 
     507         206 :                         sal_Int32 nDefaultPlacement = aAvailablePlacements[0];
     508             : 
     509         206 :                         lcl_resetLabelPlacementIfDefault( xSeriesProp, nDefaultPlacement );
     510             : 
     511         412 :                         uno::Sequence< sal_Int32 > aAttributedDataPointIndexList;
     512         206 :                         if( xSeriesProp->getPropertyValue( "AttributedDataPoints" ) >>= aAttributedDataPointIndexList )
     513         412 :                             for(sal_Int32 nN=aAttributedDataPointIndexList.getLength();nN--;)
     514           0 :                                 lcl_resetLabelPlacementIfDefault( xSeries->getDataPointByIndex(aAttributedDataPointIndexList[nN]), nDefaultPlacement );
     515         206 :                     }
     516          26 :                 }
     517          52 :             }
     518          26 :         }
     519             :     }
     520             : 
     521          26 :     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       43620 : sal_Int32 ChartTypeTemplate::getDimension() const
     532             : {
     533       43620 :     return 2;
     534             : }
     535             : 
     536        2818 : StackMode ChartTypeTemplate::getStackMode( sal_Int32 /* nChartTypeIndex */ ) const
     537             : {
     538        2818 :     return StackMode_NONE;
     539             : }
     540             : 
     541         226 : bool ChartTypeTemplate::isSwapXAndY() const
     542             : {
     543         226 :     return false;
     544             : }
     545             : 
     546         316 : void ChartTypeTemplate::createCoordinateSystems(
     547             :     const Reference< chart2::XCoordinateSystemContainer > & xOutCooSysCnt )
     548             : {
     549         316 :     if( ! xOutCooSysCnt.is())
     550          26 :         return;
     551         316 :     Sequence< Reference< XChartType > > aFormerlyUsedChartTypes;
     552         606 :     Reference< XChartType > xChartType( getChartTypeForNewSeries(aFormerlyUsedChartTypes));
     553         316 :     if( ! xChartType.is())
     554           0 :         return;
     555         606 :     Reference< XCoordinateSystem > xCooSys( xChartType->createCoordinateSystem( getDimension()));
     556         316 :     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         316 :     if( xCooSys->getDimension() >= 2 )
     564             :     {
     565         316 :         Reference< chart2::XAxis > xAxis( xCooSys->getAxisByDimension( 1, 0 ));
     566         316 :         if( xAxis.is())
     567         316 :             AxisHelper::makeGridVisible( xAxis->getGridProperties() );
     568             :     }
     569             : 
     570             :     Sequence< Reference< XCoordinateSystem > > aCoordinateSystems(
     571         606 :         xOutCooSysCnt->getCoordinateSystems());
     572             : 
     573         316 :     if( aCoordinateSystems.getLength())
     574             :     {
     575          30 :         bool bOk = true;
     576          60 :         for( sal_Int32 i=0; bOk && i<aCoordinateSystems.getLength(); ++i )
     577         116 :             bOk = bOk && ( xCooSys->getCoordinateSystemType().equals( aCoordinateSystems[i]->getCoordinateSystemType()) &&
     578          56 :                            (xCooSys->getDimension() == aCoordinateSystems[i]->getDimension()) );
     579             :         // coordinate systems are ok
     580          30 :         if( bOk )
     581          26 :             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         290 :     if( aCoordinateSystems.getLength() )
     587             :     {
     588           4 :         Reference< XCoordinateSystem > xOldCooSys( aCoordinateSystems[0] );
     589           4 :         sal_Int32 nMaxDimensionCount = std::min( xCooSys->getDimension(), xOldCooSys->getDimension() );
     590             : 
     591          12 :         for(sal_Int32 nDimensionIndex=0; nDimensionIndex<nMaxDimensionCount; nDimensionIndex++)
     592             :         {
     593           8 :             const sal_Int32 nMaximumAxisIndex = xOldCooSys->getMaximumAxisIndexByDimension(nDimensionIndex);
     594          16 :             for(sal_Int32 nAxisIndex=0; nAxisIndex<=nMaximumAxisIndex; ++nAxisIndex)
     595             :             {
     596           8 :                 uno::Reference< XAxis > xAxis( xOldCooSys->getAxisByDimension( nDimensionIndex, nAxisIndex ) );
     597           8 :                 if( xAxis.is())
     598             :                 {
     599           8 :                     xCooSys->setAxisByDimension( nDimensionIndex, xAxis, nAxisIndex );
     600             :                 }
     601           8 :             }
     602           4 :         }
     603             :     }
     604             : 
     605             :     // set new coordinate systems
     606         290 :     aCoordinateSystems.realloc( 1 );
     607         290 :     aCoordinateSystems[0] = xCooSys;
     608             : 
     609         580 :     xOutCooSysCnt->setCoordinateSystems( aCoordinateSystems );
     610             : }
     611             : 
     612         316 : 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         316 :     bool bSupportsCategories( supportsCategories() );
     618         632 :     for( sal_Int32 nCooSysIdx=0; nCooSysIdx<aCooSysSeq.getLength(); ++nCooSysIdx )
     619             :     {
     620             :         try
     621             :         {
     622         316 :             Reference< XCoordinateSystem > xCooSys( aCooSysSeq[nCooSysIdx] );
     623         316 :             if( !xCooSys.is() )
     624           0 :                 continue;
     625             : 
     626             :             // attach categories to first axis
     627         316 :             sal_Int32 nDim( xCooSys->getDimension());
     628         316 :             if( nDim > 0 )
     629             :             {
     630         316 :                 const sal_Int32 nDimensionX = 0;
     631         316 :                 const sal_Int32 nMaxIndex = xCooSys->getMaximumAxisIndexByDimension(nDimensionX);
     632         632 :                 for(sal_Int32 nI=0; nI<=nMaxIndex; ++nI)
     633             :                 {
     634         316 :                     Reference< XAxis > xAxis( xCooSys->getAxisByDimension(nDimensionX,nI) );
     635         316 :                     if( xAxis.is())
     636             :                     {
     637         316 :                         ScaleData aData( xAxis->getScaleData() );
     638         316 :                         aData.Categories = xCategories;
     639         316 :                         if(bSupportsCategories)
     640             :                         {
     641             : 
     642         258 :                             Reference< XChartType > xChartType( getChartTypeForNewSeries(Sequence< Reference< XChartType > >() ));
     643         258 :                             bool bSupportsDates = ::chart::ChartTypeHelper::isSupportingDateAxis( xChartType, 2, nDimensionX );
     644         258 :                             if( aData.AxisType != AxisType::CATEGORY && ( aData.AxisType != AxisType::DATE || !bSupportsDates) )
     645             :                             {
     646          34 :                                 aData.AxisType = AxisType::CATEGORY;
     647          34 :                                 aData.AutoDateAxis = true;
     648          34 :                                 AxisHelper::removeExplicitScaling( aData );
     649         258 :                             }
     650             :                         }
     651             :                         else
     652          58 :                             aData.AxisType = AxisType::REALNUMBER;
     653             : 
     654         316 :                         xAxis->setScaleData( aData );
     655             :                     }
     656         316 :                 }
     657             :             }
     658             :             // set percent stacking mode at second axis
     659         316 :             if( nDim > 1 )
     660             :             {
     661         316 :                 const sal_Int32 nMaxIndex = xCooSys->getMaximumAxisIndexByDimension(1);
     662         632 :                 for(sal_Int32 nI=0; nI<=nMaxIndex; ++nI)
     663             :                 {
     664         316 :                     Reference< chart2::XAxis > xAxis( xCooSys->getAxisByDimension( 1,nI ));
     665         316 :                     if( xAxis.is())
     666             :                     {
     667         316 :                         bool bPercent = (getStackMode(0) == StackMode_Y_STACKED_PERCENT);
     668         316 :                         chart2::ScaleData aScaleData = xAxis->getScaleData();
     669             : 
     670         316 :                         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         316 :                         }
     678             :                     }
     679         316 :                 }
     680         316 :             }
     681             :         }
     682           0 :         catch( const uno::Exception & ex )
     683             :         {
     684             :             ASSERT_EXCEPTION( ex );
     685             :         }
     686             :     }
     687         316 : }
     688             : 
     689         284 : void ChartTypeTemplate::adaptDiagram( const Reference< XDiagram > & /* xDiagram */ )
     690             : {
     691         284 :     return;
     692             : }
     693             : 
     694         316 : void ChartTypeTemplate::createAxes(
     695             :     const Sequence< Reference< XCoordinateSystem > > & rCoordSys )
     696             : {
     697             :     //create missing axes
     698         316 :     if( rCoordSys.getLength() > 0 )
     699             :     {
     700         316 :         sal_Int32 nCooSysIdx = 0;
     701         316 :         Reference< XCoordinateSystem > xCooSys( rCoordSys[nCooSysIdx] );
     702         316 :         if(!xCooSys.is())
     703         316 :             return;
     704             : 
     705             :         //create main axis in first coordinate system
     706         316 :         sal_Int32 nDimCount = xCooSys->getDimension();
     707         316 :         sal_Int32 nDim=0;
     708         948 :         for( nDim=0; nDim<nDimCount; ++nDim )
     709             :         {
     710         632 :             sal_Int32 nAxisCount = getAxisCountByDimension( nDim );
     711         948 :             if( nDim == 1 &&
     712         948 :                 nAxisCount < 2 && AxisHelper::isSecondaryYAxisNeeded( xCooSys ))
     713           0 :                 nAxisCount = 2;
     714        1200 :             for( sal_Int32 nAxisIndex = 0; nAxisIndex < nAxisCount; ++nAxisIndex )
     715             :             {
     716         568 :                 Reference< XAxis > xAxis = AxisHelper::getAxis( nDim, nAxisIndex, xCooSys );
     717         568 :                 if( !xAxis.is())
     718             :                 {
     719             :                     // create and add axis
     720             :                     xAxis.set( AxisHelper::createAxis(
     721           0 :                                    nDim, nAxisIndex, xCooSys, GetComponentContext() ));
     722             :                 }
     723         568 :             }
     724         316 :         }
     725             :     }
     726             : }
     727             : 
     728         284 : void ChartTypeTemplate::adaptAxes(
     729             :     const Sequence< Reference< XCoordinateSystem > > & rCoordSys )
     730             : {
     731             :     //adapt properties of exsisting axes and remove superfluous axes
     732             : 
     733         284 :     if( rCoordSys.getLength() > 0 )
     734             :     {
     735         568 :         for( sal_Int32 nCooSysIdx=0; nCooSysIdx < rCoordSys.getLength(); ++nCooSysIdx )
     736             :         {
     737         284 :             Reference< XCoordinateSystem > xCooSys( rCoordSys[nCooSysIdx] );
     738         284 :             if( !xCooSys.is() )
     739           0 :                 continue;
     740         284 :             sal_Int32 nDimCount = xCooSys->getDimension();
     741         852 :             for( sal_Int32 nDim=0; nDim<nDimCount; ++nDim )
     742             :             {
     743         568 :                 sal_Int32 nMaxAxisIndex = xCooSys->getMaximumAxisIndexByDimension( nDim );
     744        1136 :                 for( sal_Int32 nAxisIndex=0; nAxisIndex<=nMaxAxisIndex; nAxisIndex++ )
     745             :                 {
     746         568 :                     Reference< XAxis > xAxis( AxisHelper::getAxis( nDim, nAxisIndex, xCooSys ) );
     747         568 :                     if( !xAxis.is() )
     748           0 :                         continue;
     749             : 
     750         568 :                     if( nAxisIndex == MAIN_AXIS_INDEX || nAxisIndex == SECONDARY_AXIS_INDEX )
     751             :                     {
     752             :                         // adapt scales
     753         568 :                         bool bPercent = (getStackMode(0) == StackMode_Y_STACKED_PERCENT);
     754         568 :                         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         568 :                 }
     766             :             }
     767         284 :         }
     768             :     }
     769         284 : }
     770             : 
     771         544 : sal_Int32 ChartTypeTemplate::getAxisCountByDimension( sal_Int32 nDimension )
     772             : {
     773         544 :     return (nDimension < getDimension()) ? 1 : 0;
     774             : }
     775             : 
     776         316 : 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         316 :     adaptDiagram( xDiagram );
     784             : 
     785             :     try
     786             :     {
     787             :         // create coordinate systems and scales
     788         316 :         Reference< XCoordinateSystemContainer > xCoordSysCnt( xDiagram, uno::UNO_QUERY_THROW );
     789         316 :         createCoordinateSystems( xCoordSysCnt );
     790         632 :         Sequence< Reference< XCoordinateSystem > > aCoordinateSystems( xCoordSysCnt->getCoordinateSystems());
     791         316 :         createAxes( aCoordinateSystems );
     792         316 :         adaptAxes( aCoordinateSystems );
     793         316 :         adaptScales( aCoordinateSystems, xCategories );
     794             : 
     795             :         // chart types
     796         316 :         createChartTypes( aSeriesSeq, aCoordinateSystems, aOldChartTypesSeq );
     797         632 :         applyStyles( xDiagram );
     798             :     }
     799           0 :     catch( const uno::Exception & ex )
     800             :     {
     801             :         ASSERT_EXCEPTION( ex );
     802             :     }
     803         316 : }
     804             : 
     805         272 : void ChartTypeTemplate::createChartTypes(
     806             :     const Sequence< Sequence< Reference< XDataSeries > > > & aSeriesSeq,
     807             :     const Sequence< Reference< XCoordinateSystem > > & rCoordSys,
     808             :     const Sequence< Reference< XChartType > >& aOldChartTypesSeq )
     809             : {
     810         544 :     if( rCoordSys.getLength() == 0 ||
     811         272 :         ! rCoordSys[0].is() )
     812         272 :         return;
     813             : 
     814             :     try
     815             :     {
     816         272 :         sal_Int32 nCooSysIdx=0;
     817         272 :         Reference< XChartType > xCT;
     818         272 :         if( aSeriesSeq.getLength() == 0 )
     819             :         {
     820             :             // we need a new chart type
     821         212 :             xCT.set( getChartTypeForNewSeries( aOldChartTypesSeq ));
     822         212 :             Reference< XChartTypeContainer > xCTCnt( rCoordSys[nCooSysIdx], uno::UNO_QUERY_THROW );
     823         424 :             Sequence< Reference< XChartType > > aCTSeq( xCTCnt->getChartTypes());
     824         212 :             aCTSeq.realloc( 1 );
     825         212 :             aCTSeq[0] = xCT;
     826         424 :             xCTCnt->setChartTypes( aCTSeq );
     827             :         }
     828             :         else
     829             :         {
     830         120 :             for( sal_Int32 nSeriesIdx=0; nSeriesIdx<aSeriesSeq.getLength(); ++nSeriesIdx )
     831             :             {
     832          60 :                 if( nSeriesIdx == nCooSysIdx )
     833             :                 {
     834             :                     // we need a new chart type
     835          60 :                     xCT.set( getChartTypeForNewSeries( aOldChartTypesSeq ));
     836          60 :                     Reference< XChartTypeContainer > xCTCnt( rCoordSys[nCooSysIdx], uno::UNO_QUERY_THROW );
     837         120 :                     Sequence< Reference< XChartType > > aCTSeq( xCTCnt->getChartTypes());
     838          60 :                     if( aCTSeq.getLength())
     839             :                     {
     840           0 :                         aCTSeq[0] = xCT;
     841           0 :                         xCTCnt->setChartTypes( aCTSeq );
     842             :                     }
     843             :                     else
     844          60 :                         xCTCnt->addChartType( xCT );
     845             : 
     846         120 :                     Reference< chart2::XDataSeriesContainer > xDSCnt( xCT, uno::UNO_QUERY_THROW );
     847         120 :                     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].getConstArray(),
     858           0 :                                  aSeriesSeq[nSeriesIdx].getConstArray() + aSeriesSeq[nSeriesIdx].getLength(),
     859           0 :                                  aNewSeriesSeq.getArray() + nNewStartIndex );
     860           0 :                     xDSCnt->setDataSeries( aNewSeriesSeq );
     861             :                 }
     862             : 
     863             :                 // spread the series over the available coordinate systems
     864          60 :                 if( rCoordSys.getLength() > (nCooSysIdx + 1) )
     865           0 :                     ++nCooSysIdx;
     866             :             }
     867         272 :         }
     868             :     }
     869           0 :     catch( const uno::Exception & ex )
     870             :     {
     871             :         ASSERT_EXCEPTION( ex );
     872             :     }
     873             : }
     874             : 
     875      147962 : void ChartTypeTemplate::copyPropertiesFromOldToNewCoordianteSystem(
     876             :                     const Sequence< Reference< XChartType > > & rOldChartTypesSeq,
     877             :                     const Reference< XChartType > & xNewChartType )
     878             : {
     879      147962 :     Reference< beans::XPropertySet > xDestination( xNewChartType, uno::UNO_QUERY );
     880      147962 :     if( !xDestination.is() )
     881      147962 :         return;
     882             : 
     883      295924 :     OUString aNewChartType( xNewChartType->getChartType() );
     884             : 
     885      295924 :     Reference< beans::XPropertySet > xSource;
     886      147962 :     sal_Int32 nN=0;
     887      147980 :     for( nN=0; nN<rOldChartTypesSeq.getLength();++nN)
     888             :     {
     889          18 :         Reference< XChartType > xOldType( rOldChartTypesSeq[nN] );
     890          18 :         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          18 :     }
     897      147962 :     if( xSource.is() )
     898      147962 :         comphelper::copyProperties( xSource, xDestination );
     899             : }
     900             : 
     901         108 : } //  namespace chart
     902             : 
     903             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10