1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org. If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
26 ************************************************************************/
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_chart2.hxx"
30 #include "ChartTypeTemplate.hxx"
31 #include "PropertyHelper.hxx"
33 #include "DataSeriesHelper.hxx"
34 #include "DataInterpreter.hxx"
35 #include "CommonConverters.hxx"
36 #include "ContainerHelper.hxx"
37 #include "ChartTypeHelper.hxx"
39 #include "CartesianCoordinateSystem.hxx"
40 #include "AxisHelper.hxx"
41 #include "LegendHelper.hxx"
42 #include "DiagramHelper.hxx"
43 #include "ChartDebugTrace.hxx"
44 #include "AxisIndexDefines.hxx"
45 #include <cppuhelper/component_context.hxx>
46 #include <com/sun/star/chart/ChartSolidType.hpp>
47 #include <com/sun/star/chart2/AxisType.hpp>
48 #include <com/sun/star/chart2/XDataSeriesContainer.hpp>
49 #include <com/sun/star/chart2/XChartTypeContainer.hpp>
50 #include <com/sun/star/chart2/AxisType.hpp>
55 using namespace ::com::sun::star
;
56 using namespace ::com::sun::star::chart2
;
58 using ::rtl::OUString
;
59 using ::com::sun::star::uno::Sequence
;
60 using ::com::sun::star::uno::Reference
;
61 using ::com::sun::star::uno::Any
;
63 // ======================================================================
68 void lcl_applyDefaultStyle(
69 const Reference
< XDataSeries
> & xSeries
,
71 const Reference
< XDiagram
> & xDiagram
)
73 // @deprecated: correct default color should be found by view without
74 // setting color as hard attribute
75 if( xSeries
.is() && xDiagram
.is())
77 Reference
< beans::XPropertySet
> xSeriesProp( xSeries
, uno::UNO_QUERY
);
78 Reference
< chart2::XColorScheme
> xColorScheme( xDiagram
->getDefaultColorScheme());
79 if( xSeriesProp
.is() && xColorScheme
.is() )
80 xSeriesProp
->setPropertyValue(
82 uno::makeAny( xColorScheme
->getColorByIndex( nIndex
)));
86 void lcl_ensureCorrectLabelPlacement( const Reference
< beans::XPropertySet
>& xProp
, const uno::Sequence
< sal_Int32
>& rAvailablePlacements
)
88 sal_Int32 nLabelPlacement
=0;
89 if( xProp
.is() && (xProp
->getPropertyValue( C2U( "LabelPlacement" ) ) >>= nLabelPlacement
) )
92 for( sal_Int32 nN
= 0; nN
< rAvailablePlacements
.getLength(); nN
++ )
94 if( rAvailablePlacements
[nN
] == nLabelPlacement
)
103 //otherwise use the first supported one
104 if( rAvailablePlacements
.getLength() )
105 aNewValue
<<=rAvailablePlacements
[0];
106 xProp
->setPropertyValue( C2U("LabelPlacement"), aNewValue
);
111 void lcl_resetLabelPlacementIfDefault( const Reference
< beans::XPropertySet
>& xProp
, sal_Int32 nDefaultPlacement
)
114 sal_Int32 nLabelPlacement
=0;
115 if( xProp
.is() && (xProp
->getPropertyValue( C2U( "LabelPlacement" ) ) >>= nLabelPlacement
) )
117 if( nDefaultPlacement
== nLabelPlacement
)
118 xProp
->setPropertyValue( C2U("LabelPlacement"), uno::Any() );
122 void lcl_ensureCorrectMissingValueTreatment( const Reference
< chart2::XDiagram
>& xDiagram
, const Reference
< XChartType
>& xChartType
)
124 Reference
< beans::XPropertySet
> xDiaProp( xDiagram
, uno::UNO_QUERY
);
127 uno::Sequence
< sal_Int32
> aAvailableMissingValueTreatment(
128 ::chart::ChartTypeHelper::getSupportedMissingValueTreatments( xChartType
) );
130 if( aAvailableMissingValueTreatment
.getLength() )
131 xDiaProp
->setPropertyValue( C2U( "MissingValueTreatment" ), uno::makeAny( aAvailableMissingValueTreatment
[0] ) );
133 xDiaProp
->setPropertyValue( C2U( "MissingValueTreatment" ), uno::Any() );
137 } // anonymous namespace
142 ChartTypeTemplate::ChartTypeTemplate(
143 Reference
< uno::XComponentContext
> const & xContext
,
144 const ::rtl::OUString
& rServiceName
) :
145 m_xContext( xContext
),
146 m_aServiceName( rServiceName
)
150 ChartTypeTemplate::~ChartTypeTemplate()
153 // ____ XChartTypeTemplate ____
154 uno::Reference
< XDiagram
> SAL_CALL
ChartTypeTemplate::createDiagramByDataSource(
155 const uno::Reference
< data::XDataSource
>& xDataSource
,
156 const uno::Sequence
< beans::PropertyValue
>& aArguments
)
157 throw (uno::RuntimeException
)
159 Reference
< XDiagram
> xDia
;
165 GetComponentContext()->getServiceManager()->createInstanceWithContext(
166 C2U( "com.sun.star.chart2.Diagram" ),
167 GetComponentContext() ),
168 uno::UNO_QUERY_THROW
);
171 Reference
< chart2::XDataInterpreter
> xInterpreter( getDataInterpreter());
172 chart2::InterpretedData
aData(
173 xInterpreter
->interpretDataSource(
174 xDataSource
, aArguments
, Sequence
< Reference
< XDataSeries
> >() ));
176 Sequence
< Sequence
< Reference
< XDataSeries
> > > aSeries( aData
.Series
);
177 sal_Int32 i
, j
, nCount
= 0;
178 for( i
=0; i
<aSeries
.getLength(); ++i
)
180 for( j
=0; j
<aSeries
[i
].getLength(); ++j
, ++nCount
)
181 lcl_applyDefaultStyle( aSeries
[i
][j
], nCount
, xDia
);
184 Sequence
< Reference
< XChartType
> > aOldChartTypesSeq
;
185 FillDiagram( xDia
, aData
.Series
, aData
.Categories
, aOldChartTypesSeq
, true );
187 catch( uno::Exception
& ex
)
189 ASSERT_EXCEPTION( ex
);
195 sal_Bool SAL_CALL
ChartTypeTemplate::supportsCategories()
196 throw (uno::RuntimeException
)
201 void SAL_CALL
ChartTypeTemplate::changeDiagram( const uno::Reference
< XDiagram
>& xDiagram
)
202 throw (uno::RuntimeException
)
209 Sequence
< Sequence
< Reference
< XDataSeries
> > > aSeriesSeq(
210 DiagramHelper::getDataSeriesGroups( xDiagram
));
211 Sequence
< Reference
< XDataSeries
> > aFlatSeriesSeq( FlattenSequence( aSeriesSeq
));
212 const sal_Int32 nFormerSeriesCount
= aFlatSeriesSeq
.getLength();
214 // chart-type specific interpretation of existing data series
215 Reference
< chart2::XDataInterpreter
> xInterpreter( getDataInterpreter());
216 chart2::InterpretedData aData
;
217 aData
.Series
= aSeriesSeq
;
218 aData
.Categories
= DiagramHelper::getCategoriesFromDiagram( xDiagram
);
220 if( xInterpreter
->isDataCompatible( aData
) )
222 aData
= xInterpreter
->reinterpretDataSeries( aData
);
226 Reference
< data::XDataSource
> xSource( xInterpreter
->mergeInterpretedData( aData
));
227 // todo: get a "range-union" from the data provider by calling
228 // OUString aRange = getRangeRepresentationByData( xSource );
229 // xSource.set( getDataByRangeRepresentation( aRange, aParam ));
230 // where aParam == ??
231 Sequence
< beans::PropertyValue
> aParam
;
232 if( aData
.Categories
.is())
235 aParam
[0] = beans::PropertyValue( C2U("HasCategories"), -1, uno::makeAny( true ),
236 beans::PropertyState_DIRECT_VALUE
);
238 aData
= xInterpreter
->interpretDataSource( xSource
, aParam
, aFlatSeriesSeq
);
240 aSeriesSeq
= aData
.Series
;
242 sal_Int32 i
, j
, nIndex
= 0;
243 for( i
=0; i
<aSeriesSeq
.getLength(); ++i
)
244 for( j
=0; j
<aSeriesSeq
[i
].getLength(); ++j
, ++nIndex
)
246 if( nIndex
>= nFormerSeriesCount
)
247 lcl_applyDefaultStyle( aSeriesSeq
[i
][j
], nIndex
, xDiagram
);
250 // remove charttype groups from all coordinate systems
251 Sequence
< Reference
< XChartType
> > aOldChartTypesSeq(
252 DiagramHelper::getChartTypesFromDiagram(xDiagram
) );
254 Reference
< XCoordinateSystemContainer
> xCoordSysCnt( xDiagram
, uno::UNO_QUERY
);
255 OSL_ASSERT( xCoordSysCnt
.is());
256 if( xCoordSysCnt
.is())
258 Sequence
< Reference
< XCoordinateSystem
> > aCooSysSeq(
259 xCoordSysCnt
->getCoordinateSystems());
260 for( sal_Int32 nCooSysIdx
= 0; nCooSysIdx
< aCooSysSeq
.getLength(); ++nCooSysIdx
)
262 Reference
< XChartTypeContainer
> xContainer( aCooSysSeq
[nCooSysIdx
], uno::UNO_QUERY
);
263 if( xContainer
.is() )
264 xContainer
->setChartTypes( Sequence
< Reference
< XChartType
> >() );
268 FillDiagram( xDiagram
, aSeriesSeq
, aData
.Categories
, aOldChartTypesSeq
, false );
270 catch( uno::Exception
& ex
)
272 ASSERT_EXCEPTION( ex
);
276 void SAL_CALL
ChartTypeTemplate::changeDiagramData(
277 const Reference
< chart2::XDiagram
>& xDiagram
,
278 const Reference
< chart2::data::XDataSource
>& xDataSource
,
279 const Sequence
< beans::PropertyValue
>& aArguments
)
280 throw (uno::RuntimeException
)
282 if( ! (xDiagram
.is() &&
288 // interpret new data and re-use existing series
289 Sequence
< Reference
< XDataSeries
> > aFlatSeriesSeq(
290 ::chart::ContainerHelper::ContainerToSequence( DiagramHelper::getDataSeriesFromDiagram( xDiagram
)));
291 const sal_Int32 nFormerSeriesCount
= aFlatSeriesSeq
.getLength();
292 Reference
< chart2::XDataInterpreter
> xInterpreter( getDataInterpreter());
293 chart2::InterpretedData aData
=
294 xInterpreter
->interpretDataSource( xDataSource
, aArguments
, aFlatSeriesSeq
);
297 Sequence
< Sequence
< Reference
< XDataSeries
> > > aSeriesSeq( aData
.Series
);
299 sal_Int32 i
, j
, nIndex
= 0;
300 for( i
=0; i
<aSeriesSeq
.getLength(); ++i
)
301 for( j
=0; j
<aSeriesSeq
[i
].getLength(); ++j
, ++nIndex
)
303 if( nIndex
>= nFormerSeriesCount
)
305 lcl_applyDefaultStyle( aSeriesSeq
[i
][j
], nIndex
, xDiagram
);
306 applyStyle( aSeriesSeq
[i
][j
], i
, j
, aSeriesSeq
[i
].getLength() );
311 DiagramHelper::setCategoriesToDiagram( aData
.Categories
, xDiagram
, true, supportsCategories() );
313 Sequence
< Reference
< XChartType
> > aChartTypes(
314 DiagramHelper::getChartTypesFromDiagram( xDiagram
));
315 sal_Int32 nMax
= ::std::min( aChartTypes
.getLength(), aSeriesSeq
.getLength());
316 for( i
=0; i
<nMax
; ++i
)
318 Reference
< XDataSeriesContainer
> xDSCnt( aChartTypes
[i
], uno::UNO_QUERY_THROW
);
319 xDSCnt
->setDataSeries( aSeriesSeq
[i
] );
321 #if OSL_DEBUG_LEVEL >= CHART_TRACE_OSL_DEBUG_LEVEL
322 OSL_TRACE( "ChartTypeTemplate::changeDiagramData: Showing Diagram structure" );
323 OSL_TRACE( "---------------------------------------------------------------" );
324 debug::ChartDebugTraceDiagram( xDiagram
);
327 catch( uno::Exception
& ex
)
329 ASSERT_EXCEPTION( ex
);
333 sal_Bool SAL_CALL
ChartTypeTemplate::matchesTemplate(
334 const Reference
< chart2::XDiagram
>& xDiagram
,
335 sal_Bool
/* bAdaptProperties */ )
336 throw (uno::RuntimeException
)
338 sal_Bool bResult
= sal_False
;
345 Reference
< XCoordinateSystemContainer
> xCooSysCnt(
346 xDiagram
, uno::UNO_QUERY_THROW
);
347 Sequence
< Reference
< XCoordinateSystem
> > aCooSysSeq(
348 xCooSysCnt
->getCoordinateSystems());
350 // need to have at least one coordinate system
351 bResult
= (aCooSysSeq
.getLength() > 0);
354 Sequence
< Reference
< XChartType
> > aFormerlyUsedChartTypes
;
355 const OUString
aChartTypeToMatch( getChartTypeForNewSeries(aFormerlyUsedChartTypes
)->getChartType());
356 const sal_Int32 nDimensionToMatch
= getDimension();
357 for( sal_Int32 nCooSysIdx
=0; bResult
&& (nCooSysIdx
< aCooSysSeq
.getLength()); ++nCooSysIdx
)
360 bResult
= bResult
&& (aCooSysSeq
[nCooSysIdx
]->getDimension() == nDimensionToMatch
);
362 Reference
< XChartTypeContainer
> xCTCnt( aCooSysSeq
[nCooSysIdx
], uno::UNO_QUERY_THROW
);
363 Sequence
< Reference
< XChartType
> > aChartTypeSeq( xCTCnt
->getChartTypes());
364 for( sal_Int32 nCTIdx
=0; bResult
&& (nCTIdx
< aChartTypeSeq
.getLength()); ++nCTIdx
)
367 bResult
= bResult
&& aChartTypeSeq
[nCTIdx
]->getChartType().equals( aChartTypeToMatch
);
369 bool bAmbiguous
=false;
370 // match stacking mode
372 ( DiagramHelper::getStackModeFromChartType(
373 aChartTypeSeq
[nCTIdx
], bFound
, bAmbiguous
,
374 aCooSysSeq
[nCooSysIdx
] )
375 == getStackMode( nCTIdx
) );
380 catch( uno::Exception
& ex
)
382 ASSERT_EXCEPTION( ex
);
388 Reference
< chart2::XDataInterpreter
> SAL_CALL
ChartTypeTemplate::getDataInterpreter()
389 throw (uno::RuntimeException
)
391 if( ! m_xDataInterpreter
.is())
392 m_xDataInterpreter
.set( new DataInterpreter( GetComponentContext() ) );
394 return m_xDataInterpreter
;
397 void SAL_CALL
ChartTypeTemplate::applyStyle(
398 const Reference
< chart2::XDataSeries
>& xSeries
,
399 ::sal_Int32 nChartTypeIndex
,
400 ::sal_Int32
/* nSeriesIndex */,
401 ::sal_Int32
/* nSeriesCount */ )
402 throw (uno::RuntimeException
)
404 // sset stacking mode
405 Reference
< beans::XPropertySet
> xSeriesProp( xSeries
, uno::UNO_QUERY
);
406 if( xSeriesProp
.is())
410 StackMode eStackMode
= getStackMode( nChartTypeIndex
);
411 const uno::Any aPropValue
= uno::makeAny(
412 ( (eStackMode
== StackMode_Y_STACKED
) ||
413 (eStackMode
== StackMode_Y_STACKED_PERCENT
) )
414 ? chart2::StackingDirection_Y_STACKING
415 : (eStackMode
== StackMode_Z_STACKED
)
416 ? chart2::StackingDirection_Z_STACKING
417 : chart2::StackingDirection_NO_STACKING
);
418 xSeriesProp
->setPropertyValue( C2U("StackingDirection"), aPropValue
);
420 //ensure valid label placement
422 uno::Sequence
< sal_Int32
> aAvailablePlacements( ChartTypeHelper::getSupportedLabelPlacements(
423 getChartTypeForIndex( nChartTypeIndex
), getDimension(), isSwapXAndY(), xSeries
) );
424 lcl_ensureCorrectLabelPlacement( xSeriesProp
, aAvailablePlacements
);
426 uno::Sequence
< sal_Int32
> aAttributedDataPointIndexList
;
427 if( xSeriesProp
->getPropertyValue( C2U( "AttributedDataPoints" ) ) >>= aAttributedDataPointIndexList
)
428 for(sal_Int32 nN
=aAttributedDataPointIndexList
.getLength();nN
--;)
429 lcl_ensureCorrectLabelPlacement( xSeries
->getDataPointByIndex(aAttributedDataPointIndexList
[nN
]), aAvailablePlacements
);
432 catch( const uno::Exception
& ex
)
434 ASSERT_EXCEPTION( ex
);
439 void SAL_CALL
ChartTypeTemplate::applyStyles( const Reference
< chart2::XDiagram
>& xDiagram
)
440 throw (uno::RuntimeException
)
442 // apply chart-type specific styles, like "symbols on" for example
443 Sequence
< Sequence
< Reference
< XDataSeries
> > > aNewSeriesSeq(
444 DiagramHelper::getDataSeriesGroups( xDiagram
));
445 for( sal_Int32 i
=0; i
<aNewSeriesSeq
.getLength(); ++i
)
447 const sal_Int32 nNumSeries
= aNewSeriesSeq
[i
].getLength();
448 for( sal_Int32 j
=0; j
<nNumSeries
; ++j
)
449 applyStyle( aNewSeriesSeq
[i
][j
], i
, j
, nNumSeries
);
452 //ensure valid empty cell handling (for first chart type...)
453 lcl_ensureCorrectMissingValueTreatment( xDiagram
, getChartTypeForIndex( 0 ) );
456 void SAL_CALL
ChartTypeTemplate::resetStyles( const Reference
< chart2::XDiagram
>& xDiagram
)
457 throw (uno::RuntimeException
)
459 // reset number format if we had percent stacking on
460 sal_Bool bPercent
= (getStackMode(0) == StackMode_Y_STACKED_PERCENT
);
463 Sequence
< Reference
< chart2::XAxis
> > aAxisSeq( AxisHelper::getAllAxesOfDiagram( xDiagram
) );
464 for( sal_Int32 i
=0; i
<aAxisSeq
.getLength(); ++i
)
466 if( 1== AxisHelper::getDimensionIndexOfAxis( aAxisSeq
[i
], xDiagram
) )
468 Reference
< beans::XPropertySet
> xAxisProp( aAxisSeq
[i
], uno::UNO_QUERY
);
471 // set number format to source format
472 uno::Any
aValue( xAxisProp
->getPropertyValue(C2U("NumberFormat")));
473 if( aValue
.hasValue())
474 xAxisProp
->setPropertyValue(C2U("NumberFormat"), uno::Any());
480 //reset label placement if default
482 uno::Reference
< XCoordinateSystemContainer
> xCooSysContainer( xDiagram
, uno::UNO_QUERY
);
483 if( xCooSysContainer
.is() )
485 uno::Sequence
< uno::Reference
< XCoordinateSystem
> > aCooSysList( xCooSysContainer
->getCoordinateSystems() );
486 for( sal_Int32 nCS
= 0; nCS
< aCooSysList
.getLength(); ++nCS
)
488 uno::Reference
< XCoordinateSystem
> xCooSys( aCooSysList
[nCS
] );
490 //iterate through all chart types in the current coordinate system
491 uno::Reference
< XChartTypeContainer
> xChartTypeContainer( xCooSys
, uno::UNO_QUERY
);
492 OSL_ASSERT( xChartTypeContainer
.is());
493 if( !xChartTypeContainer
.is() )
495 uno::Sequence
< uno::Reference
< XChartType
> > aChartTypeList( xChartTypeContainer
->getChartTypes() );
496 for( sal_Int32 nT
= 0; nT
< aChartTypeList
.getLength(); ++nT
)
498 uno::Reference
< XChartType
> xChartType( aChartTypeList
[nT
] );
500 //iterate through all series in this chart type
501 uno::Reference
< XDataSeriesContainer
> xDataSeriesContainer( xChartType
, uno::UNO_QUERY
);
502 OSL_ASSERT( xDataSeriesContainer
.is());
503 if( !xDataSeriesContainer
.is() )
506 uno::Sequence
< uno::Reference
< XDataSeries
> > aSeriesList( xDataSeriesContainer
->getDataSeries() );
507 for( sal_Int32 nS
= 0; nS
< aSeriesList
.getLength(); ++nS
)
509 Reference
< XDataSeries
> xSeries(aSeriesList
[nS
]);
510 Reference
< beans::XPropertySet
> xSeriesProp( xSeries
, uno::UNO_QUERY
);
511 if(!xSeries
.is() || !xSeriesProp
.is() )
514 uno::Sequence
< sal_Int32
> aAvailablePlacements( ChartTypeHelper::getSupportedLabelPlacements(
515 xChartType
, getDimension(), isSwapXAndY(), xSeries
) );
516 if(!aAvailablePlacements
.getLength())
519 sal_Int32 nDefaultPlacement
= aAvailablePlacements
[0];
521 lcl_resetLabelPlacementIfDefault( xSeriesProp
, nDefaultPlacement
);
523 uno::Sequence
< sal_Int32
> aAttributedDataPointIndexList
;
524 if( xSeriesProp
->getPropertyValue( C2U( "AttributedDataPoints" ) ) >>= aAttributedDataPointIndexList
)
525 for(sal_Int32 nN
=aAttributedDataPointIndexList
.getLength();nN
--;)
526 lcl_resetLabelPlacementIfDefault( xSeries
->getDataPointByIndex(aAttributedDataPointIndexList
[nN
]), nDefaultPlacement
);
536 // ____ XServiceName ____
537 ::rtl::OUString SAL_CALL
ChartTypeTemplate::getServiceName()
538 throw (uno::RuntimeException
)
540 return m_aServiceName
;
543 // ________________________________________
545 sal_Int32
ChartTypeTemplate::getDimension() const
550 StackMode
ChartTypeTemplate::getStackMode( sal_Int32
/* nChartTypeIndex */ ) const
552 return StackMode_NONE
;
555 bool ChartTypeTemplate::isSwapXAndY() const
560 // ________________________________________
562 void ChartTypeTemplate::createCoordinateSystems(
563 const Reference
< chart2::XCoordinateSystemContainer
> & xOutCooSysCnt
)
565 if( ! xOutCooSysCnt
.is())
567 Sequence
< Reference
< XChartType
> > aFormerlyUsedChartTypes
;
568 Reference
< XChartType
> xChartType( getChartTypeForNewSeries(aFormerlyUsedChartTypes
));
569 if( ! xChartType
.is())
571 Reference
< XCoordinateSystem
> xCooSys( xChartType
->createCoordinateSystem( getDimension()));
574 // chart type wants no coordinate systems
575 xOutCooSysCnt
->setCoordinateSystems( Sequence
< Reference
< XCoordinateSystem
> >());
578 // #i69680# make grid of first y-axis visible (was in the CooSys CTOR before)
579 if( xCooSys
->getDimension() >= 2 )
581 Reference
< chart2::XAxis
> xAxis( xCooSys
->getAxisByDimension( 1, 0 ));
583 AxisHelper::makeGridVisible( xAxis
->getGridProperties() );
586 Sequence
< Reference
< XCoordinateSystem
> > aCoordinateSystems(
587 xOutCooSysCnt
->getCoordinateSystems());
589 if( aCoordinateSystems
.getLength())
592 for( sal_Int32 i
=0; bOk
&& i
<aCoordinateSystems
.getLength(); ++i
)
593 bOk
= bOk
&& ( xCooSys
->getCoordinateSystemType().equals( aCoordinateSystems
[i
]->getCoordinateSystemType()) &&
594 (xCooSys
->getDimension() == aCoordinateSystems
[i
]->getDimension()) );
595 // coordinate systems are ok
598 // there are coordinate systems but they do not fit. So overwrite them.
601 //copy as much info from former coordinate system as possible:
602 if( aCoordinateSystems
.getLength() )
604 Reference
< XCoordinateSystem
> xOldCooSys( aCoordinateSystems
[0] );
605 sal_Int32 nMaxDimensionCount
= std::min( xCooSys
->getDimension(), xOldCooSys
->getDimension() );
607 for(sal_Int32 nDimensionIndex
=0; nDimensionIndex
<nMaxDimensionCount
; nDimensionIndex
++)
609 const sal_Int32 nMaximumAxisIndex
= xOldCooSys
->getMaximumAxisIndexByDimension(nDimensionIndex
);
610 for(sal_Int32 nAxisIndex
=0; nAxisIndex
<=nMaximumAxisIndex
; ++nAxisIndex
)
612 uno::Reference
< XAxis
> xAxis( xOldCooSys
->getAxisByDimension( nDimensionIndex
, nAxisIndex
) );
615 xCooSys
->setAxisByDimension( nDimensionIndex
, xAxis
, nAxisIndex
);
621 // set new coordinate systems
622 aCoordinateSystems
.realloc( 1 );
623 aCoordinateSystems
[0] = xCooSys
;
625 xOutCooSysCnt
->setCoordinateSystems( aCoordinateSystems
);
628 void ChartTypeTemplate::adaptScales(
629 const Sequence
< Reference
< chart2::XCoordinateSystem
> > & aCooSysSeq
,
630 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 )
633 bool bSupportsCategories( supportsCategories() );
634 for( sal_Int32 nCooSysIdx
=0; nCooSysIdx
<aCooSysSeq
.getLength(); ++nCooSysIdx
)
638 Reference
< XCoordinateSystem
> xCooSys( aCooSysSeq
[nCooSysIdx
] );
642 // attach categories to first axis
643 sal_Int32
nDim( xCooSys
->getDimension());
646 const sal_Int32 nMaxIndex
= xCooSys
->getMaximumAxisIndexByDimension(0);
647 for(sal_Int32 nI
=0; nI
<=nMaxIndex
; ++nI
)
649 Reference
< XAxis
> xAxis( xCooSys
->getAxisByDimension(0,nI
) );
652 ScaleData
aData( xAxis
->getScaleData() );
653 aData
.Categories
= xCategories
;
654 aData
.AxisType
= bSupportsCategories
? AxisType::CATEGORY
: AxisType::REALNUMBER
;
655 if( bSupportsCategories
)
656 AxisHelper::removeExplicitScaling( aData
);
657 xAxis
->setScaleData( aData
);
661 // set percent stacking mode at second axis
664 const sal_Int32 nMaxIndex
= xCooSys
->getMaximumAxisIndexByDimension(1);
665 for(sal_Int32 nI
=0; nI
<=nMaxIndex
; ++nI
)
667 Reference
< chart2::XAxis
> xAxis( xCooSys
->getAxisByDimension( 1,nI
));
670 sal_Bool bPercent
= (getStackMode(0) == StackMode_Y_STACKED_PERCENT
);
671 chart2::ScaleData aScaleData
= xAxis
->getScaleData();
673 if( bPercent
!= (aScaleData
.AxisType
==AxisType::PERCENT
) )
676 aScaleData
.AxisType
= AxisType::PERCENT
;
678 aScaleData
.AxisType
= AxisType::REALNUMBER
;
679 xAxis
->setScaleData( aScaleData
);
685 catch( const uno::Exception
& ex
)
687 ASSERT_EXCEPTION( ex
);
692 void ChartTypeTemplate::adaptDiagram( const Reference
< XDiagram
> & /* xDiagram */ )
697 void ChartTypeTemplate::createAxes(
698 const Sequence
< Reference
< XCoordinateSystem
> > & rCoordSys
)
700 //create missing axes
701 if( rCoordSys
.getLength() > 0 )
703 sal_Int32 nCooSysIdx
= 0;
704 Reference
< XCoordinateSystem
> xCooSys( rCoordSys
[nCooSysIdx
] );
708 //create main axis in first coordinate system
709 sal_Int32 nDimCount
= xCooSys
->getDimension();
711 for( nDim
=0; nDim
<nDimCount
; ++nDim
)
713 sal_Int32 nAxisCount
= getAxisCountByDimension( nDim
);
715 nAxisCount
< 2 && AxisHelper::isSecondaryYAxisNeeded( xCooSys
))
717 for( sal_Int32 nAxisIndex
= 0; nAxisIndex
< nAxisCount
; ++nAxisIndex
)
719 Reference
< XAxis
> xAxis
= AxisHelper::getAxis( nDim
, nAxisIndex
, xCooSys
);
722 // create and add axis
723 xAxis
.set( AxisHelper::createAxis(
724 nDim
, nAxisIndex
, xCooSys
, GetComponentContext() ));
731 void ChartTypeTemplate::adaptAxes(
732 const Sequence
< Reference
< XCoordinateSystem
> > & rCoordSys
)
734 //adapt properties of exsisting axes and remove superfluous axes
736 if( rCoordSys
.getLength() > 0 )
738 for( sal_Int32 nCooSysIdx
=0; nCooSysIdx
< rCoordSys
.getLength(); ++nCooSysIdx
)
740 Reference
< XCoordinateSystem
> xCooSys( rCoordSys
[nCooSysIdx
] );
743 sal_Int32 nDimCount
= xCooSys
->getDimension();
744 for( sal_Int32 nDim
=0; nDim
<nDimCount
; ++nDim
)
746 sal_Int32 nMaxAxisIndex
= xCooSys
->getMaximumAxisIndexByDimension( nDim
);
747 for( sal_Int32 nAxisIndex
=0; nAxisIndex
<=nMaxAxisIndex
; nAxisIndex
++ )
749 Reference
< XAxis
> xAxis( AxisHelper::getAxis( nDim
, nAxisIndex
, xCooSys
) );
753 if( nAxisIndex
== MAIN_AXIS_INDEX
|| nAxisIndex
== SECONDARY_AXIS_INDEX
)
756 sal_Bool bPercent
= (getStackMode(0) == StackMode_Y_STACKED_PERCENT
);
757 if( bPercent
&& nDim
== 1 )
759 Reference
< beans::XPropertySet
> xAxisProp( xAxis
, uno::UNO_QUERY
);
762 // set number format to source format
763 uno::Any
aValue( xAxisProp
->getPropertyValue(C2U("NumberFormat")));
764 if( aValue
.hasValue())
765 xAxisProp
->setPropertyValue(C2U("NumberFormat"), uno::Any());
775 sal_Int32
ChartTypeTemplate::getAxisCountByDimension( sal_Int32 nDimension
)
777 return (nDimension
< getDimension()) ? 1 : 0;
780 void ChartTypeTemplate::FillDiagram(
781 const Reference
< XDiagram
>& xDiagram
,
782 const Sequence
< Sequence
< Reference
< XDataSeries
> > >& aSeriesSeq
,
783 Reference
< data::XLabeledDataSequence
> xCategories
,
784 const Sequence
< Reference
< XChartType
> >& aOldChartTypesSeq
,
787 adaptDiagram( xDiagram
);
791 // create coordinate systems and scales
792 Reference
< XCoordinateSystemContainer
> xCoordSysCnt( xDiagram
, uno::UNO_QUERY_THROW
);
793 createCoordinateSystems( xCoordSysCnt
);
794 Sequence
< Reference
< XCoordinateSystem
> > aCoordinateSystems( xCoordSysCnt
->getCoordinateSystems());
795 createAxes( aCoordinateSystems
);
796 adaptAxes( aCoordinateSystems
);
797 adaptScales( aCoordinateSystems
, xCategories
);
800 createChartTypes( aSeriesSeq
, aCoordinateSystems
, aOldChartTypesSeq
);
801 applyStyles( xDiagram
);
803 catch( const uno::Exception
& ex
)
805 ASSERT_EXCEPTION( ex
);
808 #if OSL_DEBUG_LEVEL >= CHART_TRACE_OSL_DEBUG_LEVEL
809 OSL_TRACE( "ChartTypeTemplate::FillDiagram: Showing Diagram structure" );
810 OSL_TRACE( "---------------------------------------------------------" );
811 debug::ChartDebugTraceDiagram( xDiagram
);
815 void ChartTypeTemplate::createChartTypes(
816 const Sequence
< Sequence
< Reference
< XDataSeries
> > > & aSeriesSeq
,
817 const Sequence
< Reference
< XCoordinateSystem
> > & rCoordSys
,
818 const Sequence
< Reference
< XChartType
> >& aOldChartTypesSeq
)
820 if( rCoordSys
.getLength() == 0 ||
821 ! rCoordSys
[0].is() )
826 sal_Int32 nCooSysIdx
=0;
827 Reference
< XChartType
> xCT
;
828 if( aSeriesSeq
.getLength() == 0 )
830 // we need a new chart type
831 xCT
.set( getChartTypeForNewSeries( aOldChartTypesSeq
));
832 Reference
< XChartTypeContainer
> xCTCnt( rCoordSys
[nCooSysIdx
], uno::UNO_QUERY_THROW
);
833 Sequence
< Reference
< XChartType
> > aCTSeq( xCTCnt
->getChartTypes());
836 xCTCnt
->setChartTypes( aCTSeq
);
840 for( sal_Int32 nSeriesIdx
=0; nSeriesIdx
<aSeriesSeq
.getLength(); ++nSeriesIdx
)
842 if( nSeriesIdx
== nCooSysIdx
)
844 // we need a new chart type
845 xCT
.set( getChartTypeForNewSeries( aOldChartTypesSeq
));
846 Reference
< XChartTypeContainer
> xCTCnt( rCoordSys
[nCooSysIdx
], uno::UNO_QUERY_THROW
);
847 Sequence
< Reference
< XChartType
> > aCTSeq( xCTCnt
->getChartTypes());
848 if( aCTSeq
.getLength())
851 xCTCnt
->setChartTypes( aCTSeq
);
854 xCTCnt
->addChartType( xCT
);
856 Reference
< chart2::XDataSeriesContainer
> xDSCnt( xCT
, uno::UNO_QUERY_THROW
);
857 xDSCnt
->setDataSeries( aSeriesSeq
[nSeriesIdx
] );
861 // reuse existing chart type
862 OSL_ASSERT( xCT
.is());
863 Reference
< chart2::XDataSeriesContainer
> xDSCnt( xCT
, uno::UNO_QUERY_THROW
);
864 Sequence
< Reference
< XDataSeries
> > aNewSeriesSeq( xDSCnt
->getDataSeries());
865 sal_Int32 nNewStartIndex
= aNewSeriesSeq
.getLength();
866 aNewSeriesSeq
.realloc( nNewStartIndex
+ aSeriesSeq
[nSeriesIdx
].getLength() );
867 ::std::copy( aSeriesSeq
[nSeriesIdx
].getConstArray(),
868 aSeriesSeq
[nSeriesIdx
].getConstArray() + aSeriesSeq
[nSeriesIdx
].getLength(),
869 aNewSeriesSeq
.getArray() + nNewStartIndex
);
870 xDSCnt
->setDataSeries( aNewSeriesSeq
);
873 // spread the series over the available coordinate systems
874 if( rCoordSys
.getLength() > (nCooSysIdx
+ 1) )
879 catch( uno::Exception
& ex
)
881 ASSERT_EXCEPTION( ex
);
886 void ChartTypeTemplate::copyPropertiesFromOldToNewCoordianteSystem(
887 const Sequence
< Reference
< XChartType
> > & rOldChartTypesSeq
,
888 const Reference
< XChartType
> & xNewChartType
)
890 Reference
< beans::XPropertySet
> xDestination( xNewChartType
, uno::UNO_QUERY
);
891 if( !xDestination
.is() )
894 OUString
aNewChartType( xNewChartType
->getChartType() );
896 Reference
< beans::XPropertySet
> xSource
;
898 for( nN
=0; nN
<rOldChartTypesSeq
.getLength();++nN
)
900 Reference
< XChartType
> xOldType( rOldChartTypesSeq
[nN
] );
901 if( xOldType
.is() && xOldType
->getChartType().equals( aNewChartType
) )
903 xSource
.set( Reference
< beans::XPropertySet
>(xOldType
, uno::UNO_QUERY
) );
909 comphelper::copyProperties( xSource
, xDestination
);
914 Sequence
< OUString
> ChartTypeTemplate::getSupportedServiceNames_Static()
916 Sequence
< OUString
> aServices( 3 );
917 aServices
[ 0 ] = C2U( "com.sun.star.chart2.ChartTypeTemplate" );
918 aServices
[ 1 ] = C2U( "com.sun.star.layout.LayoutElement" );
919 aServices
[ 2 ] = C2U( "com.sun.star.beans.PropertySet" );
923 Reference
< uno::XComponentContext
> ChartTypeTemplate::GetComponentContext() const
928 // ================================================================================
930 // implement XServiceInfo methods basing upon getSupportedServiceNames_Static
931 APPHELPER_XSERVICEINFO_IMPL( ChartTypeTemplate
,
932 C2U( "com.sun.star.comp.chart.ChartTypeTemplate" ));