fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / chart2 / source / model / template / ChartTypeTemplate.cxx
blob0e57e62de90dab2041c47713df9bc33b571ffb55
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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"
22 #include "macros.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>
42 #include <algorithm>
43 #include <iterator>
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;
52 namespace
55 void lcl_applyDefaultStyle(
56 const Reference< XDataSeries > & xSeries,
57 sal_Int32 nIndex,
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(
68 "Color",
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) )
78 bool bValid = false;
79 for( sal_Int32 nN = 0; nN < rAvailablePlacements.getLength(); nN++ )
81 if( rAvailablePlacements[nN] == nLabelPlacement )
83 bValid = true;
84 break;
87 if( !bValid )
89 uno::Any aNewValue;
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 );
112 if( xDiaProp.is() )
114 uno::Sequence < sal_Int32 > aAvailableMissingValueTreatment(
115 ::chart::ChartTypeHelper::getSupportedMissingValueTreatments( xChartType ) );
117 if( aAvailableMissingValueTreatment.getLength() )
118 xDiaProp->setPropertyValue( "MissingValueTreatment", uno::makeAny( aAvailableMissingValueTreatment[0] ) );
119 else
120 xDiaProp->setPropertyValue( "MissingValueTreatment", uno::Any() );
124 } // anonymous namespace
126 namespace chart
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;
150 // create diagram
151 xDia.set(
152 GetComponentContext()->getServiceManager()->createInstanceWithContext(
153 "com.sun.star.chart2.Diagram",
154 GetComponentContext() ),
155 uno::UNO_QUERY_THROW );
157 // modify diagram
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 );
179 return xDia;
182 sal_Bool SAL_CALL ChartTypeTemplate::supportsCategories()
183 throw (css::uno::RuntimeException, ::std::exception)
185 return sal_True;
188 void SAL_CALL ChartTypeTemplate::changeDiagram( const uno::Reference< XDiagram >& xDiagram )
189 throw (uno::RuntimeException, std::exception)
191 if( ! xDiagram.is())
192 return;
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 );
211 else
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())
221 aParam.realloc( 1 );
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() &&
270 xDataSource.is()) )
271 return;
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 );
283 // data series
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() );
297 // categories
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;
322 if( ! xDiagram.is())
323 return bResult;
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);
334 if( bResult )
336 Sequence< Reference< XChartType > > aFormerlyUsedChartTypes;
337 Reference<XChartType> xOldCT = getChartTypeForNewSeries(aFormerlyUsedChartTypes);
338 if (!xOldCT.is())
339 return false;
341 const OUString aChartTypeToMatch = xOldCT->getChartType();
342 const sal_Int32 nDimensionToMatch = getDimension();
343 for( sal_Int32 nCooSysIdx=0; bResult && (nCooSysIdx < aCooSysSeq.getLength()); ++nCooSysIdx )
345 // match dimension
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())
353 return false;
355 // match chart type
356 bResult = bResult && aChartTypeSeq[nCTIdx]->getChartType().equals( aChartTypeToMatch );
357 bool bFound=false;
358 bool bAmbiguous=false;
359 // match stacking mode
360 bResult = bResult &&
361 ( DiagramHelper::getStackModeFromChartType(
362 aChartTypeSeq[nCTIdx], bFound, bAmbiguous,
363 aCooSysSeq[nCooSysIdx] )
364 == getStackMode( nCTIdx ) );
369 catch( const uno::Exception & ex )
371 ASSERT_EXCEPTION( ex );
374 return bResult;
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);
450 if( bPercent )
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 );
458 if( xAxisProp.is())
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() )
482 continue;
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() )
492 continue;
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() )
500 continue;
502 uno::Sequence < sal_Int32 > aAvailablePlacements( ChartTypeHelper::getSupportedLabelPlacements(
503 xChartType, getDimension(), isSwapXAndY(), xSeries ) );
504 if(!aAvailablePlacements.getLength())
505 continue;
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 );
521 return;
524 // ____ XServiceName ____
525 OUString SAL_CALL ChartTypeTemplate::getServiceName()
526 throw (uno::RuntimeException, std::exception)
528 return m_aServiceName;
531 sal_Int32 ChartTypeTemplate::getDimension() const
533 return 2;
536 StackMode ChartTypeTemplate::getStackMode( sal_Int32 /* nChartTypeIndex */ ) const
538 return StackMode_NONE;
541 bool ChartTypeTemplate::isSwapXAndY() const
543 return false;
546 void ChartTypeTemplate::createCoordinateSystems(
547 const Reference< chart2::XCoordinateSystemContainer > & xOutCooSysCnt )
549 if( ! xOutCooSysCnt.is())
550 return;
551 Sequence< Reference< XChartType > > aFormerlyUsedChartTypes;
552 Reference< XChartType > xChartType( getChartTypeForNewSeries(aFormerlyUsedChartTypes));
553 if( ! xChartType.is())
554 return;
555 Reference< XCoordinateSystem > xCooSys( xChartType->createCoordinateSystem( getDimension()));
556 if( ! xCooSys.is())
558 // chart type wants no coordinate systems
559 xOutCooSysCnt->setCoordinateSystems( Sequence< Reference< XCoordinateSystem > >());
560 return;
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 ));
566 if( xAxis.is())
567 AxisHelper::makeGridVisible( xAxis->getGridProperties() );
570 Sequence< Reference< XCoordinateSystem > > aCoordinateSystems(
571 xOutCooSysCnt->getCoordinateSystems());
573 if( aCoordinateSystems.getLength())
575 bool bOk = true;
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
580 if( bOk )
581 return;
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 ) );
597 if( xAxis.is())
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] );
623 if( !xCooSys.is() )
624 continue;
626 // attach categories to first axis
627 sal_Int32 nDim( xCooSys->getDimension());
628 if( nDim > 0 )
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) );
635 if( xAxis.is())
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 );
651 else
652 aData.AxisType = AxisType::REALNUMBER;
654 xAxis->setScaleData( aData );
658 // set percent stacking mode at second axis
659 if( nDim > 1 )
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 ));
665 if( xAxis.is())
667 bool bPercent = (getStackMode(0) == StackMode_Y_STACKED_PERCENT);
668 chart2::ScaleData aScaleData = xAxis->getScaleData();
670 if( bPercent != (aScaleData.AxisType==AxisType::PERCENT) )
672 if( bPercent )
673 aScaleData.AxisType = AxisType::PERCENT;
674 else
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 */ )
691 return;
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] );
702 if(!xCooSys.is())
703 return;
705 //create main axis in first coordinate system
706 sal_Int32 nDimCount = xCooSys->getDimension();
707 sal_Int32 nDim=0;
708 for( nDim=0; nDim<nDimCount; ++nDim )
710 sal_Int32 nAxisCount = getAxisCountByDimension( nDim );
711 if( nDim == 1 &&
712 nAxisCount < 2 && AxisHelper::isSecondaryYAxisNeeded( xCooSys ))
713 nAxisCount = 2;
714 for( sal_Int32 nAxisIndex = 0; nAxisIndex < nAxisCount; ++nAxisIndex )
716 Reference< XAxis > xAxis = AxisHelper::getAxis( nDim, nAxisIndex, xCooSys );
717 if( !xAxis.is())
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] );
738 if( !xCooSys.is() )
739 continue;
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 ) );
747 if( !xAxis.is() )
748 continue;
750 if( nAxisIndex == MAIN_AXIS_INDEX || nAxisIndex == SECONDARY_AXIS_INDEX )
752 // adapt scales
753 bool bPercent = (getStackMode(0) == StackMode_Y_STACKED_PERCENT);
754 if( bPercent && nDim == 1 )
756 Reference< beans::XPropertySet > xAxisProp( xAxis, uno::UNO_QUERY );
757 if( xAxisProp.is())
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,
781 bool /* bCreate */ )
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 );
795 // chart types
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() )
812 return;
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());
824 aCTSeq.realloc( 1 );
825 aCTSeq[0] = xCT;
826 xCTCnt->setChartTypes( aCTSeq );
828 else
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())
840 aCTSeq[0] = xCT;
841 xCTCnt->setChartTypes( aCTSeq );
843 else
844 xCTCnt->addChartType( xCT );
846 Reference< chart2::XDataSeriesContainer > xDSCnt( xCT, uno::UNO_QUERY_THROW );
847 xDSCnt->setDataSeries( aSeriesSeq[nSeriesIdx] );
849 else
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) )
865 ++nCooSysIdx;
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() )
881 return;
883 OUString aNewChartType( xNewChartType->getChartType() );
885 Reference< beans::XPropertySet > xSource;
886 sal_Int32 nN=0;
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 ) );
893 if( xSource.is() )
894 break;
897 if( xSource.is() )
898 comphelper::copyProperties( xSource, xDestination );
901 } // namespace chart
903 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */