update dev300-m58
[ooovba.git] / chart2 / source / tools / DiagramHelper.cxx
bloba3beb62c6f771c4d3e87d6c13448451efbbc4619
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: DiagramHelper.cxx,v $
10 * $Revision: 1.18.22.4 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_chart2.hxx"
33 #include "DiagramHelper.hxx"
34 #include "LegendHelper.hxx"
35 #include "PropertyHelper.hxx"
36 #include "macros.hxx"
37 #include "DataSeriesHelper.hxx"
38 #include "AxisHelper.hxx"
39 #include "ContainerHelper.hxx"
40 #include "ChartTypeHelper.hxx"
41 #include "CommonConverters.hxx"
42 #include "servicenames_charttypes.hxx"
44 #include <com/sun/star/chart/MissingValueTreatment.hpp>
45 #include <com/sun/star/chart2/XTitled.hpp>
46 #include <com/sun/star/chart2/XChartTypeContainer.hpp>
47 #include <com/sun/star/chart2/XChartTypeTemplate.hpp>
48 #include <com/sun/star/chart2/XCoordinateSystemContainer.hpp>
49 #include <com/sun/star/chart2/XDataSeriesContainer.hpp>
50 #include <com/sun/star/chart2/InterpretedData.hpp>
51 #include <com/sun/star/chart2/AxisType.hpp>
52 #include <com/sun/star/chart2/DataPointGeometry3D.hpp>
53 #include <com/sun/star/drawing/ShadeMode.hpp>
55 #include <rtl/math.hxx>
57 using namespace ::com::sun::star;
58 using namespace ::com::sun::star::chart2;
59 using namespace ::std;
61 using ::com::sun::star::uno::Reference;
62 using ::com::sun::star::uno::Sequence;
63 using ::rtl::OUString;
65 namespace chart
68 // static
69 DiagramHelper::tTemplateWithServiceName
70 DiagramHelper::getTemplateForDiagram(
71 const Reference< XDiagram > & xDiagram,
72 const Reference< lang::XMultiServiceFactory > & xChartTypeManager,
73 const OUString & rPreferredTemplateName )
75 DiagramHelper::tTemplateWithServiceName aResult;
77 if( ! (xChartTypeManager.is() && xDiagram.is()))
78 return aResult;
80 Sequence< OUString > aServiceNames( xChartTypeManager->getAvailableServiceNames());
81 const sal_Int32 nLength = aServiceNames.getLength();
83 bool bHasPreferredTemplate = (rPreferredTemplateName.getLength() > 0);
84 bool bTemplateFound = false;
86 if( bHasPreferredTemplate )
88 Reference< XChartTypeTemplate > xTempl(
89 xChartTypeManager->createInstance( rPreferredTemplateName ), uno::UNO_QUERY );
91 if( xTempl.is() &&
92 xTempl->matchesTemplate( xDiagram, sal_True ))
94 aResult.first = xTempl;
95 aResult.second = rPreferredTemplateName;
96 bTemplateFound = true;
100 for( sal_Int32 i = 0; ! bTemplateFound && i < nLength; ++i )
104 if( ! bHasPreferredTemplate ||
105 ! rPreferredTemplateName.equals( aServiceNames[ i ] ))
107 Reference< XChartTypeTemplate > xTempl(
108 xChartTypeManager->createInstance( aServiceNames[ i ] ), uno::UNO_QUERY_THROW );
110 if( xTempl->matchesTemplate( xDiagram, sal_True ))
112 aResult.first = xTempl;
113 aResult.second = aServiceNames[ i ];
114 bTemplateFound = true;
118 catch( uno::Exception & ex )
120 ASSERT_EXCEPTION( ex );
124 return aResult;
127 // static
128 void DiagramHelper::setVertical(
129 const Reference< XDiagram > & xDiagram,
130 bool bVertical /* = true */ )
134 Reference< XCoordinateSystemContainer > xCnt( xDiagram, uno::UNO_QUERY );
135 if( xCnt.is())
137 Sequence< Reference< XCoordinateSystem > > aCooSys(
138 xCnt->getCoordinateSystems());
139 uno::Any aValue;
140 aValue <<= bVertical;
141 for( sal_Int32 i=0; i<aCooSys.getLength(); ++i )
143 uno::Reference< XCoordinateSystem > xCooSys( aCooSys[i] );
144 Reference< beans::XPropertySet > xProp( xCooSys, uno::UNO_QUERY );
145 bool bChanged = false;
146 if( xProp.is() )
148 bool bOldSwap = sal_False;
149 if( !(xProp->getPropertyValue( C2U("SwapXAndYAxis") ) >>= bOldSwap)
150 || bVertical != bOldSwap )
151 bChanged = true;
153 if( bChanged )
154 xProp->setPropertyValue( C2U("SwapXAndYAxis"), aValue );
156 if( xCooSys.is() )
158 const sal_Int32 nDimensionCount( xCooSys->getDimension() );
159 sal_Int32 nDimIndex = 0;
160 for(nDimIndex=0; nDimIndex<nDimensionCount; ++nDimIndex)
162 const sal_Int32 nMaximumScaleIndex = xCooSys->getMaximumAxisIndexByDimension(nDimIndex);
163 for(sal_Int32 nI=0; nI<=nMaximumScaleIndex; ++nI)
165 Reference< chart2::XAxis > xAxis( xCooSys->getAxisByDimension( nDimIndex,nI ));
166 if( xAxis.is() )
168 //adapt title rotation only when axis swapping has changed
169 if( bChanged )
171 Reference< XTitled > xTitled( xAxis, uno::UNO_QUERY );
172 if( xTitled.is())
174 Reference< beans::XPropertySet > xTitleProps( xTitled->getTitleObject(), uno::UNO_QUERY );
175 if( !xTitleProps.is() )
176 continue;
177 double fAngleDegree = 0.0;
178 xTitleProps->getPropertyValue( C2U( "TextRotation" ) ) >>= fAngleDegree;
179 if( !::rtl::math::approxEqual( fAngleDegree, 0.0 )
180 && !::rtl::math::approxEqual( fAngleDegree, 90.0 ) )
181 continue;
183 double fNewAngleDegree = 0.0;
184 if( !bVertical && nDimIndex == 1 )
185 fNewAngleDegree = 90.0;
186 else if( bVertical && nDimIndex == 0 )
187 fNewAngleDegree = 90.0;
189 xTitleProps->setPropertyValue( C2U( "TextRotation" ), uno::makeAny( fNewAngleDegree ));
199 catch( uno::Exception & ex )
201 ASSERT_EXCEPTION( ex );
205 //static
206 bool DiagramHelper::getVertical( const uno::Reference< chart2::XDiagram > & xDiagram,
207 bool& rbFound, bool& rbAmbiguous )
209 bool bValue = false;
210 rbFound = false;
211 rbAmbiguous = false;
213 Reference< XCoordinateSystemContainer > xCnt( xDiagram, uno::UNO_QUERY );
214 if( xCnt.is())
216 Sequence< Reference< XCoordinateSystem > > aCooSys(
217 xCnt->getCoordinateSystems());
218 for( sal_Int32 i=0; i<aCooSys.getLength(); ++i )
220 Reference< beans::XPropertySet > xProp( aCooSys[i], uno::UNO_QUERY );
221 if( xProp.is())
223 bool bCurrent = false;
224 if( xProp->getPropertyValue( C2U("SwapXAndYAxis") ) >>= bCurrent )
226 if( !rbFound )
228 bValue = bCurrent;
229 rbFound = true;
231 else if( bCurrent != bValue )
233 // ambiguous -> choose always first found
234 rbAmbiguous = true;
240 return bValue;
243 //static
244 void DiagramHelper::setStackMode(
245 const Reference< XDiagram > & xDiagram,
246 StackMode eStackMode,
247 bool bOnlyAtFirstChartType /* = true */
252 if( eStackMode == StackMode_AMBIGUOUS )
253 return;
255 bool bValueFound = false;
256 bool bIsAmbiguous = false;
257 StackMode eOldStackMode = DiagramHelper::getStackMode( xDiagram, bValueFound, bIsAmbiguous );
259 if( eStackMode == eOldStackMode && !bIsAmbiguous )
260 return;
262 StackingDirection eNewDirection = StackingDirection_NO_STACKING;
263 if( eStackMode == StackMode_Y_STACKED || eStackMode == StackMode_Y_STACKED_PERCENT )
264 eNewDirection = StackingDirection_Y_STACKING;
265 else if( eStackMode == StackMode_Z_STACKED )
266 eNewDirection = StackingDirection_Z_STACKING;
268 uno::Any aNewDirection( uno::makeAny(eNewDirection) );
270 sal_Bool bPercent = sal_False;
271 if( eStackMode == StackMode_Y_STACKED_PERCENT )
272 bPercent = sal_True;
274 //iterate through all coordinate systems
275 uno::Reference< XCoordinateSystemContainer > xCooSysContainer( xDiagram, uno::UNO_QUERY );
276 if( !xCooSysContainer.is() )
277 return;
278 uno::Sequence< uno::Reference< XCoordinateSystem > > aCooSysList( xCooSysContainer->getCoordinateSystems() );
279 for( sal_Int32 nCS = 0; nCS < aCooSysList.getLength(); ++nCS )
281 uno::Reference< XCoordinateSystem > xCooSys( aCooSysList[nCS] );
282 //set correct percent stacking
283 const sal_Int32 nMaximumScaleIndex = xCooSys->getMaximumAxisIndexByDimension(1);
284 for(sal_Int32 nI=0; nI<=nMaximumScaleIndex; ++nI)
286 Reference< chart2::XAxis > xAxis( xCooSys->getAxisByDimension( 1,nI ));
287 if( xAxis.is())
289 chart2::ScaleData aScaleData = xAxis->getScaleData();
290 if( (aScaleData.AxisType==AxisType::PERCENT) != bPercent )
292 if( bPercent )
293 aScaleData.AxisType = AxisType::PERCENT;
294 else
295 aScaleData.AxisType = AxisType::REALNUMBER;
296 xAxis->setScaleData( aScaleData );
300 //iterate through all chart types in the current coordinate system
301 uno::Reference< XChartTypeContainer > xChartTypeContainer( xCooSys, uno::UNO_QUERY );
302 if( !xChartTypeContainer.is() )
303 continue;
304 uno::Sequence< uno::Reference< XChartType > > aChartTypeList( xChartTypeContainer->getChartTypes() );
305 sal_Int32 nMax = aChartTypeList.getLength();
306 if( bOnlyAtFirstChartType
307 && nMax >= 1 )
308 nMax = 1;
309 for( sal_Int32 nT = 0; nT < nMax; ++nT )
311 uno::Reference< XChartType > xChartType( aChartTypeList[nT] );
313 //iterate through all series in this chart type
314 uno::Reference< XDataSeriesContainer > xDataSeriesContainer( xChartType, uno::UNO_QUERY );
315 OSL_ASSERT( xDataSeriesContainer.is());
316 if( !xDataSeriesContainer.is() )
317 continue;
319 uno::Sequence< uno::Reference< XDataSeries > > aSeriesList( xDataSeriesContainer->getDataSeries() );
320 for( sal_Int32 nS = 0; nS < aSeriesList.getLength(); ++nS )
322 Reference< beans::XPropertySet > xProp( aSeriesList[nS], uno::UNO_QUERY );
323 if(xProp.is())
324 xProp->setPropertyValue( C2U( "StackingDirection" ), aNewDirection );
329 catch( uno::Exception & ex )
331 ASSERT_EXCEPTION( ex );
335 //static
337 StackMode DiagramHelper::getStackMode( const Reference< XDiagram > & xDiagram, bool& rbFound, bool& rbAmbiguous )
339 rbFound=false;
340 rbAmbiguous=false;
342 StackMode eGlobalStackMode = StackMode_NONE;
344 //iterate through all coordinate systems
345 uno::Reference< XCoordinateSystemContainer > xCooSysContainer( xDiagram, uno::UNO_QUERY );
346 if( !xCooSysContainer.is() )
347 return eGlobalStackMode;
348 uno::Sequence< uno::Reference< XCoordinateSystem > > aCooSysList( xCooSysContainer->getCoordinateSystems() );
349 for( sal_Int32 nCS = 0; nCS < aCooSysList.getLength(); ++nCS )
351 uno::Reference< XCoordinateSystem > xCooSys( aCooSysList[nCS] );
353 //iterate through all chart types in the current coordinate system
354 uno::Reference< XChartTypeContainer > xChartTypeContainer( xCooSys, uno::UNO_QUERY );
355 if( !xChartTypeContainer.is() )
356 continue;
357 uno::Sequence< uno::Reference< XChartType > > aChartTypeList( xChartTypeContainer->getChartTypes() );
358 for( sal_Int32 nT = 0; nT < aChartTypeList.getLength(); ++nT )
360 uno::Reference< XChartType > xChartType( aChartTypeList[nT] );
362 StackMode eLocalStackMode = DiagramHelper::getStackModeFromChartType(
363 xChartType, rbFound, rbAmbiguous, xCooSys );
365 if( rbFound && eLocalStackMode != eGlobalStackMode && nT>0 )
367 rbAmbiguous = true;
368 return eGlobalStackMode;
371 eGlobalStackMode = eLocalStackMode;
375 return eGlobalStackMode;
378 // static
379 StackMode DiagramHelper::getStackModeFromChartType(
380 const Reference< XChartType > & xChartType,
381 bool& rbFound, bool& rbAmbiguous,
382 const Reference< XCoordinateSystem > & xCorrespondingCoordinateSystem )
384 StackMode eStackMode = StackMode_NONE;
385 rbFound = false;
386 rbAmbiguous = false;
390 Reference< XDataSeriesContainer > xDSCnt( xChartType, uno::UNO_QUERY_THROW );
391 Sequence< Reference< chart2::XDataSeries > > aSeries( xDSCnt->getDataSeries());
393 chart2::StackingDirection eCommonDirection = chart2::StackingDirection_NO_STACKING;
394 bool bDirectionInitialized = false;
396 // first series is irrelvant for stacking, start with second, unless
397 // there is only one series
398 const sal_Int32 nSeriesCount = aSeries.getLength();
399 sal_Int32 i = (nSeriesCount == 1) ? 0: 1;
400 for( ; i<nSeriesCount; ++i )
402 rbFound = true;
403 Reference< beans::XPropertySet > xProp( aSeries[i], uno::UNO_QUERY_THROW );
404 chart2::StackingDirection eCurrentDirection = eCommonDirection;
405 // property is not MAYBEVOID
406 bool bSuccess = ( xProp->getPropertyValue( C2U("StackingDirection") ) >>= eCurrentDirection );
407 OSL_ASSERT( bSuccess );
408 (void)(bSuccess); // avoid warning in non-debug builds
409 if( ! bDirectionInitialized )
411 eCommonDirection = eCurrentDirection;
412 bDirectionInitialized = true;
414 else
416 if( eCommonDirection != eCurrentDirection )
418 rbAmbiguous = true;
419 break;
424 if( rbFound )
426 if( eCommonDirection == chart2::StackingDirection_Z_STACKING )
427 eStackMode = StackMode_Z_STACKED;
428 else if( eCommonDirection == chart2::StackingDirection_Y_STACKING )
430 eStackMode = StackMode_Y_STACKED;
432 // percent stacking
433 if( xCorrespondingCoordinateSystem.is() )
435 if( 1 < xCorrespondingCoordinateSystem->getDimension() )
437 sal_Int32 nAxisIndex = 0;
438 if( nSeriesCount )
439 nAxisIndex = DataSeriesHelper::getAttachedAxisIndex(aSeries[0]);
441 Reference< chart2::XAxis > xAxis(
442 xCorrespondingCoordinateSystem->getAxisByDimension( 1,nAxisIndex ));
443 if( xAxis.is())
445 chart2::ScaleData aScaleData = xAxis->getScaleData();
446 if( aScaleData.AxisType==chart2::AxisType::PERCENT )
447 eStackMode = StackMode_Y_STACKED_PERCENT;
454 catch( uno::Exception & ex )
456 ASSERT_EXCEPTION( ex );
459 return eStackMode;
462 // static
463 sal_Int32 DiagramHelper::getDimension( const Reference< XDiagram > & xDiagram )
465 // -1: not yet set
466 sal_Int32 nResult = -1;
470 Reference< XCoordinateSystemContainer > xCooSysCnt(
471 xDiagram, uno::UNO_QUERY_THROW );
472 Sequence< Reference< XCoordinateSystem > > aCooSysSeq(
473 xCooSysCnt->getCoordinateSystems());
475 for( sal_Int32 i=0; i<aCooSysSeq.getLength(); ++i )
477 Reference< XCoordinateSystem > xCooSys( aCooSysSeq[i] );
478 if(xCooSys.is())
480 nResult = xCooSys->getDimension();
481 break;
485 catch( uno::Exception & ex )
487 ASSERT_EXCEPTION( ex );
490 return nResult;
493 // static
494 void DiagramHelper::setDimension(
495 const Reference< XDiagram > & xDiagram,
496 sal_Int32 nNewDimensionCount )
498 if( ! xDiagram.is())
499 return;
501 if( DiagramHelper::getDimension( xDiagram ) == nNewDimensionCount )
502 return;
506 bool rbFound = false;
507 bool rbAmbiguous = true;
508 StackMode eStackMode = DiagramHelper::getStackMode( xDiagram, rbFound, rbAmbiguous );
509 bool bIsSupportingOnlyDeepStackingFor3D=false;
511 //change all coordinate systems:
512 Reference< XCoordinateSystemContainer > xCooSysContainer( xDiagram, uno::UNO_QUERY_THROW );
513 Sequence< Reference< XCoordinateSystem > > aCooSysList( xCooSysContainer->getCoordinateSystems() );
514 for( sal_Int32 nCS = 0; nCS < aCooSysList.getLength(); ++nCS )
516 Reference< XCoordinateSystem > xOldCooSys( aCooSysList[nCS], uno::UNO_QUERY );
517 Reference< XCoordinateSystem > xNewCooSys;
519 Reference< XChartTypeContainer > xChartTypeContainer( xOldCooSys, uno::UNO_QUERY );
520 if( !xChartTypeContainer.is() )
521 continue;
523 Sequence< Reference< XChartType > > aChartTypeList( xChartTypeContainer->getChartTypes() );
524 for( sal_Int32 nT = 0; nT < aChartTypeList.getLength(); ++nT )
526 Reference< XChartType > xChartType( aChartTypeList[nT], uno::UNO_QUERY );
527 bIsSupportingOnlyDeepStackingFor3D = ChartTypeHelper::isSupportingOnlyDeepStackingFor3D( xChartType );
528 if(!xNewCooSys.is())
530 xNewCooSys = xChartType->createCoordinateSystem( nNewDimensionCount );
531 break;
533 //@todo make sure that all following charttypes are also capable of the new dimension
534 //otherwise separate them in a different group
535 //BM: might be done in replaceCoordinateSystem()
538 // replace the old coordinate system at all places where it was used
539 DiagramHelper::replaceCoordinateSystem( xDiagram, xOldCooSys, xNewCooSys );
542 //correct stack mode if necessary
543 if( nNewDimensionCount==3 && eStackMode != StackMode_Z_STACKED && bIsSupportingOnlyDeepStackingFor3D )
544 DiagramHelper::setStackMode( xDiagram, StackMode_Z_STACKED );
545 else if( nNewDimensionCount==2 && eStackMode == StackMode_Z_STACKED )
546 DiagramHelper::setStackMode( xDiagram, StackMode_NONE );
548 catch( uno::Exception & ex )
550 ASSERT_EXCEPTION( ex );
554 // static
555 void DiagramHelper::replaceCoordinateSystem(
556 const Reference< XDiagram > & xDiagram,
557 const Reference< XCoordinateSystem > & xCooSysToReplace,
558 const Reference< XCoordinateSystem > & xReplacement )
560 OSL_ASSERT( xDiagram.is());
561 if( ! xDiagram.is())
562 return;
564 // update the coordinate-system container
565 Reference< XCoordinateSystemContainer > xCont( xDiagram, uno::UNO_QUERY );
566 if( xCont.is())
570 Reference< chart2::data::XLabeledDataSequence > xCategories = DiagramHelper::getCategoriesFromDiagram( xDiagram );
572 // move chart types of xCooSysToReplace to xReplacement
573 Reference< XChartTypeContainer > xCTCntCooSys( xCooSysToReplace, uno::UNO_QUERY_THROW );
574 Reference< XChartTypeContainer > xCTCntReplacement( xReplacement, uno::UNO_QUERY_THROW );
575 xCTCntReplacement->setChartTypes( xCTCntCooSys->getChartTypes());
577 xCont->removeCoordinateSystem( xCooSysToReplace );
578 xCont->addCoordinateSystem( xReplacement );
580 if( xCategories.is() )
581 DiagramHelper::setCategoriesToDiagram( xCategories, xDiagram );
583 catch( uno::Exception & ex )
585 ASSERT_EXCEPTION( ex );
590 //static
591 bool DiagramHelper::isSeriesAttachedToMainAxis(
592 const uno::Reference< chart2::XDataSeries >& xDataSeries )
594 sal_Int32 nAxisIndex = DataSeriesHelper::getAttachedAxisIndex(xDataSeries);
595 return (nAxisIndex==0);
598 //static
599 bool DiagramHelper::attachSeriesToAxis( bool bAttachToMainAxis
600 , const uno::Reference< chart2::XDataSeries >& xDataSeries
601 , const uno::Reference< chart2::XDiagram >& xDiagram
602 , const uno::Reference< uno::XComponentContext > & xContext
605 bool bChanged = false;
607 //set property at axis
608 Reference< beans::XPropertySet > xProp( xDataSeries, uno::UNO_QUERY_THROW );
609 if( !xProp.is() )
610 return bChanged;
612 sal_Int32 nNewAxisIndex = bAttachToMainAxis ? 0 : 1;
613 sal_Int32 nOldAxisIndex = DataSeriesHelper::getAttachedAxisIndex(xDataSeries);
615 if( nOldAxisIndex != nNewAxisIndex )
619 xProp->setPropertyValue( C2U("AttachedAxisIndex"), uno::makeAny( nNewAxisIndex ) );
620 bChanged = true;
622 catch( const uno::Exception & ex )
624 ASSERT_EXCEPTION( ex );
628 if( bChanged && xDiagram.is() )
630 uno::Reference< XAxis > xAxis( AxisHelper::getAxis( 1, bAttachToMainAxis, xDiagram ) );
631 if(!xAxis.is()) //create an axis if necessary
632 xAxis = AxisHelper::createAxis( 1, bAttachToMainAxis, xDiagram, xContext );
635 return bChanged;
638 //static
639 uno::Reference< XAxis > DiagramHelper::getAttachedAxis(
640 const uno::Reference< XDataSeries >& xSeries,
641 const uno::Reference< XDiagram >& xDiagram )
643 return AxisHelper::getAxis( 1, DiagramHelper::isSeriesAttachedToMainAxis( xSeries ), xDiagram );
646 //static
647 uno::Reference< XChartType > DiagramHelper::getChartTypeOfSeries(
648 const uno::Reference< chart2::XDiagram >& xDiagram
649 , const uno::Reference< XDataSeries >& xGivenDataSeries )
651 if( !xGivenDataSeries.is() )
652 return 0;
653 if(!xDiagram.is())
654 return 0;
656 //iterate through the model to find the given xSeries
657 //the found parent indicates the charttype
659 //iterate through all coordinate systems
660 uno::Reference< XCoordinateSystemContainer > xCooSysContainer( xDiagram, uno::UNO_QUERY );
661 if( !xCooSysContainer.is())
662 return 0;
664 uno::Sequence< uno::Reference< XCoordinateSystem > > aCooSysList( xCooSysContainer->getCoordinateSystems() );
665 for( sal_Int32 nCS = 0; nCS < aCooSysList.getLength(); ++nCS )
667 uno::Reference< XCoordinateSystem > xCooSys( aCooSysList[nCS] );
669 //iterate through all chart types in the current coordinate system
670 uno::Reference< XChartTypeContainer > xChartTypeContainer( xCooSys, uno::UNO_QUERY );
671 OSL_ASSERT( xChartTypeContainer.is());
672 if( !xChartTypeContainer.is() )
673 continue;
674 uno::Sequence< uno::Reference< XChartType > > aChartTypeList( xChartTypeContainer->getChartTypes() );
675 for( sal_Int32 nT = 0; nT < aChartTypeList.getLength(); ++nT )
677 uno::Reference< XChartType > xChartType( aChartTypeList[nT] );
679 //iterate through all series in this chart type
680 uno::Reference< XDataSeriesContainer > xDataSeriesContainer( xChartType, uno::UNO_QUERY );
681 OSL_ASSERT( xDataSeriesContainer.is());
682 if( !xDataSeriesContainer.is() )
683 continue;
685 uno::Sequence< uno::Reference< XDataSeries > > aSeriesList( xDataSeriesContainer->getDataSeries() );
686 for( sal_Int32 nS = 0; nS < aSeriesList.getLength(); ++nS )
688 if( xGivenDataSeries==aSeriesList[nS] )
689 return xChartType;
693 return 0;
696 // static
697 ::std::vector< Reference< XDataSeries > >
698 DiagramHelper::getDataSeriesFromDiagram(
699 const Reference< XDiagram > & xDiagram )
701 ::std::vector< Reference< XDataSeries > > aResult;
705 Reference< XCoordinateSystemContainer > xCooSysCnt(
706 xDiagram, uno::UNO_QUERY_THROW );
707 Sequence< Reference< XCoordinateSystem > > aCooSysSeq(
708 xCooSysCnt->getCoordinateSystems());
709 for( sal_Int32 i=0; i<aCooSysSeq.getLength(); ++i )
711 Reference< XChartTypeContainer > xCTCnt( aCooSysSeq[i], uno::UNO_QUERY_THROW );
712 Sequence< Reference< XChartType > > aChartTypeSeq( xCTCnt->getChartTypes());
713 for( sal_Int32 j=0; j<aChartTypeSeq.getLength(); ++j )
715 Reference< XDataSeriesContainer > xDSCnt( aChartTypeSeq[j], uno::UNO_QUERY_THROW );
716 Sequence< Reference< XDataSeries > > aSeriesSeq( xDSCnt->getDataSeries() );
717 ::std::copy( aSeriesSeq.getConstArray(), aSeriesSeq.getConstArray() + aSeriesSeq.getLength(),
718 ::std::back_inserter( aResult ));
722 catch( uno::Exception & ex )
724 ASSERT_EXCEPTION( ex );
727 return aResult;
730 Sequence< Sequence< Reference< XDataSeries > > >
731 DiagramHelper::getDataSeriesGroups( const Reference< XDiagram > & xDiagram )
733 vector< Sequence< Reference< XDataSeries > > > aResult;
735 //iterate through all coordinate systems
736 Reference< XCoordinateSystemContainer > xCooSysContainer( xDiagram, uno::UNO_QUERY );
737 if( xCooSysContainer.is() )
739 Sequence< Reference< XCoordinateSystem > > aCooSysList( xCooSysContainer->getCoordinateSystems() );
740 for( sal_Int32 nCS = 0; nCS < aCooSysList.getLength(); ++nCS )
742 //iterate through all chart types in the current coordinate system
743 Reference< XChartTypeContainer > xChartTypeContainer( aCooSysList[nCS], uno::UNO_QUERY );
744 if( !xChartTypeContainer.is() )
745 continue;
746 Sequence< Reference< XChartType > > aChartTypeList( xChartTypeContainer->getChartTypes() );
747 for( sal_Int32 nT = 0; nT < aChartTypeList.getLength(); ++nT )
749 Reference< XDataSeriesContainer > xDataSeriesContainer( aChartTypeList[nT], uno::UNO_QUERY );
750 if( !xDataSeriesContainer.is() )
751 continue;
752 aResult.push_back( xDataSeriesContainer->getDataSeries() );
756 return ContainerHelper::ContainerToSequence( aResult );
759 Reference< XChartType >
760 DiagramHelper::getChartTypeByIndex( const Reference< XDiagram >& xDiagram, sal_Int32 nIndex )
762 Reference< XChartType > xChartType;
764 //iterate through all coordinate systems
765 Reference< XCoordinateSystemContainer > xCooSysContainer( xDiagram, uno::UNO_QUERY );
766 if( ! xCooSysContainer.is())
767 return xChartType;
769 Sequence< Reference< XCoordinateSystem > > aCooSysList( xCooSysContainer->getCoordinateSystems() );
770 sal_Int32 nTypesSoFar = 0;
771 for( sal_Int32 nCS = 0; nCS < aCooSysList.getLength(); ++nCS )
773 Reference< XChartTypeContainer > xChartTypeContainer( aCooSysList[nCS], uno::UNO_QUERY );
774 if( !xChartTypeContainer.is() )
775 continue;
776 Sequence< Reference< XChartType > > aChartTypeList( xChartTypeContainer->getChartTypes() );
777 if( nIndex >= 0 && nIndex < (nTypesSoFar + aChartTypeList.getLength()) )
779 xChartType.set( aChartTypeList[nIndex - nTypesSoFar] );
780 break;
782 nTypesSoFar += aChartTypeList.getLength();
785 return xChartType;
788 namespace
791 std::vector< Reference< XAxis > > lcl_getAxisHoldingCategoriesFromDiagram(
792 const Reference< XDiagram > & xDiagram )
794 std::vector< Reference< XAxis > > aRet;
796 Reference< XAxis > xResult;
797 // return first x-axis as fall-back
798 Reference< XAxis > xFallBack;
801 Reference< XCoordinateSystemContainer > xCooSysCnt(
802 xDiagram, uno::UNO_QUERY_THROW );
803 Sequence< Reference< XCoordinateSystem > > aCooSysSeq(
804 xCooSysCnt->getCoordinateSystems());
805 for( sal_Int32 i=0; i<aCooSysSeq.getLength(); ++i )
807 Reference< XCoordinateSystem > xCooSys( aCooSysSeq[i] );
808 OSL_ASSERT( xCooSys.is());
809 for( sal_Int32 nN = xCooSys->getDimension(); nN--; )
811 const sal_Int32 nMaximumScaleIndex = xCooSys->getMaximumAxisIndexByDimension(nN);
812 for(sal_Int32 nI=0; nI<=nMaximumScaleIndex; ++nI)
814 Reference< XAxis > xAxis = xCooSys->getAxisByDimension( nN,nI );
815 OSL_ASSERT( xAxis.is());
816 if( xAxis.is())
818 ScaleData aScaleData = xAxis->getScaleData();
819 if( aScaleData.Categories.is() || (aScaleData.AxisType == AxisType::CATEGORY) )
821 aRet.push_back(xAxis);
823 if( (nN == 0) && !xFallBack.is())
824 xFallBack.set( xAxis );
830 catch( uno::Exception & ex )
832 ASSERT_EXCEPTION( ex );
835 if( aRet.empty() )
836 aRet.push_back(xFallBack);
838 return aRet;
841 } // anonymous namespace
843 //static
844 bool DiagramHelper::isCategoryDiagram(
845 const Reference< XDiagram >& xDiagram )
849 Reference< XCoordinateSystemContainer > xCooSysCnt(
850 xDiagram, uno::UNO_QUERY_THROW );
851 Sequence< Reference< XCoordinateSystem > > aCooSysSeq(
852 xCooSysCnt->getCoordinateSystems());
853 for( sal_Int32 i=0; i<aCooSysSeq.getLength(); ++i )
855 Reference< XCoordinateSystem > xCooSys( aCooSysSeq[i] );
856 OSL_ASSERT( xCooSys.is());
857 for( sal_Int32 nN = xCooSys->getDimension(); nN--; )
859 const sal_Int32 nMaximumScaleIndex = xCooSys->getMaximumAxisIndexByDimension(nN);
860 for(sal_Int32 nI=0; nI<=nMaximumScaleIndex; ++nI)
862 Reference< XAxis > xAxis = xCooSys->getAxisByDimension( nN,nI );
863 OSL_ASSERT( xAxis.is());
864 if( xAxis.is())
866 ScaleData aScaleData = xAxis->getScaleData();
867 if( aScaleData.AxisType == AxisType::CATEGORY )
868 return true;
874 catch( uno::Exception & ex )
876 ASSERT_EXCEPTION( ex );
879 return false;
882 // static
883 void DiagramHelper::setCategoriesToDiagram(
884 const Reference< chart2::data::XLabeledDataSequence >& xCategories,
885 const Reference< XDiagram >& xDiagram,
886 bool bSetAxisType /* = false */,
887 bool bCategoryAxis /* = true */ )
889 std::vector< Reference< chart2::XAxis > > aCatAxes(
890 lcl_getAxisHoldingCategoriesFromDiagram( xDiagram ));
892 std::vector< Reference< chart2::XAxis > >::iterator aIt( aCatAxes.begin() );
893 std::vector< Reference< chart2::XAxis > >::const_iterator aEnd( aCatAxes.end() );
895 for( aIt = aCatAxes.begin(); aIt != aEnd; ++aIt )
897 Reference< chart2::XAxis > xCatAxis(*aIt);
898 if( xCatAxis.is())
900 ScaleData aScaleData( xCatAxis->getScaleData());
901 aScaleData.Categories = xCategories;
902 if( bSetAxisType )
904 if( bCategoryAxis )
905 aScaleData.AxisType = AxisType::CATEGORY;
906 else if( aScaleData.AxisType == AxisType::CATEGORY )
907 aScaleData.AxisType = AxisType::REALNUMBER;
909 xCatAxis->setScaleData( aScaleData );
914 // static
915 Reference< data::XLabeledDataSequence >
916 DiagramHelper::getCategoriesFromDiagram(
917 const Reference< XDiagram > & xDiagram )
919 Reference< data::XLabeledDataSequence > xResult;
923 std::vector< Reference< chart2::XAxis > > aCatAxes(
924 lcl_getAxisHoldingCategoriesFromDiagram( xDiagram ));
925 std::vector< Reference< chart2::XAxis > >::iterator aIt( aCatAxes.begin() );
926 std::vector< Reference< chart2::XAxis > >::const_iterator aEnd( aCatAxes.end() );
927 //search for first categories
928 if( aIt != aEnd )
930 Reference< chart2::XAxis > xCatAxis(*aIt);
931 if( xCatAxis.is())
933 ScaleData aScaleData( xCatAxis->getScaleData());
934 if( aScaleData.Categories.is() )
936 xResult.set( aScaleData.Categories );
937 uno::Reference<beans::XPropertySet> xProp(aScaleData.Categories->getValues(), uno::UNO_QUERY );
938 if( xProp.is() )
942 xProp->setPropertyValue( C2U( "Role" ), uno::makeAny( C2U("categories") ) );
944 catch( uno::Exception & ex )
946 ASSERT_EXCEPTION( ex );
953 catch( uno::Exception & ex )
955 ASSERT_EXCEPTION( ex );
958 return xResult;
961 //static
962 void DiagramHelper::generateAutomaticCategoriesFromChartType(
963 Sequence< rtl::OUString >& rRet,
964 const Reference< XChartType >& xChartType )
966 if(!xChartType.is())
967 return;
968 rtl::OUString aMainSeq( xChartType->getRoleOfSequenceForSeriesLabel() );
969 Reference< XDataSeriesContainer > xSeriesCnt( xChartType, uno::UNO_QUERY );
970 if( xSeriesCnt.is() )
972 Sequence< Reference< XDataSeries > > aSeriesSeq( xSeriesCnt->getDataSeries() );
973 for( sal_Int32 nS = 0; nS < aSeriesSeq.getLength(); nS++ )
975 Reference< data::XDataSource > xDataSource( aSeriesSeq[nS], uno::UNO_QUERY );
976 if( !xDataSource.is() )
977 continue;
978 Reference< chart2::data::XLabeledDataSequence > xLabeledSeq(
979 ::chart::DataSeriesHelper::getDataSequenceByRole( xDataSource, aMainSeq ));
980 if( !xLabeledSeq.is() )
981 continue;
982 Reference< chart2::data::XDataSequence > xValueSeq( xLabeledSeq->getValues() );
983 if( !xValueSeq.is() )
984 continue;
985 rRet = xValueSeq->generateLabel( chart2::data::LabelOrigin_LONG_SIDE );
986 if( rRet.getLength() )
987 return;
992 //static
993 Sequence< rtl::OUString > DiagramHelper::generateAutomaticCategories(
994 const Reference< XChartDocument >& xChartDoc )
996 Sequence< rtl::OUString > aRet;
997 if(xChartDoc.is())
999 uno::Reference< chart2::XDiagram > xDia( xChartDoc->getFirstDiagram() );
1000 if(xDia.is())
1002 Reference< data::XLabeledDataSequence > xCategories( DiagramHelper::getCategoriesFromDiagram( xDia ) );
1003 if( xCategories.is() )
1004 aRet = DataSequenceToStringSequence(xCategories->getValues());
1005 if( !aRet.getLength() )
1008 //unused ranges are very problematic as they bear the risk to damage the rectangular structure completly
1009 if( bUseUnusedDataAlso )
1011 Sequence< Reference< chart2::data::XLabeledDataSequence > > aUnusedSequences( xDia->getUnusedData() );
1012 ::std::vector< Reference< chart2::data::XLabeledDataSequence > > aUnusedCategoryVector(
1013 DataSeriesHelper::getAllDataSequencesByRole( aUnusedSequences, C2U("categories") ) );
1014 if( aUnusedCategoryVector.size() && aUnusedCategoryVector[0].is() )
1015 aRet = DataSequenceToStringSequence(aUnusedCategoryVector[0]->getValues());
1018 if( !aRet.getLength() )
1020 Reference< XCoordinateSystemContainer > xCooSysCnt( xDia, uno::UNO_QUERY );
1021 if( xCooSysCnt.is() )
1023 Sequence< Reference< XCoordinateSystem > > aCooSysSeq( xCooSysCnt->getCoordinateSystems() );
1024 if( aCooSysSeq.getLength() )
1025 aRet = DiagramHelper::generateAutomaticCategories( aCooSysSeq[0] );
1031 return aRet;
1034 //static
1035 Sequence< rtl::OUString > DiagramHelper::generateAutomaticCategories(
1036 const Reference< XCoordinateSystem > & xCooSys )
1038 Sequence< rtl::OUString > aRet;
1040 Reference< XChartTypeContainer > xTypeCntr( xCooSys, uno::UNO_QUERY );
1041 if( xTypeCntr.is() )
1043 Sequence< Reference< XChartType > > aChartTypes( xTypeCntr->getChartTypes() );
1044 for( sal_Int32 nN=0; nN<aChartTypes.getLength(); nN++ )
1046 DiagramHelper::generateAutomaticCategoriesFromChartType( aRet, aChartTypes[nN] );
1047 if( aRet.getLength() )
1048 return aRet;
1051 return aRet;
1054 // static
1055 Sequence< Reference< XChartType > >
1056 DiagramHelper::getChartTypesFromDiagram(
1057 const Reference< XDiagram > & xDiagram )
1059 ::std::vector< Reference< XChartType > > aResult;
1061 if(xDiagram.is())
1064 Reference< XCoordinateSystemContainer > xCooSysCnt(
1065 xDiagram, uno::UNO_QUERY_THROW );
1066 Sequence< Reference< XCoordinateSystem > > aCooSysSeq(
1067 xCooSysCnt->getCoordinateSystems());
1068 for( sal_Int32 i=0; i<aCooSysSeq.getLength(); ++i )
1070 Reference< XChartTypeContainer > xCTCnt( aCooSysSeq[i], uno::UNO_QUERY_THROW );
1071 Sequence< Reference< XChartType > > aChartTypeSeq( xCTCnt->getChartTypes());
1072 ::std::copy( aChartTypeSeq.getConstArray(), aChartTypeSeq.getConstArray() + aChartTypeSeq.getLength(),
1073 ::std::back_inserter( aResult ));
1076 catch( uno::Exception & ex )
1078 ASSERT_EXCEPTION( ex );
1081 return ContainerHelper::ContainerToSequence( aResult );
1084 //static
1085 bool DiagramHelper::areChartTypesCompatible( const Reference< ::chart2::XChartType >& xFirstType,
1086 const Reference< ::chart2::XChartType >& xSecondType )
1088 if( !xFirstType.is() || !xSecondType.is() )
1089 return false;
1091 ::std::vector< ::rtl::OUString > aFirstRoles( ContainerHelper::SequenceToVector( xFirstType->getSupportedMandatoryRoles() ) );
1092 ::std::vector< ::rtl::OUString > aSecondRoles( ContainerHelper::SequenceToVector( xSecondType->getSupportedMandatoryRoles() ) );
1093 ::std::sort( aFirstRoles.begin(), aFirstRoles.end() );
1094 ::std::sort( aSecondRoles.begin(), aSecondRoles.end() );
1095 return ( aFirstRoles == aSecondRoles );
1098 namespace
1101 * This method implements the logic of checking if a series can be moved
1102 * forward/backward. Depending on the "bDoMove" parameter the series will
1103 * be moved (bDoMove = true) or the function just will test if the
1104 * series can be moved without doing the move (bDoMove = false).
1106 * @param xDiagram
1107 * Reference to the diagram that contains the series.
1109 * @param xGivenDataSeries
1110 * Reference to the series that should moved or tested for moving.
1112 * @param bForward
1113 * Direction in which the series should be moved or tested for moving.
1115 * @param bDoMove
1116 * Should this function really move the series (true) or just test if it is
1117 * possible (false).
1120 * @returns
1121 * in case of bDoMove == true
1122 * - True : if the move was done
1123 * - False : the move failed
1124 * in case of bDoMove == false
1125 * - True : the series can be moved
1126 * - False : the series can not be moved
1130 bool lcl_moveSeriesOrCheckIfMoveIsAllowed(
1131 const Reference< XDiagram >& xDiagram,
1132 const Reference< XDataSeries >& xGivenDataSeries,
1133 bool bForward,
1134 bool bDoMove )
1136 bool bMovedOrMoveAllowed = false;
1140 uno::Reference< XCoordinateSystemContainer > xCooSysContainer( xDiagram, uno::UNO_QUERY );
1142 //find position of series.
1143 bool bFound = false;
1145 if( xGivenDataSeries.is() && xCooSysContainer.is() )
1147 uno::Sequence< uno::Reference< XCoordinateSystem > > aCooSysList( xCooSysContainer->getCoordinateSystems() );
1149 for( sal_Int32 nCS = 0; !bFound && nCS < aCooSysList.getLength(); ++nCS )
1151 uno::Reference< XCoordinateSystem > xCooSys( aCooSysList[nCS] );
1153 //iterate through all chart types in the current coordinate system
1154 uno::Reference< XChartTypeContainer > xChartTypeContainer( xCooSys, uno::UNO_QUERY );
1155 OSL_ASSERT( xChartTypeContainer.is());
1156 if( !xChartTypeContainer.is() )
1157 continue;
1158 uno::Sequence< uno::Reference< XChartType > > aChartTypeList( xChartTypeContainer->getChartTypes() );
1159 uno::Reference< XChartType > xFormerChartType;
1161 for( sal_Int32 nT = 0; !bFound && nT < aChartTypeList.getLength(); ++nT )
1163 uno::Reference< XChartType > xCurrentChartType( aChartTypeList[nT] );
1165 //iterate through all series in this chart type
1166 uno::Reference< XDataSeriesContainer > xDataSeriesContainer( xCurrentChartType, uno::UNO_QUERY );
1167 OSL_ASSERT( xDataSeriesContainer.is());
1168 if( !xDataSeriesContainer.is() )
1169 continue;
1171 uno::Sequence< uno::Reference< XDataSeries > > aSeriesList( xDataSeriesContainer->getDataSeries() );
1173 for( sal_Int32 nS = 0; !bFound && nS < aSeriesList.getLength(); ++nS )
1176 // We found the series we are interrested in !
1177 if( xGivenDataSeries==aSeriesList[nS] )
1179 sal_Int32 nOldSeriesIndex = nS;
1180 bFound = true;
1184 sal_Int32 nNewSeriesIndex = nS;
1186 if( bForward )
1187 nNewSeriesIndex--;
1188 else
1189 nNewSeriesIndex++;
1192 if( nNewSeriesIndex >= 0 && nNewSeriesIndex < aSeriesList.getLength() )
1194 //move series in the same charttype
1195 bMovedOrMoveAllowed = true;
1196 if( bDoMove )
1198 aSeriesList[ nOldSeriesIndex ] = aSeriesList[ nNewSeriesIndex ];
1199 aSeriesList[ nNewSeriesIndex ] = xGivenDataSeries;
1200 xDataSeriesContainer->setDataSeries( aSeriesList );
1203 else if( nNewSeriesIndex<0 )
1205 //exchange series with former charttype
1206 if( xFormerChartType.is() && DiagramHelper::areChartTypesCompatible( xFormerChartType, xCurrentChartType ) )
1208 bMovedOrMoveAllowed = true;
1209 if( bDoMove )
1211 uno::Reference< XDataSeriesContainer > xOtherDataSeriesContainer( xFormerChartType, uno::UNO_QUERY );
1212 if( xOtherDataSeriesContainer.is() )
1214 uno::Sequence< uno::Reference< XDataSeries > > aOtherSeriesList( xOtherDataSeriesContainer->getDataSeries() );
1215 sal_Int32 nOtherSeriesIndex = aOtherSeriesList.getLength()-1;
1216 if( nOtherSeriesIndex >= 0 && nOtherSeriesIndex < aOtherSeriesList.getLength() )
1218 uno::Reference< XDataSeries > xExchangeSeries( aOtherSeriesList[nOtherSeriesIndex] );
1219 aOtherSeriesList[nOtherSeriesIndex] = xGivenDataSeries;
1220 xOtherDataSeriesContainer->setDataSeries(aOtherSeriesList);
1222 aSeriesList[nOldSeriesIndex]=xExchangeSeries;
1223 xDataSeriesContainer->setDataSeries(aSeriesList);
1229 else if( nT+1 < aChartTypeList.getLength() )
1231 //exchange series with next charttype
1232 uno::Reference< XChartType > xOtherChartType( aChartTypeList[nT+1] );
1233 if( xOtherChartType.is() && DiagramHelper::areChartTypesCompatible( xOtherChartType, xCurrentChartType ) )
1235 bMovedOrMoveAllowed = true;
1236 if( bDoMove )
1238 uno::Reference< XDataSeriesContainer > xOtherDataSeriesContainer( xOtherChartType, uno::UNO_QUERY );
1239 if( xOtherDataSeriesContainer.is() )
1241 uno::Sequence< uno::Reference< XDataSeries > > aOtherSeriesList( xOtherDataSeriesContainer->getDataSeries() );
1242 sal_Int32 nOtherSeriesIndex = 0;
1243 if( nOtherSeriesIndex >= 0 && nOtherSeriesIndex < aOtherSeriesList.getLength() )
1245 uno::Reference< XDataSeries > xExchangeSeries( aOtherSeriesList[nOtherSeriesIndex] );
1246 aOtherSeriesList[nOtherSeriesIndex] = xGivenDataSeries;
1247 xOtherDataSeriesContainer->setDataSeries(aOtherSeriesList);
1249 aSeriesList[nOldSeriesIndex]=xExchangeSeries;
1250 xDataSeriesContainer->setDataSeries(aSeriesList);
1257 catch( util::CloseVetoException& )
1260 catch( uno::RuntimeException& )
1265 xFormerChartType = xCurrentChartType;
1270 catch( util::CloseVetoException& )
1273 catch( uno::RuntimeException& )
1276 return bMovedOrMoveAllowed;
1278 } // anonymous namespace
1281 bool DiagramHelper::isSeriesMoveable(
1282 const Reference< XDiagram >& xDiagram,
1283 const Reference< XDataSeries >& xGivenDataSeries,
1284 bool bForward )
1286 bool bIsMoveable = false;
1287 const bool bDoMove = false;
1289 bIsMoveable = lcl_moveSeriesOrCheckIfMoveIsAllowed(
1290 xDiagram, xGivenDataSeries, bForward, bDoMove );
1292 return bIsMoveable;
1296 bool DiagramHelper::moveSeries( const Reference< XDiagram >& xDiagram, const Reference< XDataSeries >& xGivenDataSeries, bool bForward )
1298 bool bMoved = false;
1299 const bool bDoMove = true;
1301 bMoved = lcl_moveSeriesOrCheckIfMoveIsAllowed(
1302 xDiagram, xGivenDataSeries, bForward, bDoMove );
1304 return bMoved;
1307 bool DiagramHelper::isSupportingFloorAndWall( const Reference<
1308 chart2::XDiagram >& xDiagram )
1310 //pies and donuts currently do not support this because of wrong files from older versions
1311 //todo: allow this in future again, if fileversion are available for ole objects (metastream)
1312 //thus the wrong bottom can be removed on import
1314 Sequence< Reference< chart2::XChartType > > aTypes(
1315 ::chart::DiagramHelper::getChartTypesFromDiagram( xDiagram ) );
1316 for( sal_Int32 nN = 0; nN < aTypes.getLength(); nN++ )
1318 Reference< chart2::XChartType > xType( aTypes[nN] );
1319 if( xType.is() && xType->getChartType().match(CHART2_SERVICE_NAME_CHARTTYPE_PIE) )
1320 return false;
1321 if( xType.is() && xType->getChartType().match(CHART2_SERVICE_NAME_CHARTTYPE_NET) )
1322 return false;
1323 if( xType.is() && xType->getChartType().match(CHART2_SERVICE_NAME_CHARTTYPE_FILLED_NET) )
1324 return false;
1326 return true;
1329 bool DiagramHelper::isPieOrDonutChart( const ::com::sun::star::uno::Reference<
1330 ::com::sun::star::chart2::XDiagram >& xDiagram )
1332 uno::Reference< chart2::XChartType > xChartType( DiagramHelper::getChartTypeByIndex(
1333 xDiagram, 0 ) );
1335 if( xChartType .is() )
1337 rtl::OUString aChartType = xChartType->getChartType();
1338 if( aChartType.equals(CHART2_SERVICE_NAME_CHARTTYPE_PIE) )
1339 return true;
1341 return false;
1344 // static
1345 sal_Int32 DiagramHelper::getGeometry3D(
1346 const uno::Reference< chart2::XDiagram > & xDiagram,
1347 bool& rbFound, bool& rbAmbiguous )
1349 sal_Int32 nCommonGeom( DataPointGeometry3D::CUBOID );
1350 rbFound = false;
1351 rbAmbiguous = false;
1353 ::std::vector< Reference< chart2::XDataSeries > > aSeriesVec(
1354 DiagramHelper::getDataSeriesFromDiagram( xDiagram ));
1356 if( aSeriesVec.empty())
1357 rbAmbiguous = true;
1359 for( ::std::vector< Reference< chart2::XDataSeries > >::const_iterator aIt =
1360 aSeriesVec.begin(); aIt != aSeriesVec.end(); ++aIt )
1364 sal_Int32 nGeom = 0;
1365 Reference< beans::XPropertySet > xProp( *aIt, uno::UNO_QUERY_THROW );
1366 if( xProp->getPropertyValue( C2U( "Geometry3D" )) >>= nGeom )
1368 if( ! rbFound )
1370 // first series
1371 nCommonGeom = nGeom;
1372 rbFound = true;
1374 // further series: compare for uniqueness
1375 else if( nCommonGeom != nGeom )
1377 rbAmbiguous = true;
1378 break;
1382 catch( uno::Exception & ex )
1384 ASSERT_EXCEPTION( ex );
1388 return nCommonGeom;
1391 // static
1392 void DiagramHelper::setGeometry3D(
1393 const Reference< chart2::XDiagram > & xDiagram,
1394 sal_Int32 nNewGeometry )
1396 ::std::vector< Reference< chart2::XDataSeries > > aSeriesVec(
1397 DiagramHelper::getDataSeriesFromDiagram( xDiagram ));
1399 for( ::std::vector< Reference< chart2::XDataSeries > >::const_iterator aIt =
1400 aSeriesVec.begin(); aIt != aSeriesVec.end(); ++aIt )
1402 DataSeriesHelper::setPropertyAlsoToAllAttributedDataPoints(
1403 *aIt, C2U( "Geometry3D" ), uno::makeAny( nNewGeometry ));
1407 //static
1408 sal_Int32 DiagramHelper::getCorrectedMissingValueTreatment(
1409 const Reference< chart2::XDiagram > & xDiagram,
1410 const Reference< chart2::XChartType >& xChartType )
1412 sal_Int32 nResult = ::com::sun::star::chart::MissingValueTreatment::LEAVE_GAP;
1413 uno::Sequence < sal_Int32 > aAvailableMissingValueTreatments(
1414 ChartTypeHelper::getSupportedMissingValueTreatments( xChartType ) );
1416 uno::Reference< beans::XPropertySet > xDiaProp( xDiagram, uno::UNO_QUERY );
1417 if( xDiaProp.is() && (xDiaProp->getPropertyValue( C2U( "MissingValueTreatment" ) ) >>= nResult) )
1419 //ensure that the set value is supported by this charttype
1420 for( sal_Int32 nN = 0; nN < aAvailableMissingValueTreatments.getLength(); nN++ )
1421 if( aAvailableMissingValueTreatments[nN] == nResult )
1422 return nResult; //ok
1425 //otherwise use the first supported one
1426 if( aAvailableMissingValueTreatments.getLength() )
1428 nResult = aAvailableMissingValueTreatments[0];
1429 return nResult;
1432 return nResult;
1435 } // namespace chart