LCOV - code coverage report
Current view: top level - oox/source/drawingml/chart - seriesconverter.cxx (source / functions) Hit Total Coverage
Test: commit e02a6cb2c3e2b23b203b422e4e0680877f232636 Lines: 0 314 0.0 %
Date: 2014-04-14 Functions: 0 37 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include "oox/drawingml/chart/seriesconverter.hxx"
      21             : 
      22             : #include <com/sun/star/chart/DataLabelPlacement.hpp>
      23             : #include <com/sun/star/chart/ErrorBarStyle.hpp>
      24             : #include <com/sun/star/chart2/DataPointLabel.hpp>
      25             : #include <com/sun/star/chart2/XDataSeries.hpp>
      26             : #include <com/sun/star/chart2/XRegressionCurve.hpp>
      27             : #include <com/sun/star/chart2/XRegressionCurveContainer.hpp>
      28             : #include <com/sun/star/chart2/data/XDataSink.hpp>
      29             : #include <com/sun/star/chart2/data/LabeledDataSequence.hpp>
      30             : #include <basegfx/numeric/ftools.hxx>
      31             : #include "oox/drawingml/chart/datasourceconverter.hxx"
      32             : #include "oox/drawingml/chart/seriesmodel.hxx"
      33             : #include "oox/drawingml/chart/titleconverter.hxx"
      34             : #include "oox/drawingml/chart/typegroupconverter.hxx"
      35             : #include "oox/drawingml/chart/typegroupmodel.hxx"
      36             : #include "oox/helper/containerhelper.hxx"
      37             : 
      38             : namespace oox {
      39             : namespace drawingml {
      40             : namespace chart {
      41             : 
      42             : using namespace ::com::sun::star::beans;
      43             : using namespace ::com::sun::star::chart2;
      44             : using namespace ::com::sun::star::chart2::data;
      45             : using namespace ::com::sun::star::uno;
      46             : 
      47             : namespace {
      48             : 
      49             : /** nastied-up sgn function - employs some gratuity around 0 - values
      50             :    smaller than 0.33 are clamped to 0
      51             :  */
      52           0 : int lclSgn( double nVal )
      53             : {
      54           0 :     const int intVal=nVal*3;
      55           0 :     return intVal == 0 ? 0 : (intVal < 0 ? -1 : 1);
      56             : }
      57             : 
      58           0 : Reference< XLabeledDataSequence > lclCreateLabeledDataSequence(
      59             :         const ConverterRoot& rParent,
      60             :         DataSourceModel* pValues, const OUString& rRole,
      61             :         TextModel* pTitle = 0 )
      62             : {
      63             :     // create data sequence for values
      64           0 :     Reference< XDataSequence > xValueSeq;
      65           0 :     if( pValues )
      66             :     {
      67           0 :         DataSourceConverter aSourceConv( rParent, *pValues );
      68           0 :         xValueSeq = aSourceConv.createDataSequence( rRole );
      69             :     }
      70             : 
      71             :     // create data sequence for title
      72           0 :     Reference< XDataSequence > xTitleSeq;
      73           0 :     if( pTitle )
      74             :     {
      75           0 :         TextConverter aTextConv( rParent, *pTitle );
      76           0 :         xTitleSeq = aTextConv.createDataSequence( "label" );
      77             :     }
      78             : 
      79             :     // create the labeled data sequence, if values or title are present
      80           0 :     Reference< XLabeledDataSequence > xLabeledSeq;
      81           0 :     if( xValueSeq.is() || xTitleSeq.is() )
      82             :     {
      83           0 :         xLabeledSeq.set( LabeledDataSequence::create(rParent.getComponentContext()), UNO_QUERY );
      84           0 :         if( xLabeledSeq.is() )
      85             :         {
      86           0 :             xLabeledSeq->setValues( xValueSeq );
      87           0 :             xLabeledSeq->setLabel( xTitleSeq );
      88             :         }
      89             :     }
      90           0 :     return xLabeledSeq;
      91             : }
      92             : 
      93           0 : void lclConvertLabelFormatting( PropertySet& rPropSet, ObjectFormatter& rFormatter,
      94             :         const DataLabelModelBase& rDataLabel, const TypeGroupConverter& rTypeGroup, bool bDataSeriesLabel )
      95             : {
      96           0 :     const TypeGroupInfo& rTypeInfo = rTypeGroup.getTypeInfo();
      97             : 
      98             :     /*  Excel 2007 does not change the series setting for a single data point,
      99             :         if none of some specific elements occur. But only one existing element
     100             :         in a data point will reset most other of these elements from the series
     101             :         (e.g.: series has <c:showVal>, data point has <c:showCatName>, this
     102             :         will reset <c:showVal> for this point, unless <c:showVal> is repeated
     103             :         in the data point). The elements <c:layout>, <c:numberFormat>,
     104             :         <c:spPr>, <c:tx>, and <c:txPr> are not affected at all. */
     105             :     bool bHasAnyElement =
     106           0 :         rDataLabel.moaSeparator.has() || rDataLabel.monLabelPos.has() ||
     107           0 :         rDataLabel.mobShowCatName.has() || rDataLabel.mobShowLegendKey.has() ||
     108           0 :         rDataLabel.mobShowPercent.has() || rDataLabel.mobShowSerName.has() ||
     109           0 :         rDataLabel.mobShowVal.has();
     110             : 
     111           0 :     bool bShowValue   = !rDataLabel.mbDeleted && rDataLabel.mobShowVal.get( false );
     112           0 :     bool bShowPercent = !rDataLabel.mbDeleted && rDataLabel.mobShowPercent.get( false ) && (rTypeInfo.meTypeCategory == TYPECATEGORY_PIE);
     113           0 :     if( bShowValue &&
     114           0 :         !bShowPercent && rTypeInfo.meTypeCategory == TYPECATEGORY_PIE &&
     115           0 :         rDataLabel.maNumberFormat.maFormatCode.indexOf('%') >= 0 )
     116             :     {
     117           0 :         bShowValue = false;
     118           0 :         bShowPercent = true;
     119             :     }
     120           0 :     bool bShowCateg   = !rDataLabel.mbDeleted && rDataLabel.mobShowCatName.get( false );
     121           0 :     bool bShowSymbol  = !rDataLabel.mbDeleted && rDataLabel.mobShowLegendKey.get( false );
     122             : 
     123             :     // type of attached label
     124           0 :     if( bHasAnyElement || rDataLabel.mbDeleted )
     125             :     {
     126           0 :         DataPointLabel aPointLabel( bShowValue, bShowPercent, bShowCateg, bShowSymbol );
     127           0 :         rPropSet.setProperty( PROP_Label, aPointLabel );
     128             :     }
     129             : 
     130           0 :     if( !rDataLabel.mbDeleted )
     131             :     {
     132             :         // data label number format (percentage format wins over value format)
     133           0 :         rFormatter.convertNumberFormat( rPropSet, rDataLabel.maNumberFormat, bShowPercent );
     134             : 
     135             :         // data label text formatting (frame formatting not supported by Chart2)
     136           0 :         rFormatter.convertTextFormatting( rPropSet, rDataLabel.mxTextProp, OBJECTTYPE_DATALABEL );
     137           0 :         rFormatter.convertTextRotation( rPropSet, rDataLabel.mxTextProp, false );
     138             : 
     139             :         // data label separator (do not overwrite series separator, if no explicit point separator is present)
     140           0 :         if( bDataSeriesLabel || rDataLabel.moaSeparator.has() )
     141           0 :             rPropSet.setProperty( PROP_LabelSeparator, rDataLabel.moaSeparator.get( "; " ) );
     142             : 
     143             :         // data label placement (do not overwrite series placement, if no explicit point placement is present)
     144           0 :         if( bDataSeriesLabel || rDataLabel.monLabelPos.has() )
     145             :         {
     146             :             namespace csscd = ::com::sun::star::chart::DataLabelPlacement;
     147           0 :             sal_Int32 nPlacement = rTypeInfo.mnDefLabelPos;
     148           0 :             switch( rDataLabel.monLabelPos.get( XML_TOKEN_INVALID ) )
     149             :             {
     150           0 :                 case XML_outEnd:    nPlacement = csscd::OUTSIDE;        break;
     151           0 :                 case XML_inEnd:     nPlacement = csscd::INSIDE;         break;
     152           0 :                 case XML_ctr:       nPlacement = csscd::CENTER;         break;
     153           0 :                 case XML_inBase:    nPlacement = csscd::NEAR_ORIGIN;    break;
     154           0 :                 case XML_t:         nPlacement = csscd::TOP;            break;
     155           0 :                 case XML_b:         nPlacement = csscd::BOTTOM;         break;
     156           0 :                 case XML_l:         nPlacement = csscd::LEFT;           break;
     157           0 :                 case XML_r:         nPlacement = csscd::RIGHT;          break;
     158           0 :                 case XML_bestFit:   nPlacement = csscd::AVOID_OVERLAP;  break;
     159             :             }
     160           0 :             rPropSet.setProperty( PROP_LabelPlacement, nPlacement );
     161             :         }
     162             :     }
     163           0 : }
     164             : 
     165             : } // namespace
     166             : 
     167           0 : DataLabelConverter::DataLabelConverter( const ConverterRoot& rParent, DataLabelModel& rModel ) :
     168           0 :     ConverterBase< DataLabelModel >( rParent, rModel )
     169             : {
     170           0 : }
     171             : 
     172           0 : DataLabelConverter::~DataLabelConverter()
     173             : {
     174           0 : }
     175             : 
     176           0 : void DataLabelConverter::convertFromModel( const Reference< XDataSeries >& rxDataSeries, const TypeGroupConverter& rTypeGroup )
     177             : {
     178           0 :     if( rxDataSeries.is() ) try
     179             :     {
     180           0 :         PropertySet aPropSet( rxDataSeries->getDataPointByIndex( mrModel.mnIndex ) );
     181           0 :         lclConvertLabelFormatting( aPropSet, getFormatter(), mrModel, rTypeGroup, false );
     182           0 :         const TypeGroupInfo& rTypeInfo = rTypeGroup.getTypeInfo();
     183           0 :         bool bIsPie = rTypeInfo.meTypeCategory == TYPECATEGORY_PIE;
     184           0 :         if( mrModel.mxLayout && !mrModel.mxLayout->mbAutoLayout && !bIsPie )
     185             :         {
     186             :             // bnc#694340 - nasty hack - chart2 cannot individually
     187             :             // place data labels, let's try to find a useful
     188             :             // compromise instead
     189             :             namespace csscd = ::com::sun::star::chart::DataLabelPlacement;
     190             :             const sal_Int32 aPositionsLookupTable[] =
     191             :                 {
     192             :                     csscd::TOP_LEFT,    csscd::TOP,    csscd::TOP_RIGHT,
     193             :                     csscd::LEFT,        csscd::CENTER, csscd::RIGHT,
     194             :                     csscd::BOTTOM_LEFT, csscd::BOTTOM, csscd::BOTTOM_RIGHT
     195           0 :                 };
     196             :             const double nMax=std::max(
     197           0 :                 fabs(mrModel.mxLayout->mfX),
     198           0 :                 fabs(mrModel.mxLayout->mfY));
     199           0 :             const int simplifiedX=lclSgn(mrModel.mxLayout->mfX/nMax);
     200           0 :             const int simplifiedY=lclSgn(mrModel.mxLayout->mfY/nMax);
     201             :             aPropSet.setProperty( PROP_LabelPlacement,
     202           0 :                                   aPositionsLookupTable[ simplifiedX+1 + 3*(simplifiedY+1) ] );
     203           0 :         }
     204             :     }
     205           0 :     catch( Exception& )
     206             :     {
     207             :     }
     208           0 : }
     209             : 
     210           0 : DataLabelsConverter::DataLabelsConverter( const ConverterRoot& rParent, DataLabelsModel& rModel ) :
     211           0 :     ConverterBase< DataLabelsModel >( rParent, rModel )
     212             : {
     213           0 : }
     214             : 
     215           0 : DataLabelsConverter::~DataLabelsConverter()
     216             : {
     217           0 : }
     218             : 
     219           0 : void DataLabelsConverter::convertFromModel( const Reference< XDataSeries >& rxDataSeries, const TypeGroupConverter& rTypeGroup )
     220             : {
     221           0 :     if( !mrModel.mbDeleted )
     222             :     {
     223           0 :         PropertySet aPropSet( rxDataSeries );
     224           0 :         lclConvertLabelFormatting( aPropSet, getFormatter(), mrModel, rTypeGroup, true );
     225             :     }
     226             : 
     227             :     // data point label settings
     228           0 :     for( DataLabelsModel::DataLabelVector::iterator aIt = mrModel.maPointLabels.begin(), aEnd = mrModel.maPointLabels.end(); aIt != aEnd; ++aIt )
     229             :     {
     230           0 :         (*aIt)->maNumberFormat.maFormatCode = mrModel.maNumberFormat.maFormatCode;
     231           0 :         if( !mrModel.maNumberFormat.maFormatCode.isEmpty() )
     232           0 :             (*aIt)->maNumberFormat.mbSourceLinked = false;
     233             : 
     234           0 :         DataLabelConverter aLabelConv( *this, **aIt );
     235           0 :         aLabelConv.convertFromModel( rxDataSeries, rTypeGroup );
     236           0 :     }
     237           0 : }
     238             : 
     239           0 : ErrorBarConverter::ErrorBarConverter( const ConverterRoot& rParent, ErrorBarModel& rModel ) :
     240           0 :     ConverterBase< ErrorBarModel >( rParent, rModel )
     241             : {
     242           0 : }
     243             : 
     244           0 : ErrorBarConverter::~ErrorBarConverter()
     245             : {
     246           0 : }
     247             : 
     248           0 : void ErrorBarConverter::convertFromModel( const Reference< XDataSeries >& rxDataSeries )
     249             : {
     250           0 :     bool bShowPos = (mrModel.mnTypeId == XML_plus) || (mrModel.mnTypeId == XML_both);
     251           0 :     bool bShowNeg = (mrModel.mnTypeId == XML_minus) || (mrModel.mnTypeId == XML_both);
     252           0 :     if( bShowPos || bShowNeg ) try
     253             :     {
     254           0 :         Reference< XPropertySet > xErrorBar( createInstance( "com.sun.star.chart2.ErrorBar" ), UNO_QUERY_THROW );
     255           0 :         PropertySet aBarProp( xErrorBar );
     256             : 
     257             :         // plus/minus bars
     258           0 :         aBarProp.setProperty( PROP_ShowPositiveError, bShowPos );
     259           0 :         aBarProp.setProperty( PROP_ShowNegativeError, bShowNeg );
     260             : 
     261             :         // type of displayed error
     262             :         namespace cssc = ::com::sun::star::chart;
     263           0 :         switch( mrModel.mnValueType )
     264             :         {
     265             :             case XML_cust:
     266             :             {
     267             :                 // #i87806# manual error bars
     268           0 :                 aBarProp.setProperty( PROP_ErrorBarStyle, cssc::ErrorBarStyle::FROM_DATA );
     269             :                 // attach data sequences to erorr bar
     270           0 :                 Reference< XDataSink > xDataSink( xErrorBar, UNO_QUERY );
     271           0 :                 if( xDataSink.is() )
     272             :                 {
     273             :                     // create vector of all value sequences
     274           0 :                     ::std::vector< Reference< XLabeledDataSequence > > aLabeledSeqVec;
     275             :                     // add positive values
     276           0 :                     if( bShowPos )
     277             :                     {
     278           0 :                         Reference< XLabeledDataSequence > xValueSeq = createLabeledDataSequence( ErrorBarModel::PLUS );
     279           0 :                         if( xValueSeq.is() )
     280           0 :                             aLabeledSeqVec.push_back( xValueSeq );
     281             :                     }
     282             :                     // add negative values
     283           0 :                     if( bShowNeg )
     284             :                     {
     285           0 :                         Reference< XLabeledDataSequence > xValueSeq = createLabeledDataSequence( ErrorBarModel::MINUS );
     286           0 :                         if( xValueSeq.is() )
     287           0 :                             aLabeledSeqVec.push_back( xValueSeq );
     288             :                     }
     289             :                     // attach labeled data sequences to series
     290           0 :                     if( aLabeledSeqVec.empty() )
     291           0 :                         xErrorBar.clear();
     292             :                     else
     293           0 :                         xDataSink->setData( ContainerHelper::vectorToSequence( aLabeledSeqVec ) );
     294           0 :                 }
     295             :             }
     296           0 :             break;
     297             :             case XML_fixedVal:
     298           0 :                 aBarProp.setProperty( PROP_ErrorBarStyle, cssc::ErrorBarStyle::ABSOLUTE );
     299           0 :                 aBarProp.setProperty( PROP_PositiveError, mrModel.mfValue );
     300           0 :                 aBarProp.setProperty( PROP_NegativeError, mrModel.mfValue );
     301           0 :             break;
     302             :             case XML_percentage:
     303           0 :                 aBarProp.setProperty( PROP_ErrorBarStyle, cssc::ErrorBarStyle::RELATIVE );
     304           0 :                 aBarProp.setProperty( PROP_PositiveError, mrModel.mfValue );
     305           0 :                 aBarProp.setProperty( PROP_NegativeError, mrModel.mfValue );
     306           0 :             break;
     307             :             case XML_stdDev:
     308           0 :                 aBarProp.setProperty( PROP_ErrorBarStyle, cssc::ErrorBarStyle::STANDARD_DEVIATION );
     309           0 :                 aBarProp.setProperty( PROP_Weight, mrModel.mfValue );
     310           0 :             break;
     311             :             case XML_stdErr:
     312           0 :                 aBarProp.setProperty( PROP_ErrorBarStyle, cssc::ErrorBarStyle::STANDARD_ERROR );
     313           0 :             break;
     314             :             default:
     315             :                 OSL_FAIL( "ErrorBarConverter::convertFromModel - unknown error bar type" );
     316           0 :                 xErrorBar.clear();
     317             :         }
     318             : 
     319             :         // error bar formatting
     320           0 :         getFormatter().convertFrameFormatting( aBarProp, mrModel.mxShapeProp, OBJECTTYPE_ERRORBAR );
     321             : 
     322           0 :         if( xErrorBar.is() )
     323             :         {
     324           0 :             PropertySet aSeriesProp( rxDataSeries );
     325           0 :             switch( mrModel.mnDirection )
     326             :             {
     327           0 :                 case XML_x: aSeriesProp.setProperty( PROP_ErrorBarX, xErrorBar );   break;
     328           0 :                 case XML_y: aSeriesProp.setProperty( PROP_ErrorBarY, xErrorBar );   break;
     329             :                 default:    OSL_FAIL( "ErrorBarConverter::convertFromModel - invalid error bar direction" );
     330           0 :             }
     331           0 :         }
     332             :     }
     333           0 :     catch( Exception& )
     334             :     {
     335             :         OSL_FAIL( "ErrorBarConverter::convertFromModel - error while creating error bars" );
     336             :     }
     337           0 : }
     338             : 
     339           0 : Reference< XLabeledDataSequence > ErrorBarConverter::createLabeledDataSequence( ErrorBarModel::SourceType eSourceType )
     340             : {
     341           0 :     OUString aRole;
     342           0 :     switch( eSourceType )
     343             :     {
     344             :         case ErrorBarModel::PLUS:
     345           0 :             switch( mrModel.mnDirection )
     346             :             {
     347           0 :                 case XML_x: aRole = "error-bars-x-positive"; break;
     348           0 :                 case XML_y: aRole = "error-bars-y-positive"; break;
     349             :             }
     350           0 :         break;
     351             :         case ErrorBarModel::MINUS:
     352           0 :             switch( mrModel.mnDirection )
     353             :             {
     354           0 :                 case XML_x: aRole = "error-bars-x-negative"; break;
     355           0 :                 case XML_y: aRole = "error-bars-y-negative"; break;
     356             :             }
     357           0 :         break;
     358             :     }
     359             :     OSL_ENSURE( !aRole.isEmpty(), "ErrorBarConverter::createLabeledDataSequence - invalid error bar direction" );
     360           0 :     return lclCreateLabeledDataSequence( *this, mrModel.maSources.get( eSourceType ).get(), aRole );
     361             : }
     362             : 
     363           0 : TrendlineLabelConverter::TrendlineLabelConverter( const ConverterRoot& rParent, TrendlineLabelModel& rModel ) :
     364           0 :     ConverterBase< TrendlineLabelModel >( rParent, rModel )
     365             : {
     366           0 : }
     367             : 
     368           0 : TrendlineLabelConverter::~TrendlineLabelConverter()
     369             : {
     370           0 : }
     371             : 
     372           0 : void TrendlineLabelConverter::convertFromModel( PropertySet& rPropSet )
     373             : {
     374             :     // formatting
     375           0 :     getFormatter().convertFormatting( rPropSet, mrModel.mxShapeProp, mrModel.mxTextProp, OBJECTTYPE_TRENDLINELABEL );
     376           0 : }
     377             : 
     378           0 : TrendlineConverter::TrendlineConverter( const ConverterRoot& rParent, TrendlineModel& rModel ) :
     379           0 :     ConverterBase< TrendlineModel >( rParent, rModel )
     380             : {
     381           0 : }
     382             : 
     383           0 : TrendlineConverter::~TrendlineConverter()
     384             : {
     385           0 : }
     386             : 
     387           0 : void TrendlineConverter::convertFromModel( const Reference< XDataSeries >& rxDataSeries )
     388             : {
     389             :     try
     390             :     {
     391             :         // trend line type
     392           0 :         OUString aServiceName;
     393           0 :         switch( mrModel.mnTypeId )
     394             :         {
     395             :             case XML_exp:
     396           0 :                 aServiceName = "com.sun.star.chart2.ExponentialRegressionCurve";
     397           0 :             break;
     398             :             case XML_linear:
     399           0 :                 aServiceName = "com.sun.star.chart2.LinearRegressionCurve";
     400           0 :             break;
     401             :             case XML_log:
     402           0 :                 aServiceName = "com.sun.star.chart2.LogarithmicRegressionCurve";
     403           0 :             break;
     404             :             case XML_movingAvg:
     405           0 :                 aServiceName = "com.sun.star.chart2.MovingAverageRegressionCurve";
     406           0 :             break;
     407             :             case XML_poly:
     408           0 :                 aServiceName = "com.sun.star.chart2.PolynomialRegressionCurve";
     409           0 :             break;
     410             :             case XML_power:
     411           0 :                 aServiceName = "com.sun.star.chart2.PotentialRegressionCurve";
     412           0 :             break;
     413             :             default:
     414             :                 OSL_FAIL( "TrendlineConverter::convertFromModel - unknown trendline type" );
     415             :         }
     416           0 :         if( !aServiceName.isEmpty() )
     417             :         {
     418           0 :             Reference< XRegressionCurve > xRegCurve( createInstance( aServiceName ), UNO_QUERY_THROW );
     419           0 :             PropertySet aPropSet( xRegCurve );
     420             : 
     421             :             // Name
     422           0 :             aPropSet.setProperty( PROP_CurveName, mrModel.maName );
     423           0 :             aPropSet.setProperty( PROP_PolynomialDegree, mrModel.mnOrder );
     424           0 :             aPropSet.setProperty( PROP_MovingAveragePeriod, mrModel.mnPeriod );
     425             : 
     426             :             // Intercept
     427           0 :             sal_Bool hasIntercept = mrModel.mfIntercept.has();
     428           0 :             aPropSet.setProperty( PROP_ForceIntercept, hasIntercept);
     429           0 :             if (hasIntercept)
     430           0 :                 aPropSet.setProperty( PROP_InterceptValue,  mrModel.mfIntercept.get());
     431             : 
     432             :             // Extrapolation
     433           0 :             if (mrModel.mfForward.has())
     434           0 :                 aPropSet.setProperty( PROP_ExtrapolateForward, mrModel.mfForward.get() );
     435           0 :             if (mrModel.mfBackward.has())
     436           0 :                 aPropSet.setProperty( PROP_ExtrapolateBackward, mrModel.mfBackward.get() );
     437             : 
     438             :             // trendline formatting
     439           0 :             getFormatter().convertFrameFormatting( aPropSet, mrModel.mxShapeProp, OBJECTTYPE_TRENDLINE );
     440             : 
     441             :             // #i83100# show equation and correlation coefficient
     442           0 :             PropertySet aLabelProp( xRegCurve->getEquationProperties() );
     443           0 :             aLabelProp.setProperty( PROP_ShowEquation, mrModel.mbDispEquation );
     444           0 :             aLabelProp.setProperty( PROP_ShowCorrelationCoefficient, mrModel.mbDispRSquared );
     445             : 
     446             :             // #i83100# formatting of the equation text box
     447           0 :             if( mrModel.mbDispEquation || mrModel.mbDispRSquared )
     448             :             {
     449           0 :                 TrendlineLabelConverter aLabelConv( *this, mrModel.mxLabel.getOrCreate() );
     450           0 :                 aLabelConv.convertFromModel( aLabelProp );
     451             :             }
     452             : 
     453             :             // unsupported: #i5085# manual trendline size
     454             :             // unsupported: #i34093# manual crossing point
     455             : 
     456           0 :             Reference< XRegressionCurveContainer > xRegCurveCont( rxDataSeries, UNO_QUERY_THROW );
     457           0 :             xRegCurveCont->addRegressionCurve( xRegCurve );
     458           0 :         }
     459             :     }
     460           0 :     catch( Exception& )
     461             :     {
     462             :         OSL_FAIL( "TrendlineConverter::convertFromModel - error while creating trendline" );
     463             :     }
     464           0 : }
     465             : 
     466           0 : DataPointConverter::DataPointConverter( const ConverterRoot& rParent, DataPointModel& rModel ) :
     467           0 :     ConverterBase< DataPointModel >( rParent, rModel )
     468             : {
     469           0 : }
     470             : 
     471           0 : DataPointConverter::~DataPointConverter()
     472             : {
     473           0 : }
     474             : 
     475           0 : void DataPointConverter::convertFromModel( const Reference< XDataSeries >& rxDataSeries,
     476             :         const TypeGroupConverter& rTypeGroup, const SeriesModel& rSeries )
     477             : {
     478             :     try
     479             :     {
     480           0 :         PropertySet aPropSet( rxDataSeries->getDataPointByIndex( mrModel.mnIndex ) );
     481             : 
     482             :         // data point marker
     483           0 :         if( mrModel.monMarkerSymbol.differsFrom( rSeries.mnMarkerSymbol ) || mrModel.monMarkerSize.differsFrom( rSeries.mnMarkerSize ) )
     484           0 :             rTypeGroup.convertMarker( aPropSet, mrModel.monMarkerSymbol.get( rSeries.mnMarkerSymbol ),
     485           0 :                     mrModel.monMarkerSize.get( rSeries.mnMarkerSize ), mrModel.mxMarkerProp );
     486             : 
     487             :         // data point pie explosion
     488           0 :         if( mrModel.monExplosion.differsFrom( rSeries.mnExplosion ) )
     489           0 :             rTypeGroup.convertPieExplosion( aPropSet, mrModel.monExplosion.get() );
     490             : 
     491             :         // point formatting
     492           0 :         if( mrModel.mxShapeProp.is() )
     493             :         {
     494           0 :             if( rTypeGroup.getTypeInfo().mbPictureOptions )
     495           0 :                 getFormatter().convertFrameFormatting( aPropSet, mrModel.mxShapeProp, mrModel.mxPicOptions.getOrCreate(), rTypeGroup.getSeriesObjectType(), rSeries.mnIndex );
     496             :             else
     497           0 :                 getFormatter().convertFrameFormatting( aPropSet, mrModel.mxShapeProp, rTypeGroup.getSeriesObjectType(), rSeries.mnIndex );
     498           0 :         }
     499             :     }
     500           0 :     catch( Exception& )
     501             :     {
     502             :     }
     503           0 : }
     504             : 
     505           0 : SeriesConverter::SeriesConverter( const ConverterRoot& rParent, SeriesModel& rModel ) :
     506           0 :     ConverterBase< SeriesModel >( rParent, rModel )
     507             : {
     508           0 : }
     509             : 
     510           0 : SeriesConverter::~SeriesConverter()
     511             : {
     512           0 : }
     513             : 
     514           0 : Reference< XLabeledDataSequence > SeriesConverter::createCategorySequence( const OUString& rRole )
     515             : {
     516           0 :     return createLabeledDataSequence( SeriesModel::CATEGORIES, rRole, false );
     517             : }
     518             : 
     519           0 : Reference< XLabeledDataSequence > SeriesConverter::createValueSequence( const OUString& rRole )
     520             : {
     521           0 :     return createLabeledDataSequence( SeriesModel::VALUES, rRole, true );
     522             : }
     523             : 
     524           0 : Reference< XDataSeries > SeriesConverter::createDataSeries( const TypeGroupConverter& rTypeGroup, bool bVaryColorsByPoint )
     525             : {
     526           0 :     const TypeGroupInfo& rTypeInfo = rTypeGroup.getTypeInfo();
     527             : 
     528             :     // create the data series object
     529           0 :     Reference< XDataSeries > xDataSeries( createInstance( "com.sun.star.chart2.DataSeries" ), UNO_QUERY );
     530           0 :     PropertySet aSeriesProp( xDataSeries );
     531             : 
     532             :     // attach data and title sequences to series
     533           0 :     sal_Int32 nDataPointCount = 0;
     534           0 :     Reference< XDataSink > xDataSink( xDataSeries, UNO_QUERY );
     535           0 :     if( xDataSink.is() )
     536             :     {
     537             :         // create vector of all value sequences
     538           0 :         ::std::vector< Reference< XLabeledDataSequence > > aLabeledSeqVec;
     539             :         // add Y values
     540           0 :         Reference< XLabeledDataSequence > xYValueSeq = createValueSequence( "values-y" );
     541           0 :         if( xYValueSeq.is() )
     542             :         {
     543           0 :             aLabeledSeqVec.push_back( xYValueSeq );
     544           0 :             Reference< XDataSequence > xValues = xYValueSeq->getValues();
     545           0 :             if( xValues.is() )
     546           0 :                 nDataPointCount = xValues->getData().getLength();
     547             :         }
     548             :         // add X values of scatter and bubble charts
     549           0 :         if( !rTypeInfo.mbCategoryAxis )
     550             :         {
     551           0 :             Reference< XLabeledDataSequence > xXValueSeq = createCategorySequence( "values-x" );
     552           0 :             if( xXValueSeq.is() )
     553           0 :                 aLabeledSeqVec.push_back( xXValueSeq );
     554             :             // add size values of bubble charts
     555           0 :             if( rTypeInfo.meTypeId == TYPEID_BUBBLE )
     556             :             {
     557           0 :                 Reference< XLabeledDataSequence > xSizeValueSeq = createLabeledDataSequence( SeriesModel::POINTS, "values-size", true );
     558           0 :                 if( xSizeValueSeq.is() )
     559           0 :                     aLabeledSeqVec.push_back( xSizeValueSeq );
     560           0 :             }
     561             :         }
     562             :         // attach labeled data sequences to series
     563           0 :         if( !aLabeledSeqVec.empty() )
     564           0 :             xDataSink->setData( ContainerHelper::vectorToSequence( aLabeledSeqVec ) );
     565             :     }
     566             : 
     567             :     // error bars
     568           0 :     for( SeriesModel::ErrorBarVector::iterator aIt = mrModel.maErrorBars.begin(), aEnd = mrModel.maErrorBars.end(); aIt != aEnd; ++aIt )
     569             :     {
     570           0 :         ErrorBarConverter aErrorBarConv( *this, **aIt );
     571           0 :         aErrorBarConv.convertFromModel( xDataSeries );
     572           0 :     }
     573             : 
     574             :     // trendlines
     575           0 :     for( SeriesModel::TrendlineVector::iterator aIt = mrModel.maTrendlines.begin(), aEnd = mrModel.maTrendlines.end(); aIt != aEnd; ++aIt )
     576             :     {
     577           0 :         TrendlineConverter aTrendlineConv( *this, **aIt );
     578           0 :         aTrendlineConv.convertFromModel( xDataSeries );
     579           0 :     }
     580             : 
     581             :     // data point markers
     582           0 :     rTypeGroup.convertMarker( aSeriesProp, mrModel.mnMarkerSymbol, mrModel.mnMarkerSize, mrModel.mxMarkerProp );
     583             : #if OOX_CHART_SMOOTHED_PER_SERIES
     584             :     // #i66858# smoothed series lines
     585             :     rTypeGroup.convertLineSmooth( aSeriesProp, mrModel.mbSmooth );
     586             : #endif
     587             :     // 3D bar style (not possible to set at chart type -> set at all series)
     588           0 :     rTypeGroup.convertBarGeometry( aSeriesProp, mrModel.monShape.get( rTypeGroup.getModel().mnShape ) );
     589             :     // pie explosion (restricted to [0%,100%] in Chart2)
     590           0 :     rTypeGroup.convertPieExplosion( aSeriesProp, mrModel.mnExplosion );
     591             : 
     592             :     // series formatting
     593           0 :     ObjectFormatter& rFormatter = getFormatter();
     594           0 :     ObjectType eObjType = rTypeGroup.getSeriesObjectType();
     595           0 :     if( rTypeInfo.mbPictureOptions )
     596           0 :         rFormatter.convertFrameFormatting( aSeriesProp, mrModel.mxShapeProp, mrModel.mxPicOptions.getOrCreate(), eObjType, mrModel.mnIndex );
     597             :     else
     598           0 :         rFormatter.convertFrameFormatting( aSeriesProp, mrModel.mxShapeProp, eObjType, mrModel.mnIndex );
     599             : 
     600             :     // set the (unused) property default value used by the Chart2 templates (true for pie/doughnut charts)
     601           0 :     bool bIsPie = rTypeInfo.meTypeCategory == TYPECATEGORY_PIE;
     602           0 :     aSeriesProp.setProperty( PROP_VaryColorsByPoint, bIsPie );
     603             : 
     604             :     // own area formatting for every data point (TODO: varying line color not supported)
     605             :     // #i91271# always set area formatting for every point in pie/doughnut charts to override their automatic point formatting
     606           0 :     if( bIsPie || (bVaryColorsByPoint && rTypeGroup.isSeriesFrameFormat() && ObjectFormatter::isAutomaticFill( mrModel.mxShapeProp )) )
     607             :     {
     608             :         /*  Set the series point number as color cycle size at the object
     609             :             formatter to get correct start-shade/end-tint. TODO: in doughnut
     610             :             charts, the sizes of the series may vary, need to use the maximum
     611             :             point count of all series. */
     612           0 :         sal_Int32 nOldMax = rFormatter.getMaxSeriesIndex();
     613           0 :         if( bVaryColorsByPoint )
     614           0 :             rFormatter.setMaxSeriesIndex( nDataPointCount - 1 );
     615           0 :         for( sal_Int32 nIndex = 0; nIndex < nDataPointCount; ++nIndex )
     616             :         {
     617             :             try
     618             :             {
     619           0 :                 PropertySet aPointProp( xDataSeries->getDataPointByIndex( nIndex ) );
     620           0 :                 rFormatter.convertAutomaticFill( aPointProp, eObjType, bVaryColorsByPoint ? nIndex : mrModel.mnIndex );
     621             :             }
     622           0 :             catch( Exception& )
     623             :             {
     624             :             }
     625             :         }
     626           0 :         rFormatter.setMaxSeriesIndex( nOldMax );
     627             :     }
     628             : 
     629             :     // data point settings
     630           0 :     for( SeriesModel::DataPointVector::iterator aIt = mrModel.maPoints.begin(), aEnd = mrModel.maPoints.end(); aIt != aEnd; ++aIt )
     631             :     {
     632           0 :         DataPointConverter aPointConv( *this, **aIt );
     633           0 :         aPointConv.convertFromModel( xDataSeries, rTypeGroup, mrModel );
     634           0 :     }
     635             : 
     636             :     /*  Series data label settings. If and only if the series does not contain
     637             :         a c:dLbls element, then the c:dLbls element of the parent chart type is
     638             :         used (data label settings of the parent chart type are *not* merged
     639             :         into own existing data label settings). */
     640           0 :     ModelRef< DataLabelsModel > xLabels = mrModel.mxLabels.is() ? mrModel.mxLabels : rTypeGroup.getModel().mxLabels;
     641           0 :     if( xLabels.is() )
     642             :     {
     643           0 :         if( xLabels->maNumberFormat.maFormatCode.isEmpty() )
     644             :         {
     645             :             // Use number format code from Value series
     646           0 :             DataSourceModel* pValues = mrModel.maSources.get( SeriesModel::VALUES ).get();
     647           0 :             if( pValues )
     648           0 :                 xLabels->maNumberFormat.maFormatCode = pValues->mxDataSeq->maFormatCode;
     649             :         }
     650           0 :         DataLabelsConverter aLabelsConv( *this, *xLabels );
     651           0 :         aLabelsConv.convertFromModel( xDataSeries, rTypeGroup );
     652             :     }
     653             : 
     654           0 :     return xDataSeries;
     655             : }
     656             : 
     657             : // private --------------------------------------------------------------------
     658             : 
     659           0 : Reference< XLabeledDataSequence > SeriesConverter::createLabeledDataSequence(
     660             :         SeriesModel::SourceType eSourceType, const OUString& rRole, bool bUseTextLabel )
     661             : {
     662           0 :     DataSourceModel* pValues = mrModel.maSources.get( eSourceType ).get();
     663           0 :     TextModel* pTitle = bUseTextLabel ? mrModel.mxText.get() : 0;
     664           0 :     return lclCreateLabeledDataSequence( *this, pValues, rRole, pTitle );
     665             : }
     666             : 
     667             : } // namespace chart
     668             : } // namespace drawingml
     669           0 : } // namespace oox
     670             : 
     671             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10