LCOV - code coverage report
Current view: top level - libreoffice/oox/source/drawingml/chart - seriesconverter.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 1 291 0.3 %
Date: 2012-12-17 Functions: 2 37 5.4 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10