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/token/tokens.hxx>
21 : #include "oox/core/xmlfilterbase.hxx"
22 : #include "oox/export/chartexport.hxx"
23 : #include "oox/export/utils.hxx"
24 : #include "oox/drawingml/chart/typegroupconverter.hxx"
25 :
26 : #include <cstdio>
27 :
28 : #include <com/sun/star/awt/Gradient.hpp>
29 : #include <com/sun/star/chart/XChartDocument.hpp>
30 : #include <com/sun/star/chart/ChartLegendPosition.hpp>
31 : #include <com/sun/star/chart/XTwoAxisXSupplier.hpp>
32 : #include <com/sun/star/chart/XTwoAxisYSupplier.hpp>
33 : #include <com/sun/star/chart/XAxisZSupplier.hpp>
34 : #include <com/sun/star/chart/XChartDataArray.hpp>
35 : #include <com/sun/star/chart/ChartDataRowSource.hpp>
36 : #include <com/sun/star/chart/ChartAxisAssign.hpp>
37 : #include <com/sun/star/chart/ChartSeriesAddress.hpp>
38 : #include <com/sun/star/chart/X3DDisplay.hpp>
39 : #include <com/sun/star/chart/XStatisticDisplay.hpp>
40 : #include <com/sun/star/chart/XSecondAxisTitleSupplier.hpp>
41 : #include <com/sun/star/chart/ChartSymbolType.hpp>
42 : #include <com/sun/star/chart/ChartAxisMarks.hpp>
43 : #include <com/sun/star/chart/ChartAxisLabelPosition.hpp>
44 : #include <com/sun/star/chart/ChartAxisPosition.hpp>
45 : #include <com/sun/star/chart/ChartSolidType.hpp>
46 : #include <com/sun/star/chart/DataLabelPlacement.hpp>
47 : #include <com/sun/star/chart/ErrorBarStyle.hpp>
48 :
49 : #include <com/sun/star/chart2/XChartDocument.hpp>
50 : #include <com/sun/star/chart2/XDiagram.hpp>
51 : #include <com/sun/star/chart2/RelativePosition.hpp>
52 : #include <com/sun/star/chart2/XCoordinateSystemContainer.hpp>
53 : #include <com/sun/star/chart2/XRegressionCurveContainer.hpp>
54 : #include <com/sun/star/chart2/XChartTypeContainer.hpp>
55 : #include <com/sun/star/chart2/XDataSeriesContainer.hpp>
56 : #include <com/sun/star/chart2/DataPointGeometry3D.hpp>
57 : #include <com/sun/star/chart2/DataPointLabel.hpp>
58 : #include <com/sun/star/chart2/Symbol.hpp>
59 : #include <com/sun/star/chart2/data/XDataSource.hpp>
60 : #include <com/sun/star/chart2/data/XDataSink.hpp>
61 : #include <com/sun/star/chart2/data/XDataReceiver.hpp>
62 : #include <com/sun/star/chart2/data/XDataProvider.hpp>
63 : #include <com/sun/star/chart2/data/XDatabaseDataProvider.hpp>
64 : #include <com/sun/star/chart2/data/XRangeXMLConversion.hpp>
65 : #include <com/sun/star/chart2/data/XTextualDataSequence.hpp>
66 : #include <com/sun/star/chart2/data/XNumericalDataSequence.hpp>
67 :
68 : #include <com/sun/star/beans/XPropertySet.hpp>
69 : #include <com/sun/star/beans/XPropertyState.hpp>
70 : #include <com/sun/star/container/XEnumerationAccess.hpp>
71 : #include <com/sun/star/drawing/XShape.hpp>
72 : #include <com/sun/star/drawing/FillStyle.hpp>
73 : #include <com/sun/star/drawing/BitmapMode.hpp>
74 : #include <com/sun/star/lang/XServiceName.hpp>
75 :
76 : #include <com/sun/star/table/CellAddress.hpp>
77 : #include <com/sun/star/sheet/XFormulaParser.hpp>
78 : #include <com/sun/star/sheet/XFormulaTokens.hpp>
79 : #include <com/sun/star/sheet/FormulaToken.hpp>
80 : #include <com/sun/star/sheet/AddressConvention.hpp>
81 :
82 : #include <com/sun/star/text/WritingMode.hpp>
83 : #include <com/sun/star/container/XNamed.hpp>
84 :
85 : #include <comphelper/processfactory.hxx>
86 : #include <xmloff/SchXMLSeriesHelper.hxx>
87 : #include "ColorPropertySet.hxx"
88 : #include <set>
89 :
90 : #include <rtl/math.hxx>
91 :
92 : using namespace ::com::sun::star;
93 : using namespace ::com::sun::star::uno;
94 : using namespace ::com::sun::star::drawing;
95 : using namespace ::oox::core;
96 : using ::com::sun::star::beans::PropertyState;
97 : using ::com::sun::star::beans::PropertyValue;
98 : using ::com::sun::star::beans::XPropertySet;
99 : using ::com::sun::star::beans::XPropertyState;
100 : using ::com::sun::star::container::XEnumeration;
101 : using ::com::sun::star::container::XEnumerationAccess;
102 : using ::com::sun::star::container::XIndexAccess;
103 : using ::com::sun::star::container::XNamed;
104 : using ::com::sun::star::io::XOutputStream;
105 : using ::com::sun::star::table::CellAddress;
106 : using ::com::sun::star::sheet::XFormulaParser;
107 : using ::com::sun::star::sheet::XFormulaTokens;
108 : using ::oox::core::XmlFilterBase;
109 : using ::sax_fastparser::FSHelperPtr;
110 :
111 : namespace cssc = com::sun::star::chart;
112 :
113 : DBG(extern void dump_pset(Reference< XPropertySet > rXPropSet));
114 :
115 : namespace oox { namespace drawingml {
116 :
117 125 : class lcl_MatchesRole : public ::std::unary_function< Reference< chart2::data::XLabeledDataSequence >, bool >
118 : {
119 : public:
120 59 : explicit lcl_MatchesRole( const OUString & aRole ) :
121 59 : m_aRole( aRole )
122 59 : {}
123 :
124 140 : bool operator () ( const Reference< chart2::data::XLabeledDataSequence > & xSeq ) const
125 : {
126 140 : if( !xSeq.is() )
127 0 : return false;
128 140 : Reference< beans::XPropertySet > xProp( xSeq->getValues(), uno::UNO_QUERY );
129 280 : OUString aRole;
130 :
131 420 : return ( xProp.is() &&
132 140 : (xProp->getPropertyValue(
133 980 : OUString( "Role" ) ) >>= aRole ) &&
134 420 : m_aRole.equals( aRole ));
135 : }
136 :
137 : private:
138 : OUString m_aRole;
139 : };
140 :
141 : template< typename T >
142 61 : void lcl_SequenceToVectorAppend( const Sequence< T > & rSource, ::std::vector< T > & rDestination )
143 : {
144 61 : rDestination.reserve( rDestination.size() + rSource.getLength());
145 122 : ::std::copy( rSource.getConstArray(), rSource.getConstArray() + rSource.getLength(),
146 122 : ::std::back_inserter( rDestination ));
147 61 : }
148 :
149 46 : Reference< chart2::data::XLabeledDataSequence > lcl_getCategories( const Reference< chart2::XDiagram > & xDiagram )
150 : {
151 46 : Reference< chart2::data::XLabeledDataSequence > xResult;
152 : try
153 : {
154 : Reference< chart2::XCoordinateSystemContainer > xCooSysCnt(
155 46 : xDiagram, uno::UNO_QUERY_THROW );
156 : Sequence< Reference< chart2::XCoordinateSystem > > aCooSysSeq(
157 92 : xCooSysCnt->getCoordinateSystems());
158 92 : for( sal_Int32 i=0; i<aCooSysSeq.getLength(); ++i )
159 : {
160 46 : Reference< chart2::XCoordinateSystem > xCooSys( aCooSysSeq[i] );
161 : OSL_ASSERT( xCooSys.is());
162 206 : for( sal_Int32 nN = xCooSys->getDimension(); nN--; )
163 : {
164 114 : const sal_Int32 nMaxAxisIndex = xCooSys->getMaximumAxisIndexByDimension(nN);
165 192 : for(sal_Int32 nI=0; nI<=nMaxAxisIndex; ++nI)
166 : {
167 118 : Reference< chart2::XAxis > xAxis = xCooSys->getAxisByDimension( nN, nI );
168 : OSL_ASSERT( xAxis.is());
169 118 : if( xAxis.is())
170 : {
171 118 : chart2::ScaleData aScaleData = xAxis->getScaleData();
172 118 : if( aScaleData.Categories.is())
173 : {
174 40 : xResult.set( aScaleData.Categories );
175 40 : break;
176 78 : }
177 : }
178 78 : }
179 : }
180 92 : }
181 : }
182 0 : catch( const uno::Exception & ex )
183 : {
184 : (void)ex; // avoid warning for pro build
185 : OSL_FAIL( OUStringToOString(
186 : OUString( "Exception caught. Type: " ) +
187 : OUString::createFromAscii( typeid( ex ).name()) +
188 : OUString( ", Message: " ) +
189 : ex.Message, RTL_TEXTENCODING_ASCII_US ).getStr());
190 : }
191 :
192 46 : return xResult;
193 : }
194 :
195 26 : Reference< chart2::data::XDataSource > lcl_createDataSource(
196 : const Sequence< Reference< chart2::data::XLabeledDataSequence > > & aData )
197 : {
198 : Reference< uno::XComponentContext > xContext(
199 26 : comphelper::getProcessComponentContext() );
200 : Reference< chart2::data::XDataSink > xSink(
201 52 : xContext->getServiceManager()->createInstanceWithContext(
202 26 : "com.sun.star.chart2.data.DataSource", xContext ),
203 52 : uno::UNO_QUERY_THROW );
204 26 : if( xSink.is())
205 26 : xSink->setData( aData );
206 :
207 52 : return Reference< chart2::data::XDataSource >( xSink, uno::UNO_QUERY );
208 : }
209 :
210 26 : Sequence< Reference< chart2::data::XLabeledDataSequence > > lcl_getAllSeriesSequences( const Reference< chart2::XChartDocument >& xChartDoc )
211 : {
212 26 : ::std::vector< Reference< chart2::data::XLabeledDataSequence > > aContainer;
213 26 : if( xChartDoc.is() )
214 : {
215 26 : Reference< chart2::XDiagram > xDiagram( xChartDoc->getFirstDiagram());
216 52 : ::std::vector< Reference< chart2::XDataSeries > > aSeriesVector( SchXMLSeriesHelper::getDataSeriesFromDiagram( xDiagram ));
217 261 : for( ::std::vector< Reference< chart2::XDataSeries > >::const_iterator aSeriesIt( aSeriesVector.begin() )
218 174 : ; aSeriesIt != aSeriesVector.end(); ++aSeriesIt )
219 : {
220 61 : Reference< chart2::data::XDataSource > xDataSource( *aSeriesIt, uno::UNO_QUERY );
221 61 : if( !xDataSource.is() )
222 0 : continue;
223 122 : uno::Sequence< Reference< chart2::data::XLabeledDataSequence > > aDataSequences( xDataSource->getDataSequences() );
224 61 : lcl_SequenceToVectorAppend( aDataSequences, aContainer );
225 87 : }
226 : }
227 :
228 26 : Sequence< Reference< chart2::data::XLabeledDataSequence > > aRet( aContainer.size());
229 26 : ::std::copy( aContainer.begin(), aContainer.end(), aRet.getArray());
230 :
231 26 : return aRet;
232 : }
233 :
234 : Reference< chart2::data::XLabeledDataSequence >
235 33 : lcl_getDataSequenceByRole(
236 : const Sequence< Reference< chart2::data::XLabeledDataSequence > > & aLabeledSeq,
237 : const OUString & rRole )
238 : {
239 33 : Reference< chart2::data::XLabeledDataSequence > aNoResult;
240 :
241 33 : const Reference< chart2::data::XLabeledDataSequence > * pBegin = aLabeledSeq.getConstArray();
242 33 : const Reference< chart2::data::XLabeledDataSequence > * pEnd = pBegin + aLabeledSeq.getLength();
243 : const Reference< chart2::data::XLabeledDataSequence > * pMatch =
244 33 : ::std::find_if( pBegin, pEnd, lcl_MatchesRole( rRole ));
245 :
246 33 : if( pMatch != pEnd )
247 10 : return *pMatch;
248 :
249 23 : return aNoResult;
250 : }
251 :
252 26 : Reference< chart2::data::XDataSource > lcl_pressUsedDataIntoRectangularFormat( const Reference< chart2::XChartDocument >& xChartDoc, bool& rOutSourceHasCategoryLabels )
253 : {
254 26 : ::std::vector< Reference< chart2::data::XLabeledDataSequence > > aLabeledSeqVector;
255 :
256 : //categories are always the first sequence
257 52 : Reference< chart2::XDiagram > xDiagram( xChartDoc->getFirstDiagram());
258 52 : Reference< chart2::data::XLabeledDataSequence > xCategories( lcl_getCategories( xDiagram ) );
259 26 : if( xCategories.is() )
260 20 : aLabeledSeqVector.push_back( xCategories );
261 26 : rOutSourceHasCategoryLabels = xCategories.is();
262 :
263 : Sequence< Reference< chart2::data::XLabeledDataSequence > > aSeriesSeqVector(
264 52 : lcl_getAllSeriesSequences( xChartDoc ) );
265 :
266 : //the first x-values is always the next sequence //todo ... other x-values get lost for old format
267 : Reference< chart2::data::XLabeledDataSequence > xXValues(
268 52 : lcl_getDataSequenceByRole( aSeriesSeqVector, OUString("values-x") ) );
269 26 : if( xXValues.is() )
270 3 : aLabeledSeqVector.push_back( xXValues );
271 :
272 : //add all other sequences now without x-values
273 52 : lcl_MatchesRole aHasXValues( OUString("values-x") );
274 91 : for( sal_Int32 nN=0; nN<aSeriesSeqVector.getLength(); nN++ )
275 : {
276 65 : if( !aHasXValues( aSeriesSeqVector[nN] ) )
277 62 : aLabeledSeqVector.push_back( aSeriesSeqVector[nN] );
278 : }
279 :
280 52 : Sequence< Reference< chart2::data::XLabeledDataSequence > > aSeq( aLabeledSeqVector.size() );
281 26 : ::std::copy( aLabeledSeqVector.begin(), aLabeledSeqVector.end(), aSeq.getArray() );
282 :
283 52 : return lcl_createDataSource( aSeq );
284 : }
285 :
286 1 : bool lcl_isSeriesAttachedToFirstAxis(
287 : const Reference< chart2::XDataSeries > & xDataSeries )
288 : {
289 1 : bool bResult=true;
290 :
291 : try
292 : {
293 1 : sal_Int32 nAxisIndex = 0;
294 1 : Reference< beans::XPropertySet > xProp( xDataSeries, uno::UNO_QUERY_THROW );
295 1 : if( xProp.is() )
296 1 : xProp->getPropertyValue("AttachedAxisIndex") >>= nAxisIndex;
297 1 : bResult = (0==nAxisIndex);
298 : }
299 0 : catch( const uno::Exception & ex )
300 : {
301 : (void)ex; // avoid warning for pro build
302 : OSL_FAIL( OUStringToOString(
303 : OUString( "Exception caught. Type: " ) +
304 : OUString::createFromAscii( typeid( ex ).name()) +
305 : OUString( ", Message: " ) +
306 : ex.Message, RTL_TEXTENCODING_ASCII_US ).getStr());
307 : }
308 :
309 1 : return bResult;
310 : }
311 :
312 62 : OUString lcl_flattenStringSequence( const Sequence< OUString > & rSequence )
313 : {
314 62 : OUStringBuffer aResult;
315 62 : bool bPrecedeWithSpace = false;
316 124 : for( sal_Int32 nIndex=0; nIndex<rSequence.getLength(); ++nIndex )
317 : {
318 62 : if( !rSequence[nIndex].isEmpty())
319 : {
320 61 : if( bPrecedeWithSpace )
321 0 : aResult.append( ' ' );
322 61 : aResult.append( rSequence[nIndex] );
323 61 : bPrecedeWithSpace = true;
324 : }
325 : }
326 62 : return aResult.makeStringAndClear();
327 : }
328 :
329 62 : OUString lcl_getLabelString( const Reference< chart2::data::XDataSequence > & xLabelSeq )
330 : {
331 62 : Sequence< OUString > aLabels;
332 :
333 124 : uno::Reference< chart2::data::XTextualDataSequence > xTextualDataSequence( xLabelSeq, uno::UNO_QUERY );
334 62 : if( xTextualDataSequence.is())
335 : {
336 62 : aLabels = xTextualDataSequence->getTextualData();
337 : }
338 0 : else if( xLabelSeq.is())
339 : {
340 0 : Sequence< uno::Any > aAnies( xLabelSeq->getData());
341 0 : aLabels.realloc( aAnies.getLength());
342 0 : for( sal_Int32 i=0; i<aAnies.getLength(); ++i )
343 0 : aAnies[i] >>= aLabels[i];
344 : }
345 :
346 124 : return lcl_flattenStringSequence( aLabels );
347 : }
348 :
349 53 : void lcl_fillCategoriesIntoStringVector(
350 : const Reference< chart2::data::XDataSequence > & xCategories,
351 : ::std::vector< OUString > & rOutCategories )
352 : {
353 : OSL_ASSERT( xCategories.is());
354 53 : if( !xCategories.is())
355 53 : return;
356 53 : Reference< chart2::data::XTextualDataSequence > xTextualDataSequence( xCategories, uno::UNO_QUERY );
357 53 : if( xTextualDataSequence.is())
358 : {
359 53 : rOutCategories.clear();
360 53 : Sequence< OUString > aTextData( xTextualDataSequence->getTextualData());
361 53 : ::std::copy( aTextData.getConstArray(), aTextData.getConstArray() + aTextData.getLength(),
362 106 : ::std::back_inserter( rOutCategories ));
363 : }
364 : else
365 : {
366 0 : Sequence< uno::Any > aAnies( xCategories->getData());
367 0 : rOutCategories.resize( aAnies.getLength());
368 0 : for( sal_Int32 i=0; i<aAnies.getLength(); ++i )
369 0 : aAnies[i] >>= rOutCategories[i];
370 53 : }
371 : }
372 :
373 65 : ::std::vector< double > lcl_getAllValuesFromSequence( const Reference< chart2::data::XDataSequence > & xSeq )
374 : {
375 65 : double fNan = 0.0;
376 65 : ::rtl::math::setNan( &fNan );
377 65 : ::std::vector< double > aResult;
378 :
379 130 : Reference< chart2::data::XNumericalDataSequence > xNumSeq( xSeq, uno::UNO_QUERY );
380 65 : if( xNumSeq.is())
381 : {
382 65 : Sequence< double > aValues( xNumSeq->getNumericalData());
383 65 : ::std::copy( aValues.getConstArray(), aValues.getConstArray() + aValues.getLength(),
384 130 : ::std::back_inserter( aResult ));
385 : }
386 0 : else if( xSeq.is())
387 : {
388 0 : Sequence< uno::Any > aAnies( xSeq->getData());
389 0 : aResult.resize( aAnies.getLength(), fNan );
390 0 : for( sal_Int32 i=0; i<aAnies.getLength(); ++i )
391 0 : aAnies[i] >>= aResult[i];
392 : }
393 130 : return aResult;
394 : }
395 :
396 95 : sal_Int32 lcl_getChartType( const OUString& sChartType )
397 : {
398 95 : chart::TypeId eChartTypeId = chart::TYPEID_UNKNOWN;
399 190 : if( sChartType == "com.sun.star.chart.BarDiagram"
400 95 : || sChartType == "com.sun.star.chart2.ColumnChartType" )
401 57 : eChartTypeId = chart::TYPEID_BAR;
402 76 : else if( sChartType == "com.sun.star.chart.AreaDiagram"
403 38 : || sChartType == "com.sun.star.chart2.AreaChartType" )
404 3 : eChartTypeId = chart::TYPEID_AREA;
405 70 : else if( sChartType == "com.sun.star.chart.LineDiagram"
406 35 : || sChartType == "com.sun.star.chart2.LineChartType" )
407 8 : eChartTypeId = chart::TYPEID_LINE;
408 54 : else if( sChartType == "com.sun.star.chart.PieDiagram"
409 27 : || sChartType == "com.sun.star.chart2.PieChartType" )
410 13 : eChartTypeId = chart::TYPEID_PIE;
411 28 : else if( sChartType == "com.sun.star.chart.DonutDiagram"
412 14 : || sChartType == "com.sun.star.chart2.DonutChartType" )
413 1 : eChartTypeId = chart::TYPEID_DOUGHNUT;
414 26 : else if( sChartType == "com.sun.star.chart.XYDiagram"
415 13 : || sChartType == "com.sun.star.chart2.ScatterChartType" )
416 9 : eChartTypeId = chart::TYPEID_SCATTER;
417 8 : else if( sChartType == "com.sun.star.chart.NetDiagram"
418 4 : || sChartType == "com.sun.star.chart2.NetChartType" )
419 0 : eChartTypeId = chart::TYPEID_RADARLINE;
420 8 : else if( sChartType == "com.sun.star.chart.FilledNetDiagram"
421 4 : || sChartType == "com.sun.star.chart2.FilledNetChartType" )
422 0 : eChartTypeId = chart::TYPEID_RADARAREA;
423 8 : else if( sChartType == "com.sun.star.chart.StockDiagram"
424 4 : || sChartType == "com.sun.star.chart2.CandleStickChartType" )
425 4 : eChartTypeId = chart::TYPEID_STOCK;
426 0 : else if( sChartType == "com.sun.star.chart.BubbleDiagram"
427 0 : || sChartType == "com.sun.star.chart2.BubbleChartType" )
428 0 : eChartTypeId = chart::TYPEID_BUBBLE;
429 :
430 95 : return eChartTypeId;
431 : }
432 :
433 48 : sal_Int32 lcl_generateRandomValue()
434 : {
435 : static sal_Int32 MAX_NUMBER = 100000000;
436 48 : return sal_Int32( rand() % MAX_NUMBER );
437 : }
438 :
439 26 : ChartExport::ChartExport( sal_Int32 nXmlNamespace, FSHelperPtr pFS, Reference< frame::XModel >& xModel, XmlFilterBase* pFB, DocumentType eDocumentType )
440 : : DrawingML( pFS, pFB, eDocumentType )
441 : , mnXmlNamespace( nXmlNamespace )
442 : , mnSeriesCount(0)
443 : , maFraction( 1, 576 )
444 : , mxChartModel( xModel )
445 : , mbHasCategoryLabels( false )
446 : , mbHasZAxis( false )
447 26 : , mbIs3DChart( false )
448 : {
449 26 : }
450 :
451 6 : sal_Int32 ChartExport::GetChartID( )
452 : {
453 6 : sal_Int32 nID = GetFB()->GetUniqueId();
454 6 : return nID;
455 : }
456 :
457 39 : sal_Int32 ChartExport::getChartType( )
458 : {
459 39 : OUString sChartType = mxDiagram->getDiagramType();
460 39 : return lcl_getChartType( sChartType );
461 : }
462 :
463 180 : OUString ChartExport::parseFormula( const OUString& rRange )
464 : {
465 180 : OUString aResult;
466 360 : Reference< XFormulaParser > xParser;
467 360 : uno::Reference< lang::XMultiServiceFactory > xSF( GetFB()->getModelFactory(), uno::UNO_QUERY );
468 180 : if( xSF.is() )
469 : {
470 : try
471 : {
472 180 : xParser.set( xSF->createInstance("com.sun.star.sheet.FormulaParser"), UNO_QUERY );
473 : }
474 159 : catch( Exception& )
475 : {
476 : }
477 : }
478 180 : if( xParser.is() )
479 : {
480 : OSL_TRACE("ChartExport::parseFormula, parser is valid");
481 21 : Reference< XPropertySet > xParserProps( xParser, uno::UNO_QUERY );
482 21 : if( xParserProps.is() )
483 : {
484 21 : xParserProps->setPropertyValue("FormulaConvention", uno::makeAny(::com::sun::star::sheet::AddressConvention::OOO) );
485 : }
486 42 : uno::Sequence<sheet::FormulaToken> aTokens = xParser->parseFormula( rRange, CellAddress( 0, 0, 0 ) );
487 21 : if( xParserProps.is() )
488 : {
489 21 : xParserProps->setPropertyValue("FormulaConvention", uno::makeAny(::com::sun::star::sheet::AddressConvention::XL_OOX) );
490 : }
491 42 : aResult = xParser->printFormula( aTokens, CellAddress( 0, 0, 0 ) );
492 : }
493 : else
494 : {
495 : OSL_TRACE("ChartExport::parseFormula, parser is invalid");
496 : //FIXME: currently just using simple converter, e.g $Sheet1.$A$1:$C$1 -> Sheet1!$A$1:$C$1
497 159 : OUString aRange( rRange );
498 159 : if( aRange.startsWith("$") )
499 0 : aRange = aRange.copy(1);
500 159 : aRange = aRange.replaceAll(".$", "!$" );
501 159 : aResult = aRange;
502 : }
503 :
504 : OSL_TRACE("ChartExport::parseFormula, the originla formula is %s, the new formula is %s ", OUStringToOString( rRange, RTL_TEXTENCODING_UTF8 ).getStr(), OUStringToOString( aResult, RTL_TEXTENCODING_UTF8 ).getStr());
505 360 : return aResult;
506 : }
507 :
508 6 : ChartExport& ChartExport::WriteChartObj( const Reference< XShape >& xShape, sal_Int32 nChartCount )
509 : {
510 : OSL_TRACE("ChartExport::WriteChartObj -- writer chart object");
511 6 : FSHelperPtr pFS = GetFS();
512 :
513 6 : pFS->startElementNS( mnXmlNamespace, XML_graphicFrame, FSEND );
514 :
515 6 : pFS->startElementNS( mnXmlNamespace, XML_nvGraphicFramePr, FSEND );
516 :
517 : // TODO: get the correct chart name chart id
518 12 : OUString sName = "Object 1";
519 12 : Reference< XNamed > xNamed( xShape, UNO_QUERY );
520 6 : if (xNamed.is())
521 6 : sName = xNamed->getName();
522 :
523 6 : sal_Int32 nID = GetChartID();
524 :
525 : pFS->singleElementNS( mnXmlNamespace, XML_cNvPr,
526 : XML_id, I32S( nID ),
527 : XML_name, USS( sName ),
528 6 : FSEND );
529 :
530 : pFS->singleElementNS( mnXmlNamespace, XML_cNvGraphicFramePr,
531 6 : FSEND );
532 :
533 6 : if( GetDocumentType() == DOCUMENT_PPTX )
534 : pFS->singleElementNS( mnXmlNamespace, XML_nvPr,
535 0 : FSEND );
536 6 : pFS->endElementNS( mnXmlNamespace, XML_nvGraphicFramePr );
537 :
538 : // visual chart properties
539 6 : WriteShapeTransformation( xShape, mnXmlNamespace );
540 :
541 : // writer chart object
542 6 : pFS->startElement( FSNS( XML_a, XML_graphic ), FSEND );
543 : pFS->startElement( FSNS( XML_a, XML_graphicData ),
544 : XML_uri, "http://schemas.openxmlformats.org/drawingml/2006/chart",
545 6 : FSEND );
546 12 : OUString sId;
547 6 : const char* sFullPath = NULL;
548 6 : const char* sRelativePath = NULL;
549 6 : switch( GetDocumentType() )
550 : {
551 : case DOCUMENT_DOCX:
552 : {
553 0 : sFullPath = "word/charts/chart";
554 0 : sRelativePath = "charts/chart";
555 0 : break;
556 : }
557 : case DOCUMENT_PPTX:
558 : {
559 0 : sFullPath = "ppt/charts/chart";
560 0 : sRelativePath = "../charts/chart";
561 0 : break;
562 : }
563 : case DOCUMENT_XLSX:
564 : {
565 6 : sFullPath = "xl/charts/chart";
566 6 : sRelativePath = "../charts/chart";
567 6 : break;
568 : }
569 : default:
570 : {
571 0 : sFullPath = "charts/chart";
572 0 : sRelativePath = "charts/chart";
573 0 : break;
574 : }
575 : }
576 : OUString sFullStream = OUStringBuffer()
577 12 : .appendAscii(sFullPath)
578 6 : .append(nChartCount)
579 6 : .appendAscii( ".xml" )
580 6 : .makeStringAndClear();
581 : OUString sRelativeStream = OUStringBuffer()
582 12 : .appendAscii(sRelativePath)
583 6 : .append(nChartCount)
584 6 : .appendAscii( ".xml" )
585 12 : .makeStringAndClear();
586 : FSHelperPtr pChart = CreateOutputStream(
587 : sFullStream,
588 : sRelativeStream,
589 : pFS->getOutputStream(),
590 : "application/vnd.openxmlformats-officedocument.drawingml.chart+xml",
591 : "http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart",
592 12 : &sId );
593 :
594 : pFS->singleElement( FSNS( XML_c, XML_chart ),
595 : FSNS( XML_xmlns, XML_c ), "http://schemas.openxmlformats.org/drawingml/2006/chart",
596 : FSNS( XML_xmlns, XML_r ), "http://schemas.openxmlformats.org/officeDocument/2006/relationships",
597 : FSNS( XML_r, XML_id ), USS( sId ),
598 6 : FSEND );
599 :
600 6 : pFS->endElement( FSNS( XML_a, XML_graphicData ) );
601 6 : pFS->endElement( FSNS( XML_a, XML_graphic ) );
602 6 : pFS->endElementNS( mnXmlNamespace, XML_graphicFrame );
603 :
604 6 : SetFS( pChart );
605 6 : ExportContent();
606 :
607 18 : return *this;
608 : }
609 :
610 26 : void ChartExport::InitRangeSegmentationProperties( const Reference< chart2::XChartDocument > & xChartDoc )
611 : {
612 26 : if( xChartDoc.is())
613 : try
614 : {
615 26 : Reference< chart2::data::XDataProvider > xDataProvider( xChartDoc->getDataProvider() );
616 : OSL_ENSURE( xDataProvider.is(), "No DataProvider" );
617 26 : if( xDataProvider.is())
618 : {
619 26 : Reference< chart2::data::XDataSource > xDataSource( lcl_pressUsedDataIntoRectangularFormat( xChartDoc, mbHasCategoryLabels ));
620 52 : Sequence< beans::PropertyValue > aArgs( xDataProvider->detectArguments( xDataSource ));
621 52 : OUString sCellRange, sBrokenRange;
622 26 : bool bBrokenRangeAvailable = false;
623 136 : for( sal_Int32 i=0; i<aArgs.getLength(); ++i )
624 : {
625 110 : if ( aArgs[i].Name == "CellRangeRepresentation" )
626 26 : aArgs[i].Value >>= sCellRange;
627 84 : else if ( aArgs[i].Name == "BrokenCellRangeForExport" )
628 : {
629 0 : if( aArgs[i].Value >>= sBrokenRange )
630 0 : bBrokenRangeAvailable = true;
631 : }
632 84 : else if ( aArgs[i].Name == "SequenceMapping" )
633 0 : aArgs[i].Value >>= maSequenceMapping;
634 : }
635 :
636 : // #i79009# For Writer we have to export a broken version of the
637 : // range, where every row number is noe too large, so that older
638 : // version can correctly read those files.
639 26 : msChartAddress = (bBrokenRangeAvailable ? sBrokenRange : sCellRange);
640 26 : if( !msChartAddress.isEmpty() )
641 : {
642 : // convert format to XML-conform one
643 26 : Reference< chart2::data::XRangeXMLConversion > xConversion( xDataProvider, uno::UNO_QUERY );
644 26 : if( xConversion.is())
645 26 : msChartAddress = xConversion->convertRangeToXML( msChartAddress );
646 26 : }
647 26 : }
648 : }
649 0 : catch( const uno::Exception & ex )
650 : {
651 : (void)ex; // avoid warning for pro build
652 : OSL_FAIL( OUStringToOString(
653 : OUString( "Exception caught. Type: " ) +
654 : OUString::createFromAscii( typeid( ex ).name()) +
655 : OUString( ", Message: " ) +
656 : ex.Message, RTL_TEXTENCODING_ASCII_US ).getStr());
657 : }
658 26 : }
659 :
660 26 : void ChartExport::ExportContent()
661 : {
662 26 : Reference< chart2::XChartDocument > xChartDoc( getModel(), uno::UNO_QUERY );
663 : OSL_ASSERT( xChartDoc.is() );
664 26 : if( !xChartDoc.is() )
665 26 : return;
666 26 : InitRangeSegmentationProperties( xChartDoc );
667 : // TODO: export chart
668 26 : _ExportContent( );
669 : }
670 :
671 26 : void ChartExport::_ExportContent()
672 : {
673 26 : Reference< ::com::sun::star::chart::XChartDocument > xChartDoc( getModel(), uno::UNO_QUERY );
674 26 : if( xChartDoc.is())
675 : {
676 : // determine if data comes from the outside
677 26 : bool bIncludeTable = true;
678 :
679 26 : Reference< chart2::XChartDocument > xNewDoc( xChartDoc, uno::UNO_QUERY );
680 26 : if( xNewDoc.is())
681 : {
682 : // check if we have own data. If so we must not export the complete
683 : // range string, as this is our only indicator for having own or
684 : // external data. @todo: fix this in the file format!
685 26 : Reference< lang::XServiceInfo > xDPServiceInfo( xNewDoc->getDataProvider(), uno::UNO_QUERY );
686 26 : if( ! (xDPServiceInfo.is() && xDPServiceInfo->getImplementationName() == "com.sun.star.comp.chart.InternalDataProvider" ))
687 : {
688 6 : bIncludeTable = false;
689 26 : }
690 : }
691 : else
692 : {
693 0 : Reference< lang::XServiceInfo > xServ( xChartDoc, uno::UNO_QUERY );
694 0 : if( xServ.is())
695 : {
696 0 : if( xServ->supportsService(
697 0 : OUString("com.sun.star.chart.ChartTableAddressSupplier")))
698 : {
699 0 : Reference< beans::XPropertySet > xProp( xServ, uno::UNO_QUERY );
700 0 : if( xProp.is())
701 : {
702 0 : Any aAny;
703 : try
704 : {
705 0 : OUString sChartAddress;
706 0 : aAny = xProp->getPropertyValue(
707 0 : OUString("ChartRangeAddress"));
708 0 : aAny >>= msChartAddress;
709 : //maExportHelper.SetChartRangeAddress( sChartAddress );
710 :
711 : //maExportHelper.SetTableNumberList( sTableNumberList );
712 :
713 : // do not include own table if there are external addresses
714 0 : bIncludeTable = sChartAddress.isEmpty();
715 : }
716 0 : catch( beans::UnknownPropertyException & )
717 : {
718 : OSL_FAIL( "Property ChartRangeAddress not supported by ChartDocument" );
719 0 : }
720 0 : }
721 : }
722 0 : }
723 : }
724 26 : exportChartSpace( xChartDoc, bIncludeTable );
725 : }
726 : else
727 : {
728 : OSL_FAIL( "Couldn't export chart due to wrong XModel" );
729 26 : }
730 26 : }
731 :
732 26 : void ChartExport::exportChartSpace( Reference< ::com::sun::star::chart::XChartDocument > rChartDoc,
733 : bool bIncludeTable )
734 : {
735 26 : FSHelperPtr pFS = GetFS();
736 : pFS->startElement( FSNS( XML_c, XML_chartSpace ),
737 : FSNS( XML_xmlns, XML_c ), "http://schemas.openxmlformats.org/drawingml/2006/chart",
738 : FSNS( XML_xmlns, XML_a ), "http://schemas.openxmlformats.org/drawingml/2006/main",
739 : FSNS( XML_xmlns, XML_r ), "http://schemas.openxmlformats.org/officeDocument/2006/relationships",
740 26 : FSEND );
741 : // TODO: get the correct editing lanauge
742 : pFS->singleElement( FSNS( XML_c, XML_lang ),
743 : XML_val, "en-US",
744 26 : FSEND );
745 :
746 26 : if( !bIncludeTable )
747 : {
748 : // TODO:external data
749 : }
750 : //XML_chart
751 26 : exportChart(rChartDoc);
752 :
753 : // TODO: printSettings
754 : // TODO: style
755 : // TODO: text properties
756 : // TODO: shape properties
757 52 : Reference< XPropertySet > xPropSet( rChartDoc->getArea(), uno::UNO_QUERY );
758 26 : if( xPropSet.is() )
759 26 : exportShapeProps( xPropSet );
760 :
761 : //XML_externalData
762 26 : exportExternalData(rChartDoc);
763 :
764 52 : pFS->endElement( FSNS( XML_c, XML_chartSpace ) );
765 26 : }
766 :
767 26 : void ChartExport::exportExternalData( Reference< ::com::sun::star::chart::XChartDocument > rChartDoc )
768 : {
769 : // Embedded external data is grab bagged for docx file hence adding export part of
770 : // external data for docx files only.
771 26 : if(GetDocumentType() != DOCUMENT_DOCX)
772 32 : return;
773 :
774 20 : OUString externalDataPath;
775 40 : Reference< beans::XPropertySet > xDocPropSet( rChartDoc->getDiagram(), uno::UNO_QUERY );
776 20 : if( xDocPropSet.is())
777 : {
778 : try
779 : {
780 20 : Any aAny( xDocPropSet->getPropertyValue(
781 20 : OUString( "ExternalData" )));
782 20 : aAny >>= externalDataPath;
783 : }
784 0 : catch( beans::UnknownPropertyException & )
785 : {
786 : DBG_WARNING( "Required property not found in ChartDocument" );
787 : }
788 : }
789 20 : if(!externalDataPath.isEmpty())
790 : {
791 : // Here adding external data entry to relationship.
792 19 : OUString relationPath = externalDataPath;
793 : // Converting absolute path to relative path.
794 19 : if( externalDataPath[ 0 ] != '.' && externalDataPath[ 1 ] != '.')
795 : {
796 19 : sal_Int32 nStartPos = 0;
797 19 : sal_Int32 nSepPos = externalDataPath.indexOf( '/', nStartPos );
798 19 : if( nSepPos > 0)
799 : {
800 19 : relationPath = relationPath.copy( nSepPos, ::std::max< sal_Int32 >( externalDataPath.getLength(), 0 ) - nSepPos );
801 19 : relationPath = OUStringBuffer( ".." ).append( relationPath ).makeStringAndClear();
802 : }
803 : }
804 38 : FSHelperPtr pFS = GetFS();
805 38 : OUString type = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/package";
806 19 : if (relationPath.endsWith(OUString(".bin")))
807 0 : type = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/oleObject";
808 :
809 : OUString sRelId = GetFB()->addRelation(pFS->getOutputStream(),
810 : type,
811 38 : relationPath);
812 : pFS->singleElementNS( XML_c, XML_externalData,
813 : FSNS(XML_r, XML_id), OUStringToOString(sRelId, RTL_TEXTENCODING_UTF8),
814 38 : FSEND);
815 20 : }
816 : }
817 :
818 26 : void ChartExport::exportChart( Reference< ::com::sun::star::chart::XChartDocument > rChartDoc )
819 : {
820 26 : Reference< chart2::XChartDocument > xNewDoc( rChartDoc, uno::UNO_QUERY );
821 26 : mxDiagram.set( rChartDoc->getDiagram() );
822 26 : if( xNewDoc.is())
823 26 : mxNewDiagram.set( xNewDoc->getFirstDiagram());
824 :
825 : // get Properties of ChartDocument
826 26 : sal_Bool bHasMainTitle = sal_False;
827 26 : sal_Bool bHasSubTitle = sal_False;
828 26 : sal_Bool bHasLegend = sal_False;
829 52 : Reference< beans::XPropertySet > xDocPropSet( rChartDoc, uno::UNO_QUERY );
830 26 : if( xDocPropSet.is())
831 : {
832 : try
833 : {
834 26 : Any aAny( xDocPropSet->getPropertyValue(
835 26 : OUString( "HasMainTitle" )));
836 26 : aAny >>= bHasMainTitle;
837 78 : aAny = xDocPropSet->getPropertyValue(
838 52 : OUString( "HasSubTitle" ));
839 26 : aAny >>= bHasSubTitle;
840 78 : aAny = xDocPropSet->getPropertyValue(
841 52 : OUString( "HasLegend" ));
842 26 : aAny >>= bHasLegend;
843 : }
844 0 : catch( beans::UnknownPropertyException & )
845 : {
846 : DBG_WARNING( "Required property not found in ChartDocument" );
847 : }
848 : } // if( xDocPropSet.is())
849 :
850 : // chart element
851 :
852 52 : FSHelperPtr pFS = GetFS();
853 : pFS->startElement( FSNS( XML_c, XML_chart ),
854 26 : FSEND );
855 :
856 : // title
857 26 : if( bHasMainTitle )
858 : {
859 13 : Reference< drawing::XShape > xShape = rChartDoc->getTitle();
860 13 : if( xShape.is() )
861 13 : exportTitle( xShape );
862 : }
863 26 : InitPlotArea( );
864 26 : if( mbIs3DChart )
865 : {
866 11 : exportView3D();
867 :
868 : // floor
869 11 : Reference< beans::XPropertySet > xFloor( mxNewDiagram->getFloor(), uno::UNO_QUERY );
870 11 : if( xFloor.is() )
871 : {
872 : pFS->startElement( FSNS( XML_c, XML_floor ),
873 11 : FSEND );
874 11 : exportShapeProps( xFloor );
875 11 : pFS->endElement( FSNS( XML_c, XML_floor ) );
876 : }
877 :
878 : // sideWall
879 :
880 : // backWall
881 22 : Reference< beans::XPropertySet > xBackWall( mxNewDiagram->getWall(), uno::UNO_QUERY );
882 11 : if( xBackWall.is() )
883 : {
884 : pFS->startElement( FSNS( XML_c, XML_backWall ),
885 11 : FSEND );
886 11 : exportShapeProps( xBackWall );
887 11 : pFS->endElement( FSNS( XML_c, XML_backWall ) );
888 11 : }
889 :
890 : }
891 : // plot area
892 26 : exportPlotArea( );
893 : // legend
894 26 : if( bHasLegend )
895 25 : exportLegend( rChartDoc );
896 : // only visible cells should be plotted on the chart
897 : pFS->singleElement( FSNS( XML_c, XML_plotVisOnly ),
898 : XML_val, "1",
899 26 : FSEND );
900 :
901 52 : pFS->endElement( FSNS( XML_c, XML_chart ) );
902 26 : }
903 :
904 25 : void ChartExport::exportLegend( Reference< ::com::sun::star::chart::XChartDocument > rChartDoc )
905 : {
906 25 : FSHelperPtr pFS = GetFS();
907 : pFS->startElement( FSNS( XML_c, XML_legend ),
908 25 : FSEND );
909 :
910 50 : Reference< beans::XPropertySet > xProp( rChartDoc->getLegend(), uno::UNO_QUERY );
911 25 : if( xProp.is() )
912 : {
913 : // position
914 25 : ::com::sun::star::chart::ChartLegendPosition aLegendPos = ::com::sun::star::chart::ChartLegendPosition_NONE;
915 : try
916 : {
917 25 : Any aAny( xProp->getPropertyValue(
918 25 : OUString( "Alignment" )));
919 25 : aAny >>= aLegendPos;
920 : }
921 0 : catch( beans::UnknownPropertyException & )
922 : {
923 : DBG_WARNING( "Property Align not found in ChartLegend" );
924 : }
925 :
926 25 : const char* strPos = NULL;
927 25 : switch( aLegendPos )
928 : {
929 : case ::com::sun::star::chart::ChartLegendPosition_LEFT:
930 1 : strPos = "l";
931 1 : break;
932 : case ::com::sun::star::chart::ChartLegendPosition_RIGHT:
933 20 : strPos = "r";
934 20 : break;
935 : case ::com::sun::star::chart::ChartLegendPosition_TOP:
936 1 : strPos = "t";
937 1 : break;
938 : case ::com::sun::star::chart::ChartLegendPosition_BOTTOM:
939 3 : strPos = "b";
940 3 : break;
941 : case ::com::sun::star::chart::ChartLegendPosition_NONE:
942 : case ::com::sun::star::chart::ChartLegendPosition_MAKE_FIXED_SIZE:
943 : // nothing
944 0 : break;
945 : }
946 :
947 25 : if( strPos != NULL )
948 : {
949 : pFS->singleElement( FSNS( XML_c, XML_legendPos ),
950 : XML_val, strPos,
951 25 : FSEND );
952 : pFS->singleElement( FSNS( XML_c, XML_overlay ),
953 : XML_val, "0",
954 25 : FSEND );
955 : }
956 :
957 : // shape properties
958 25 : exportShapeProps( xProp );
959 : }
960 :
961 : // legendEntry
962 :
963 50 : pFS->endElement( FSNS( XML_c, XML_legend ) );
964 25 : }
965 :
966 22 : void ChartExport::exportTitle( Reference< XShape > xShape )
967 : {
968 22 : OUString sText;
969 44 : Reference< beans::XPropertySet > xPropSet( xShape, uno::UNO_QUERY );
970 22 : if( xPropSet.is())
971 : {
972 22 : xPropSet->getPropertyValue("String") >>= sText;
973 : }
974 22 : if( sText.isEmpty() )
975 22 : return;
976 :
977 44 : FSHelperPtr pFS = GetFS();
978 : pFS->startElement( FSNS( XML_c, XML_title ),
979 22 : FSEND );
980 :
981 : pFS->startElement( FSNS( XML_c, XML_tx ),
982 22 : FSEND );
983 : pFS->startElement( FSNS( XML_c, XML_rich ),
984 22 : FSEND );
985 :
986 : // TODO: bodyPr
987 22 : const char* sWritingMode = NULL;
988 22 : sal_Bool bVertical = sal_False;
989 22 : xPropSet->getPropertyValue("StackedText") >>= bVertical;
990 22 : if( bVertical )
991 0 : sWritingMode = "wordArtVert";
992 :
993 : pFS->singleElement( FSNS( XML_a, XML_bodyPr ),
994 : XML_vert, sWritingMode,
995 22 : FSEND );
996 : // TODO: lstStyle
997 : pFS->singleElement( FSNS( XML_a, XML_lstStyle ),
998 22 : FSEND );
999 : // FIXME: handle multipul paragraphs to parse aText
1000 : pFS->startElement( FSNS( XML_a, XML_p ),
1001 22 : FSEND );
1002 :
1003 : pFS->startElement( FSNS( XML_a, XML_pPr ),
1004 22 : FSEND );
1005 : pFS->singleElement( FSNS( XML_a, XML_defRPr ),
1006 22 : FSEND );
1007 22 : pFS->endElement( FSNS( XML_a, XML_pPr ) );
1008 :
1009 : pFS->startElement( FSNS( XML_a, XML_r ),
1010 22 : FSEND );
1011 22 : WriteRunProperties( xPropSet, false );
1012 : pFS->startElement( FSNS( XML_a, XML_t ),
1013 22 : FSEND );
1014 22 : pFS->writeEscaped( sText );
1015 22 : pFS->endElement( FSNS( XML_a, XML_t ) );
1016 22 : pFS->endElement( FSNS( XML_a, XML_r ) );
1017 :
1018 22 : pFS->endElement( FSNS( XML_a, XML_p ) );
1019 :
1020 22 : pFS->endElement( FSNS( XML_c, XML_rich ) );
1021 22 : pFS->endElement( FSNS( XML_c, XML_tx ) );
1022 :
1023 : // TODO:customize layout
1024 : pFS->singleElement( FSNS( XML_c, XML_layout ),
1025 22 : FSEND );
1026 :
1027 44 : pFS->endElement( FSNS( XML_c, XML_title ) );
1028 : }
1029 :
1030 26 : void ChartExport::exportPlotArea( )
1031 : {
1032 26 : Reference< chart2::XCoordinateSystemContainer > xBCooSysCnt( mxNewDiagram, uno::UNO_QUERY );
1033 26 : if( ! xBCooSysCnt.is())
1034 0 : return;
1035 :
1036 : // plot-area element
1037 :
1038 52 : FSHelperPtr pFS = GetFS();
1039 : pFS->startElement( FSNS( XML_c, XML_plotArea ),
1040 26 : FSEND );
1041 : // layout
1042 : pFS->singleElement( FSNS( XML_c, XML_layout ),
1043 26 : FSEND );
1044 :
1045 : // chart type
1046 : Sequence< Reference< chart2::XCoordinateSystem > >
1047 52 : aCooSysSeq( xBCooSysCnt->getCoordinateSystems());
1048 52 : for( sal_Int32 nCSIdx=0; nCSIdx<aCooSysSeq.getLength(); ++nCSIdx )
1049 : {
1050 :
1051 26 : Reference< chart2::XChartTypeContainer > xCTCnt( aCooSysSeq[nCSIdx], uno::UNO_QUERY );
1052 26 : if( ! xCTCnt.is())
1053 0 : continue;
1054 26 : mnSeriesCount=0;
1055 52 : Sequence< Reference< chart2::XChartType > > aCTSeq( xCTCnt->getChartTypes());
1056 54 : for( sal_Int32 nCTIdx=0; nCTIdx<aCTSeq.getLength(); ++nCTIdx )
1057 : {
1058 28 : Reference< chart2::XDataSeriesContainer > xDSCnt( aCTSeq[nCTIdx], uno::UNO_QUERY );
1059 28 : if( ! xDSCnt.is())
1060 0 : return;
1061 56 : Reference< chart2::XChartType > xChartType( aCTSeq[nCTIdx], uno::UNO_QUERY );
1062 28 : if( ! xChartType.is())
1063 0 : continue;
1064 : // note: if xDSCnt.is() then also aCTSeq[nCTIdx]
1065 56 : OUString aChartType( xChartType->getChartType());
1066 28 : sal_Int32 eChartType = lcl_getChartType( aChartType );
1067 28 : switch( eChartType )
1068 : {
1069 : case chart::TYPEID_BAR:
1070 : {
1071 16 : exportBarChart( xChartType );
1072 16 : break;
1073 : }
1074 : case chart::TYPEID_AREA:
1075 : {
1076 1 : exportAreaChart( xChartType );
1077 1 : break;
1078 : }
1079 : case chart::TYPEID_LINE:
1080 : {
1081 3 : exportLineChart( xChartType );
1082 3 : break;
1083 : }
1084 : case chart::TYPEID_BUBBLE:
1085 : {
1086 0 : exportBubbleChart( xChartType );
1087 0 : break;
1088 : }
1089 : case chart::TYPEID_OFPIE:
1090 : {
1091 0 : exportOfPieChart( xChartType );
1092 0 : break;
1093 : }
1094 : case chart::TYPEID_DOUGHNUT:
1095 : case chart::TYPEID_PIE:
1096 : {
1097 4 : exportPieChart( xChartType );
1098 4 : break;
1099 : }
1100 : case chart::TYPEID_RADARLINE:
1101 : case chart::TYPEID_RADARAREA:
1102 : {
1103 0 : exportRadarChart( xChartType );
1104 0 : break;
1105 : }
1106 : case chart::TYPEID_SCATTER:
1107 : {
1108 3 : exportScatterChart( xChartType );
1109 3 : break;
1110 : }
1111 : case chart::TYPEID_STOCK:
1112 : {
1113 1 : exportStockChart( xChartType );
1114 1 : break;
1115 : }
1116 : case chart::TYPEID_SURFACE:
1117 : {
1118 0 : exportSuffaceChart( xChartType );
1119 0 : break;
1120 : }
1121 : default:
1122 : {
1123 : OSL_TRACE("ChartExport::exportPlotArea -- not support chart type");
1124 0 : break;
1125 : }
1126 : }
1127 :
1128 28 : }
1129 26 : }
1130 : //Axis Data
1131 26 : exportAxes( );
1132 : // Data Table
1133 26 : exportDataTable();
1134 :
1135 : // shape properties
1136 : /*
1137 : * Export the Plot area Shape Properties
1138 : * eg: Fill and Outline
1139 : */
1140 26 : Reference< ::com::sun::star::chart::X3DDisplay > xWallFloorSupplier( mxDiagram, uno::UNO_QUERY );
1141 26 : if( xWallFloorSupplier.is() )
1142 : {
1143 26 : Reference< beans::XPropertySet > xWallPropSet( xWallFloorSupplier->getWall(), uno::UNO_QUERY );
1144 26 : if( xWallPropSet.is() )
1145 : {
1146 26 : exportPlotAreaShapeProps( xWallPropSet );
1147 26 : }
1148 : }
1149 :
1150 52 : pFS->endElement( FSNS( XML_c, XML_plotArea ) );
1151 :
1152 : }
1153 :
1154 26 : void ChartExport::exportPlotAreaShapeProps( Reference< XPropertySet > xPropSet )
1155 : {
1156 26 : FSHelperPtr pFS = GetFS();
1157 : pFS->startElement( FSNS( XML_c, XML_spPr ),
1158 26 : FSEND );
1159 :
1160 26 : exportFill( xPropSet );
1161 26 : WriteOutline( xPropSet );
1162 :
1163 26 : pFS->endElement( FSNS( XML_c, XML_spPr ) );
1164 26 : }
1165 :
1166 26 : void ChartExport::exportFill( Reference< XPropertySet > xPropSet )
1167 : {
1168 26 : if ( !GetProperty( xPropSet, "FillStyle" ) )
1169 26 : return;
1170 26 : FillStyle aFillStyle( FillStyle_NONE );
1171 26 : xPropSet->getPropertyValue( "FillStyle" ) >>= aFillStyle;
1172 26 : switch( aFillStyle )
1173 : {
1174 : case FillStyle_GRADIENT :
1175 0 : exportGradientFill( xPropSet );
1176 0 : break;
1177 : case FillStyle_BITMAP :
1178 1 : exportBitmapFill( xPropSet );
1179 1 : break;
1180 : default:
1181 25 : WriteFill( xPropSet );
1182 : }
1183 : }
1184 :
1185 1 : void ChartExport::exportBitmapFill( Reference< XPropertySet > xPropSet )
1186 : {
1187 1 : if( xPropSet.is() )
1188 : {
1189 1 : OUString sFillGradientName;
1190 1 : xPropSet->getPropertyValue("FillBitmapName") >>= sFillGradientName;
1191 :
1192 2 : uno::Reference< lang::XMultiServiceFactory > xFact( getModel(), uno::UNO_QUERY );
1193 : try
1194 : {
1195 1 : uno::Reference< container::XNameAccess > xGradient( xFact->createInstance("com.sun.star.drawing.BitmapTable"), uno::UNO_QUERY );
1196 2 : uno::Any rValue = xGradient->getByName( sFillGradientName );
1197 2 : OUString sBitmapURL;
1198 1 : if( (rValue >>= sBitmapURL) )
1199 : {
1200 1 : WriteBlipFill( xPropSet, sBitmapURL, XML_a, true, true );
1201 1 : }
1202 : }
1203 0 : catch (const uno::Exception & rEx)
1204 : {
1205 : SAL_INFO("oox", "ChartExport::exportBitmapFill " << rEx.Message);
1206 1 : }
1207 :
1208 : }
1209 1 : }
1210 :
1211 0 : void ChartExport::exportGradientFill( Reference< XPropertySet > xPropSet )
1212 : {
1213 0 : if( xPropSet.is() )
1214 : {
1215 0 : OUString sFillGradientName;
1216 0 : xPropSet->getPropertyValue("FillGradientName") >>= sFillGradientName;
1217 :
1218 0 : awt::Gradient aGradient;
1219 0 : uno::Reference< lang::XMultiServiceFactory > xFact( getModel(), uno::UNO_QUERY );
1220 : try
1221 : {
1222 0 : uno::Reference< container::XNameAccess > xGradient( xFact->createInstance("com.sun.star.drawing.GradientTable"), uno::UNO_QUERY );
1223 0 : uno::Any rValue = xGradient->getByName( sFillGradientName );
1224 0 : if( (rValue >>= aGradient) )
1225 : {
1226 0 : mpFS->startElementNS( XML_a, XML_gradFill, FSEND );
1227 0 : WriteGradientFill( aGradient );
1228 0 : mpFS->endElementNS( XML_a, XML_gradFill );
1229 0 : }
1230 : }
1231 0 : catch (const uno::Exception & rEx)
1232 : {
1233 : SAL_INFO("oox",
1234 : "ChartExport::exportGradientFill " << rEx.Message);
1235 0 : }
1236 :
1237 : }
1238 0 : }
1239 :
1240 26 : void ChartExport::exportDataTable( )
1241 : {
1242 26 : FSHelperPtr pFS = GetFS();
1243 52 : Reference< beans::XPropertySet > aPropSet( mxDiagram, uno::UNO_QUERY );
1244 :
1245 26 : sal_Bool bShowVBorder = sal_False;
1246 26 : sal_Bool bShowHBorder = sal_False;
1247 26 : sal_Bool bShowOutline = sal_False;
1248 :
1249 26 : if (GetProperty( aPropSet, "DataTableHBorder"))
1250 26 : mAny >>= bShowHBorder;
1251 26 : if (GetProperty( aPropSet, "DataTableVBorder"))
1252 26 : mAny >>= bShowVBorder;
1253 26 : if (GetProperty( aPropSet, "DataTableOutline"))
1254 26 : mAny >>= bShowOutline;
1255 :
1256 26 : if (bShowVBorder || bShowHBorder || bShowOutline)
1257 : {
1258 : pFS->startElement( FSNS( XML_c, XML_dTable),
1259 5 : FSEND );
1260 5 : if (bShowHBorder)
1261 : pFS->singleElement( FSNS( XML_c, XML_showHorzBorder ),
1262 : XML_val, "1",
1263 5 : FSEND );
1264 5 : if (bShowVBorder)
1265 : pFS->singleElement( FSNS( XML_c, XML_showVertBorder ),
1266 : XML_val, "1",
1267 5 : FSEND );
1268 5 : if (bShowOutline)
1269 : pFS->singleElement( FSNS( XML_c, XML_showOutline ),
1270 : XML_val, "1",
1271 5 : FSEND );
1272 :
1273 5 : pFS->endElement( FSNS( XML_c, XML_dTable));
1274 26 : }
1275 :
1276 26 : }
1277 1 : void ChartExport::exportAreaChart( Reference< chart2::XChartType > xChartType )
1278 : {
1279 1 : FSHelperPtr pFS = GetFS();
1280 1 : sal_Int32 nTypeId = XML_areaChart;
1281 1 : if( mbIs3DChart )
1282 0 : nTypeId = XML_area3DChart;
1283 : pFS->startElement( FSNS( XML_c, nTypeId ),
1284 1 : FSEND );
1285 :
1286 1 : exportGrouping( );
1287 1 : sal_Int32 nAttachedAxis = AXIS_PRIMARY_Y;
1288 1 : exportSeries( xChartType, nAttachedAxis );
1289 1 : exportAxesId( nAttachedAxis );
1290 :
1291 1 : pFS->endElement( FSNS( XML_c, nTypeId ) );
1292 1 : }
1293 :
1294 16 : void ChartExport::exportBarChart( Reference< chart2::XChartType > xChartType )
1295 : {
1296 16 : sal_Int32 nTypeId = XML_barChart;
1297 16 : if( mbIs3DChart )
1298 9 : nTypeId = XML_bar3DChart;
1299 16 : FSHelperPtr pFS = GetFS();
1300 : pFS->startElement( FSNS( XML_c, nTypeId ),
1301 16 : FSEND );
1302 : // bar direction
1303 16 : sal_Bool bVertical = sal_False;
1304 32 : Reference< XPropertySet > xPropSet( mxDiagram , uno::UNO_QUERY);
1305 16 : if( GetProperty( xPropSet, "Vertical" ) )
1306 16 : mAny >>= bVertical;
1307 :
1308 16 : const char* bardir = bVertical? "bar":"col";
1309 : pFS->singleElement( FSNS( XML_c, XML_barDir ),
1310 : XML_val, bardir,
1311 16 : FSEND );
1312 :
1313 16 : exportGrouping( true );
1314 16 : sal_Int32 nAttachedAxis = AXIS_PRIMARY_Y;
1315 16 : exportSeries( xChartType, nAttachedAxis );
1316 :
1317 32 : Reference< XPropertySet > xTypeProp( xChartType, uno::UNO_QUERY );
1318 :
1319 16 : if( xTypeProp.is() && GetProperty( xTypeProp, "GapwidthSequence") )
1320 : {
1321 16 : uno::Sequence< sal_Int32 > aBarPositionSequence;
1322 16 : mAny >>= aBarPositionSequence;
1323 16 : if( aBarPositionSequence.getLength() )
1324 : {
1325 16 : sal_Int32 nGapWidth = aBarPositionSequence[0];
1326 : pFS->singleElement( FSNS( XML_c, XML_gapWidth ),
1327 : XML_val, I32S( nGapWidth ),
1328 16 : FSEND );
1329 16 : }
1330 : }
1331 :
1332 16 : if( mbIs3DChart )
1333 : {
1334 : // Shape
1335 : namespace cssc = ::com::sun::star::chart;
1336 9 : sal_Int32 nGeom3d = cssc::ChartSolidType::RECTANGULAR_SOLID;
1337 9 : if( xPropSet.is() && GetProperty( xPropSet, "SolidType") )
1338 9 : mAny >>= nGeom3d;
1339 9 : const char* sShapeType = NULL;
1340 9 : switch( nGeom3d )
1341 : {
1342 : case cssc::ChartSolidType::RECTANGULAR_SOLID:
1343 3 : sShapeType = "box";
1344 3 : break;
1345 : case cssc::ChartSolidType::CONE:
1346 4 : sShapeType = "cone";
1347 4 : break;
1348 : case cssc::ChartSolidType::CYLINDER:
1349 2 : sShapeType = "cylinder";
1350 2 : break;
1351 : case cssc::ChartSolidType::PYRAMID:
1352 0 : sShapeType = "pyramid";
1353 0 : break;
1354 : }
1355 : pFS->singleElement( FSNS( XML_c, XML_shape ),
1356 : XML_val, sShapeType,
1357 9 : FSEND );
1358 : }
1359 :
1360 : //overlap
1361 16 : if( !mbIs3DChart && xTypeProp.is() && GetProperty( xTypeProp, "OverlapSequence") )
1362 : {
1363 7 : uno::Sequence< sal_Int32 > aBarPositionSequence;
1364 7 : mAny >>= aBarPositionSequence;
1365 7 : if( aBarPositionSequence.getLength() )
1366 : {
1367 7 : sal_Int32 nOverlap = aBarPositionSequence[0];
1368 : pFS->singleElement( FSNS( XML_c, XML_overlap ),
1369 : XML_val, I32S( nOverlap ),
1370 7 : FSEND );
1371 7 : }
1372 : }
1373 :
1374 16 : exportAxesId( nAttachedAxis );
1375 :
1376 32 : pFS->endElement( FSNS( XML_c, nTypeId ) );
1377 16 : }
1378 :
1379 0 : void ChartExport::exportBubbleChart( Reference< chart2::XChartType > xChartType )
1380 : {
1381 0 : FSHelperPtr pFS = GetFS();
1382 : pFS->startElement( FSNS( XML_c, XML_bubbleChart ),
1383 0 : FSEND );
1384 :
1385 0 : sal_Int32 nAttachedAxis = AXIS_PRIMARY_Y;
1386 0 : exportSeries( xChartType, nAttachedAxis );
1387 0 : exportAxesId( nAttachedAxis );
1388 :
1389 0 : pFS->endElement( FSNS( XML_c, XML_bubbleChart ) );
1390 0 : }
1391 :
1392 1 : void ChartExport::exportDoughnutChart( Reference< chart2::XChartType > xChartType )
1393 : {
1394 1 : FSHelperPtr pFS = GetFS();
1395 : pFS->startElement( FSNS( XML_c, XML_doughnutChart ),
1396 1 : FSEND );
1397 :
1398 1 : sal_Int32 nAttachedAxis = AXIS_PRIMARY_Y;
1399 1 : exportSeries( xChartType, nAttachedAxis );
1400 : // firstSliceAng
1401 1 : exportFirstSliceAng( );
1402 : //FIXME: holeSize
1403 1 : sal_Int32 nHoleSize = 50;
1404 : pFS->singleElement( FSNS( XML_c, XML_holeSize ),
1405 : XML_val, I32S( nHoleSize ),
1406 1 : FSEND );
1407 :
1408 1 : pFS->endElement( FSNS( XML_c, XML_doughnutChart ) );
1409 1 : }
1410 :
1411 3 : void ChartExport::exportLineChart( Reference< chart2::XChartType > xChartType )
1412 : {
1413 3 : FSHelperPtr pFS = GetFS();
1414 3 : sal_Int32 nTypeId = XML_lineChart;
1415 3 : if( mbIs3DChart )
1416 0 : nTypeId = XML_line3DChart;
1417 : pFS->startElement( FSNS( XML_c, nTypeId ),
1418 3 : FSEND );
1419 :
1420 3 : exportGrouping( );
1421 : // TODO: show marker symbol in series?
1422 3 : sal_Int32 nAttachedAxis = AXIS_PRIMARY_Y;
1423 3 : exportSeries( xChartType, nAttachedAxis );
1424 :
1425 : // show marker?
1426 3 : sal_Int32 nSymbolType = ::com::sun::star::chart::ChartSymbolType::NONE;
1427 6 : Reference< XPropertySet > xPropSet( mxDiagram , uno::UNO_QUERY);
1428 3 : if( GetProperty( xPropSet, "SymbolType" ) )
1429 3 : mAny >>= nSymbolType;
1430 :
1431 3 : if( !mbIs3DChart )
1432 : {
1433 3 : exportHiLowLines();
1434 3 : exportUpDownBars(xChartType);
1435 3 : const char* marker = nSymbolType == ::com::sun::star::chart::ChartSymbolType::NONE? "0":"1";
1436 : pFS->singleElement( FSNS( XML_c, XML_marker ),
1437 : XML_val, marker,
1438 3 : FSEND );
1439 : }
1440 :
1441 3 : exportAxesId( nAttachedAxis );
1442 :
1443 6 : pFS->endElement( FSNS( XML_c, nTypeId ) );
1444 3 : }
1445 :
1446 0 : void ChartExport::exportOfPieChart( Reference< chart2::XChartType > /*xChartType*/ )
1447 : {
1448 : // TODO:
1449 0 : }
1450 :
1451 4 : void ChartExport::exportPieChart( Reference< chart2::XChartType > xChartType )
1452 : {
1453 4 : sal_Int32 eChartType = getChartType( );
1454 4 : if(eChartType == chart::TYPEID_DOUGHNUT)
1455 : {
1456 1 : exportDoughnutChart( xChartType );
1457 5 : return;
1458 : }
1459 3 : FSHelperPtr pFS = GetFS();
1460 3 : sal_Int32 nTypeId = XML_pieChart;
1461 3 : if( mbIs3DChart )
1462 2 : nTypeId = XML_pie3DChart;
1463 : pFS->startElement( FSNS( XML_c, nTypeId ),
1464 3 : FSEND );
1465 : // TODO: varyColors
1466 3 : const char* varyColors = "1";
1467 : pFS->singleElement( FSNS( XML_c, XML_varyColors ),
1468 : XML_val, varyColors,
1469 3 : FSEND );
1470 :
1471 3 : sal_Int32 nAttachedAxis = AXIS_PRIMARY_Y;
1472 3 : exportSeries( xChartType, nAttachedAxis );
1473 :
1474 3 : if( !mbIs3DChart )
1475 : {
1476 : // firstSliceAng
1477 1 : exportFirstSliceAng( );
1478 : }
1479 :
1480 3 : pFS->endElement( FSNS( XML_c, nTypeId ) );
1481 : }
1482 :
1483 0 : void ChartExport::exportRadarChart( Reference< chart2::XChartType > xChartType)
1484 : {
1485 0 : FSHelperPtr pFS = GetFS();
1486 : pFS->startElement( FSNS( XML_c, XML_radarChart ),
1487 0 : FSEND );
1488 :
1489 : // radarStyle
1490 0 : sal_Int32 eChartType = getChartType( );
1491 0 : const char* radarStyle = NULL;
1492 0 : if( eChartType == chart::TYPEID_RADARAREA )
1493 0 : radarStyle = "filled";
1494 : else
1495 0 : radarStyle = "marker";
1496 : pFS->singleElement( FSNS( XML_c, XML_radarStyle ),
1497 : XML_val, radarStyle,
1498 0 : FSEND );
1499 0 : sal_Int32 nAttachedAxis = AXIS_PRIMARY_Y;
1500 0 : exportSeries( xChartType, nAttachedAxis );
1501 0 : exportAxesId( nAttachedAxis );
1502 :
1503 0 : pFS->endElement( FSNS( XML_c, XML_radarChart ) );
1504 0 : }
1505 :
1506 3 : void ChartExport::exportScatterChart( Reference< chart2::XChartType > xChartType )
1507 : {
1508 3 : FSHelperPtr pFS = GetFS();
1509 : pFS->startElement( FSNS( XML_c, XML_scatterChart ),
1510 3 : FSEND );
1511 : // TODO:scatterStyle
1512 3 : const char* scatterStyle = "lineMarker";
1513 : pFS->singleElement( FSNS( XML_c, XML_scatterStyle ),
1514 : XML_val, scatterStyle,
1515 3 : FSEND );
1516 :
1517 : pFS->singleElement( FSNS( XML_c, XML_varyColors ),
1518 : XML_val, "0",
1519 3 : FSEND );
1520 :
1521 : // FIXME: should export xVal and yVal
1522 3 : sal_Int32 nAttachedAxis = AXIS_PRIMARY_Y;
1523 3 : exportSeries( xChartType, nAttachedAxis );
1524 3 : exportAxesId( nAttachedAxis );
1525 :
1526 3 : pFS->endElement( FSNS( XML_c, XML_scatterChart ) );
1527 3 : }
1528 :
1529 1 : void ChartExport::exportStockChart( Reference< chart2::XChartType > xChartType )
1530 : {
1531 1 : FSHelperPtr pFS = GetFS();
1532 : pFS->startElement( FSNS( XML_c, XML_stockChart ),
1533 1 : FSEND );
1534 :
1535 1 : sal_Int32 nAttachedAxis = AXIS_PRIMARY_Y;
1536 1 : exportSeries( xChartType, nAttachedAxis );
1537 : // export stock properties
1538 2 : Reference< ::com::sun::star::chart::XStatisticDisplay > xStockPropProvider( mxDiagram, uno::UNO_QUERY );
1539 1 : if( xStockPropProvider.is())
1540 : {
1541 1 : exportHiLowLines();
1542 1 : exportUpDownBars(xChartType);
1543 : }
1544 :
1545 1 : exportAxesId( nAttachedAxis );
1546 :
1547 2 : pFS->endElement( FSNS( XML_c, XML_stockChart ) );
1548 1 : }
1549 :
1550 4 : void ChartExport::exportHiLowLines()
1551 : {
1552 4 : FSHelperPtr pFS = GetFS();
1553 : // export the chart property
1554 8 : Reference< ::com::sun::star::chart::XStatisticDisplay > xChartPropProvider( mxDiagram, uno::UNO_QUERY );
1555 :
1556 4 : if (!xChartPropProvider.is())
1557 4 : return;
1558 :
1559 8 : Reference< beans::XPropertySet > xStockPropSet = xChartPropProvider->getMinMaxLine();
1560 4 : if( xStockPropSet.is() )
1561 : {
1562 : pFS->startElement( FSNS( XML_c, XML_hiLowLines ),
1563 4 : FSEND );
1564 4 : exportShapeProps( xStockPropSet );
1565 4 : pFS->endElement( FSNS( XML_c, XML_hiLowLines ) );
1566 4 : }
1567 : }
1568 :
1569 4 : void ChartExport::exportUpDownBars( Reference< chart2::XChartType > xChartType)
1570 : {
1571 4 : FSHelperPtr pFS = GetFS();
1572 : // export the chart property
1573 8 : Reference< ::com::sun::star::chart::XStatisticDisplay > xChartPropProvider( mxDiagram, uno::UNO_QUERY );
1574 4 : if(xChartPropProvider.is())
1575 : {
1576 4 : Reference< beans::XPropertySet > xChartPropSet = xChartPropProvider->getMinMaxLine();
1577 : // updownbar
1578 : pFS->startElement( FSNS( XML_c, XML_upDownBars ),
1579 4 : FSEND );
1580 : // TODO: gapWidth
1581 4 : sal_Int32 nGapWidth = 150;
1582 : pFS->singleElement( FSNS( XML_c, XML_gapWidth ),
1583 : XML_val, I32S( nGapWidth ),
1584 4 : FSEND );
1585 :
1586 4 : xChartPropSet = xChartPropProvider->getUpBar();
1587 4 : if( xChartPropSet.is() )
1588 : {
1589 : pFS->startElement( FSNS( XML_c, XML_upBars ),
1590 4 : FSEND );
1591 : // For Linechart with UpDownBars, spPr is not getting imported
1592 : // so no need to call the exportShapeProps() for LineChart
1593 4 : if(xChartType->getChartType().equals("com.sun.star.chart2.CandleStickChartType"))
1594 : {
1595 1 : exportShapeProps(xChartPropSet);
1596 : }
1597 4 : pFS->endElement( FSNS( XML_c, XML_upBars ) );
1598 : }
1599 4 : xChartPropSet = xChartPropProvider->getDownBar();
1600 4 : if( xChartPropSet.is() )
1601 : {
1602 : pFS->startElement( FSNS( XML_c, XML_downBars ),
1603 4 : FSEND );
1604 4 : if(xChartType->getChartType().equals("com.sun.star.chart2.CandleStickChartType"))
1605 : {
1606 1 : exportShapeProps(xChartPropSet);
1607 : }
1608 4 : pFS->endElement( FSNS( XML_c, XML_downBars ) );
1609 : }
1610 4 : pFS->endElement( FSNS( XML_c, XML_upDownBars ) );
1611 4 : }
1612 4 : }
1613 :
1614 0 : void ChartExport::exportSuffaceChart( Reference< chart2::XChartType > xChartType )
1615 : {
1616 0 : FSHelperPtr pFS = GetFS();
1617 0 : sal_Int32 nTypeId = XML_surfaceChart;
1618 0 : if( mbIs3DChart )
1619 0 : nTypeId = XML_surface3DChart;
1620 : pFS->startElement( FSNS( XML_c, nTypeId ),
1621 0 : FSEND );
1622 0 : sal_Int32 nAttachedAxis = AXIS_PRIMARY_Y;
1623 0 : exportSeries( xChartType, nAttachedAxis );
1624 0 : exportAxesId( nAttachedAxis );
1625 :
1626 0 : pFS->endElement( FSNS( XML_c, nTypeId ) );
1627 0 : }
1628 :
1629 28 : void ChartExport::exportSeries( Reference< chart2::XChartType > xChartType, sal_Int32& nAttachedAxis )
1630 : {
1631 :
1632 28 : OUString aLabelRole = xChartType->getRoleOfSequenceForSeriesLabel();
1633 55 : Reference< chart2::XDataSeriesContainer > xDSCnt( xChartType, uno::UNO_QUERY );
1634 28 : if( ! xDSCnt.is())
1635 0 : return;
1636 :
1637 55 : OUString aChartType( xChartType->getChartType());
1638 28 : sal_Int32 eChartType = lcl_getChartType( aChartType );
1639 :
1640 : // special export for stock charts
1641 28 : if( eChartType == chart::TYPEID_STOCK )
1642 : {
1643 1 : sal_Bool bJapaneseCandleSticks = sal_False;
1644 1 : Reference< beans::XPropertySet > xCTProp( xChartType, uno::UNO_QUERY );
1645 1 : if( xCTProp.is())
1646 1 : xCTProp->getPropertyValue("Japanese") >>= bJapaneseCandleSticks;
1647 : exportCandleStickSeries(
1648 1 : xDSCnt->getDataSeries(), bJapaneseCandleSticks, nAttachedAxis );
1649 1 : return;
1650 : }
1651 :
1652 :
1653 : // export dataseries for current chart-type
1654 54 : Sequence< Reference< chart2::XDataSeries > > aSeriesSeq( xDSCnt->getDataSeries());
1655 87 : for( sal_Int32 nSeriesIdx=0; nSeriesIdx<aSeriesSeq.getLength(); ++nSeriesIdx )
1656 : {
1657 : // export series
1658 60 : Reference< chart2::data::XDataSource > xSource( aSeriesSeq[nSeriesIdx], uno::UNO_QUERY );
1659 60 : if( xSource.is())
1660 : {
1661 60 : Reference< chart2::XDataSeries > xDataSeries( xSource, uno::UNO_QUERY );
1662 : Sequence< Reference< chart2::data::XLabeledDataSequence > > aSeqCnt(
1663 120 : xSource->getDataSequences());
1664 : // search for main sequence and create a series element
1665 : {
1666 60 : sal_Int32 nMainSequenceIndex = -1;
1667 60 : sal_Int32 nSeriesLength = 0;
1668 60 : Reference< chart2::data::XDataSequence > xValuesSeq;
1669 120 : Reference< chart2::data::XDataSequence > xLabelSeq;
1670 60 : sal_Int32 nSeqIdx=0;
1671 121 : for( ; nSeqIdx<aSeqCnt.getLength(); ++nSeqIdx )
1672 : {
1673 61 : OUString aRole;
1674 122 : Reference< chart2::data::XDataSequence > xTempValueSeq( aSeqCnt[nSeqIdx]->getValues() );
1675 61 : if( nMainSequenceIndex==-1 )
1676 : {
1677 61 : Reference< beans::XPropertySet > xSeqProp( xTempValueSeq, uno::UNO_QUERY );
1678 61 : if( xSeqProp.is())
1679 61 : xSeqProp->getPropertyValue("Role") >>= aRole;
1680 : // "main" sequence
1681 61 : if( aRole.equals( aLabelRole ))
1682 : {
1683 58 : xValuesSeq.set( xTempValueSeq );
1684 58 : xLabelSeq.set( aSeqCnt[nSeqIdx]->getLabel());
1685 58 : nMainSequenceIndex = nSeqIdx;
1686 61 : }
1687 : }
1688 61 : sal_Int32 nSequenceLength = (xTempValueSeq.is()? xTempValueSeq->getData().getLength() : sal_Int32(0));
1689 61 : if( nSeriesLength < nSequenceLength )
1690 58 : nSeriesLength = nSequenceLength;
1691 61 : }
1692 :
1693 : // have found the main sequence, then xValuesSeq and
1694 : // xLabelSeq contain those. Otherwise both are empty
1695 : {
1696 60 : FSHelperPtr pFS = GetFS();
1697 : pFS->startElement( FSNS( XML_c, XML_ser ),
1698 60 : FSEND );
1699 :
1700 : // TODO: idx and order
1701 : pFS->singleElement( FSNS( XML_c, XML_idx ),
1702 : XML_val, I32S(mnSeriesCount),
1703 60 : FSEND );
1704 : pFS->singleElement( FSNS( XML_c, XML_order ),
1705 : XML_val, I32S(mnSeriesCount++),
1706 60 : FSEND );
1707 :
1708 : // export label
1709 60 : if( xLabelSeq.is() )
1710 58 : exportSeriesText( xLabelSeq );
1711 :
1712 : // export shape properties
1713 : Reference< XPropertySet > xPropSet = SchXMLSeriesHelper::createOldAPISeriesPropertySet(
1714 120 : aSeriesSeq[nSeriesIdx], getModel() );
1715 60 : if( xPropSet.is() )
1716 : {
1717 60 : if( GetProperty( xPropSet, "Axis") )
1718 : {
1719 60 : mAny >>= nAttachedAxis;
1720 60 : if( nAttachedAxis == ::com::sun::star::chart::ChartAxisAssign::SECONDARY_Y )
1721 1 : nAttachedAxis = AXIS_SECONDARY_Y;
1722 : else
1723 59 : nAttachedAxis = AXIS_PRIMARY_Y;
1724 : }
1725 60 : exportShapeProps( xPropSet );
1726 : }
1727 :
1728 60 : switch( eChartType )
1729 : {
1730 : case chart::TYPEID_LINE:
1731 : {
1732 6 : exportMarker(xDataSeries);
1733 6 : break;
1734 : }
1735 : case chart::TYPEID_PIE:
1736 : case chart::TYPEID_DOUGHNUT:
1737 : {
1738 4 : if( xPropSet.is() && GetProperty( xPropSet, "SegmentOffset") )
1739 : {
1740 4 : sal_Int32 nOffset = 0;
1741 4 : mAny >>= nOffset;
1742 : pFS->singleElement( FSNS( XML_c, XML_explosion ),
1743 : XML_val, I32S( nOffset ),
1744 4 : FSEND );
1745 : }
1746 4 : break;
1747 : }
1748 : case chart::TYPEID_SCATTER:
1749 : {
1750 3 : exportMarker(xDataSeries);
1751 3 : break;
1752 : }
1753 : case chart::TYPEID_RADARLINE:
1754 : {
1755 0 : exportMarker(xDataSeries);
1756 0 : break;
1757 : }
1758 : }
1759 :
1760 : // export data points
1761 60 : exportDataPoints( uno::Reference< beans::XPropertySet >( aSeriesSeq[nSeriesIdx], uno::UNO_QUERY ), nSeriesLength );
1762 :
1763 : // export data labels
1764 : // Excel does not like our current data label export
1765 : // for scatter charts
1766 60 : if( eChartType != chart::TYPEID_SCATTER && eChartType != chart::TYPEID_BAR )
1767 11 : exportDataLabels( uno::Reference< beans::XPropertySet >( aSeriesSeq[nSeriesIdx], uno::UNO_QUERY ), nSeriesLength );
1768 :
1769 60 : exportTrendlines( aSeriesSeq[nSeriesIdx] );
1770 :
1771 60 : if( eChartType != chart::TYPEID_PIE &&
1772 : eChartType != chart::TYPEID_RADARLINE )
1773 : {
1774 : //export error bars here
1775 56 : Reference< XPropertySet > xSeriesPropSet( xSource, uno::UNO_QUERY );
1776 112 : Reference< XPropertySet > xErrorBarYProps;
1777 56 : xSeriesPropSet->getPropertyValue("ErrorBarY") >>= xErrorBarYProps;
1778 56 : if(xErrorBarYProps.is())
1779 1 : exportErrorBar(xErrorBarYProps, true);
1780 112 : Reference< XPropertySet > xErrorBarXProps;
1781 56 : xSeriesPropSet->getPropertyValue("ErrorBarX") >>= xErrorBarXProps;
1782 56 : if(xErrorBarXProps.is())
1783 56 : exportErrorBar(xErrorBarXProps, false);
1784 : }
1785 :
1786 : // export categories
1787 60 : if( eChartType != chart::TYPEID_SCATTER && mxCategoriesValues.is() )
1788 49 : exportSeriesCategory( mxCategoriesValues );
1789 :
1790 60 : if( (eChartType == chart::TYPEID_SCATTER)
1791 57 : || (eChartType == chart::TYPEID_BUBBLE) )
1792 : {
1793 : // export xVal
1794 3 : Reference< chart2::data::XLabeledDataSequence > xSequence( lcl_getDataSequenceByRole( aSeqCnt, OUString("values-x") ) );
1795 3 : if( xSequence.is() )
1796 : {
1797 3 : Reference< chart2::data::XDataSequence > xValues( xSequence->getValues() );
1798 3 : if( xValues.is() )
1799 3 : exportSeriesValues( xValues, XML_xVal );
1800 3 : }
1801 : }
1802 :
1803 :
1804 60 : if( eChartType == chart::TYPEID_BUBBLE )
1805 : {
1806 : // export yVal
1807 0 : Reference< chart2::data::XLabeledDataSequence > xSequence( lcl_getDataSequenceByRole( aSeqCnt, OUString("values-y") ) );
1808 0 : if( xSequence.is() )
1809 : {
1810 0 : Reference< chart2::data::XDataSequence > xValues( xSequence->getValues() );
1811 0 : if( xValues.is() )
1812 0 : exportSeriesValues( xValues, XML_yVal );
1813 0 : }
1814 : }
1815 :
1816 : // export values
1817 60 : if( xValuesSeq.is() )
1818 : {
1819 58 : sal_Int32 nYValueType = XML_val;
1820 58 : if( eChartType == chart::TYPEID_SCATTER )
1821 3 : nYValueType = XML_yVal;
1822 55 : else if( eChartType == chart::TYPEID_BUBBLE )
1823 0 : nYValueType = XML_bubbleSize;
1824 58 : exportSeriesValues( xValuesSeq, nYValueType );
1825 : }
1826 :
1827 60 : if( eChartType == chart::TYPEID_SCATTER
1828 57 : || eChartType == chart::TYPEID_LINE )
1829 9 : exportSmooth();
1830 :
1831 120 : pFS->endElement( FSNS( XML_c, XML_ser ) );
1832 60 : }
1833 60 : }
1834 : }
1835 87 : }
1836 : }
1837 :
1838 1 : void ChartExport::exportCandleStickSeries(
1839 : const Sequence< Reference< chart2::XDataSeries > > & aSeriesSeq,
1840 : bool /*bJapaneseCandleSticks*/,
1841 : sal_Int32& nAttachedAxis )
1842 : {
1843 2 : for( sal_Int32 nSeriesIdx=0; nSeriesIdx<aSeriesSeq.getLength(); ++nSeriesIdx )
1844 : {
1845 1 : Reference< chart2::XDataSeries > xSeries( aSeriesSeq[nSeriesIdx] );
1846 1 : nAttachedAxis = lcl_isSeriesAttachedToFirstAxis( xSeries ) ? AXIS_PRIMARY_Y : AXIS_SECONDARY_Y;
1847 :
1848 2 : Reference< chart2::data::XDataSource > xSource( xSeries, uno::UNO_QUERY );
1849 1 : if( xSource.is())
1850 : {
1851 : // export series in correct order (as we don't store roles)
1852 : // with japanese candlesticks: open, low, high, close
1853 : // otherwise: low, high, close
1854 : Sequence< Reference< chart2::data::XLabeledDataSequence > > aSeqCnt(
1855 1 : xSource->getDataSequences());
1856 :
1857 2 : Reference< chart2::XChartDocument > xNewDoc( getModel(), uno::UNO_QUERY );
1858 1 : const char* sSeries[] = {"values-first","values-max","values-min","values-last",0};
1859 :
1860 5 : for( sal_Int32 idx = 0; sSeries[idx] != 0 ; idx++ )
1861 : {
1862 4 : Reference< chart2::data::XLabeledDataSequence > xLabeledSeq( lcl_getDataSequenceByRole( aSeqCnt, OUString::createFromAscii(sSeries[idx]) ) );
1863 4 : if( xLabeledSeq.is())
1864 : {
1865 4 : Reference< chart2::data::XDataSequence > xLabelSeq( xLabeledSeq->getLabel());
1866 8 : Reference< chart2::data::XDataSequence > xValueSeq( xLabeledSeq->getValues());
1867 : {
1868 4 : FSHelperPtr pFS = GetFS();
1869 : pFS->startElement( FSNS( XML_c, XML_ser ),
1870 4 : FSEND );
1871 :
1872 : // TODO: idx and order
1873 : // idx attribute should start from 1 and not from 0.
1874 : pFS->singleElement( FSNS( XML_c, XML_idx ),
1875 : XML_val, I32S(idx+1),
1876 4 : FSEND );
1877 : pFS->singleElement( FSNS( XML_c, XML_order ),
1878 : XML_val, I32S(idx+1),
1879 4 : FSEND );
1880 :
1881 : // export label
1882 4 : if( xLabelSeq.is() )
1883 4 : exportSeriesText( xLabelSeq );
1884 :
1885 : // TODO:export shape properties
1886 :
1887 : // export categories
1888 4 : if( mxCategoriesValues.is() )
1889 4 : exportSeriesCategory( mxCategoriesValues );
1890 :
1891 : // export values
1892 4 : if( xValueSeq.is() )
1893 4 : exportSeriesValues( xValueSeq );
1894 :
1895 4 : pFS->endElement( FSNS( XML_c, XML_ser ) );
1896 4 : }
1897 : }
1898 5 : }
1899 : }
1900 1 : }
1901 1 : }
1902 :
1903 62 : void ChartExport::exportSeriesText( const Reference< chart2::data::XDataSequence > & xValueSeq )
1904 : {
1905 62 : FSHelperPtr pFS = GetFS();
1906 124 : Reference< chart2::XChartDocument > xNewDoc( getModel(), uno::UNO_QUERY );
1907 : pFS->startElement( FSNS( XML_c, XML_tx ),
1908 62 : FSEND );
1909 :
1910 124 : OUString aCellRange = xValueSeq->getSourceRangeRepresentation();
1911 62 : aCellRange = parseFormula( aCellRange );
1912 : pFS->startElement( FSNS( XML_c, XML_strRef ),
1913 62 : FSEND );
1914 :
1915 : pFS->startElement( FSNS( XML_c, XML_f ),
1916 62 : FSEND );
1917 62 : pFS->writeEscaped( aCellRange );
1918 62 : pFS->endElement( FSNS( XML_c, XML_f ) );
1919 :
1920 124 : OUString aLabelString = lcl_getLabelString( xValueSeq );
1921 : pFS->startElement( FSNS( XML_c, XML_strCache ),
1922 62 : FSEND );
1923 : pFS->singleElement( FSNS( XML_c, XML_ptCount ),
1924 : XML_val, "1",
1925 62 : FSEND );
1926 : pFS->startElement( FSNS( XML_c, XML_pt ),
1927 : XML_idx, "0",
1928 62 : FSEND );
1929 : pFS->startElement( FSNS( XML_c, XML_v ),
1930 62 : FSEND );
1931 62 : pFS->writeEscaped( aLabelString );
1932 62 : pFS->endElement( FSNS( XML_c, XML_v ) );
1933 62 : pFS->endElement( FSNS( XML_c, XML_pt ) );
1934 62 : pFS->endElement( FSNS( XML_c, XML_strCache ) );
1935 62 : pFS->endElement( FSNS( XML_c, XML_strRef ) );
1936 124 : pFS->endElement( FSNS( XML_c, XML_tx ) );
1937 62 : }
1938 :
1939 53 : void ChartExport::exportSeriesCategory( const Reference< chart2::data::XDataSequence > & xValueSeq )
1940 : {
1941 53 : FSHelperPtr pFS = GetFS();
1942 106 : Reference< chart2::XChartDocument > xNewDoc( getModel(), uno::UNO_QUERY );
1943 : pFS->startElement( FSNS( XML_c, XML_cat ),
1944 53 : FSEND );
1945 :
1946 106 : OUString aCellRange = xValueSeq->getSourceRangeRepresentation();
1947 53 : aCellRange = parseFormula( aCellRange );
1948 : // TODO: need to handle XML_multiLvlStrRef according to aCellRange
1949 : pFS->startElement( FSNS( XML_c, XML_strRef ),
1950 53 : FSEND );
1951 :
1952 : pFS->startElement( FSNS( XML_c, XML_f ),
1953 53 : FSEND );
1954 53 : pFS->writeEscaped( aCellRange );
1955 53 : pFS->endElement( FSNS( XML_c, XML_f ) );
1956 :
1957 106 : ::std::vector< OUString > aCategories;
1958 53 : lcl_fillCategoriesIntoStringVector( xValueSeq, aCategories );
1959 53 : sal_Int32 ptCount = aCategories.size();
1960 : pFS->startElement( FSNS( XML_c, XML_strCache ),
1961 53 : FSEND );
1962 : pFS->singleElement( FSNS( XML_c, XML_ptCount ),
1963 : XML_val, I32S( ptCount ),
1964 53 : FSEND );
1965 307 : for( sal_Int32 i = 0; i < ptCount; i++ )
1966 : {
1967 : pFS->startElement( FSNS( XML_c, XML_pt ),
1968 : XML_idx, I32S( i ),
1969 254 : FSEND );
1970 : pFS->startElement( FSNS( XML_c, XML_v ),
1971 254 : FSEND );
1972 254 : pFS->writeEscaped( aCategories[i] );
1973 254 : pFS->endElement( FSNS( XML_c, XML_v ) );
1974 254 : pFS->endElement( FSNS( XML_c, XML_pt ) );
1975 : }
1976 :
1977 53 : pFS->endElement( FSNS( XML_c, XML_strCache ) );
1978 53 : pFS->endElement( FSNS( XML_c, XML_strRef ) );
1979 106 : pFS->endElement( FSNS( XML_c, XML_cat ) );
1980 53 : }
1981 :
1982 65 : void ChartExport::exportSeriesValues( const Reference< chart2::data::XDataSequence > & xValueSeq, sal_Int32 nValueType )
1983 : {
1984 65 : FSHelperPtr pFS = GetFS();
1985 130 : Reference< chart2::XChartDocument > xNewDoc( getModel(), uno::UNO_QUERY );
1986 : pFS->startElement( FSNS( XML_c, nValueType ),
1987 65 : FSEND );
1988 :
1989 130 : OUString aCellRange = xValueSeq->getSourceRangeRepresentation();
1990 65 : aCellRange = parseFormula( aCellRange );
1991 : // TODO: need to handle XML_multiLvlStrRef according to aCellRange
1992 : pFS->startElement( FSNS( XML_c, XML_numRef ),
1993 65 : FSEND );
1994 :
1995 : pFS->startElement( FSNS( XML_c, XML_f ),
1996 65 : FSEND );
1997 65 : pFS->writeEscaped( aCellRange );
1998 65 : pFS->endElement( FSNS( XML_c, XML_f ) );
1999 :
2000 130 : ::std::vector< double > aValues;
2001 65 : aValues = lcl_getAllValuesFromSequence( xValueSeq );
2002 65 : sal_Int32 ptCount = aValues.size();
2003 : pFS->startElement( FSNS( XML_c, XML_numCache ),
2004 65 : FSEND );
2005 : pFS->startElement( FSNS( XML_c, XML_formatCode ),
2006 65 : FSEND );
2007 : // TODO: what format code?
2008 65 : pFS->writeEscaped( "General" );
2009 65 : pFS->endElement( FSNS( XML_c, XML_formatCode ) );
2010 : pFS->singleElement( FSNS( XML_c, XML_ptCount ),
2011 : XML_val, I32S( ptCount ),
2012 65 : FSEND );
2013 373 : for( sal_Int32 i = 0; i < ptCount; i++ )
2014 : {
2015 : pFS->startElement( FSNS( XML_c, XML_pt ),
2016 : XML_idx, I32S( i ),
2017 308 : FSEND );
2018 : pFS->startElement( FSNS( XML_c, XML_v ),
2019 308 : FSEND );
2020 308 : if (!rtl::math::isNan(aValues[i]))
2021 308 : pFS->write( aValues[i] );
2022 308 : pFS->endElement( FSNS( XML_c, XML_v ) );
2023 308 : pFS->endElement( FSNS( XML_c, XML_pt ) );
2024 : }
2025 :
2026 65 : pFS->endElement( FSNS( XML_c, XML_numCache ) );
2027 65 : pFS->endElement( FSNS( XML_c, XML_numRef ) );
2028 130 : pFS->endElement( FSNS( XML_c, nValueType ) );
2029 65 : }
2030 :
2031 242 : void ChartExport::exportShapeProps( Reference< XPropertySet > xPropSet )
2032 : {
2033 242 : FSHelperPtr pFS = GetFS();
2034 : pFS->startElement( FSNS( XML_c, XML_spPr ),
2035 242 : FSEND );
2036 :
2037 242 : WriteFill( xPropSet );
2038 242 : WriteOutline( xPropSet );
2039 :
2040 242 : pFS->endElement( FSNS( XML_c, XML_spPr ) );
2041 242 : }
2042 :
2043 26 : void ChartExport::InitPlotArea( )
2044 : {
2045 26 : Reference< XPropertySet > xDiagramProperties (mxDiagram, uno::UNO_QUERY);
2046 :
2047 : // Check for supported services and then the properties provided by this service.
2048 52 : Reference<lang::XServiceInfo> xServiceInfo (mxDiagram, uno::UNO_QUERY);
2049 26 : if (xServiceInfo.is())
2050 : {
2051 78 : if (xServiceInfo->supportsService(
2052 52 : OUString("com.sun.star.chart.ChartAxisZSupplier")))
2053 : {
2054 26 : xDiagramProperties->getPropertyValue(
2055 52 : OUString("HasZAxis")) >>= mbHasZAxis;
2056 : }
2057 : }
2058 :
2059 26 : xDiagramProperties->getPropertyValue(
2060 52 : OUString ("Dim3D")) >>= mbIs3DChart;
2061 :
2062 52 : Reference< chart2::XChartDocument > xNewDoc( getModel(), uno::UNO_QUERY );
2063 26 : if( mbHasCategoryLabels && mxNewDiagram.is())
2064 : {
2065 20 : Reference< chart2::data::XLabeledDataSequence > xCategories( lcl_getCategories( mxNewDiagram ) );
2066 20 : if( xCategories.is() )
2067 : {
2068 20 : mxCategoriesValues.set( xCategories->getValues() );
2069 20 : }
2070 26 : }
2071 26 : }
2072 :
2073 26 : void ChartExport::exportAxes( )
2074 : {
2075 26 : sal_Int32 nSize = maAxes.size();
2076 74 : for( sal_Int32 nIdx = 0; nIdx < nSize; nIdx++ )
2077 : {
2078 48 : exportAxis( maAxes[nIdx] );
2079 : }
2080 26 : }
2081 :
2082 48 : void ChartExport::exportAxis( AxisIdPair aAxisIdPair )
2083 : {
2084 : // get some properties from document first
2085 48 : sal_Bool bHasXAxisTitle = sal_False,
2086 48 : bHasYAxisTitle = sal_False,
2087 48 : bHasZAxisTitle = sal_False,
2088 48 : bHasSecondaryXAxisTitle = sal_False,
2089 48 : bHasSecondaryYAxisTitle = sal_False;
2090 48 : sal_Bool bHasXAxisMajorGrid = sal_False,
2091 48 : bHasXAxisMinorGrid = sal_False,
2092 48 : bHasYAxisMajorGrid = sal_False,
2093 48 : bHasYAxisMinorGrid = sal_False,
2094 48 : bHasZAxisMajorGrid = sal_False,
2095 48 : bHasZAxisMinorGrid = sal_False;
2096 :
2097 48 : Reference< XPropertySet > xDiagramProperties (mxDiagram, uno::UNO_QUERY);
2098 :
2099 48 : xDiagramProperties->getPropertyValue(
2100 48 : OUString ("HasXAxisTitle")) >>= bHasXAxisTitle;
2101 48 : xDiagramProperties->getPropertyValue(
2102 48 : OUString ("HasYAxisTitle")) >>= bHasYAxisTitle;
2103 48 : xDiagramProperties->getPropertyValue(
2104 48 : OUString ("HasZAxisTitle")) >>= bHasZAxisTitle;
2105 48 : xDiagramProperties->getPropertyValue(
2106 48 : OUString ("HasSecondaryXAxisTitle")) >>= bHasSecondaryXAxisTitle;
2107 48 : xDiagramProperties->getPropertyValue(
2108 48 : OUString ("HasSecondaryYAxisTitle")) >>= bHasSecondaryYAxisTitle;
2109 :
2110 48 : xDiagramProperties->getPropertyValue(
2111 48 : OUString ("HasXAxisGrid")) >>= bHasXAxisMajorGrid;
2112 48 : xDiagramProperties->getPropertyValue(
2113 48 : OUString ("HasYAxisGrid")) >>= bHasYAxisMajorGrid;
2114 48 : xDiagramProperties->getPropertyValue(
2115 48 : OUString ("HasZAxisGrid")) >>= bHasZAxisMajorGrid;
2116 :
2117 48 : xDiagramProperties->getPropertyValue(
2118 48 : OUString ("HasXAxisHelpGrid")) >>= bHasXAxisMinorGrid;
2119 48 : xDiagramProperties->getPropertyValue(
2120 48 : OUString ("HasYAxisHelpGrid")) >>= bHasYAxisMinorGrid;
2121 48 : xDiagramProperties->getPropertyValue(
2122 48 : OUString ("HasZAxisHelpGrid")) >>= bHasZAxisMinorGrid;
2123 :
2124 96 : Reference< XPropertySet > xAxisProp;
2125 96 : Reference< drawing::XShape > xAxisTitle;
2126 96 : Reference< beans::XPropertySet > xMajorGrid;
2127 96 : Reference< beans::XPropertySet > xMinorGrid;
2128 48 : sal_Int32 nAxisType = XML_catAx;
2129 48 : const char* sAxPos = NULL;
2130 :
2131 48 : switch( aAxisIdPair.nAxisType )
2132 : {
2133 : case AXIS_PRIMARY_X:
2134 : {
2135 24 : Reference< ::com::sun::star::chart::XAxisXSupplier > xAxisXSupp( mxDiagram, uno::UNO_QUERY );
2136 24 : if( xAxisXSupp.is())
2137 24 : xAxisProp = xAxisXSupp->getXAxis();
2138 24 : if( bHasXAxisTitle )
2139 5 : xAxisTitle.set( xAxisXSupp->getXAxisTitle(), uno::UNO_QUERY );
2140 24 : if( bHasXAxisMajorGrid )
2141 3 : xMajorGrid.set( xAxisXSupp->getXMainGrid(), uno::UNO_QUERY );
2142 24 : if( bHasXAxisMinorGrid )
2143 0 : xMinorGrid.set( xAxisXSupp->getXHelpGrid(), uno::UNO_QUERY );
2144 :
2145 24 : sal_Int32 eChartType = getChartType( );
2146 24 : if( (eChartType == chart::TYPEID_SCATTER)
2147 21 : || (eChartType == chart::TYPEID_BUBBLE) )
2148 3 : nAxisType = XML_valAx;
2149 21 : else if( eChartType == chart::TYPEID_STOCK )
2150 2 : nAxisType = XML_dateAx;
2151 : // FIXME: axPos, need to check axis direction
2152 24 : sAxPos = "b";
2153 24 : break;
2154 : }
2155 : case AXIS_PRIMARY_Y:
2156 : {
2157 22 : Reference< ::com::sun::star::chart::XAxisYSupplier > xAxisYSupp( mxDiagram, uno::UNO_QUERY );
2158 22 : if( xAxisYSupp.is())
2159 22 : xAxisProp = xAxisYSupp->getYAxis();
2160 22 : if( bHasYAxisTitle )
2161 4 : xAxisTitle.set( xAxisYSupp->getYAxisTitle(), uno::UNO_QUERY );
2162 22 : if( bHasYAxisMajorGrid )
2163 20 : xMajorGrid.set( xAxisYSupp->getYMainGrid(), uno::UNO_QUERY );
2164 22 : if( bHasYAxisMinorGrid )
2165 5 : xMinorGrid.set( xAxisYSupp->getYHelpGrid(), uno::UNO_QUERY );
2166 :
2167 22 : nAxisType = XML_valAx;
2168 : // FIXME: axPos, need to check axis direction
2169 22 : sAxPos = "l";
2170 22 : break;
2171 : }
2172 : case AXIS_PRIMARY_Z:
2173 : {
2174 0 : Reference< ::com::sun::star::chart::XAxisZSupplier > xAxisZSupp( mxDiagram, uno::UNO_QUERY );
2175 0 : if( xAxisZSupp.is())
2176 0 : xAxisProp = xAxisZSupp->getZAxis();
2177 0 : if( bHasZAxisTitle )
2178 0 : xAxisTitle.set( xAxisZSupp->getZAxisTitle(), uno::UNO_QUERY );
2179 0 : if( bHasZAxisMajorGrid )
2180 0 : xMajorGrid.set( xAxisZSupp->getZMainGrid(), uno::UNO_QUERY );
2181 0 : if( bHasZAxisMinorGrid )
2182 0 : xMinorGrid.set( xAxisZSupp->getZHelpGrid(), uno::UNO_QUERY );
2183 :
2184 0 : sal_Int32 eChartType = getChartType( );
2185 0 : if( (eChartType == chart::TYPEID_SCATTER)
2186 0 : || (eChartType == chart::TYPEID_BUBBLE) )
2187 0 : nAxisType = XML_valAx;
2188 0 : else if( eChartType == chart::TYPEID_STOCK )
2189 0 : nAxisType = XML_dateAx;
2190 : // FIXME: axPos, need to check axis direction
2191 0 : sAxPos = "b";
2192 0 : break;
2193 : }
2194 : case AXIS_SECONDARY_Y:
2195 : {
2196 2 : Reference< ::com::sun::star::chart::XTwoAxisYSupplier > xAxisTwoYSupp( mxDiagram, uno::UNO_QUERY );
2197 2 : if( xAxisTwoYSupp.is())
2198 2 : xAxisProp = xAxisTwoYSupp->getSecondaryYAxis();
2199 2 : if( bHasSecondaryYAxisTitle )
2200 : {
2201 0 : Reference< ::com::sun::star::chart::XSecondAxisTitleSupplier > xAxisSupp( mxDiagram, uno::UNO_QUERY );
2202 0 : xAxisTitle.set( xAxisSupp->getSecondYAxisTitle(), uno::UNO_QUERY );
2203 : }
2204 :
2205 2 : nAxisType = XML_valAx;
2206 : // FIXME: axPos, need to check axis direction
2207 2 : sAxPos = "l";
2208 2 : break;
2209 : }
2210 : }
2211 :
2212 :
2213 96 : _exportAxis( xAxisProp, xAxisTitle, xMajorGrid, xMinorGrid, nAxisType, sAxPos, aAxisIdPair );
2214 48 : }
2215 :
2216 48 : void ChartExport::_exportAxis(
2217 : const Reference< XPropertySet >& xAxisProp,
2218 : const Reference< drawing::XShape >& xAxisTitle,
2219 : const Reference< XPropertySet >& xMajorGrid,
2220 : const Reference< XPropertySet >& xMinorGrid,
2221 : sal_Int32 nAxisType,
2222 : const char* sAxisPos,
2223 : AxisIdPair aAxisIdPair )
2224 : {
2225 48 : FSHelperPtr pFS = GetFS();
2226 : pFS->startElement( FSNS( XML_c, nAxisType ),
2227 48 : FSEND );
2228 : pFS->singleElement( FSNS( XML_c, XML_axId ),
2229 : XML_val, I32S( aAxisIdPair.nAxisId ),
2230 48 : FSEND );
2231 :
2232 : pFS->startElement( FSNS( XML_c, XML_scaling ),
2233 48 : FSEND );
2234 : // logBase, min, max
2235 48 : if(GetProperty( xAxisProp, "Logarithmic" ) )
2236 : {
2237 48 : sal_Bool bLogarithmic = sal_False;
2238 48 : mAny >>= bLogarithmic;
2239 48 : if( bLogarithmic )
2240 : {
2241 : // default value is 10?
2242 1 : sal_Int32 nLogBase = 10;
2243 : pFS->singleElement( FSNS( XML_c, XML_logBase ),
2244 : XML_val, I32S( nLogBase ),
2245 1 : FSEND );
2246 : }
2247 : }
2248 :
2249 : // orientation: minMax, maxMin
2250 48 : sal_Bool bReverseDirection = sal_False;
2251 48 : if(GetProperty( xAxisProp, "ReverseDirection" ) )
2252 48 : mAny >>= bReverseDirection;
2253 :
2254 48 : const char* orientation = bReverseDirection ? "maxMin":"minMax";
2255 : pFS->singleElement( FSNS( XML_c, XML_orientation ),
2256 : XML_val, orientation,
2257 48 : FSEND );
2258 :
2259 48 : sal_Bool bAutoMax = sal_False;
2260 48 : if(GetProperty( xAxisProp, "AutoMax" ) )
2261 48 : mAny >>= bAutoMax;
2262 :
2263 48 : if( !bAutoMax && (GetProperty( xAxisProp, "Max" ) ) )
2264 : {
2265 0 : double dMax = 0;
2266 0 : mAny >>= dMax;
2267 : pFS->singleElement( FSNS( XML_c, XML_max ),
2268 : XML_val, IS( dMax ),
2269 0 : FSEND );
2270 : }
2271 :
2272 48 : sal_Bool bAutoMin = sal_False;
2273 48 : if(GetProperty( xAxisProp, "AutoMin" ) )
2274 48 : mAny >>= bAutoMin;
2275 :
2276 48 : if( !bAutoMin && (GetProperty( xAxisProp, "Min" ) ) )
2277 : {
2278 0 : double dMin = 0;
2279 0 : mAny >>= dMin;
2280 : pFS->singleElement( FSNS( XML_c, XML_min ),
2281 : XML_val, IS( dMin ),
2282 0 : FSEND );
2283 : }
2284 :
2285 48 : pFS->endElement( FSNS( XML_c, XML_scaling ) );
2286 :
2287 48 : sal_Bool bVisible = sal_True;
2288 48 : if( xAxisProp.is() )
2289 : {
2290 48 : xAxisProp->getPropertyValue(
2291 48 : OUString ("Visible")) >>= bVisible;
2292 : }
2293 :
2294 : pFS->singleElement( FSNS( XML_c, XML_delete ),
2295 : XML_val, bVisible ? "0" : "1",
2296 48 : FSEND );
2297 :
2298 : // FIXME: axPos, need to check the property "ReverseDirection"
2299 : pFS->singleElement( FSNS( XML_c, XML_axPos ),
2300 : XML_val, sAxisPos,
2301 48 : FSEND );
2302 : // major grid line
2303 48 : if( xMajorGrid.is())
2304 : {
2305 : pFS->startElement( FSNS( XML_c, XML_majorGridlines ),
2306 23 : FSEND );
2307 23 : exportShapeProps( xMajorGrid );
2308 23 : pFS->endElement( FSNS( XML_c, XML_majorGridlines ) );
2309 : }
2310 :
2311 : // minor grid line
2312 48 : if( xMinorGrid.is())
2313 : {
2314 : pFS->startElement( FSNS( XML_c, XML_minorGridlines ),
2315 5 : FSEND );
2316 5 : exportShapeProps( xMinorGrid );
2317 5 : pFS->endElement( FSNS( XML_c, XML_minorGridlines ) );
2318 : }
2319 :
2320 : // title
2321 48 : if( xAxisTitle.is() )
2322 9 : exportTitle( xAxisTitle );
2323 :
2324 : // majorTickMark
2325 48 : sal_Int32 nValue = 0;
2326 48 : if(GetProperty( xAxisProp, "Marks" ) )
2327 : {
2328 48 : mAny >>= nValue;
2329 48 : sal_Bool bInner = nValue & ::com::sun::star::chart::ChartAxisMarks::INNER;
2330 48 : sal_Bool bOuter = nValue & ::com::sun::star::chart::ChartAxisMarks::OUTER;
2331 48 : const char* majorTickMark = NULL;
2332 48 : if( bInner && bOuter )
2333 0 : majorTickMark = "cross";
2334 48 : else if( bInner )
2335 0 : majorTickMark = "in";
2336 48 : else if( bOuter )
2337 34 : majorTickMark = "out";
2338 : else
2339 14 : majorTickMark = "none";
2340 : pFS->singleElement( FSNS( XML_c, XML_majorTickMark ),
2341 : XML_val, majorTickMark,
2342 48 : FSEND );
2343 : }
2344 : // minorTickMark
2345 48 : if(GetProperty( xAxisProp, "HelpMarks" ) )
2346 : {
2347 48 : mAny >>= nValue;
2348 48 : sal_Bool bInner = nValue & ::com::sun::star::chart::ChartAxisMarks::INNER;
2349 48 : sal_Bool bOuter = nValue & ::com::sun::star::chart::ChartAxisMarks::OUTER;
2350 48 : const char* minorTickMark = NULL;
2351 48 : if( bInner && bOuter )
2352 0 : minorTickMark = "cross";
2353 48 : else if( bInner )
2354 0 : minorTickMark = "in";
2355 48 : else if( bOuter )
2356 0 : minorTickMark = "out";
2357 : else
2358 48 : minorTickMark = "none";
2359 : pFS->singleElement( FSNS( XML_c, XML_minorTickMark ),
2360 : XML_val, minorTickMark,
2361 48 : FSEND );
2362 : }
2363 : // tickLblPos
2364 48 : const char* sTickLblPos = NULL;
2365 48 : sal_Bool bDisplayLabel = sal_True;
2366 48 : if(GetProperty( xAxisProp, "DisplayLabels" ) )
2367 48 : mAny >>= bDisplayLabel;
2368 48 : if( bDisplayLabel && (GetProperty( xAxisProp, "LabelPosition" ) ) )
2369 : {
2370 47 : ::com::sun::star::chart::ChartAxisLabelPosition eLabelPosition = ::com::sun::star::chart::ChartAxisLabelPosition_NEAR_AXIS;
2371 47 : mAny >>= eLabelPosition;
2372 47 : switch( eLabelPosition )
2373 : {
2374 : case ::com::sun::star::chart::ChartAxisLabelPosition_NEAR_AXIS:
2375 : case ::com::sun::star::chart::ChartAxisLabelPosition_NEAR_AXIS_OTHER_SIDE:
2376 47 : sTickLblPos = "nextTo";
2377 47 : break;
2378 : case ::com::sun::star::chart::ChartAxisLabelPosition_OUTSIDE_START:
2379 0 : sTickLblPos = "low";
2380 0 : break;
2381 : case ::com::sun::star::chart::ChartAxisLabelPosition_OUTSIDE_END:
2382 0 : sTickLblPos = "high";
2383 0 : break;
2384 : default:
2385 0 : sTickLblPos = "nextTo";
2386 0 : break;
2387 : }
2388 : }
2389 : else
2390 : {
2391 1 : sTickLblPos = "none";
2392 : }
2393 : pFS->singleElement( FSNS( XML_c, XML_tickLblPos ),
2394 : XML_val, sTickLblPos,
2395 48 : FSEND );
2396 :
2397 : // shape properties
2398 48 : exportShapeProps( xAxisProp );
2399 :
2400 : pFS->singleElement( FSNS( XML_c, XML_crossAx ),
2401 : XML_val, I32S( aAxisIdPair.nCrossAx ),
2402 48 : FSEND );
2403 :
2404 : // crosses & crossesAt
2405 48 : sal_Bool bCrossesValue = sal_False;
2406 48 : const char* sCrosses = NULL;
2407 48 : if(GetProperty( xAxisProp, "CrossoverPosition" ) )
2408 : {
2409 48 : ::com::sun::star::chart::ChartAxisPosition ePosition( ::com::sun::star::chart::ChartAxisPosition_ZERO );
2410 48 : mAny >>= ePosition;
2411 48 : switch( ePosition )
2412 : {
2413 : case ::com::sun::star::chart::ChartAxisPosition_START:
2414 0 : sCrosses = "min";
2415 0 : break;
2416 : case ::com::sun::star::chart::ChartAxisPosition_END:
2417 2 : sCrosses = "max";
2418 2 : break;
2419 : case ::com::sun::star::chart::ChartAxisPosition_ZERO:
2420 46 : sCrosses = "autoZero";
2421 46 : break;
2422 : default:
2423 0 : bCrossesValue = sal_True;
2424 0 : break;
2425 : }
2426 : }
2427 :
2428 48 : if( bCrossesValue && GetProperty( xAxisProp, "CrossoverValue" ) )
2429 : {
2430 0 : double dValue = 0;
2431 0 : mAny >>= dValue;
2432 : pFS->singleElement( FSNS( XML_c, XML_crossesAt ),
2433 : XML_val, IS( dValue ),
2434 0 : FSEND );
2435 : }
2436 : else
2437 : {
2438 : pFS->singleElement( FSNS( XML_c, XML_crosses ),
2439 : XML_val, sCrosses,
2440 48 : FSEND );
2441 : }
2442 :
2443 48 : if( ( nAxisType == XML_catAx )
2444 29 : || ( nAxisType == XML_dateAx ) )
2445 : {
2446 : // FIXME: seems not support? use default value,
2447 21 : const char* isAuto = "1";
2448 : pFS->singleElement( FSNS( XML_c, XML_auto ),
2449 : XML_val, isAuto,
2450 21 : FSEND );
2451 :
2452 21 : if( nAxisType == XML_catAx )
2453 : {
2454 : // FIXME: seems not support? lblAlgn
2455 19 : const char* sLblAlgn = "ctr";
2456 : pFS->singleElement( FSNS( XML_c, XML_lblAlgn ),
2457 : XML_val, sLblAlgn,
2458 19 : FSEND );
2459 : }
2460 :
2461 : // FIXME: seems not support? lblOffset
2462 21 : sal_Int32 nLblOffset = 100;
2463 : pFS->singleElement( FSNS( XML_c, XML_lblOffset ),
2464 : XML_val, I32S( nLblOffset ),
2465 21 : FSEND );
2466 : }
2467 :
2468 : // majorUnit
2469 48 : sal_Bool bAutoStepMain = sal_False;
2470 48 : if(GetProperty( xAxisProp, "AutoStepMain" ) )
2471 48 : mAny >>= bAutoStepMain;
2472 :
2473 48 : if( !bAutoStepMain && (GetProperty( xAxisProp, "StepMain" ) ) )
2474 : {
2475 0 : double dMajorUnit = 0;
2476 0 : mAny >>= dMajorUnit;
2477 : pFS->singleElement( FSNS( XML_c, XML_majorUnit ),
2478 : XML_val, IS( dMajorUnit ),
2479 0 : FSEND );
2480 : }
2481 : // minorUnit
2482 48 : sal_Bool bAutoStepHelp = sal_False;
2483 48 : if(GetProperty( xAxisProp, "AutoStepHelp" ) )
2484 48 : mAny >>= bAutoStepHelp;
2485 :
2486 48 : if( !bAutoStepHelp && (GetProperty( xAxisProp, "StepHelp" ) ) )
2487 : {
2488 0 : double dMinorUnit = 0;
2489 0 : mAny >>= dMinorUnit;
2490 : pFS->singleElement( FSNS( XML_c, XML_minorUnit ),
2491 : XML_val, IS( dMinorUnit ),
2492 0 : FSEND );
2493 : }
2494 :
2495 48 : sal_Bool bDisplayUnits = sal_False;
2496 48 : if( nAxisType == XML_valAx && GetProperty( xAxisProp, "DisplayUnits" ) )
2497 : {
2498 27 : mAny >>= bDisplayUnits;
2499 27 : if(bDisplayUnits)
2500 : {
2501 1 : OUString aVal;
2502 1 : if(GetProperty( xAxisProp, "BuiltInUnit" ))
2503 : {
2504 1 : mAny >>= aVal;
2505 1 : if(!aVal.isEmpty())
2506 : {
2507 : pFS->startElement( FSNS( XML_c, XML_dispUnits ),
2508 1 : FSEND );
2509 :
2510 1 : OString aBuiltInUnit = OUStringToOString(aVal, RTL_TEXTENCODING_UTF8);
2511 : pFS->singleElement( FSNS( XML_c, XML_builtInUnit ),
2512 : XML_val, aBuiltInUnit.getStr(),
2513 1 : FSEND );
2514 :
2515 1 : pFS->singleElement(FSNS( XML_c, XML_dispUnitsLbl ),FSEND);
2516 1 : pFS->endElement( FSNS( XML_c, XML_dispUnits ) );
2517 : }
2518 1 : }
2519 : }
2520 : }
2521 : // TODO: text properties
2522 :
2523 48 : pFS->endElement( FSNS( XML_c, nAxisType ) );
2524 48 : }
2525 :
2526 11 : void ChartExport::exportDataLabels(
2527 : const uno::Reference< beans::XPropertySet > & xSeriesProperties,
2528 : sal_Int32 nSeriesLength )
2529 : {
2530 : // TODO: export field separators, missing flag vs. showing series name or not
2531 11 : uno::Reference< chart2::XDataSeries > xSeries( xSeriesProperties, uno::UNO_QUERY );
2532 :
2533 11 : if( xSeriesProperties.is())
2534 : {
2535 11 : FSHelperPtr pFS = GetFS();
2536 : pFS->startElement( FSNS( XML_c, XML_dLbls ),
2537 11 : FSEND );
2538 :
2539 11 : bool showLegendSymbol = false;
2540 11 : bool showNumber = false;
2541 11 : bool showCategoryName = false;
2542 11 : bool showNumberInPercent = false;
2543 :
2544 11 : sal_Int32 nElem = 0;
2545 :
2546 :
2547 22 : uno::Reference< beans::XPropertySet > xPropSet;
2548 11 : if(nSeriesLength != 0)
2549 : {
2550 : try
2551 : {
2552 22 : xPropSet = SchXMLSeriesHelper::createOldAPIDataPointPropertySet(
2553 11 : xSeries, nElem, getModel() );
2554 : }
2555 0 : catch( const uno::Exception & rEx )
2556 : {
2557 : SAL_WARN("oox", "Exception caught during Export of data label: " << rEx.Message );
2558 : }
2559 : }
2560 :
2561 : namespace cssc2 = ::com::sun::star::chart2;
2562 11 : cssc2::DataPointLabel aTempLabel;
2563 11 : if( xPropSet.is() )
2564 : {
2565 11 : if (GetProperty( xPropSet, "Label"))
2566 11 : mAny >>= aTempLabel;
2567 : }
2568 :
2569 :
2570 :
2571 62 : for( nElem = 1; nElem < nSeriesLength; ++nElem)
2572 : {
2573 : try
2574 : {
2575 102 : xPropSet = SchXMLSeriesHelper::createOldAPIDataPointPropertySet(
2576 51 : xSeries, nElem, getModel() );
2577 : }
2578 0 : catch( const uno::Exception & rEx )
2579 : {
2580 : SAL_WARN("oox", "Exception caught during Export of data label: " << rEx.Message );
2581 : }
2582 :
2583 51 : if( xPropSet.is() )
2584 : {
2585 : namespace cssc2 = ::com::sun::star::chart2;
2586 51 : cssc2::DataPointLabel aLabel;
2587 51 : if (GetProperty( xPropSet, "Label"))
2588 : {
2589 51 : mAny >>= aLabel;
2590 :
2591 : namespace csscd = ::com::sun::star::chart::DataLabelPlacement;
2592 51 : sal_Int32 nPlacement(csscd::AVOID_OVERLAP);
2593 51 : const char *aPlacement = NULL;
2594 51 : OUString aSep;
2595 :
2596 51 : if (GetProperty( xPropSet, "LabelPlacement"))
2597 42 : mAny >>= nPlacement;
2598 :
2599 51 : switch( nPlacement )
2600 : {
2601 0 : case csscd::OUTSIDE: aPlacement = "outEnd"; break;
2602 0 : case csscd::INSIDE: aPlacement = "inEnd"; break;
2603 4 : case csscd::CENTER: aPlacement = "ctr"; break;
2604 0 : case csscd::NEAR_ORIGIN: aPlacement = "inBase"; break;
2605 0 : case csscd::TOP: aPlacement = "t"; break;
2606 0 : case csscd::BOTTOM: aPlacement = "b"; break;
2607 0 : case csscd::LEFT: aPlacement = "l"; break;
2608 21 : case csscd::RIGHT: aPlacement = "r"; break;
2609 26 : case csscd::AVOID_OVERLAP: aPlacement = "bestFit"; break;
2610 : }
2611 :
2612 51 : if (aLabel.ShowLegendSymbol)
2613 0 : showLegendSymbol = true;
2614 51 : if(aLabel.ShowNumber)
2615 4 : showNumber = true;
2616 51 : if(aLabel.ShowCategoryName)
2617 7 : showCategoryName = true;
2618 51 : if(aLabel.ShowNumberInPercent)
2619 7 : showNumberInPercent = true;
2620 :
2621 102 : if(aTempLabel.ShowLegendSymbol != aLabel.ShowLegendSymbol || aTempLabel.ShowNumber!= aLabel.ShowNumber ||
2622 95 : aTempLabel.ShowCategoryName != aLabel.ShowCategoryName || aTempLabel.ShowNumberInPercent != aLabel.ShowNumberInPercent)
2623 : {
2624 7 : pFS->startElement( FSNS( XML_c, XML_dLbl ), FSEND);
2625 7 : pFS->singleElement( FSNS( XML_c, XML_idx), XML_val, I32S(nElem), FSEND);
2626 7 : pFS->singleElement( FSNS( XML_c, XML_dLblPos), XML_val, aPlacement, FSEND);
2627 :
2628 7 : if(aTempLabel.ShowLegendSymbol != aLabel.ShowLegendSymbol)
2629 : {
2630 0 : pFS->singleElement( FSNS( XML_c, XML_showLegendKey), XML_val, aLabel.ShowLegendSymbol ? "1": "0", FSEND);
2631 : }
2632 :
2633 7 : if (aTempLabel.ShowNumber!= aLabel.ShowNumber)
2634 : {
2635 0 : pFS->singleElement( FSNS( XML_c, XML_showVal), XML_val,aLabel.ShowNumber ? "1": "0", FSEND);
2636 : }
2637 :
2638 :
2639 7 : if(aTempLabel.ShowCategoryName != aLabel.ShowCategoryName)
2640 : {
2641 7 : pFS->singleElement( FSNS( XML_c, XML_showCatName), XML_val, aLabel.ShowCategoryName ? "1": "0", FSEND);
2642 : }
2643 : // MSO somehow assumes series name to be on (=displayed) by default.
2644 : // Let's put false here and switch it off then, since we have no UI means
2645 : // in LibO to toggle it on anyway
2646 7 : pFS->singleElement( FSNS( XML_c, XML_showSerName), XML_val, "0", FSEND);
2647 :
2648 7 : if(aTempLabel.ShowNumberInPercent != aLabel.ShowNumberInPercent)
2649 : {
2650 7 : pFS->singleElement( FSNS( XML_c, XML_showPercent), XML_val,aLabel.ShowNumberInPercent ? "1": "0", FSEND);
2651 : }
2652 :
2653 7 : if (GetProperty( xPropSet, "LabelSeparator"))
2654 : {
2655 7 : mAny >>= aSep;
2656 7 : pFS->startElement( FSNS( XML_c, XML_separator), FSEND);
2657 7 : pFS->writeEscaped(aSep);
2658 7 : pFS->endElement( FSNS( XML_c, XML_separator) );
2659 : }
2660 7 : pFS->endElement( FSNS( XML_c, XML_dLbl ));
2661 51 : }
2662 : }
2663 : }
2664 : }
2665 :
2666 11 : pFS->singleElement( FSNS( XML_c, XML_showLegendKey), XML_val, showLegendSymbol ? "1": "0", FSEND);
2667 11 : pFS->singleElement( FSNS( XML_c, XML_showVal), XML_val, showNumber ? "1": "0", FSEND);
2668 11 : pFS->singleElement( FSNS( XML_c, XML_showCatName), XML_val, showCategoryName ? "1": "0", FSEND);
2669 :
2670 11 : pFS->singleElement( FSNS( XML_c, XML_showSerName), XML_val, "0", FSEND);
2671 :
2672 11 : pFS->singleElement( FSNS( XML_c, XML_showPercent), XML_val, showNumberInPercent ? "1": "0", FSEND);
2673 :
2674 22 : pFS->endElement( FSNS( XML_c, XML_dLbls ) );
2675 11 : }
2676 11 : }
2677 :
2678 60 : void ChartExport::exportDataPoints(
2679 : const uno::Reference< beans::XPropertySet > & xSeriesProperties,
2680 : sal_Int32 nSeriesLength )
2681 : {
2682 60 : uno::Reference< chart2::XDataSeries > xSeries( xSeriesProperties, uno::UNO_QUERY );
2683 60 : bool bVaryColorsByPoint = false;
2684 120 : Sequence< sal_Int32 > aDataPointSeq;
2685 60 : if( xSeriesProperties.is())
2686 : {
2687 60 : Any aAny = xSeriesProperties->getPropertyValue(
2688 60 : OUString( "AttributedDataPoints" ));
2689 60 : aAny >>= aDataPointSeq;
2690 60 : xSeriesProperties->getPropertyValue(
2691 60 : OUString( "VaryColorsByPoint" )) >>= bVaryColorsByPoint;
2692 : }
2693 :
2694 60 : const sal_Int32 * pPoints = aDataPointSeq.getConstArray();
2695 : sal_Int32 nElement;
2696 120 : Reference< chart2::XColorScheme > xColorScheme;
2697 60 : if( mxNewDiagram.is())
2698 60 : xColorScheme.set( mxNewDiagram->getDefaultColorScheme());
2699 :
2700 60 : if( bVaryColorsByPoint && xColorScheme.is() )
2701 : {
2702 4 : ::std::set< sal_Int32 > aAttrPointSet;
2703 4 : ::std::copy( pPoints, pPoints + aDataPointSeq.getLength(),
2704 8 : ::std::inserter( aAttrPointSet, aAttrPointSet.begin()));
2705 4 : const ::std::set< sal_Int32 >::const_iterator aEndIt( aAttrPointSet.end());
2706 28 : for( nElement = 0; nElement < nSeriesLength; ++nElement )
2707 : {
2708 24 : uno::Reference< beans::XPropertySet > xPropSet;
2709 24 : if( aAttrPointSet.find( nElement ) != aEndIt )
2710 : {
2711 : try
2712 : {
2713 48 : xPropSet = SchXMLSeriesHelper::createOldAPIDataPointPropertySet(
2714 24 : xSeries, nElement, getModel() );
2715 : }
2716 0 : catch( const uno::Exception & rEx )
2717 : {
2718 : SAL_WARN( "oox", "Exception caught during Export of data point: " << rEx.Message );
2719 : }
2720 : }
2721 : else
2722 : {
2723 : // property set only containing the color
2724 0 : xPropSet.set( new ColorPropertySet( xColorScheme->getColorByIndex( nElement )));
2725 : }
2726 :
2727 24 : if( xPropSet.is() )
2728 : {
2729 : OSL_TRACE("ChartExport::exportDataPoints -- writer data points ");
2730 24 : FSHelperPtr pFS = GetFS();
2731 : pFS->startElement( FSNS( XML_c, XML_dPt ),
2732 24 : FSEND );
2733 : pFS->singleElement( FSNS( XML_c, XML_idx ),
2734 : XML_val, I32S(nElement),
2735 24 : FSEND );
2736 24 : exportShapeProps( xPropSet );
2737 :
2738 24 : pFS->endElement( FSNS( XML_c, XML_dPt ) );
2739 : }
2740 28 : }
2741 60 : }
2742 60 : }
2743 :
2744 24 : void ChartExport::exportAxesId( sal_Int32 nAttachedAxis )
2745 : {
2746 24 : sal_Int32 nAxisIdx = lcl_generateRandomValue();
2747 24 : sal_Int32 nAxisIdy = lcl_generateRandomValue();
2748 24 : maAxes.push_back( AxisIdPair( AXIS_PRIMARY_X, nAxisIdx, nAxisIdy ) );
2749 24 : maAxes.push_back( AxisIdPair( nAttachedAxis, nAxisIdy, nAxisIdx ) );
2750 24 : FSHelperPtr pFS = GetFS();
2751 : pFS->singleElement( FSNS( XML_c, XML_axId ),
2752 : XML_val, I32S( nAxisIdx ),
2753 24 : FSEND );
2754 : pFS->singleElement( FSNS( XML_c, XML_axId ),
2755 : XML_val, I32S( nAxisIdy ),
2756 24 : FSEND );
2757 24 : if( mbHasZAxis )
2758 : {
2759 9 : sal_Int32 nAxisIdz = 0;
2760 9 : if( isDeep3dChart() )
2761 : {
2762 0 : nAxisIdz = lcl_generateRandomValue();
2763 0 : maAxes.push_back( AxisIdPair( AXIS_PRIMARY_Z, nAxisIdz, nAxisIdy ) );
2764 : }
2765 : pFS->singleElement( FSNS( XML_c, XML_axId ),
2766 : XML_val, I32S( nAxisIdz ),
2767 9 : FSEND );
2768 24 : }
2769 24 : }
2770 :
2771 20 : void ChartExport::exportGrouping( bool isBar )
2772 : {
2773 20 : FSHelperPtr pFS = GetFS();
2774 40 : Reference< XPropertySet > xPropSet( mxDiagram , uno::UNO_QUERY);
2775 : // grouping
2776 20 : sal_Bool bStacked = sal_False;
2777 20 : if( GetProperty( xPropSet, "Stacked" ) )
2778 20 : mAny >>= bStacked;
2779 20 : sal_Bool bPercentage = sal_False;
2780 20 : if( GetProperty( xPropSet, "Percent" ) )
2781 20 : mAny >>= bPercentage;
2782 :
2783 20 : const char* grouping = NULL;
2784 20 : if( bStacked )
2785 4 : grouping = "stacked";
2786 16 : else if( bPercentage )
2787 3 : grouping = "percentStacked";
2788 : else
2789 : {
2790 13 : if( isBar && !isDeep3dChart() )
2791 11 : grouping = "clustered";
2792 : else
2793 2 : grouping = "standard";
2794 : }
2795 : pFS->singleElement( FSNS( XML_c, XML_grouping ),
2796 : XML_val, grouping,
2797 40 : FSEND );
2798 20 : }
2799 :
2800 60 : void ChartExport::exportTrendlines( Reference< chart2::XDataSeries > xSeries )
2801 : {
2802 60 : FSHelperPtr pFS = GetFS();
2803 120 : Reference< chart2::XRegressionCurveContainer > xRegressionCurveContainer( xSeries, UNO_QUERY );
2804 60 : if( xRegressionCurveContainer.is() )
2805 : {
2806 60 : Sequence< Reference< chart2::XRegressionCurve > > aRegCurveSeq = xRegressionCurveContainer->getRegressionCurves();
2807 60 : const Reference< chart2::XRegressionCurve >* pBeg = aRegCurveSeq.getConstArray();
2808 60 : const Reference< chart2::XRegressionCurve >* pEnd = pBeg + aRegCurveSeq.getLength();
2809 63 : for( const Reference< chart2::XRegressionCurve >* pIt = pBeg; pIt != pEnd; ++pIt )
2810 : {
2811 3 : Reference< chart2::XRegressionCurve > xRegCurve = *pIt;
2812 3 : if (!xRegCurve.is())
2813 0 : continue;
2814 :
2815 6 : Reference< XPropertySet > xProperties( xRegCurve , uno::UNO_QUERY );
2816 :
2817 6 : OUString aService;
2818 6 : Reference< lang::XServiceName > xServiceName( xProperties, UNO_QUERY );
2819 3 : if( !xServiceName.is() )
2820 0 : continue;
2821 :
2822 3 : aService = xServiceName->getServiceName();
2823 :
2824 8 : if(aService != "com.sun.star.chart2.LinearRegressionCurve" &&
2825 4 : aService != "com.sun.star.chart2.ExponentialRegressionCurve" &&
2826 4 : aService != "com.sun.star.chart2.LogarithmicRegressionCurve" &&
2827 4 : aService != "com.sun.star.chart2.PotentialRegressionCurve" &&
2828 6 : aService != "com.sun.star.chart2.PolynomialRegressionCurve" &&
2829 1 : aService != "com.sun.star.chart2.MovingAverageRegressionCurve")
2830 0 : continue;
2831 :
2832 3 : pFS->startElement( FSNS( XML_c, XML_trendline ), FSEND );
2833 :
2834 6 : OUString aName;
2835 3 : xProperties->getPropertyValue("CurveName") >>= aName;
2836 3 : if(!aName.isEmpty())
2837 : {
2838 3 : pFS->startElement( FSNS( XML_c, XML_name), FSEND);
2839 3 : pFS->writeEscaped(aName);
2840 3 : pFS->endElement( FSNS( XML_c, XML_name) );
2841 : }
2842 :
2843 3 : exportShapeProps( xProperties );
2844 :
2845 3 : if( aService == "com.sun.star.chart2.LinearRegressionCurve" )
2846 : {
2847 : pFS->singleElement( FSNS( XML_c, XML_trendlineType ),
2848 : XML_val, "linear",
2849 1 : FSEND );
2850 : }
2851 2 : else if( aService == "com.sun.star.chart2.ExponentialRegressionCurve" )
2852 : {
2853 : pFS->singleElement( FSNS( XML_c, XML_trendlineType ),
2854 : XML_val, "exp",
2855 0 : FSEND );
2856 : }
2857 2 : else if( aService == "com.sun.star.chart2.LogarithmicRegressionCurve" )
2858 : {
2859 : pFS->singleElement( FSNS( XML_c, XML_trendlineType ),
2860 : XML_val, "log",
2861 0 : FSEND );
2862 : }
2863 2 : else if( aService == "com.sun.star.chart2.PotentialRegressionCurve" )
2864 : {
2865 : pFS->singleElement( FSNS( XML_c, XML_trendlineType ),
2866 : XML_val, "power",
2867 0 : FSEND );
2868 : }
2869 2 : else if( aService == "com.sun.star.chart2.PolynomialRegressionCurve" )
2870 : {
2871 : pFS->singleElement( FSNS( XML_c, XML_trendlineType ),
2872 : XML_val, "poly",
2873 1 : FSEND );
2874 :
2875 1 : sal_Int32 aDegree = 2;
2876 1 : xProperties->getPropertyValue( "PolynomialDegree") >>= aDegree;
2877 : pFS->singleElement( FSNS( XML_c, XML_order ),
2878 : XML_val, I32S(aDegree),
2879 1 : FSEND );
2880 : }
2881 1 : else if( aService == "com.sun.star.chart2.MovingAverageRegressionCurve" )
2882 : {
2883 : pFS->singleElement( FSNS( XML_c, XML_trendlineType ),
2884 : XML_val, "movingAvg",
2885 1 : FSEND );
2886 :
2887 1 : sal_Int32 aPeriod = 2;
2888 1 : xProperties->getPropertyValue( "MovingAveragePeriod") >>= aPeriod;
2889 :
2890 : pFS->singleElement( FSNS( XML_c, XML_period ),
2891 : XML_val, I32S(aPeriod),
2892 1 : FSEND );
2893 : }
2894 : else
2895 : {
2896 : // should never happen
2897 : // This would produce invalid OOXML files so we check earlier for the type
2898 : assert(false);
2899 : }
2900 :
2901 3 : double aExtrapolateForward = 0.0;
2902 3 : double aExtrapolateBackward = 0.0;
2903 :
2904 3 : xProperties->getPropertyValue("ExtrapolateForward") >>= aExtrapolateForward;
2905 3 : xProperties->getPropertyValue("ExtrapolateBackward") >>= aExtrapolateBackward;
2906 :
2907 : pFS->singleElement( FSNS( XML_c, XML_forward ),
2908 : XML_val, OString::number(aExtrapolateForward).getStr(),
2909 3 : FSEND );
2910 :
2911 : pFS->singleElement( FSNS( XML_c, XML_backward ),
2912 : XML_val, OString::number(aExtrapolateBackward).getStr(),
2913 3 : FSEND );
2914 :
2915 3 : sal_Bool aForceIntercept = false;
2916 3 : xProperties->getPropertyValue("ForceIntercept") >>= aForceIntercept;
2917 :
2918 3 : if (aForceIntercept)
2919 : {
2920 1 : double aInterceptValue = 0.0;
2921 1 : xProperties->getPropertyValue("InterceptValue") >>= aInterceptValue;
2922 :
2923 : pFS->singleElement( FSNS( XML_c, XML_intercept ),
2924 : XML_val, OString::number(aInterceptValue).getStr(),
2925 1 : FSEND );
2926 : }
2927 :
2928 : // Equation properties
2929 6 : Reference< XPropertySet > xEquationProperties( xRegCurve->getEquationProperties() );
2930 :
2931 : // Show Equation
2932 3 : sal_Bool aShowEquation = false;
2933 3 : xEquationProperties->getPropertyValue("ShowEquation") >>= aShowEquation;
2934 :
2935 : // Show R^2
2936 3 : sal_Bool aShowCorrelationCoefficient = false;
2937 3 : xEquationProperties->getPropertyValue("ShowCorrelationCoefficient") >>= aShowCorrelationCoefficient;
2938 :
2939 : pFS->singleElement( FSNS( XML_c, XML_dispRSqr ),
2940 : XML_val, aShowCorrelationCoefficient ? "1" : "0",
2941 3 : FSEND );
2942 :
2943 : pFS->singleElement( FSNS( XML_c, XML_dispEq ),
2944 : XML_val, aShowEquation ? "1" : "0",
2945 3 : FSEND );
2946 :
2947 3 : pFS->endElement( FSNS( XML_c, XML_trendline ) );
2948 63 : }
2949 60 : }
2950 60 : }
2951 :
2952 9 : void ChartExport::exportMarker(Reference< chart2::XDataSeries > xSeries)
2953 : {
2954 9 : Reference< XPropertySet > xPropSet( xSeries, uno::UNO_QUERY );
2955 14 : chart2::Symbol aSymbol;
2956 9 : if( GetProperty( xPropSet, "Symbol" ) )
2957 9 : mAny >>= aSymbol;
2958 :
2959 9 : if(aSymbol.Style != chart2::SymbolStyle_STANDARD && aSymbol.Style != chart2::SymbolStyle_AUTO)
2960 13 : return;
2961 :
2962 10 : FSHelperPtr pFS = GetFS();
2963 : pFS->startElement( FSNS( XML_c, XML_marker ),
2964 5 : FSEND );
2965 :
2966 5 : sal_Int32 nSymbol = aSymbol.StandardSymbol;
2967 : // TODO: more properties support for marker
2968 5 : const char* pSymbolType = NULL;
2969 5 : switch( nSymbol )
2970 : {
2971 : case 0:
2972 3 : pSymbolType = "square";
2973 3 : break;
2974 : case 1:
2975 1 : pSymbolType = "diamond";
2976 1 : break;
2977 : case 2:
2978 : case 3:
2979 : case 4:
2980 : case 5:
2981 0 : pSymbolType = "triangle";
2982 0 : break;
2983 : case 8:
2984 0 : pSymbolType = "circle";
2985 0 : break;
2986 : case 9:
2987 0 : pSymbolType = "star";
2988 0 : break;
2989 : case 10:
2990 0 : pSymbolType = "X";
2991 0 : break;
2992 : case 11:
2993 0 : pSymbolType = "plus";
2994 0 : break;
2995 : case 13:
2996 0 : pSymbolType = "dash";
2997 0 : break;
2998 : default:
2999 1 : pSymbolType = "square";
3000 1 : break;
3001 : }
3002 :
3003 5 : if( aSymbol.Style == chart2::SymbolStyle_AUTO )
3004 0 : pSymbolType = "auto";
3005 :
3006 5 : if( pSymbolType )
3007 : {
3008 : pFS->singleElement( FSNS( XML_c, XML_symbol ),
3009 : XML_val, pSymbolType,
3010 5 : FSEND );
3011 : }
3012 :
3013 5 : awt::Size aSymbolSize = aSymbol.Size;
3014 5 : sal_Int32 nSize = std::max( aSymbolSize.Width, aSymbolSize.Height );
3015 :
3016 5 : nSize = nSize/250.0*7.0; // just guessed based on some test cases
3017 5 : nSize = std::min<sal_Int32>( 72, std::max<sal_Int32>( 2, nSize ) );
3018 : pFS->singleElement( FSNS( XML_c, XML_size),
3019 : XML_val, I32S(nSize),
3020 5 : FSEND );
3021 :
3022 : pFS->startElement( FSNS( XML_c, XML_spPr ),
3023 5 : FSEND );
3024 5 : WriteSolidFill(aSymbol.FillColor);
3025 5 : pFS->endElement( FSNS( XML_c, XML_spPr ) );
3026 :
3027 10 : pFS->endElement( FSNS( XML_c, XML_marker ) );
3028 : }
3029 :
3030 9 : void ChartExport::exportSmooth()
3031 : {
3032 9 : FSHelperPtr pFS = GetFS();
3033 18 : Reference< XPropertySet > xPropSet( mxDiagram , uno::UNO_QUERY );
3034 9 : sal_Int32 nSplineType = 0;
3035 9 : if( GetProperty( xPropSet, "SplineType" ) )
3036 9 : mAny >>= nSplineType;
3037 9 : const char* pVal = nSplineType != 0 ? "1" : "0";
3038 : pFS->singleElement( FSNS( XML_c, XML_smooth ),
3039 : XML_val, pVal,
3040 18 : FSEND );
3041 9 : }
3042 :
3043 2 : void ChartExport::exportFirstSliceAng( )
3044 : {
3045 2 : FSHelperPtr pFS = GetFS();
3046 2 : sal_Int32 nStartingAngle = 0;
3047 4 : Reference< XPropertySet > xPropSet( mxDiagram , uno::UNO_QUERY);
3048 2 : if( GetProperty( xPropSet, "StartingAngle" ) )
3049 2 : mAny >>= nStartingAngle;
3050 :
3051 : // convert to ooxml angle
3052 2 : nStartingAngle = (450 - nStartingAngle ) % 360;
3053 : pFS->singleElement( FSNS( XML_c, XML_firstSliceAng ),
3054 : XML_val, I32S( nStartingAngle ),
3055 4 : FSEND );
3056 2 : }
3057 :
3058 : namespace {
3059 :
3060 1 : const char* getErrorBarStyle(sal_Int32 nErrorBarStyle)
3061 : {
3062 1 : switch(nErrorBarStyle)
3063 : {
3064 : case cssc::ErrorBarStyle::NONE:
3065 : // I have no idea how to map it to OOXML
3066 : // this approach is as good as any else
3067 0 : return "fixedVal";
3068 : case cssc::ErrorBarStyle::VARIANCE:
3069 0 : break;
3070 : case cssc::ErrorBarStyle::STANDARD_DEVIATION:
3071 0 : return "stdDev";
3072 : case cssc::ErrorBarStyle::ABSOLUTE:
3073 0 : return "fixedVal";
3074 : case cssc::ErrorBarStyle::RELATIVE:
3075 1 : return "percentage";
3076 : case cssc::ErrorBarStyle::ERROR_MARGIN:
3077 0 : break;
3078 : case cssc::ErrorBarStyle::STANDARD_ERROR:
3079 0 : return "stdErr";
3080 : case cssc::ErrorBarStyle::FROM_DATA:
3081 0 : return "cust";
3082 : default:
3083 : assert(false); // can't happen
3084 : }
3085 0 : return NULL;
3086 : }
3087 :
3088 0 : Reference< chart2::data::XDataSequence> getLabeledSequence(
3089 : uno::Sequence< uno::Reference< chart2::data::XLabeledDataSequence > > aSequences,
3090 : bool bPositive )
3091 : {
3092 0 : const OUString aRolePrefix( "error-bars" );
3093 0 : OUString aDirection;
3094 0 : if(bPositive)
3095 0 : aDirection = "positive";
3096 : else
3097 0 : aDirection = "negative";
3098 :
3099 0 : for( sal_Int32 nI=0; nI< aSequences.getLength(); ++nI )
3100 : {
3101 0 : if( aSequences[nI].is())
3102 : {
3103 0 : uno::Reference< chart2::data::XDataSequence > xSequence( aSequences[nI]->getValues());
3104 0 : uno::Reference< beans::XPropertySet > xSeqProp( xSequence, uno::UNO_QUERY_THROW );
3105 0 : OUString aRole;
3106 0 : if( ( xSeqProp->getPropertyValue(
3107 0 : OUString( "Role" )) >>= aRole ) &&
3108 0 : aRole.match( aRolePrefix ) && aRole.indexOf(aDirection) >= 0 )
3109 : {
3110 0 : return xSequence;
3111 0 : }
3112 : }
3113 : }
3114 :
3115 0 : return Reference< chart2::data::XDataSequence > ();
3116 : }
3117 :
3118 : }
3119 :
3120 1 : void ChartExport::exportErrorBar(Reference< XPropertySet> xErrorBarProps, bool bYError)
3121 : {
3122 1 : sal_Int32 nErrorBarStyle = cssc::ErrorBarStyle::NONE;
3123 1 : xErrorBarProps->getPropertyValue("ErrorBarStyle") >>= nErrorBarStyle;
3124 1 : const char* pErrorBarStyle = getErrorBarStyle(nErrorBarStyle);
3125 1 : if(!pErrorBarStyle)
3126 1 : return;
3127 :
3128 1 : FSHelperPtr pFS = GetFS();
3129 : pFS->startElement( FSNS( XML_c, XML_errBars ),
3130 1 : FSEND );
3131 : pFS->singleElement( FSNS( XML_c, XML_errDir ),
3132 : XML_val, bYError ? "y" : "x",
3133 1 : FSEND );
3134 1 : bool bPositive = false, bNegative = false;
3135 1 : xErrorBarProps->getPropertyValue("ShowPositiveError") >>= bPositive;
3136 1 : xErrorBarProps->getPropertyValue("ShowNegativeError") >>= bNegative;
3137 : const char* pErrBarType;
3138 1 : if(bPositive && bNegative)
3139 1 : pErrBarType = "both";
3140 0 : else if(bPositive)
3141 0 : pErrBarType = "plus";
3142 0 : else if(bNegative)
3143 0 : pErrBarType = "minus";
3144 : else
3145 : {
3146 : // what the hell should we do now?
3147 : // at least this makes the file valid
3148 0 : pErrBarType = "both";
3149 : }
3150 : pFS->singleElement( FSNS( XML_c, XML_errBarType ),
3151 : XML_val, pErrBarType,
3152 1 : FSEND );
3153 : pFS->singleElement( FSNS( XML_c, XML_errValType ),
3154 : XML_val, pErrorBarStyle,
3155 1 : FSEND );
3156 : pFS->singleElement( FSNS( XML_c, XML_noEndCap ),
3157 : XML_val, "0",
3158 1 : FSEND );
3159 1 : if(nErrorBarStyle == cssc::ErrorBarStyle::FROM_DATA)
3160 : {
3161 0 : uno::Reference< chart2::data::XDataSource > xDataSource(xErrorBarProps, uno::UNO_QUERY);
3162 : Sequence< Reference < chart2::data::XLabeledDataSequence > > aSequences =
3163 0 : xDataSource->getDataSequences();
3164 :
3165 0 : if(bPositive)
3166 : {
3167 0 : exportSeriesValues(getLabeledSequence(aSequences, true), XML_plus);
3168 : }
3169 :
3170 0 : if(bNegative)
3171 : {
3172 0 : exportSeriesValues(getLabeledSequence(aSequences, false), XML_minus);
3173 0 : }
3174 : }
3175 : else
3176 : {
3177 1 : double nVal = 0.0;
3178 1 : if(nErrorBarStyle == cssc::ErrorBarStyle::STANDARD_DEVIATION)
3179 : {
3180 0 : xErrorBarProps->getPropertyValue("Weight") >>= nVal;
3181 : }
3182 : else
3183 : {
3184 1 : if(bPositive)
3185 1 : xErrorBarProps->getPropertyValue("PositiveError") >>= nVal;
3186 : else
3187 0 : xErrorBarProps->getPropertyValue("NegativeError") >>= nVal;
3188 : }
3189 :
3190 1 : OString aVal = OString::number(nVal);
3191 :
3192 : pFS->singleElement( FSNS( XML_c, XML_val ),
3193 : XML_val, aVal.getStr(),
3194 1 : FSEND );
3195 : }
3196 :
3197 1 : pFS->endElement( FSNS( XML_c, XML_errBars) );
3198 : }
3199 :
3200 11 : void ChartExport::exportView3D()
3201 : {
3202 11 : Reference< XPropertySet > xPropSet( mxDiagram , uno::UNO_QUERY);
3203 11 : if( !xPropSet.is() )
3204 11 : return;
3205 22 : FSHelperPtr pFS = GetFS();
3206 : pFS->startElement( FSNS( XML_c, XML_view3D ),
3207 11 : FSEND );
3208 11 : sal_Int32 eChartType = getChartType( );
3209 : // rotX
3210 11 : if( GetProperty( xPropSet, "RotationHorizontal" ) )
3211 : {
3212 11 : sal_Int32 nRotationX = 0;
3213 11 : mAny >>= nRotationX;
3214 11 : if( nRotationX < 0 )
3215 : {
3216 2 : if(eChartType == chart::TYPEID_PIE)
3217 : {
3218 : /* In OOXML we get value in 0..90 range for pie chart X rotation , whereas we expect it to be in -90..90 range,
3219 : so we conver that during import. It is modified in View3DConverter::convertFromModel()
3220 : here we convert it back to 0..90 as we received in import */
3221 2 : nRotationX += 90; // X rotation (map Chart2 [-179,180] to OOXML [0..90])
3222 : }
3223 : else
3224 0 : nRotationX += 360; // X rotation (map Chart2 [-179,180] to OOXML [-90..90])
3225 : }
3226 : pFS->singleElement( FSNS( XML_c, XML_rotX ),
3227 : XML_val, I32S( nRotationX ),
3228 11 : FSEND );
3229 : }
3230 : // rotY
3231 11 : if( GetProperty( xPropSet, "RotationVertical" ) )
3232 : {
3233 : // Y rotation (map Chart2 [-179,180] to OOXML [0..359])
3234 11 : if( eChartType == chart::TYPEID_PIE && GetProperty( xPropSet, "StartingAngle" ) )
3235 : {
3236 : // Y rotation used as 'first pie slice angle' in 3D pie charts
3237 2 : sal_Int32 nStartingAngle=0;
3238 2 : mAny >>= nStartingAngle;
3239 : // convert to ooxml angle
3240 2 : nStartingAngle = (450 - nStartingAngle ) % 360;
3241 : pFS->singleElement( FSNS( XML_c, XML_rotY ),
3242 : XML_val, I32S( nStartingAngle ),
3243 2 : FSEND );
3244 : }
3245 : else
3246 : {
3247 9 : sal_Int32 nRotationY = 0;
3248 9 : mAny >>= nRotationY;
3249 : // Y rotation (map Chart2 [-179,180] to OOXML [0..359])
3250 9 : if( nRotationY < 0 )
3251 0 : nRotationY += 360;
3252 : pFS->singleElement( FSNS( XML_c, XML_rotY ),
3253 : XML_val, I32S( nRotationY ),
3254 9 : FSEND );
3255 : }
3256 : }
3257 : // rAngAx
3258 11 : if( GetProperty( xPropSet, "RightAngledAxes" ) )
3259 : {
3260 11 : sal_Bool bRightAngled = sal_False;
3261 11 : mAny >>= bRightAngled;
3262 11 : const char* sRightAngled = bRightAngled ? "1":"0";
3263 : pFS->singleElement( FSNS( XML_c, XML_rAngAx ),
3264 : XML_val, sRightAngled,
3265 11 : FSEND );
3266 : }
3267 : // perspective
3268 11 : if( GetProperty( xPropSet, "Perspective" ) )
3269 : {
3270 11 : sal_Int32 nPerspective = 0;
3271 11 : mAny >>= nPerspective;
3272 : // map Chart2 [0,100] to OOXML [0..200]
3273 11 : nPerspective *= 2;
3274 : pFS->singleElement( FSNS( XML_c, XML_perspective ),
3275 : XML_val, I32S( nPerspective ),
3276 11 : FSEND );
3277 : }
3278 22 : pFS->endElement( FSNS( XML_c, XML_view3D ) );
3279 : }
3280 :
3281 20 : bool ChartExport::isDeep3dChart()
3282 : {
3283 20 : sal_Bool isDeep = sal_False;
3284 20 : if( mbIs3DChart )
3285 : {
3286 13 : Reference< XPropertySet > xPropSet( mxDiagram , uno::UNO_QUERY);
3287 13 : if( GetProperty( xPropSet, "Deep" ) )
3288 13 : mAny >>= isDeep;
3289 : }
3290 20 : return isDeep;
3291 : }
3292 :
3293 : }// drawingml
3294 177 : }// oox
3295 :
3296 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|