1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: ChartTypeTemplate.cxx,v $
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 "ChartTypeTemplate.hxx"
34 #include "PropertyHelper.hxx"
36 #include "DataSeriesHelper.hxx"
37 #include "DataInterpreter.hxx"
38 #include "CommonConverters.hxx"
39 #include "ContainerHelper.hxx"
40 #include "ChartTypeHelper.hxx"
42 #include "CartesianCoordinateSystem.hxx"
43 #include "AxisHelper.hxx"
44 #include "LegendHelper.hxx"
45 #include "DiagramHelper.hxx"
46 #include "ChartDebugTrace.hxx"
47 #include "AxisIndexDefines.hxx"
48 #include <cppuhelper/component_context.hxx>
49 #include <com/sun/star/chart/ChartSolidType.hpp>
50 #include <com/sun/star/chart2/AxisType.hpp>
51 #include <com/sun/star/chart2/XDataSeriesContainer.hpp>
52 #include <com/sun/star/chart2/XChartTypeContainer.hpp>
53 #include <com/sun/star/chart2/AxisType.hpp>
58 using namespace ::com::sun::star
;
59 using namespace ::com::sun::star::chart2
;
61 using ::rtl::OUString
;
62 using ::com::sun::star::uno::Sequence
;
63 using ::com::sun::star::uno::Reference
;
64 using ::com::sun::star::uno::Any
;
65 using ::com::sun::star::uno::UNO_QUERY
;
67 // ======================================================================
72 void lcl_applyDefaultStyle(
73 const Reference
< XDataSeries
> & xSeries
,
75 const Reference
< XDiagram
> & xDiagram
)
77 // @deprecated: correct default color should be found by view without
78 // setting color as hard attribute
79 if( xSeries
.is() && xDiagram
.is())
81 Reference
< beans::XPropertySet
> xSeriesProp( xSeries
, uno::UNO_QUERY
);
82 Reference
< chart2::XColorScheme
> xColorScheme( xDiagram
->getDefaultColorScheme());
83 if( xSeriesProp
.is() && xColorScheme
.is() )
84 xSeriesProp
->setPropertyValue(
86 uno::makeAny( xColorScheme
->getColorByIndex( nIndex
)));
90 void lcl_ensureCorrectLabelPlacement( const Reference
< beans::XPropertySet
>& xProp
, const uno::Sequence
< sal_Int32
>& rAvailablePlacements
)
92 sal_Int32 nLabelPlacement
=0;
93 if( xProp
->getPropertyValue( C2U( "LabelPlacement" ) ) >>= nLabelPlacement
)
96 for( sal_Int32 nN
= 0; nN
< rAvailablePlacements
.getLength(); nN
++ )
98 if( rAvailablePlacements
[nN
] == nLabelPlacement
)
107 //otherwise use the first supported one
108 if( rAvailablePlacements
.getLength() )
109 aNewValue
<<=rAvailablePlacements
[0];
110 xProp
->setPropertyValue( C2U("LabelPlacement"), aNewValue
);
115 void lcl_resetLabelPlacementIfDefault( const Reference
< beans::XPropertySet
>& xProp
, sal_Int32 nDefaultPlacement
)
118 sal_Int32 nLabelPlacement
=0;
119 if( xProp
->getPropertyValue( C2U( "LabelPlacement" ) ) >>= nLabelPlacement
)
121 if( nDefaultPlacement
== nLabelPlacement
)
122 xProp
->setPropertyValue( C2U("LabelPlacement"), uno::Any() );
126 void lcl_ensureCorrectMissingValueTreatment( const Reference
< chart2::XDiagram
>& xDiagram
, const Reference
< XChartType
>& xChartType
)
128 Reference
< beans::XPropertySet
> xDiaProp( xDiagram
, uno::UNO_QUERY
);
131 uno::Sequence
< sal_Int32
> aAvailableMissingValueTreatment(
132 ::chart::ChartTypeHelper::getSupportedMissingValueTreatments( xChartType
) );
134 if( aAvailableMissingValueTreatment
.getLength() )
135 xDiaProp
->setPropertyValue( C2U( "MissingValueTreatment" ), uno::makeAny( aAvailableMissingValueTreatment
[0] ) );
137 xDiaProp
->setPropertyValue( C2U( "MissingValueTreatment" ), uno::Any() );
141 } // anonymous namespace
146 ChartTypeTemplate::ChartTypeTemplate(
147 Reference
< uno::XComponentContext
> const & xContext
,
148 const ::rtl::OUString
& rServiceName
) :
149 m_xContext( xContext
),
150 m_aServiceName( rServiceName
)
154 ChartTypeTemplate::~ChartTypeTemplate()
157 // ____ XChartTypeTemplate ____
158 uno::Reference
< XDiagram
> SAL_CALL
ChartTypeTemplate::createDiagramByDataSource(
159 const uno::Reference
< data::XDataSource
>& xDataSource
,
160 const uno::Sequence
< beans::PropertyValue
>& aArguments
)
161 throw (uno::RuntimeException
)
163 Reference
< XDiagram
> xDia
;
169 GetComponentContext()->getServiceManager()->createInstanceWithContext(
170 C2U( "com.sun.star.chart2.Diagram" ),
171 GetComponentContext() ),
172 uno::UNO_QUERY_THROW
);
175 Reference
< chart2::XDataInterpreter
> xInterpreter( getDataInterpreter());
176 chart2::InterpretedData
aData(
177 xInterpreter
->interpretDataSource(
178 xDataSource
, aArguments
, Sequence
< Reference
< XDataSeries
> >() ));
180 Sequence
< Sequence
< Reference
< XDataSeries
> > > aSeries( aData
.Series
);
181 sal_Int32 i
, j
, nCount
= 0;
182 for( i
=0; i
<aSeries
.getLength(); ++i
)
184 for( j
=0; j
<aSeries
[i
].getLength(); ++j
, ++nCount
)
185 lcl_applyDefaultStyle( aSeries
[i
][j
], nCount
, xDia
);
188 Sequence
< Reference
< XChartType
> > aOldChartTypesSeq
;
189 FillDiagram( xDia
, aData
.Series
, aData
.Categories
, aOldChartTypesSeq
, true );
191 catch( uno::Exception
& ex
)
193 ASSERT_EXCEPTION( ex
);
199 Sequence
< OUString
> SAL_CALL
ChartTypeTemplate::getAvailableCreationParameterNames()
200 throw (uno::RuntimeException
)
202 OUString
aHasCat( C2U("HasCategories"));
203 return Sequence
< OUString
>( & aHasCat
, 1 );
206 void SAL_CALL
ChartTypeTemplate::changeDiagram( const uno::Reference
< XDiagram
>& xDiagram
)
207 throw (uno::RuntimeException
)
214 Sequence
< Sequence
< Reference
< XDataSeries
> > > aSeriesSeq(
215 DiagramHelper::getDataSeriesGroups( xDiagram
));
216 Sequence
< Reference
< XDataSeries
> > aFlatSeriesSeq( FlattenSequence( aSeriesSeq
));
217 const sal_Int32 nFormerSeriesCount
= aFlatSeriesSeq
.getLength();
219 // chart-type specific interpretation of existing data series
220 Reference
< chart2::XDataInterpreter
> xInterpreter( getDataInterpreter());
221 chart2::InterpretedData aData
;
222 aData
.Series
= aSeriesSeq
;
223 aData
.Categories
= DiagramHelper::getCategoriesFromDiagram( xDiagram
);
224 aData
.UnusedData
= xDiagram
->getUnusedData();
226 if( (aData
.UnusedData
.getLength() == 0) &&
227 xInterpreter
->isDataCompatible( aData
))
229 aData
= xInterpreter
->reinterpretDataSeries( aData
);
233 Reference
< data::XDataSource
> xSource( xInterpreter
->mergeInterpretedData( aData
));
234 // todo: get a "range-union" from the data provider by calling
235 // OUString aRange = getRangeRepresentationByData( xSource );
236 // xSource.set( getDataByRangeRepresentation( aRange, aParam ));
237 // where aParam == ??
238 Sequence
< beans::PropertyValue
> aParam
;
239 if( aData
.Categories
.is())
242 aParam
[0] = beans::PropertyValue( C2U("HasCategories"), -1, uno::makeAny( true ),
243 beans::PropertyState_DIRECT_VALUE
);
245 else if( aData
.UnusedData
.getLength())
247 for( sal_Int32 i
=0; i
<aData
.UnusedData
.getLength(); ++i
)
250 Reference
< beans::XPropertySet
> xProp( aData
.UnusedData
[i
]->getValues(), uno::UNO_QUERY_THROW
);
252 if( (xProp
->getPropertyValue(C2U("Role")) >>= aRole
) &
253 aRole
.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("categories")) )
255 aData
.Categories
= aData
.UnusedData
[i
];
256 for( ++i
; i
<aData
.UnusedData
.getLength(); ++i
)
257 aData
.UnusedData
[i
-1] = aData
.UnusedData
[i
];
258 aData
.UnusedData
.realloc( aData
.UnusedData
.getLength() - 1 );
262 catch( const uno::Exception
& ex
)
264 ASSERT_EXCEPTION( ex
);
267 aData
= xInterpreter
->interpretDataSource( xSource
, aParam
, aFlatSeriesSeq
);
269 aSeriesSeq
= aData
.Series
;
270 xDiagram
->setUnusedData( aData
.UnusedData
);
272 sal_Int32 i
, j
, nIndex
= 0;
273 for( i
=0; i
<aSeriesSeq
.getLength(); ++i
)
274 for( j
=0; j
<aSeriesSeq
[i
].getLength(); ++j
, ++nIndex
)
276 if( nIndex
>= nFormerSeriesCount
)
277 lcl_applyDefaultStyle( aSeriesSeq
[i
][j
], nIndex
, xDiagram
);
280 // remove charttype groups from all coordinate systems
281 Sequence
< Reference
< XChartType
> > aOldChartTypesSeq(
282 DiagramHelper::getChartTypesFromDiagram(xDiagram
) );
284 Reference
< XCoordinateSystemContainer
> xCoordSysCnt( xDiagram
, uno::UNO_QUERY
);
285 OSL_ASSERT( xCoordSysCnt
.is());
286 if( xCoordSysCnt
.is())
288 Sequence
< Reference
< XCoordinateSystem
> > aCooSysSeq(
289 xCoordSysCnt
->getCoordinateSystems());
290 for( sal_Int32 nCooSysIdx
= 0; nCooSysIdx
< aCooSysSeq
.getLength(); ++nCooSysIdx
)
292 Reference
< XChartTypeContainer
> xContainer( aCooSysSeq
[nCooSysIdx
], uno::UNO_QUERY
);
293 if( xContainer
.is() )
294 xContainer
->setChartTypes( Sequence
< Reference
< XChartType
> >() );
298 FillDiagram( xDiagram
, aSeriesSeq
, aData
.Categories
, aOldChartTypesSeq
, false );
300 catch( uno::Exception
& ex
)
302 ASSERT_EXCEPTION( ex
);
306 void SAL_CALL
ChartTypeTemplate::changeDiagramData(
307 const Reference
< chart2::XDiagram
>& xDiagram
,
308 const Reference
< chart2::data::XDataSource
>& xDataSource
,
309 const Sequence
< beans::PropertyValue
>& aArguments
)
310 throw (uno::RuntimeException
)
312 if( ! (xDiagram
.is() &&
318 // interpret new data and re-use existing series
319 Sequence
< Reference
< XDataSeries
> > aFlatSeriesSeq(
320 ::chart::ContainerHelper::ContainerToSequence( DiagramHelper::getDataSeriesFromDiagram( xDiagram
)));
321 const sal_Int32 nFormerSeriesCount
= aFlatSeriesSeq
.getLength();
322 Reference
< chart2::XDataInterpreter
> xInterpreter( getDataInterpreter());
323 chart2::InterpretedData aData
=
324 xInterpreter
->interpretDataSource( xDataSource
, aArguments
, aFlatSeriesSeq
);
327 Sequence
< Sequence
< Reference
< XDataSeries
> > > aSeriesSeq( aData
.Series
);
329 sal_Int32 i
, j
, nIndex
= 0;
330 for( i
=0; i
<aSeriesSeq
.getLength(); ++i
)
331 for( j
=0; j
<aSeriesSeq
[i
].getLength(); ++j
, ++nIndex
)
333 if( nIndex
>= nFormerSeriesCount
)
335 lcl_applyDefaultStyle( aSeriesSeq
[i
][j
], nIndex
, xDiagram
);
336 applyStyle( aSeriesSeq
[i
][j
], i
, j
, aSeriesSeq
[i
].getLength() );
341 DiagramHelper::setCategoriesToDiagram( aData
.Categories
, xDiagram
, true, supportsCategories() );
343 Sequence
< Reference
< XChartType
> > aChartTypes(
344 DiagramHelper::getChartTypesFromDiagram( xDiagram
));
345 sal_Int32 nMax
= ::std::min( aChartTypes
.getLength(), aSeriesSeq
.getLength());
346 for( i
=0; i
<nMax
; ++i
)
348 Reference
< XDataSeriesContainer
> xDSCnt( aChartTypes
[i
], uno::UNO_QUERY_THROW
);
349 xDSCnt
->setDataSeries( aSeriesSeq
[i
] );
351 #if OSL_DEBUG_LEVEL >= CHART_TRACE_OSL_DEBUG_LEVEL
352 OSL_TRACE( "ChartTypeTemplate::changeDiagramData: Showing Diagram structure" );
353 OSL_TRACE( "---------------------------------------------------------------" );
354 debug::ChartDebugTraceDiagram( xDiagram
);
357 catch( uno::Exception
& ex
)
359 ASSERT_EXCEPTION( ex
);
363 sal_Bool SAL_CALL
ChartTypeTemplate::matchesTemplate(
364 const Reference
< chart2::XDiagram
>& xDiagram
,
365 sal_Bool
/* bAdaptProperties */ )
366 throw (uno::RuntimeException
)
368 sal_Bool bResult
= sal_False
;
375 Reference
< XCoordinateSystemContainer
> xCooSysCnt(
376 xDiagram
, uno::UNO_QUERY_THROW
);
377 Sequence
< Reference
< XCoordinateSystem
> > aCooSysSeq(
378 xCooSysCnt
->getCoordinateSystems());
380 // need to have at least one coordinate system
381 bResult
= (aCooSysSeq
.getLength() > 0);
384 Sequence
< Reference
< XChartType
> > aFormerlyUsedChartTypes
;
385 const OUString
aChartTypeToMatch( getChartTypeForNewSeries(aFormerlyUsedChartTypes
)->getChartType());
386 const sal_Int32 nDimensionToMatch
= getDimension();
387 for( sal_Int32 nCooSysIdx
=0; bResult
&& (nCooSysIdx
< aCooSysSeq
.getLength()); ++nCooSysIdx
)
390 bResult
= bResult
&& (aCooSysSeq
[nCooSysIdx
]->getDimension() == nDimensionToMatch
);
392 Reference
< XChartTypeContainer
> xCTCnt( aCooSysSeq
[nCooSysIdx
], uno::UNO_QUERY_THROW
);
393 Sequence
< Reference
< XChartType
> > aChartTypeSeq( xCTCnt
->getChartTypes());
394 for( sal_Int32 nCTIdx
=0; bResult
&& (nCTIdx
< aChartTypeSeq
.getLength()); ++nCTIdx
)
397 bResult
= bResult
&& aChartTypeSeq
[nCTIdx
]->getChartType().equals( aChartTypeToMatch
);
399 bool bAmbiguous
=false;
400 // match stacking mode
402 ( DiagramHelper::getStackModeFromChartType(
403 aChartTypeSeq
[nCTIdx
], bFound
, bAmbiguous
,
404 aCooSysSeq
[nCooSysIdx
] )
405 == getStackMode( nCTIdx
) );
410 catch( uno::Exception
& ex
)
412 ASSERT_EXCEPTION( ex
);
418 Reference
< chart2::XDataInterpreter
> SAL_CALL
ChartTypeTemplate::getDataInterpreter()
419 throw (uno::RuntimeException
)
421 if( ! m_xDataInterpreter
.is())
422 m_xDataInterpreter
.set( new DataInterpreter( GetComponentContext() ) );
424 return m_xDataInterpreter
;
427 void SAL_CALL
ChartTypeTemplate::applyStyle(
428 const Reference
< chart2::XDataSeries
>& xSeries
,
429 ::sal_Int32 nChartTypeIndex
,
430 ::sal_Int32
/* nSeriesIndex */,
431 ::sal_Int32
/* nSeriesCount */ )
432 throw (uno::RuntimeException
)
434 // sset stacking mode
435 Reference
< beans::XPropertySet
> xSeriesProp( xSeries
, uno::UNO_QUERY
);
436 if( xSeriesProp
.is())
440 StackMode eStackMode
= getStackMode( nChartTypeIndex
);
441 const uno::Any aPropValue
= uno::makeAny(
442 ( (eStackMode
== StackMode_Y_STACKED
) ||
443 (eStackMode
== StackMode_Y_STACKED_PERCENT
) )
444 ? chart2::StackingDirection_Y_STACKING
445 : (eStackMode
== StackMode_Z_STACKED
)
446 ? chart2::StackingDirection_Z_STACKING
447 : chart2::StackingDirection_NO_STACKING
);
448 xSeriesProp
->setPropertyValue( C2U("StackingDirection"), aPropValue
);
450 //ensure valid label placement
452 uno::Sequence
< sal_Int32
> aAvailablePlacements( ChartTypeHelper::getSupportedLabelPlacements(
453 getChartTypeForIndex( nChartTypeIndex
), getDimension(), isSwapXAndY(), xSeries
) );
454 lcl_ensureCorrectLabelPlacement( xSeriesProp
, aAvailablePlacements
);
456 uno::Sequence
< sal_Int32
> aAttributedDataPointIndexList
;
457 if( xSeriesProp
->getPropertyValue( C2U( "AttributedDataPoints" ) ) >>= aAttributedDataPointIndexList
)
458 for(sal_Int32 nN
=aAttributedDataPointIndexList
.getLength();nN
--;)
459 lcl_ensureCorrectLabelPlacement( xSeries
->getDataPointByIndex(aAttributedDataPointIndexList
[nN
]), aAvailablePlacements
);
462 catch( const uno::Exception
& ex
)
464 ASSERT_EXCEPTION( ex
);
469 void SAL_CALL
ChartTypeTemplate::applyStyles( const Reference
< chart2::XDiagram
>& xDiagram
)
470 throw (uno::RuntimeException
)
472 // apply chart-type specific styles, like "symbols on" for example
473 Sequence
< Sequence
< Reference
< XDataSeries
> > > aNewSeriesSeq(
474 DiagramHelper::getDataSeriesGroups( xDiagram
));
475 for( sal_Int32 i
=0; i
<aNewSeriesSeq
.getLength(); ++i
)
477 const sal_Int32 nNumSeries
= aNewSeriesSeq
[i
].getLength();
478 for( sal_Int32 j
=0; j
<nNumSeries
; ++j
)
479 applyStyle( aNewSeriesSeq
[i
][j
], i
, j
, nNumSeries
);
482 //ensure valid empty cell handling (for first chart type...)
483 lcl_ensureCorrectMissingValueTreatment( xDiagram
, getChartTypeForIndex( 0 ) );
486 void SAL_CALL
ChartTypeTemplate::resetStyles( const Reference
< chart2::XDiagram
>& xDiagram
)
487 throw (uno::RuntimeException
)
489 // reset number format if we had percent stacking on
490 sal_Bool bPercent
= (getStackMode(0) == StackMode_Y_STACKED_PERCENT
);
493 Sequence
< Reference
< chart2::XAxis
> > aAxisSeq( AxisHelper::getAllAxesOfDiagram( xDiagram
) );
494 for( sal_Int32 i
=0; i
<aAxisSeq
.getLength(); ++i
)
496 if( 1== AxisHelper::getDimensionIndexOfAxis( aAxisSeq
[i
], xDiagram
) )
498 Reference
< beans::XPropertySet
> xAxisProp( aAxisSeq
[i
], uno::UNO_QUERY
);
501 // set number format to source format
502 uno::Any
aValue( xAxisProp
->getPropertyValue(C2U("NumberFormat")));
503 if( aValue
.hasValue())
504 xAxisProp
->setPropertyValue(C2U("NumberFormat"), uno::Any());
510 //reset label placement if default
512 uno::Reference
< XCoordinateSystemContainer
> xCooSysContainer( xDiagram
, uno::UNO_QUERY
);
513 if( xCooSysContainer
.is() )
515 uno::Sequence
< uno::Reference
< XCoordinateSystem
> > aCooSysList( xCooSysContainer
->getCoordinateSystems() );
516 for( sal_Int32 nCS
= 0; nCS
< aCooSysList
.getLength(); ++nCS
)
518 uno::Reference
< XCoordinateSystem
> xCooSys( aCooSysList
[nCS
] );
520 //iterate through all chart types in the current coordinate system
521 uno::Reference
< XChartTypeContainer
> xChartTypeContainer( xCooSys
, uno::UNO_QUERY
);
522 OSL_ASSERT( xChartTypeContainer
.is());
523 if( !xChartTypeContainer
.is() )
525 uno::Sequence
< uno::Reference
< XChartType
> > aChartTypeList( xChartTypeContainer
->getChartTypes() );
526 for( sal_Int32 nT
= 0; nT
< aChartTypeList
.getLength(); ++nT
)
528 uno::Reference
< XChartType
> xChartType( aChartTypeList
[nT
] );
530 //iterate through all series in this chart type
531 uno::Reference
< XDataSeriesContainer
> xDataSeriesContainer( xChartType
, uno::UNO_QUERY
);
532 OSL_ASSERT( xDataSeriesContainer
.is());
533 if( !xDataSeriesContainer
.is() )
536 uno::Sequence
< uno::Reference
< XDataSeries
> > aSeriesList( xDataSeriesContainer
->getDataSeries() );
537 for( sal_Int32 nS
= 0; nS
< aSeriesList
.getLength(); ++nS
)
539 Reference
< XDataSeries
> xSeries(aSeriesList
[nS
]);
540 Reference
< beans::XPropertySet
> xSeriesProp( xSeries
, uno::UNO_QUERY
);
541 if(!xSeries
.is() || !xSeriesProp
.is() )
544 uno::Sequence
< sal_Int32
> aAvailablePlacements( ChartTypeHelper::getSupportedLabelPlacements(
545 xChartType
, getDimension(), isSwapXAndY(), xSeries
) );
546 if(!aAvailablePlacements
.getLength())
549 sal_Int32 nDefaultPlacement
= aAvailablePlacements
[0];
551 lcl_resetLabelPlacementIfDefault( xSeriesProp
, nDefaultPlacement
);
553 uno::Sequence
< sal_Int32
> aAttributedDataPointIndexList
;
554 if( xSeriesProp
->getPropertyValue( C2U( "AttributedDataPoints" ) ) >>= aAttributedDataPointIndexList
)
555 for(sal_Int32 nN
=aAttributedDataPointIndexList
.getLength();nN
--;)
556 lcl_resetLabelPlacementIfDefault( xSeries
->getDataPointByIndex(aAttributedDataPointIndexList
[nN
]), nDefaultPlacement
);
566 // ____ XServiceName ____
567 ::rtl::OUString SAL_CALL
ChartTypeTemplate::getServiceName()
568 throw (uno::RuntimeException
)
570 return m_aServiceName
;
573 // ________________________________________
575 sal_Int32
ChartTypeTemplate::getDimension() const
580 StackMode
ChartTypeTemplate::getStackMode( sal_Int32
/* nChartTypeIndex */ ) const
582 return StackMode_NONE
;
585 bool ChartTypeTemplate::isSwapXAndY() const
590 bool ChartTypeTemplate::supportsCategories() const
595 // ________________________________________
597 void ChartTypeTemplate::createCoordinateSystems(
598 const Reference
< chart2::XCoordinateSystemContainer
> & xOutCooSysCnt
)
600 if( ! xOutCooSysCnt
.is())
602 Sequence
< Reference
< XChartType
> > aFormerlyUsedChartTypes
;
603 Reference
< XChartType
> xChartType( getChartTypeForNewSeries(aFormerlyUsedChartTypes
));
604 if( ! xChartType
.is())
606 Reference
< XCoordinateSystem
> xCooSys( xChartType
->createCoordinateSystem( getDimension()));
609 // chart type wants no coordinate systems
610 xOutCooSysCnt
->setCoordinateSystems( Sequence
< Reference
< XCoordinateSystem
> >());
613 // #i69680# make grid of first y-axis visible (was in the CooSys CTOR before)
614 if( xCooSys
->getDimension() >= 2 )
616 Reference
< chart2::XAxis
> xAxis( xCooSys
->getAxisByDimension( 1, 0 ));
618 AxisHelper::makeGridVisible( xAxis
->getGridProperties() );
621 Sequence
< Reference
< XCoordinateSystem
> > aCoordinateSystems(
622 xOutCooSysCnt
->getCoordinateSystems());
624 if( aCoordinateSystems
.getLength())
627 for( sal_Int32 i
=0; bOk
&& i
<aCoordinateSystems
.getLength(); ++i
)
628 bOk
= bOk
&& ( xCooSys
->getCoordinateSystemType().equals( aCoordinateSystems
[i
]->getCoordinateSystemType()) &&
629 (xCooSys
->getDimension() == aCoordinateSystems
[i
]->getDimension()) );
630 // coordinate systems are ok
633 // there are coordinate systems but they do not fit. So overwrite them.
636 //copy as much info from former coordinate system as possible:
637 if( aCoordinateSystems
.getLength() )
639 Reference
< XCoordinateSystem
> xOldCooSys( aCoordinateSystems
[0] );
640 sal_Int32 nMaxDimensionCount
= std::min( xCooSys
->getDimension(), xOldCooSys
->getDimension() );
642 for(sal_Int32 nDimensionIndex
=0; nDimensionIndex
<nMaxDimensionCount
; nDimensionIndex
++)
644 const sal_Int32 nMaximumAxisIndex
= xOldCooSys
->getMaximumAxisIndexByDimension(nDimensionIndex
);
645 for(sal_Int32 nAxisIndex
=0; nAxisIndex
<=nMaximumAxisIndex
; ++nAxisIndex
)
647 uno::Reference
< XAxis
> xAxis( xOldCooSys
->getAxisByDimension( nDimensionIndex
, nAxisIndex
) );
650 xCooSys
->setAxisByDimension( nDimensionIndex
, xAxis
, nAxisIndex
);
656 // set new coordinate systems
657 aCoordinateSystems
.realloc( 1 );
658 aCoordinateSystems
[0] = xCooSys
;
660 xOutCooSysCnt
->setCoordinateSystems( aCoordinateSystems
);
663 void ChartTypeTemplate::adaptScales(
664 const Sequence
< Reference
< chart2::XCoordinateSystem
> > & aCooSysSeq
,
665 const Reference
< data::XLabeledDataSequence
> & xCategories
//@todo: in future there may be more than one sequence of categories (e.g. charttype with categories at x and y axis )
668 bool bSupportsCategories( supportsCategories());
669 for( sal_Int32 nCooSysIdx
=0; nCooSysIdx
<aCooSysSeq
.getLength(); ++nCooSysIdx
)
673 Reference
< XCoordinateSystem
> xCooSys( aCooSysSeq
[nCooSysIdx
] );
677 // attach categories to first axis
678 sal_Int32
nDim( xCooSys
->getDimension());
681 const sal_Int32 nMaxIndex
= xCooSys
->getMaximumAxisIndexByDimension(0);
682 for(sal_Int32 nI
=0; nI
<=nMaxIndex
; ++nI
)
684 Reference
< XAxis
> xAxis( xCooSys
->getAxisByDimension(0,nI
) );
687 ScaleData
aData( xAxis
->getScaleData() );
688 aData
.Categories
= xCategories
;
689 aData
.AxisType
= bSupportsCategories
? AxisType::CATEGORY
: AxisType::REALNUMBER
;
690 if( bSupportsCategories
)
691 AxisHelper::removeExplicitScaling( aData
);
692 xAxis
->setScaleData( aData
);
696 // set percent stacking mode at second axis
699 const sal_Int32 nMaxIndex
= xCooSys
->getMaximumAxisIndexByDimension(1);
700 for(sal_Int32 nI
=0; nI
<=nMaxIndex
; ++nI
)
702 Reference
< chart2::XAxis
> xAxis( xCooSys
->getAxisByDimension( 1,nI
));
705 sal_Bool bPercent
= (getStackMode(0) == StackMode_Y_STACKED_PERCENT
);
706 chart2::ScaleData aScaleData
= xAxis
->getScaleData();
708 if( bPercent
!= (aScaleData
.AxisType
==AxisType::PERCENT
) )
711 aScaleData
.AxisType
= AxisType::PERCENT
;
713 aScaleData
.AxisType
= AxisType::REALNUMBER
;
714 xAxis
->setScaleData( aScaleData
);
720 catch( const uno::Exception
& ex
)
722 ASSERT_EXCEPTION( ex
);
727 void ChartTypeTemplate::adaptDiagram( const Reference
< XDiagram
> & /* xDiagram */ )
732 void ChartTypeTemplate::createAxes(
733 const Sequence
< Reference
< XCoordinateSystem
> > & rCoordSys
)
735 //create missing axes
736 if( rCoordSys
.getLength() > 0 )
738 sal_Int32 nCooSysIdx
= 0;
739 Reference
< XCoordinateSystem
> xCooSys( rCoordSys
[nCooSysIdx
] );
743 //create main axis in first coordinate system
744 sal_Int32 nDimCount
= xCooSys
->getDimension();
746 for( nDim
=0; nDim
<nDimCount
; ++nDim
)
748 sal_Int32 nAxisCount
= getAxisCountByDimension( nDim
);
750 nAxisCount
< 2 && AxisHelper::isSecondaryYAxisNeeded( xCooSys
))
752 for( sal_Int32 nAxisIndex
= 0; nAxisIndex
< nAxisCount
; ++nAxisIndex
)
754 Reference
< XAxis
> xAxis
= AxisHelper::getAxis( nDim
, nAxisIndex
, xCooSys
);
757 // create and add axis
758 xAxis
.set( AxisHelper::createAxis(
759 nDim
, nAxisIndex
, xCooSys
, GetComponentContext() ));
766 void ChartTypeTemplate::adaptAxes(
767 const Sequence
< Reference
< XCoordinateSystem
> > & rCoordSys
)
769 //adapt properties of exsisting axes and remove superfluous axes
771 if( rCoordSys
.getLength() > 0 )
773 for( sal_Int32 nCooSysIdx
=0; nCooSysIdx
< rCoordSys
.getLength(); ++nCooSysIdx
)
775 Reference
< XCoordinateSystem
> xCooSys( rCoordSys
[nCooSysIdx
] );
778 sal_Int32 nDimCount
= xCooSys
->getDimension();
779 for( sal_Int32 nDim
=0; nDim
<nDimCount
; ++nDim
)
781 sal_Int32 nMaxAxisIndex
= xCooSys
->getMaximumAxisIndexByDimension( nDim
);
782 for( sal_Int32 nAxisIndex
=0; nAxisIndex
<=nMaxAxisIndex
; nAxisIndex
++ )
784 Reference
< XAxis
> xAxis( AxisHelper::getAxis( nDim
, nAxisIndex
, xCooSys
) );
788 if( nAxisIndex
== MAIN_AXIS_INDEX
|| nAxisIndex
== SECONDARY_AXIS_INDEX
)
791 sal_Bool bPercent
= (getStackMode(0) == StackMode_Y_STACKED_PERCENT
);
792 if( bPercent
&& nDim
== 1 )
794 Reference
< beans::XPropertySet
> xAxisProp( xAxis
, uno::UNO_QUERY
);
797 // set number format to source format
798 uno::Any
aValue( xAxisProp
->getPropertyValue(C2U("NumberFormat")));
799 if( aValue
.hasValue())
800 xAxisProp
->setPropertyValue(C2U("NumberFormat"), uno::Any());
810 sal_Int32
ChartTypeTemplate::getAxisCountByDimension( sal_Int32 nDimension
)
812 return (nDimension
< getDimension()) ? 1 : 0;
815 void ChartTypeTemplate::FillDiagram(
816 const Reference
< XDiagram
>& xDiagram
,
817 const Sequence
< Sequence
< Reference
< XDataSeries
> > >& aSeriesSeq
,
818 Reference
< data::XLabeledDataSequence
> xCategories
,
819 const Sequence
< Reference
< XChartType
> >& aOldChartTypesSeq
,
822 adaptDiagram( xDiagram
);
826 // create coordinate systems and scales
827 Reference
< XCoordinateSystemContainer
> xCoordSysCnt( xDiagram
, uno::UNO_QUERY_THROW
);
828 createCoordinateSystems( xCoordSysCnt
);
829 Sequence
< Reference
< XCoordinateSystem
> > aCoordinateSystems( xCoordSysCnt
->getCoordinateSystems());
830 createAxes( aCoordinateSystems
);
831 adaptAxes( aCoordinateSystems
);
832 adaptScales( aCoordinateSystems
, xCategories
);
835 createChartTypes( aSeriesSeq
, aCoordinateSystems
, aOldChartTypesSeq
);
836 applyStyles( xDiagram
);
838 catch( const uno::Exception
& ex
)
840 ASSERT_EXCEPTION( ex
);
843 #if OSL_DEBUG_LEVEL >= CHART_TRACE_OSL_DEBUG_LEVEL
844 OSL_TRACE( "ChartTypeTemplate::FillDiagram: Showing Diagram structure" );
845 OSL_TRACE( "---------------------------------------------------------" );
846 debug::ChartDebugTraceDiagram( xDiagram
);
850 void ChartTypeTemplate::createChartTypes(
851 const Sequence
< Sequence
< Reference
< XDataSeries
> > > & aSeriesSeq
,
852 const Sequence
< Reference
< XCoordinateSystem
> > & rCoordSys
,
853 const Sequence
< Reference
< XChartType
> >& aOldChartTypesSeq
)
855 if( rCoordSys
.getLength() == 0 ||
856 ! rCoordSys
[0].is() )
861 sal_Int32 nCooSysIdx
=0;
862 Reference
< XChartType
> xCT
;
863 if( aSeriesSeq
.getLength() == 0 )
865 // we need a new chart type
866 xCT
.set( getChartTypeForNewSeries( aOldChartTypesSeq
));
867 Reference
< XChartTypeContainer
> xCTCnt( rCoordSys
[nCooSysIdx
], uno::UNO_QUERY_THROW
);
868 Sequence
< Reference
< XChartType
> > aCTSeq( xCTCnt
->getChartTypes());
871 xCTCnt
->setChartTypes( aCTSeq
);
875 for( sal_Int32 nSeriesIdx
=0; nSeriesIdx
<aSeriesSeq
.getLength(); ++nSeriesIdx
)
877 if( nSeriesIdx
== nCooSysIdx
)
879 // we need a new chart type
880 xCT
.set( getChartTypeForNewSeries( aOldChartTypesSeq
));
881 Reference
< XChartTypeContainer
> xCTCnt( rCoordSys
[nCooSysIdx
], uno::UNO_QUERY_THROW
);
882 Sequence
< Reference
< XChartType
> > aCTSeq( xCTCnt
->getChartTypes());
883 if( aCTSeq
.getLength())
886 xCTCnt
->setChartTypes( aCTSeq
);
889 xCTCnt
->addChartType( xCT
);
891 Reference
< chart2::XDataSeriesContainer
> xDSCnt( xCT
, uno::UNO_QUERY_THROW
);
892 xDSCnt
->setDataSeries( aSeriesSeq
[nSeriesIdx
] );
896 // reuse existing chart type
897 OSL_ASSERT( xCT
.is());
898 Reference
< chart2::XDataSeriesContainer
> xDSCnt( xCT
, uno::UNO_QUERY_THROW
);
899 Sequence
< Reference
< XDataSeries
> > aNewSeriesSeq( xDSCnt
->getDataSeries());
900 sal_Int32 nNewStartIndex
= aNewSeriesSeq
.getLength();
901 aNewSeriesSeq
.realloc( nNewStartIndex
+ aSeriesSeq
[nSeriesIdx
].getLength() );
902 ::std::copy( aSeriesSeq
[nSeriesIdx
].getConstArray(),
903 aSeriesSeq
[nSeriesIdx
].getConstArray() + aSeriesSeq
[nSeriesIdx
].getLength(),
904 aNewSeriesSeq
.getArray() + nNewStartIndex
);
905 xDSCnt
->setDataSeries( aNewSeriesSeq
);
908 // spread the series over the available coordinate systems
909 if( rCoordSys
.getLength() > (nCooSysIdx
+ 1) )
914 catch( uno::Exception
& ex
)
916 ASSERT_EXCEPTION( ex
);
921 void ChartTypeTemplate::copyPropertiesFromOldToNewCoordianteSystem(
922 const Sequence
< Reference
< XChartType
> > & rOldChartTypesSeq
,
923 const Reference
< XChartType
> & xNewChartType
)
925 Reference
< beans::XPropertySet
> xDestination( xNewChartType
, uno::UNO_QUERY
);
926 if( !xDestination
.is() )
929 OUString
aNewChartType( xNewChartType
->getChartType() );
931 Reference
< beans::XPropertySet
> xSource
;
933 for( nN
=0; nN
<rOldChartTypesSeq
.getLength();++nN
)
935 Reference
< XChartType
> xOldType( rOldChartTypesSeq
[nN
] );
936 if( xOldType
.is() && xOldType
->getChartType().equals( aNewChartType
) )
938 xSource
.set( Reference
< beans::XPropertySet
>(xOldType
, uno::UNO_QUERY
) );
944 comphelper::copyProperties( xSource
, xDestination
);
947 void ChartTypeTemplate::setStackModePropertiesToChartType(const Reference
<XChartType
>& xChartType
)
949 Reference
<beans::XPropertySet
> xPropSet(xChartType
, UNO_QUERY
);
953 bool bStacked
= false;
954 bool bPercent
= false;
955 switch (getStackMode(0))
957 case StackMode_Y_STACKED
:
960 case StackMode_Y_STACKED_PERCENT
:
964 case StackMode_Z_STACKED
:
972 xPropSet
->setPropertyValue(
973 C2U("Stacked"), uno::makeAny(static_cast<sal_Bool
>(bStacked
)));
975 catch (const beans::UnknownPropertyException
&)
981 xPropSet
->setPropertyValue(
982 C2U("Percent"), uno::makeAny(static_cast<sal_Bool
>(bPercent
)));
984 catch (const beans::UnknownPropertyException
&)
991 Sequence
< OUString
> ChartTypeTemplate::getSupportedServiceNames_Static()
993 Sequence
< OUString
> aServices( 3 );
994 aServices
[ 0 ] = C2U( "com.sun.star.chart2.ChartTypeTemplate" );
995 aServices
[ 1 ] = C2U( "com.sun.star.layout.LayoutElement" );
996 aServices
[ 2 ] = C2U( "com.sun.star.beans.PropertySet" );
1000 Reference
< uno::XComponentContext
> ChartTypeTemplate::GetComponentContext() const
1005 // ================================================================================
1007 // implement XServiceInfo methods basing upon getSupportedServiceNames_Static
1008 APPHELPER_XSERVICEINFO_IMPL( ChartTypeTemplate
,
1009 C2U( "com.sun.star.comp.chart.ChartTypeTemplate" ));
1010 } // namespace chart