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