1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "ChartTypeTemplate.hxx"
21 #include "PropertyHelper.hxx"
23 #include "DataSeriesHelper.hxx"
24 #include "DataInterpreter.hxx"
25 #include "CommonConverters.hxx"
26 #include "ContainerHelper.hxx"
27 #include "ChartTypeHelper.hxx"
29 #include "CartesianCoordinateSystem.hxx"
30 #include "AxisHelper.hxx"
31 #include "LegendHelper.hxx"
32 #include "DiagramHelper.hxx"
33 #include "AxisIndexDefines.hxx"
34 #include <unonames.hxx>
36 #include <cppuhelper/component_context.hxx>
37 #include <com/sun/star/chart/ChartSolidType.hpp>
38 #include <com/sun/star/chart2/AxisType.hpp>
39 #include <com/sun/star/chart2/XDataSeriesContainer.hpp>
40 #include <com/sun/star/chart2/XChartTypeContainer.hpp>
45 using namespace ::com::sun::star
;
46 using namespace ::com::sun::star::chart2
;
48 using ::com::sun::star::uno::Sequence
;
49 using ::com::sun::star::uno::Reference
;
50 using ::com::sun::star::uno::Any
;
55 void lcl_applyDefaultStyle(
56 const Reference
< XDataSeries
> & xSeries
,
58 const Reference
< XDiagram
> & xDiagram
)
60 // @deprecated: correct default color should be found by view without
61 // setting color as hard attribute
62 if( xSeries
.is() && xDiagram
.is())
64 Reference
< beans::XPropertySet
> xSeriesProp( xSeries
, uno::UNO_QUERY
);
65 Reference
< chart2::XColorScheme
> xColorScheme( xDiagram
->getDefaultColorScheme());
66 if( xSeriesProp
.is() && xColorScheme
.is() )
67 xSeriesProp
->setPropertyValue(
69 uno::makeAny( xColorScheme
->getColorByIndex( nIndex
)));
73 void lcl_ensureCorrectLabelPlacement( const Reference
< beans::XPropertySet
>& xProp
, const uno::Sequence
< sal_Int32
>& rAvailablePlacements
)
75 sal_Int32 nLabelPlacement
=0;
76 if( xProp
.is() && (xProp
->getPropertyValue( "LabelPlacement" ) >>= nLabelPlacement
) )
79 for( sal_Int32 nN
= 0; nN
< rAvailablePlacements
.getLength(); nN
++ )
81 if( rAvailablePlacements
[nN
] == nLabelPlacement
)
90 //otherwise use the first supported one
91 if( rAvailablePlacements
.getLength() )
92 aNewValue
<<=rAvailablePlacements
[0];
93 xProp
->setPropertyValue( "LabelPlacement", aNewValue
);
98 void lcl_resetLabelPlacementIfDefault( const Reference
< beans::XPropertySet
>& xProp
, sal_Int32 nDefaultPlacement
)
101 sal_Int32 nLabelPlacement
=0;
102 if( xProp
.is() && (xProp
->getPropertyValue( "LabelPlacement" ) >>= nLabelPlacement
) )
104 if( nDefaultPlacement
== nLabelPlacement
)
105 xProp
->setPropertyValue( "LabelPlacement", uno::Any() );
109 void lcl_ensureCorrectMissingValueTreatment( const Reference
< chart2::XDiagram
>& xDiagram
, const Reference
< XChartType
>& xChartType
)
111 Reference
< beans::XPropertySet
> xDiaProp( xDiagram
, uno::UNO_QUERY
);
114 uno::Sequence
< sal_Int32
> aAvailableMissingValueTreatment(
115 ::chart::ChartTypeHelper::getSupportedMissingValueTreatments( xChartType
) );
117 if( aAvailableMissingValueTreatment
.getLength() )
118 xDiaProp
->setPropertyValue( "MissingValueTreatment", uno::makeAny( aAvailableMissingValueTreatment
[0] ) );
120 xDiaProp
->setPropertyValue( "MissingValueTreatment", uno::Any() );
124 } // anonymous namespace
129 ChartTypeTemplate::ChartTypeTemplate(
130 Reference
< uno::XComponentContext
> const & xContext
,
131 const OUString
& rServiceName
) :
132 m_xContext( xContext
),
133 m_aServiceName( rServiceName
)
137 ChartTypeTemplate::~ChartTypeTemplate()
140 // ____ XChartTypeTemplate ____
141 uno::Reference
< XDiagram
> SAL_CALL
ChartTypeTemplate::createDiagramByDataSource(
142 const uno::Reference
< data::XDataSource
>& xDataSource
,
143 const uno::Sequence
< beans::PropertyValue
>& aArguments
)
144 throw (uno::RuntimeException
, std::exception
)
146 Reference
< XDiagram
> xDia
;
152 GetComponentContext()->getServiceManager()->createInstanceWithContext(
153 "com.sun.star.chart2.Diagram",
154 GetComponentContext() ),
155 uno::UNO_QUERY_THROW
);
158 Reference
< chart2::XDataInterpreter
> xInterpreter( getDataInterpreter());
159 chart2::InterpretedData
aData(
160 xInterpreter
->interpretDataSource(
161 xDataSource
, aArguments
, Sequence
< Reference
< XDataSeries
> >() ));
163 Sequence
< Sequence
< Reference
< XDataSeries
> > > aSeries( aData
.Series
);
164 sal_Int32 i
, j
, nCount
= 0;
165 for( i
=0; i
<aSeries
.getLength(); ++i
)
167 for( j
=0; j
<aSeries
[i
].getLength(); ++j
, ++nCount
)
168 lcl_applyDefaultStyle( aSeries
[i
][j
], nCount
, xDia
);
171 Sequence
< Reference
< XChartType
> > aOldChartTypesSeq
;
172 FillDiagram( xDia
, aData
.Series
, aData
.Categories
, aOldChartTypesSeq
, true );
174 catch( const uno::Exception
& ex
)
176 ASSERT_EXCEPTION( ex
);
182 sal_Bool SAL_CALL
ChartTypeTemplate::supportsCategories()
183 throw (css::uno::RuntimeException
, ::std::exception
)
188 void SAL_CALL
ChartTypeTemplate::changeDiagram( const uno::Reference
< XDiagram
>& xDiagram
)
189 throw (uno::RuntimeException
, std::exception
)
196 Sequence
< Sequence
< Reference
< XDataSeries
> > > aSeriesSeq(
197 DiagramHelper::getDataSeriesGroups( xDiagram
));
198 Sequence
< Reference
< XDataSeries
> > aFlatSeriesSeq( FlattenSequence( aSeriesSeq
));
199 const sal_Int32 nFormerSeriesCount
= aFlatSeriesSeq
.getLength();
201 // chart-type specific interpretation of existing data series
202 Reference
< chart2::XDataInterpreter
> xInterpreter( getDataInterpreter());
203 chart2::InterpretedData aData
;
204 aData
.Series
= aSeriesSeq
;
205 aData
.Categories
= DiagramHelper::getCategoriesFromDiagram( xDiagram
);
207 if( xInterpreter
->isDataCompatible( aData
) )
209 aData
= xInterpreter
->reinterpretDataSeries( aData
);
213 Reference
< data::XDataSource
> xSource( xInterpreter
->mergeInterpretedData( aData
));
214 // todo: get a "range-union" from the data provider by calling
215 // OUString aRange = getRangeRepresentationByData( xSource );
216 // xSource.set( getDataByRangeRepresentation( aRange, aParam ));
217 // where aParam == ??
218 Sequence
< beans::PropertyValue
> aParam
;
219 if( aData
.Categories
.is())
222 aParam
[0] = beans::PropertyValue( "HasCategories", -1, uno::makeAny( true ),
223 beans::PropertyState_DIRECT_VALUE
);
225 aData
= xInterpreter
->interpretDataSource( xSource
, aParam
, aFlatSeriesSeq
);
227 aSeriesSeq
= aData
.Series
;
229 sal_Int32 i
, j
, nIndex
= 0;
230 for( i
=0; i
<aSeriesSeq
.getLength(); ++i
)
231 for( j
=0; j
<aSeriesSeq
[i
].getLength(); ++j
, ++nIndex
)
233 if( nIndex
>= nFormerSeriesCount
)
234 lcl_applyDefaultStyle( aSeriesSeq
[i
][j
], nIndex
, xDiagram
);
237 // remove charttype groups from all coordinate systems
238 Sequence
< Reference
< XChartType
> > aOldChartTypesSeq(
239 DiagramHelper::getChartTypesFromDiagram(xDiagram
) );
241 Reference
< XCoordinateSystemContainer
> xCoordSysCnt( xDiagram
, uno::UNO_QUERY
);
242 OSL_ASSERT( xCoordSysCnt
.is());
243 if( xCoordSysCnt
.is())
245 Sequence
< Reference
< XCoordinateSystem
> > aCooSysSeq(
246 xCoordSysCnt
->getCoordinateSystems());
247 for( sal_Int32 nCooSysIdx
= 0; nCooSysIdx
< aCooSysSeq
.getLength(); ++nCooSysIdx
)
249 Reference
< XChartTypeContainer
> xContainer( aCooSysSeq
[nCooSysIdx
], uno::UNO_QUERY
);
250 if( xContainer
.is() )
251 xContainer
->setChartTypes( Sequence
< Reference
< XChartType
> >() );
255 FillDiagram( xDiagram
, aSeriesSeq
, aData
.Categories
, aOldChartTypesSeq
, false );
257 catch( const uno::Exception
& ex
)
259 ASSERT_EXCEPTION( ex
);
263 void SAL_CALL
ChartTypeTemplate::changeDiagramData(
264 const Reference
< chart2::XDiagram
>& xDiagram
,
265 const Reference
< chart2::data::XDataSource
>& xDataSource
,
266 const Sequence
< beans::PropertyValue
>& aArguments
)
267 throw (uno::RuntimeException
, std::exception
)
269 if( ! (xDiagram
.is() &&
275 // interpret new data and re-use existing series
276 Sequence
< Reference
< XDataSeries
> > aFlatSeriesSeq(
277 ::chart::ContainerHelper::ContainerToSequence( DiagramHelper::getDataSeriesFromDiagram( xDiagram
)));
278 const sal_Int32 nFormerSeriesCount
= aFlatSeriesSeq
.getLength();
279 Reference
< chart2::XDataInterpreter
> xInterpreter( getDataInterpreter());
280 chart2::InterpretedData aData
=
281 xInterpreter
->interpretDataSource( xDataSource
, aArguments
, aFlatSeriesSeq
);
284 Sequence
< Sequence
< Reference
< XDataSeries
> > > aSeriesSeq( aData
.Series
);
286 sal_Int32 i
, j
, nIndex
= 0;
287 for( i
=0; i
<aSeriesSeq
.getLength(); ++i
)
288 for( j
=0; j
<aSeriesSeq
[i
].getLength(); ++j
, ++nIndex
)
290 if( nIndex
>= nFormerSeriesCount
)
292 lcl_applyDefaultStyle( aSeriesSeq
[i
][j
], nIndex
, xDiagram
);
293 applyStyle( aSeriesSeq
[i
][j
], i
, j
, aSeriesSeq
[i
].getLength() );
298 DiagramHelper::setCategoriesToDiagram( aData
.Categories
, xDiagram
, true, supportsCategories() );
300 Sequence
< Reference
< XChartType
> > aChartTypes(
301 DiagramHelper::getChartTypesFromDiagram( xDiagram
));
302 sal_Int32 nMax
= ::std::min( aChartTypes
.getLength(), aSeriesSeq
.getLength());
303 for( i
=0; i
<nMax
; ++i
)
305 Reference
< XDataSeriesContainer
> xDSCnt( aChartTypes
[i
], uno::UNO_QUERY_THROW
);
306 xDSCnt
->setDataSeries( aSeriesSeq
[i
] );
309 catch( const uno::Exception
& ex
)
311 ASSERT_EXCEPTION( ex
);
315 sal_Bool SAL_CALL
ChartTypeTemplate::matchesTemplate(
316 const Reference
< chart2::XDiagram
>& xDiagram
,
317 sal_Bool
/* bAdaptProperties */ )
318 throw (uno::RuntimeException
, std::exception
)
320 bool bResult
= false;
327 Reference
< XCoordinateSystemContainer
> xCooSysCnt(
328 xDiagram
, uno::UNO_QUERY_THROW
);
329 Sequence
< Reference
< XCoordinateSystem
> > aCooSysSeq(
330 xCooSysCnt
->getCoordinateSystems());
332 // need to have at least one coordinate system
333 bResult
= (aCooSysSeq
.getLength() > 0);
336 Sequence
< Reference
< XChartType
> > aFormerlyUsedChartTypes
;
337 Reference
<XChartType
> xOldCT
= getChartTypeForNewSeries(aFormerlyUsedChartTypes
);
341 const OUString aChartTypeToMatch
= xOldCT
->getChartType();
342 const sal_Int32 nDimensionToMatch
= getDimension();
343 for( sal_Int32 nCooSysIdx
=0; bResult
&& (nCooSysIdx
< aCooSysSeq
.getLength()); ++nCooSysIdx
)
346 bResult
= bResult
&& (aCooSysSeq
[nCooSysIdx
]->getDimension() == nDimensionToMatch
);
348 Reference
< XChartTypeContainer
> xCTCnt( aCooSysSeq
[nCooSysIdx
], uno::UNO_QUERY_THROW
);
349 Sequence
< Reference
< XChartType
> > aChartTypeSeq( xCTCnt
->getChartTypes());
350 for( sal_Int32 nCTIdx
=0; bResult
&& (nCTIdx
< aChartTypeSeq
.getLength()); ++nCTIdx
)
352 if (!aChartTypeSeq
[nCTIdx
].is())
356 bResult
= bResult
&& aChartTypeSeq
[nCTIdx
]->getChartType().equals( aChartTypeToMatch
);
358 bool bAmbiguous
=false;
359 // match stacking mode
361 ( DiagramHelper::getStackModeFromChartType(
362 aChartTypeSeq
[nCTIdx
], bFound
, bAmbiguous
,
363 aCooSysSeq
[nCooSysIdx
] )
364 == getStackMode( nCTIdx
) );
369 catch( const uno::Exception
& ex
)
371 ASSERT_EXCEPTION( ex
);
377 Reference
< chart2::XDataInterpreter
> SAL_CALL
ChartTypeTemplate::getDataInterpreter()
378 throw (uno::RuntimeException
, std::exception
)
380 if( ! m_xDataInterpreter
.is())
381 m_xDataInterpreter
.set( new DataInterpreter( GetComponentContext() ) );
383 return m_xDataInterpreter
;
386 void SAL_CALL
ChartTypeTemplate::applyStyle(
387 const Reference
< chart2::XDataSeries
>& xSeries
,
388 ::sal_Int32 nChartTypeIndex
,
389 ::sal_Int32
/* nSeriesIndex */,
390 ::sal_Int32
/* nSeriesCount */ )
391 throw (uno::RuntimeException
, std::exception
)
393 // sset stacking mode
394 Reference
< beans::XPropertySet
> xSeriesProp( xSeries
, uno::UNO_QUERY
);
395 if( xSeriesProp
.is())
399 StackMode eStackMode
= getStackMode( nChartTypeIndex
);
400 const uno::Any aPropValue
= uno::makeAny(
401 ( (eStackMode
== StackMode_Y_STACKED
) ||
402 (eStackMode
== StackMode_Y_STACKED_PERCENT
) )
403 ? chart2::StackingDirection_Y_STACKING
404 : (eStackMode
== StackMode_Z_STACKED
)
405 ? chart2::StackingDirection_Z_STACKING
406 : chart2::StackingDirection_NO_STACKING
);
407 xSeriesProp
->setPropertyValue( "StackingDirection", aPropValue
);
409 //ensure valid label placement
411 uno::Sequence
< sal_Int32
> aAvailablePlacements( ChartTypeHelper::getSupportedLabelPlacements(
412 getChartTypeForIndex( nChartTypeIndex
), getDimension(), isSwapXAndY(), xSeries
) );
413 lcl_ensureCorrectLabelPlacement( xSeriesProp
, aAvailablePlacements
);
415 uno::Sequence
< sal_Int32
> aAttributedDataPointIndexList
;
416 if( xSeriesProp
->getPropertyValue( "AttributedDataPoints" ) >>= aAttributedDataPointIndexList
)
417 for(sal_Int32 nN
=aAttributedDataPointIndexList
.getLength();nN
--;)
418 lcl_ensureCorrectLabelPlacement( xSeries
->getDataPointByIndex(aAttributedDataPointIndexList
[nN
]), aAvailablePlacements
);
421 catch( const uno::Exception
& ex
)
423 ASSERT_EXCEPTION( ex
);
428 void SAL_CALL
ChartTypeTemplate::applyStyles( const Reference
< chart2::XDiagram
>& xDiagram
)
429 throw (uno::RuntimeException
)
431 // apply chart-type specific styles, like "symbols on" for example
432 Sequence
< Sequence
< Reference
< XDataSeries
> > > aNewSeriesSeq(
433 DiagramHelper::getDataSeriesGroups( xDiagram
));
434 for( sal_Int32 i
=0; i
<aNewSeriesSeq
.getLength(); ++i
)
436 const sal_Int32 nNumSeries
= aNewSeriesSeq
[i
].getLength();
437 for( sal_Int32 j
=0; j
<nNumSeries
; ++j
)
438 applyStyle( aNewSeriesSeq
[i
][j
], i
, j
, nNumSeries
);
441 //ensure valid empty cell handling (for first chart type...)
442 lcl_ensureCorrectMissingValueTreatment( xDiagram
, getChartTypeForIndex( 0 ) );
445 void SAL_CALL
ChartTypeTemplate::resetStyles( const Reference
< chart2::XDiagram
>& xDiagram
)
446 throw (uno::RuntimeException
, std::exception
)
448 // reset number format if we had percent stacking on
449 bool bPercent
= (getStackMode(0) == StackMode_Y_STACKED_PERCENT
);
452 Sequence
< Reference
< chart2::XAxis
> > aAxisSeq( AxisHelper::getAllAxesOfDiagram( xDiagram
) );
453 for( sal_Int32 i
=0; i
<aAxisSeq
.getLength(); ++i
)
455 if( 1== AxisHelper::getDimensionIndexOfAxis( aAxisSeq
[i
], xDiagram
) )
457 Reference
< beans::XPropertySet
> xAxisProp( aAxisSeq
[i
], uno::UNO_QUERY
);
460 // set number format to source format
461 xAxisProp
->setPropertyValue(CHART_UNONAME_LINK_TO_SRC_NUMFMT
, uno::makeAny(true));
462 xAxisProp
->setPropertyValue(CHART_UNONAME_NUMFMT
, uno::Any());
468 //reset label placement if default
470 uno::Reference
< XCoordinateSystemContainer
> xCooSysContainer( xDiagram
, uno::UNO_QUERY
);
471 if( xCooSysContainer
.is() )
473 uno::Sequence
< uno::Reference
< XCoordinateSystem
> > aCooSysList( xCooSysContainer
->getCoordinateSystems() );
474 for( sal_Int32 nCS
= 0; nCS
< aCooSysList
.getLength(); ++nCS
)
476 uno::Reference
< XCoordinateSystem
> xCooSys( aCooSysList
[nCS
] );
478 //iterate through all chart types in the current coordinate system
479 uno::Reference
< XChartTypeContainer
> xChartTypeContainer( xCooSys
, uno::UNO_QUERY
);
480 OSL_ASSERT( xChartTypeContainer
.is());
481 if( !xChartTypeContainer
.is() )
483 uno::Sequence
< uno::Reference
< XChartType
> > aChartTypeList( xChartTypeContainer
->getChartTypes() );
484 for( sal_Int32 nT
= 0; nT
< aChartTypeList
.getLength(); ++nT
)
486 uno::Reference
< XChartType
> xChartType( aChartTypeList
[nT
] );
488 //iterate through all series in this chart type
489 uno::Reference
< XDataSeriesContainer
> xDataSeriesContainer( xChartType
, uno::UNO_QUERY
);
490 OSL_ASSERT( xDataSeriesContainer
.is());
491 if( !xDataSeriesContainer
.is() )
494 uno::Sequence
< uno::Reference
< XDataSeries
> > aSeriesList( xDataSeriesContainer
->getDataSeries() );
495 for( sal_Int32 nS
= 0; nS
< aSeriesList
.getLength(); ++nS
)
497 Reference
< XDataSeries
> xSeries(aSeriesList
[nS
]);
498 Reference
< beans::XPropertySet
> xSeriesProp( xSeries
, uno::UNO_QUERY
);
499 if(!xSeries
.is() || !xSeriesProp
.is() )
502 uno::Sequence
< sal_Int32
> aAvailablePlacements( ChartTypeHelper::getSupportedLabelPlacements(
503 xChartType
, getDimension(), isSwapXAndY(), xSeries
) );
504 if(!aAvailablePlacements
.getLength())
507 sal_Int32 nDefaultPlacement
= aAvailablePlacements
[0];
509 lcl_resetLabelPlacementIfDefault( xSeriesProp
, nDefaultPlacement
);
511 uno::Sequence
< sal_Int32
> aAttributedDataPointIndexList
;
512 if( xSeriesProp
->getPropertyValue( "AttributedDataPoints" ) >>= aAttributedDataPointIndexList
)
513 for(sal_Int32 nN
=aAttributedDataPointIndexList
.getLength();nN
--;)
514 lcl_resetLabelPlacementIfDefault( xSeries
->getDataPointByIndex(aAttributedDataPointIndexList
[nN
]), nDefaultPlacement
);
524 // ____ XServiceName ____
525 OUString SAL_CALL
ChartTypeTemplate::getServiceName()
526 throw (uno::RuntimeException
, std::exception
)
528 return m_aServiceName
;
531 sal_Int32
ChartTypeTemplate::getDimension() const
536 StackMode
ChartTypeTemplate::getStackMode( sal_Int32
/* nChartTypeIndex */ ) const
538 return StackMode_NONE
;
541 bool ChartTypeTemplate::isSwapXAndY() const
546 void ChartTypeTemplate::createCoordinateSystems(
547 const Reference
< chart2::XCoordinateSystemContainer
> & xOutCooSysCnt
)
549 if( ! xOutCooSysCnt
.is())
551 Sequence
< Reference
< XChartType
> > aFormerlyUsedChartTypes
;
552 Reference
< XChartType
> xChartType( getChartTypeForNewSeries(aFormerlyUsedChartTypes
));
553 if( ! xChartType
.is())
555 Reference
< XCoordinateSystem
> xCooSys( xChartType
->createCoordinateSystem( getDimension()));
558 // chart type wants no coordinate systems
559 xOutCooSysCnt
->setCoordinateSystems( Sequence
< Reference
< XCoordinateSystem
> >());
562 // #i69680# make grid of first y-axis visible (was in the CooSys CTOR before)
563 if( xCooSys
->getDimension() >= 2 )
565 Reference
< chart2::XAxis
> xAxis( xCooSys
->getAxisByDimension( 1, 0 ));
567 AxisHelper::makeGridVisible( xAxis
->getGridProperties() );
570 Sequence
< Reference
< XCoordinateSystem
> > aCoordinateSystems(
571 xOutCooSysCnt
->getCoordinateSystems());
573 if( aCoordinateSystems
.getLength())
576 for( sal_Int32 i
=0; bOk
&& i
<aCoordinateSystems
.getLength(); ++i
)
577 bOk
= bOk
&& ( xCooSys
->getCoordinateSystemType().equals( aCoordinateSystems
[i
]->getCoordinateSystemType()) &&
578 (xCooSys
->getDimension() == aCoordinateSystems
[i
]->getDimension()) );
579 // coordinate systems are ok
582 // there are coordinate systems but they do not fit. So overwrite them.
585 //copy as much info from former coordinate system as possible:
586 if( aCoordinateSystems
.getLength() )
588 Reference
< XCoordinateSystem
> xOldCooSys( aCoordinateSystems
[0] );
589 sal_Int32 nMaxDimensionCount
= std::min( xCooSys
->getDimension(), xOldCooSys
->getDimension() );
591 for(sal_Int32 nDimensionIndex
=0; nDimensionIndex
<nMaxDimensionCount
; nDimensionIndex
++)
593 const sal_Int32 nMaximumAxisIndex
= xOldCooSys
->getMaximumAxisIndexByDimension(nDimensionIndex
);
594 for(sal_Int32 nAxisIndex
=0; nAxisIndex
<=nMaximumAxisIndex
; ++nAxisIndex
)
596 uno::Reference
< XAxis
> xAxis( xOldCooSys
->getAxisByDimension( nDimensionIndex
, nAxisIndex
) );
599 xCooSys
->setAxisByDimension( nDimensionIndex
, xAxis
, nAxisIndex
);
605 // set new coordinate systems
606 aCoordinateSystems
.realloc( 1 );
607 aCoordinateSystems
[0] = xCooSys
;
609 xOutCooSysCnt
->setCoordinateSystems( aCoordinateSystems
);
612 void ChartTypeTemplate::adaptScales(
613 const Sequence
< Reference
< chart2::XCoordinateSystem
> > & aCooSysSeq
,
614 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 )
617 bool bSupportsCategories( supportsCategories() );
618 for( sal_Int32 nCooSysIdx
=0; nCooSysIdx
<aCooSysSeq
.getLength(); ++nCooSysIdx
)
622 Reference
< XCoordinateSystem
> xCooSys( aCooSysSeq
[nCooSysIdx
] );
626 // attach categories to first axis
627 sal_Int32
nDim( xCooSys
->getDimension());
630 const sal_Int32 nDimensionX
= 0;
631 const sal_Int32 nMaxIndex
= xCooSys
->getMaximumAxisIndexByDimension(nDimensionX
);
632 for(sal_Int32 nI
=0; nI
<=nMaxIndex
; ++nI
)
634 Reference
< XAxis
> xAxis( xCooSys
->getAxisByDimension(nDimensionX
,nI
) );
637 ScaleData
aData( xAxis
->getScaleData() );
638 aData
.Categories
= xCategories
;
639 if(bSupportsCategories
)
642 Reference
< XChartType
> xChartType( getChartTypeForNewSeries(Sequence
< Reference
< XChartType
> >() ));
643 bool bSupportsDates
= ::chart::ChartTypeHelper::isSupportingDateAxis( xChartType
, 2, nDimensionX
);
644 if( aData
.AxisType
!= AxisType::CATEGORY
&& ( aData
.AxisType
!= AxisType::DATE
|| !bSupportsDates
) )
646 aData
.AxisType
= AxisType::CATEGORY
;
647 aData
.AutoDateAxis
= true;
648 AxisHelper::removeExplicitScaling( aData
);
652 aData
.AxisType
= AxisType::REALNUMBER
;
654 xAxis
->setScaleData( aData
);
658 // set percent stacking mode at second axis
661 const sal_Int32 nMaxIndex
= xCooSys
->getMaximumAxisIndexByDimension(1);
662 for(sal_Int32 nI
=0; nI
<=nMaxIndex
; ++nI
)
664 Reference
< chart2::XAxis
> xAxis( xCooSys
->getAxisByDimension( 1,nI
));
667 bool bPercent
= (getStackMode(0) == StackMode_Y_STACKED_PERCENT
);
668 chart2::ScaleData aScaleData
= xAxis
->getScaleData();
670 if( bPercent
!= (aScaleData
.AxisType
==AxisType::PERCENT
) )
673 aScaleData
.AxisType
= AxisType::PERCENT
;
675 aScaleData
.AxisType
= AxisType::REALNUMBER
;
676 xAxis
->setScaleData( aScaleData
);
682 catch( const uno::Exception
& ex
)
684 ASSERT_EXCEPTION( ex
);
689 void ChartTypeTemplate::adaptDiagram( const Reference
< XDiagram
> & /* xDiagram */ )
694 void ChartTypeTemplate::createAxes(
695 const Sequence
< Reference
< XCoordinateSystem
> > & rCoordSys
)
697 //create missing axes
698 if( rCoordSys
.getLength() > 0 )
700 sal_Int32 nCooSysIdx
= 0;
701 Reference
< XCoordinateSystem
> xCooSys( rCoordSys
[nCooSysIdx
] );
705 //create main axis in first coordinate system
706 sal_Int32 nDimCount
= xCooSys
->getDimension();
708 for( nDim
=0; nDim
<nDimCount
; ++nDim
)
710 sal_Int32 nAxisCount
= getAxisCountByDimension( nDim
);
712 nAxisCount
< 2 && AxisHelper::isSecondaryYAxisNeeded( xCooSys
))
714 for( sal_Int32 nAxisIndex
= 0; nAxisIndex
< nAxisCount
; ++nAxisIndex
)
716 Reference
< XAxis
> xAxis
= AxisHelper::getAxis( nDim
, nAxisIndex
, xCooSys
);
719 // create and add axis
720 xAxis
.set( AxisHelper::createAxis(
721 nDim
, nAxisIndex
, xCooSys
, GetComponentContext() ));
728 void ChartTypeTemplate::adaptAxes(
729 const Sequence
< Reference
< XCoordinateSystem
> > & rCoordSys
)
731 //adapt properties of exsisting axes and remove superfluous axes
733 if( rCoordSys
.getLength() > 0 )
735 for( sal_Int32 nCooSysIdx
=0; nCooSysIdx
< rCoordSys
.getLength(); ++nCooSysIdx
)
737 Reference
< XCoordinateSystem
> xCooSys( rCoordSys
[nCooSysIdx
] );
740 sal_Int32 nDimCount
= xCooSys
->getDimension();
741 for( sal_Int32 nDim
=0; nDim
<nDimCount
; ++nDim
)
743 sal_Int32 nMaxAxisIndex
= xCooSys
->getMaximumAxisIndexByDimension( nDim
);
744 for( sal_Int32 nAxisIndex
=0; nAxisIndex
<=nMaxAxisIndex
; nAxisIndex
++ )
746 Reference
< XAxis
> xAxis( AxisHelper::getAxis( nDim
, nAxisIndex
, xCooSys
) );
750 if( nAxisIndex
== MAIN_AXIS_INDEX
|| nAxisIndex
== SECONDARY_AXIS_INDEX
)
753 bool bPercent
= (getStackMode(0) == StackMode_Y_STACKED_PERCENT
);
754 if( bPercent
&& nDim
== 1 )
756 Reference
< beans::XPropertySet
> xAxisProp( xAxis
, uno::UNO_QUERY
);
759 // set number format to source format
760 xAxisProp
->setPropertyValue(CHART_UNONAME_LINK_TO_SRC_NUMFMT
, uno::makeAny(true));
761 xAxisProp
->setPropertyValue(CHART_UNONAME_NUMFMT
, uno::Any());
771 sal_Int32
ChartTypeTemplate::getAxisCountByDimension( sal_Int32 nDimension
)
773 return (nDimension
< getDimension()) ? 1 : 0;
776 void ChartTypeTemplate::FillDiagram(
777 const Reference
< XDiagram
>& xDiagram
,
778 const Sequence
< Sequence
< Reference
< XDataSeries
> > >& aSeriesSeq
,
779 Reference
< data::XLabeledDataSequence
> xCategories
,
780 const Sequence
< Reference
< XChartType
> >& aOldChartTypesSeq
,
783 adaptDiagram( xDiagram
);
787 // create coordinate systems and scales
788 Reference
< XCoordinateSystemContainer
> xCoordSysCnt( xDiagram
, uno::UNO_QUERY_THROW
);
789 createCoordinateSystems( xCoordSysCnt
);
790 Sequence
< Reference
< XCoordinateSystem
> > aCoordinateSystems( xCoordSysCnt
->getCoordinateSystems());
791 createAxes( aCoordinateSystems
);
792 adaptAxes( aCoordinateSystems
);
793 adaptScales( aCoordinateSystems
, xCategories
);
796 createChartTypes( aSeriesSeq
, aCoordinateSystems
, aOldChartTypesSeq
);
797 applyStyles( xDiagram
);
799 catch( const uno::Exception
& ex
)
801 ASSERT_EXCEPTION( ex
);
805 void ChartTypeTemplate::createChartTypes(
806 const Sequence
< Sequence
< Reference
< XDataSeries
> > > & aSeriesSeq
,
807 const Sequence
< Reference
< XCoordinateSystem
> > & rCoordSys
,
808 const Sequence
< Reference
< XChartType
> >& aOldChartTypesSeq
)
810 if( rCoordSys
.getLength() == 0 ||
811 ! rCoordSys
[0].is() )
816 sal_Int32 nCooSysIdx
=0;
817 Reference
< XChartType
> xCT
;
818 if( aSeriesSeq
.getLength() == 0 )
820 // we need a new chart type
821 xCT
.set( getChartTypeForNewSeries( aOldChartTypesSeq
));
822 Reference
< XChartTypeContainer
> xCTCnt( rCoordSys
[nCooSysIdx
], uno::UNO_QUERY_THROW
);
823 Sequence
< Reference
< XChartType
> > aCTSeq( xCTCnt
->getChartTypes());
826 xCTCnt
->setChartTypes( aCTSeq
);
830 for( sal_Int32 nSeriesIdx
=0; nSeriesIdx
<aSeriesSeq
.getLength(); ++nSeriesIdx
)
832 if( nSeriesIdx
== nCooSysIdx
)
834 // we need a new chart type
835 xCT
.set( getChartTypeForNewSeries( aOldChartTypesSeq
));
836 Reference
< XChartTypeContainer
> xCTCnt( rCoordSys
[nCooSysIdx
], uno::UNO_QUERY_THROW
);
837 Sequence
< Reference
< XChartType
> > aCTSeq( xCTCnt
->getChartTypes());
838 if( aCTSeq
.getLength())
841 xCTCnt
->setChartTypes( aCTSeq
);
844 xCTCnt
->addChartType( xCT
);
846 Reference
< chart2::XDataSeriesContainer
> xDSCnt( xCT
, uno::UNO_QUERY_THROW
);
847 xDSCnt
->setDataSeries( aSeriesSeq
[nSeriesIdx
] );
851 // reuse existing chart type
852 OSL_ASSERT( xCT
.is());
853 Reference
< chart2::XDataSeriesContainer
> xDSCnt( xCT
, uno::UNO_QUERY_THROW
);
854 Sequence
< Reference
< XDataSeries
> > aNewSeriesSeq( xDSCnt
->getDataSeries());
855 sal_Int32 nNewStartIndex
= aNewSeriesSeq
.getLength();
856 aNewSeriesSeq
.realloc( nNewStartIndex
+ aSeriesSeq
[nSeriesIdx
].getLength() );
857 ::std::copy( aSeriesSeq
[nSeriesIdx
].getConstArray(),
858 aSeriesSeq
[nSeriesIdx
].getConstArray() + aSeriesSeq
[nSeriesIdx
].getLength(),
859 aNewSeriesSeq
.getArray() + nNewStartIndex
);
860 xDSCnt
->setDataSeries( aNewSeriesSeq
);
863 // spread the series over the available coordinate systems
864 if( rCoordSys
.getLength() > (nCooSysIdx
+ 1) )
869 catch( const uno::Exception
& ex
)
871 ASSERT_EXCEPTION( ex
);
875 void ChartTypeTemplate::copyPropertiesFromOldToNewCoordianteSystem(
876 const Sequence
< Reference
< XChartType
> > & rOldChartTypesSeq
,
877 const Reference
< XChartType
> & xNewChartType
)
879 Reference
< beans::XPropertySet
> xDestination( xNewChartType
, uno::UNO_QUERY
);
880 if( !xDestination
.is() )
883 OUString
aNewChartType( xNewChartType
->getChartType() );
885 Reference
< beans::XPropertySet
> xSource
;
887 for( nN
=0; nN
<rOldChartTypesSeq
.getLength();++nN
)
889 Reference
< XChartType
> xOldType( rOldChartTypesSeq
[nN
] );
890 if( xOldType
.is() && xOldType
->getChartType().equals( aNewChartType
) )
892 xSource
.set( Reference
< beans::XPropertySet
>(xOldType
, uno::UNO_QUERY
) );
898 comphelper::copyProperties( xSource
, xDestination
);
903 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */