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 <AxisHelper.hxx>
21 #include <DiagramHelper.hxx>
22 #include <ChartTypeHelper.hxx>
23 #include <AxisIndexDefines.hxx>
24 #include <LinePropertiesHelper.hxx>
25 #include <servicenames_coosystems.hxx>
26 #include <DataSeriesHelper.hxx>
27 #include <Scaling.hxx>
28 #include <ChartModel.hxx>
29 #include <ChartModelHelper.hxx>
30 #include <DataSourceHelper.hxx>
31 #include <ReferenceSizeProvider.hxx>
32 #include <ExplicitCategoriesProvider.hxx>
33 #include <unonames.hxx>
35 #include <unotools/saveopt.hxx>
37 #include <com/sun/star/chart/ChartAxisPosition.hpp>
38 #include <com/sun/star/chart2/AxisType.hpp>
39 #include <com/sun/star/chart2/XCoordinateSystemContainer.hpp>
40 #include <com/sun/star/chart2/XChartTypeContainer.hpp>
41 #include <com/sun/star/chart2/XDataSeriesContainer.hpp>
42 #include <com/sun/star/chart2/data/XDataSource.hpp>
44 #include <rtl/math.hxx>
45 #include <sal/log.hxx>
47 #include <com/sun/star/lang/XServiceName.hpp>
48 #include <com/sun/star/uno/XComponentContext.hpp>
49 #include <comphelper/sequence.hxx>
50 #include <tools/diagnose_ex.h>
56 using namespace ::com::sun::star
;
57 using namespace ::com::sun::star::chart2
;
58 using ::com::sun::star::uno::Reference
;
59 using ::com::sun::star::uno::Sequence
;
61 Reference
< chart2::XScaling
> AxisHelper::createLinearScaling()
63 return new LinearScaling( 1.0, 0.0 );
66 Reference
< chart2::XScaling
> AxisHelper::createLogarithmicScaling( double fBase
)
68 return new LogarithmicScaling( fBase
);
71 ScaleData
AxisHelper::createDefaultScale()
74 aScaleData
.AxisType
= chart2::AxisType::REALNUMBER
;
75 aScaleData
.AutoDateAxis
= true;
76 aScaleData
.ShiftedCategoryPosition
= false;//this is adapted in the view code currently
77 Sequence
< SubIncrement
> aSubIncrements(1);
78 aSubIncrements
[0] = SubIncrement();
79 aScaleData
.IncrementData
.SubIncrements
= aSubIncrements
;
83 void AxisHelper::removeExplicitScaling( ScaleData
& rScaleData
)
86 rScaleData
.Minimum
= rScaleData
.Maximum
= rScaleData
.Origin
= aEmpty
;
87 rScaleData
.Scaling
= nullptr;
88 ScaleData
aDefaultScale( createDefaultScale() );
89 rScaleData
.IncrementData
= aDefaultScale
.IncrementData
;
90 rScaleData
.TimeIncrement
= aDefaultScale
.TimeIncrement
;
93 bool AxisHelper::isLogarithmic( const Reference
< XScaling
>& xScaling
)
95 Reference
< lang::XServiceName
> xServiceName( xScaling
, uno::UNO_QUERY
);
96 return xServiceName
.is()
97 && xServiceName
->getServiceName() == "com.sun.star.chart2.LogarithmicScaling";
100 chart2::ScaleData
AxisHelper::getDateCheckedScale( const Reference
< chart2::XAxis
>& xAxis
, ChartModel
& rModel
)
102 ScaleData aScale
= xAxis
->getScaleData();
103 Reference
< chart2::XCoordinateSystem
> xCooSys( ChartModelHelper::getFirstCoordinateSystem( rModel
) );
104 if( aScale
.AutoDateAxis
&& aScale
.AxisType
== AxisType::CATEGORY
)
106 sal_Int32 nDimensionIndex
=0; sal_Int32 nAxisIndex
=0;
107 AxisHelper::getIndicesForAxis(xAxis
, xCooSys
, nDimensionIndex
, nAxisIndex
);
108 bool bChartTypeAllowsDateAxis
= ChartTypeHelper::isSupportingDateAxis( AxisHelper::getChartTypeByIndex( xCooSys
, 0 ), nDimensionIndex
);
109 if( bChartTypeAllowsDateAxis
)
110 aScale
.AxisType
= AxisType::DATE
;
112 if( aScale
.AxisType
== AxisType::DATE
)
114 ExplicitCategoriesProvider
aExplicitCategoriesProvider( xCooSys
, rModel
);
115 if( !aExplicitCategoriesProvider
.isDateAxis() )
116 aScale
.AxisType
= AxisType::CATEGORY
;
121 void AxisHelper::checkDateAxis( chart2::ScaleData
& rScale
, ExplicitCategoriesProvider
* pExplicitCategoriesProvider
, bool bChartTypeAllowsDateAxis
)
123 if( rScale
.AutoDateAxis
&& rScale
.AxisType
== AxisType::CATEGORY
&& bChartTypeAllowsDateAxis
)
125 rScale
.AxisType
= AxisType::DATE
;
126 removeExplicitScaling( rScale
);
128 if( rScale
.AxisType
== AxisType::DATE
&& (!pExplicitCategoriesProvider
|| !pExplicitCategoriesProvider
->isDateAxis()) )
130 rScale
.AxisType
= AxisType::CATEGORY
;
131 removeExplicitScaling( rScale
);
135 sal_Int32
AxisHelper::getExplicitNumberFormatKeyForAxis(
136 const Reference
< chart2::XAxis
>& xAxis
137 , const Reference
< chart2::XCoordinateSystem
> & xCorrespondingCoordinateSystem
138 , const Reference
<chart2::XChartDocument
>& xChartDoc
139 , bool bSearchForParallelAxisIfNothingIsFound
)
141 sal_Int32
nNumberFormatKey(0);
142 sal_Int32 nAxisIndex
= 0;
143 sal_Int32 nDimensionIndex
= 1;
144 AxisHelper::getIndicesForAxis( xAxis
, xCorrespondingCoordinateSystem
, nDimensionIndex
, nAxisIndex
);
145 Reference
<util::XNumberFormatsSupplier
> const xNumberFormatsSupplier(xChartDoc
, uno::UNO_QUERY
);
147 Reference
< beans::XPropertySet
> xProp( xAxis
, uno::UNO_QUERY
);
151 bool bLinkToSource
= true;
152 xProp
->getPropertyValue(CHART_UNONAME_LINK_TO_SRC_NUMFMT
) >>= bLinkToSource
;
153 xProp
->getPropertyValue(CHART_UNONAME_NUMFMT
) >>= nNumberFormatKey
;
157 bool bFormatSet
= false;
158 //check whether we have a percent scale -> use percent format
159 ChartModel
* pModel
= nullptr;
160 if( xNumberFormatsSupplier
.is() )
162 pModel
= dynamic_cast<ChartModel
*>( xChartDoc
.get() );
167 ScaleData aData
= AxisHelper::getDateCheckedScale( xAxis
, *pModel
);
168 if( aData
.AxisType
==AxisType::PERCENT
)
170 sal_Int32 nPercentFormat
= DiagramHelper::getPercentNumberFormat( xNumberFormatsSupplier
);
171 if( nPercentFormat
!= -1 )
173 nNumberFormatKey
= nPercentFormat
;
177 else if( aData
.AxisType
==AxisType::DATE
)
179 if( aData
.Categories
.is() )
181 Reference
< data::XDataSequence
> xSeq( aData
.Categories
->getValues());
182 if( xSeq
.is() && !( xChartDoc
.is() && xChartDoc
->hasInternalDataProvider()) )
183 nNumberFormatKey
= xSeq
->getNumberFormatKeyByIndex( -1 );
185 nNumberFormatKey
= DiagramHelper::getDateNumberFormat( xNumberFormatsSupplier
);
189 else if( xChartDoc
.is() && xChartDoc
->hasInternalDataProvider() && nDimensionIndex
== 0 ) //maybe date axis
191 Reference
< chart2::XDiagram
> xDiagram( xChartDoc
->getFirstDiagram() );
192 if( DiagramHelper::isSupportingDateAxis( xDiagram
) )
194 nNumberFormatKey
= DiagramHelper::getDateNumberFormat( xNumberFormatsSupplier
);
198 Reference
< data::XDataSource
> xSource( DataSourceHelper::getUsedData( xChartDoc
) );
201 std::vector
< Reference
< chart2::data::XLabeledDataSequence
> > aXValues(
202 DataSeriesHelper::getAllDataSequencesByRole( xSource
->getDataSequences(), "values-x" ) );
203 if( aXValues
.empty() )
205 Reference
< data::XLabeledDataSequence
> xCategories( DiagramHelper::getCategoriesFromDiagram( xDiagram
) );
206 if( xCategories
.is() )
208 Reference
< data::XDataSequence
> xSeq( xCategories
->getValues());
211 bool bHasValidDoubles
= false;
213 Sequence
< uno::Any
> aCats( xSeq
->getData() );
214 sal_Int32 nCount
= aCats
.getLength();
215 for( sal_Int32 i
= 0; i
< nCount
; ++i
)
217 if( (aCats
[i
]>>=fTest
) && !::rtl::math::isNan(fTest
) )
219 bHasValidDoubles
=true;
223 if( bHasValidDoubles
)
224 nNumberFormatKey
= DiagramHelper::getDateNumberFormat( xNumberFormatsSupplier
);
236 typedef std::map
< sal_Int32
, sal_Int32
> tNumberformatFrequency
;
237 tNumberformatFrequency aKeyMap
;
238 bool bNumberFormatKeyFoundViaAttachedData
= false;
242 Reference
< XChartTypeContainer
> xCTCnt( xCorrespondingCoordinateSystem
, uno::UNO_QUERY_THROW
);
243 OUString aRoleToMatch
;
244 if( nDimensionIndex
== 0 )
245 aRoleToMatch
= "values-x";
246 Sequence
< Reference
< XChartType
> > aChartTypes( xCTCnt
->getChartTypes());
247 for( sal_Int32 nCTIdx
=0; nCTIdx
<aChartTypes
.getLength(); ++nCTIdx
)
249 if( nDimensionIndex
!= 0 )
250 aRoleToMatch
= ChartTypeHelper::getRoleOfSequenceForYAxisNumberFormatDetection( aChartTypes
[nCTIdx
] );
251 Reference
< XDataSeriesContainer
> xDSCnt( aChartTypes
[nCTIdx
], uno::UNO_QUERY_THROW
);
252 Sequence
< Reference
< XDataSeries
> > aDataSeriesSeq( xDSCnt
->getDataSeries());
253 for( sal_Int32 nSeriesIdx
=0; nSeriesIdx
<aDataSeriesSeq
.getLength(); ++nSeriesIdx
)
255 Reference
< chart2::XDataSeries
> xDataSeries(aDataSeriesSeq
[nSeriesIdx
]);
256 Reference
< data::XDataSource
> xSource( xDataSeries
, uno::UNO_QUERY_THROW
);
258 if( nDimensionIndex
== 1 )
260 //only take those series into account that are attached to this axis
261 sal_Int32 nAttachedAxisIndex
= DataSeriesHelper::getAttachedAxisIndex(xDataSeries
);
262 if( nAttachedAxisIndex
!= nAxisIndex
)
266 Reference
< data::XLabeledDataSequence
> xLabeledSeq(
267 DataSeriesHelper::getDataSequenceByRole( xSource
, aRoleToMatch
) );
269 if( !xLabeledSeq
.is() && nDimensionIndex
==0 )
271 ScaleData aData
= xAxis
->getScaleData();
272 xLabeledSeq
= aData
.Categories
;
275 if( xLabeledSeq
.is() )
277 Reference
< data::XDataSequence
> xSeq( xLabeledSeq
->getValues());
280 sal_Int32 nKey
= xSeq
->getNumberFormatKeyByIndex( -1 );
281 // initialize the value
282 if( aKeyMap
.find( nKey
) == aKeyMap
.end())
284 // increase frequency
285 aKeyMap
[ nKey
] = (aKeyMap
[ nKey
] + 1);
291 catch( const uno::Exception
& )
293 DBG_UNHANDLED_EXCEPTION("chart2");
296 if( ! aKeyMap
.empty())
298 sal_Int32 nMaxFreq
= 0;
299 // find most frequent key
300 for (auto const& elem
: aKeyMap
)
304 "NumberFormatKey " << elem
.first
<< " appears "
305 << elem
.second
<< " times");
306 // all values must at least be 1
307 if( elem
.second
> nMaxFreq
)
309 nNumberFormatKey
= elem
.first
;
310 bNumberFormatKeyFoundViaAttachedData
= true;
311 nMaxFreq
= elem
.second
;
316 if( bSearchForParallelAxisIfNothingIsFound
)
318 //no format is set to this axis and no data is set to this axis
319 //--> try to obtain the format from the parallel y-axis
320 if( !bNumberFormatKeyFoundViaAttachedData
&& nDimensionIndex
== 1 )
322 sal_Int32 nParallelAxisIndex
= (nAxisIndex
==1) ?0 :1;
323 Reference
< XAxis
> xParallelAxis( AxisHelper::getAxis( 1, nParallelAxisIndex
, xCorrespondingCoordinateSystem
) );
324 nNumberFormatKey
= AxisHelper::getExplicitNumberFormatKeyForAxis(xParallelAxis
, xCorrespondingCoordinateSystem
, xChartDoc
, false);
330 return nNumberFormatKey
;
333 Reference
< XAxis
> AxisHelper::createAxis(
334 sal_Int32 nDimensionIndex
335 , sal_Int32 nAxisIndex
// 0==main or 1==secondary axis
336 , const Reference
< XCoordinateSystem
>& xCooSys
337 , const Reference
< uno::XComponentContext
> & xContext
338 , ReferenceSizeProvider
* pRefSizeProvider
)
340 if( !xContext
.is() || !xCooSys
.is() )
342 if( nDimensionIndex
>= xCooSys
->getDimension() )
345 Reference
< XAxis
> xAxis( xContext
->getServiceManager()->createInstanceWithContext(
346 "com.sun.star.chart2.Axis", xContext
), uno::UNO_QUERY
);
348 OSL_ASSERT( xAxis
.is());
351 xCooSys
->setAxisByDimension( nDimensionIndex
, xAxis
, nAxisIndex
);
353 if( nAxisIndex
>0 )//when inserting secondary axes copy some things from the main axis
355 css::chart::ChartAxisPosition
eNewAxisPos( css::chart::ChartAxisPosition_END
);
357 Reference
< XAxis
> xMainAxis( xCooSys
->getAxisByDimension( nDimensionIndex
, 0 ) );
360 ScaleData aScale
= xAxis
->getScaleData();
361 ScaleData aMainScale
= xMainAxis
->getScaleData();
363 aScale
.AxisType
= aMainScale
.AxisType
;
364 aScale
.AutoDateAxis
= aMainScale
.AutoDateAxis
;
365 aScale
.Categories
= aMainScale
.Categories
;
366 aScale
.Orientation
= aMainScale
.Orientation
;
368 xAxis
->setScaleData( aScale
);
370 //ensure that the second axis is not placed on the main axis
371 Reference
< beans::XPropertySet
> xMainProp( xMainAxis
, uno::UNO_QUERY
);
374 css::chart::ChartAxisPosition
eMainAxisPos( css::chart::ChartAxisPosition_ZERO
);
375 xMainProp
->getPropertyValue("CrossoverPosition") >>= eMainAxisPos
;
376 if( eMainAxisPos
== css::chart::ChartAxisPosition_END
)
377 eNewAxisPos
= css::chart::ChartAxisPosition_START
;
381 Reference
< beans::XPropertySet
> xProp( xAxis
, uno::UNO_QUERY
);
383 xProp
->setPropertyValue("CrossoverPosition", uno::Any(eNewAxisPos
) );
386 Reference
< beans::XPropertySet
> xProp( xAxis
, uno::UNO_QUERY
);
389 // set correct initial AutoScale
390 if( pRefSizeProvider
)
391 pRefSizeProvider
->setValuesAtPropertySet( xProp
);
393 catch( const uno::Exception
& )
395 TOOLS_WARN_EXCEPTION("chart2", "" );
401 Reference
< XAxis
> AxisHelper::createAxis( sal_Int32 nDimensionIndex
, bool bMainAxis
402 , const Reference
< chart2::XDiagram
>& xDiagram
403 , const Reference
< uno::XComponentContext
>& xContext
404 , ReferenceSizeProvider
* pRefSizeProvider
)
406 OSL_ENSURE( xContext
.is(), "need a context to create an axis" );
410 sal_Int32 nAxisIndex
= bMainAxis
? MAIN_AXIS_INDEX
: SECONDARY_AXIS_INDEX
;
411 Reference
< XCoordinateSystem
> xCooSys
= AxisHelper::getCoordinateSystemByIndex( xDiagram
, 0 );
414 return AxisHelper::createAxis(
415 nDimensionIndex
, nAxisIndex
, xCooSys
, xContext
, pRefSizeProvider
);
418 void AxisHelper::showAxis( sal_Int32 nDimensionIndex
, bool bMainAxis
419 , const Reference
< chart2::XDiagram
>& xDiagram
420 , const Reference
< uno::XComponentContext
>& xContext
421 , ReferenceSizeProvider
* pRefSizeProvider
)
426 bool bNewAxisCreated
= false;
427 Reference
< XAxis
> xAxis( AxisHelper::getAxis( nDimensionIndex
, bMainAxis
, xDiagram
) );
428 if( !xAxis
.is() && xContext
.is() )
431 bNewAxisCreated
= true;
432 xAxis
.set( AxisHelper::createAxis( nDimensionIndex
, bMainAxis
, xDiagram
, xContext
, pRefSizeProvider
) );
435 OSL_ASSERT( xAxis
.is());
436 if( !bNewAxisCreated
) //default is true already if created
437 AxisHelper::makeAxisVisible( xAxis
);
440 void AxisHelper::showGrid( sal_Int32 nDimensionIndex
, sal_Int32 nCooSysIndex
, bool bMainGrid
441 , const Reference
< XDiagram
>& xDiagram
)
446 Reference
< XCoordinateSystem
> xCooSys
= AxisHelper::getCoordinateSystemByIndex( xDiagram
, nCooSysIndex
);
450 Reference
< XAxis
> xAxis( AxisHelper::getAxis( nDimensionIndex
, MAIN_AXIS_INDEX
, xCooSys
) );
453 //hhhh todo create axis without axis visibility
459 AxisHelper::makeGridVisible( xAxis
->getGridProperties() );
462 Sequence
< Reference
< beans::XPropertySet
> > aSubGrids( xAxis
->getSubGridProperties() );
463 for( sal_Int32 nN
=0; nN
<aSubGrids
.getLength(); nN
++)
464 AxisHelper::makeGridVisible( aSubGrids
[nN
] );
468 void AxisHelper::makeAxisVisible( const Reference
< XAxis
>& xAxis
)
470 Reference
< beans::XPropertySet
> xProps( xAxis
, uno::UNO_QUERY
);
473 xProps
->setPropertyValue( "Show", uno::Any( true ) );
474 LinePropertiesHelper::SetLineVisible( xProps
);
475 xProps
->setPropertyValue( "DisplayLabels", uno::Any( true ) );
479 void AxisHelper::makeGridVisible( const Reference
< beans::XPropertySet
>& xGridProperties
)
481 if( xGridProperties
.is() )
483 xGridProperties
->setPropertyValue( "Show", uno::Any( true ) );
484 LinePropertiesHelper::SetLineVisible( xGridProperties
);
488 void AxisHelper::hideAxis( sal_Int32 nDimensionIndex
, bool bMainAxis
489 , const Reference
< XDiagram
>& xDiagram
)
491 AxisHelper::makeAxisInvisible( AxisHelper::getAxis( nDimensionIndex
, bMainAxis
, xDiagram
) );
494 void AxisHelper::makeAxisInvisible( const Reference
< XAxis
>& xAxis
)
496 Reference
< beans::XPropertySet
> xProps( xAxis
, uno::UNO_QUERY
);
499 xProps
->setPropertyValue( "Show", uno::Any( false ) );
503 void AxisHelper::hideAxisIfNoDataIsAttached( const Reference
< XAxis
>& xAxis
, const Reference
< XDiagram
>& xDiagram
)
505 //axis is hidden if no data is attached anymore but data is available
506 bool bOtherSeriesAttachedToThisAxis
= false;
507 std::vector
< Reference
< chart2::XDataSeries
> > aSeriesVector( DiagramHelper::getDataSeriesFromDiagram( xDiagram
) );
508 for (auto const& series
: aSeriesVector
)
510 uno::Reference
< chart2::XAxis
> xCurrentAxis
= DiagramHelper::getAttachedAxis(series
, xDiagram
);
511 if( xCurrentAxis
==xAxis
)
513 bOtherSeriesAttachedToThisAxis
= true;
517 if(!bOtherSeriesAttachedToThisAxis
&& !aSeriesVector
.empty() )
518 AxisHelper::makeAxisInvisible( xAxis
);
521 void AxisHelper::hideGrid( sal_Int32 nDimensionIndex
, sal_Int32 nCooSysIndex
, bool bMainGrid
522 , const Reference
< XDiagram
>& xDiagram
)
527 Reference
< XCoordinateSystem
> xCooSys
= AxisHelper::getCoordinateSystemByIndex( xDiagram
, nCooSysIndex
);
531 Reference
< XAxis
> xAxis( AxisHelper::getAxis( nDimensionIndex
, MAIN_AXIS_INDEX
, xCooSys
) );
536 AxisHelper::makeGridInvisible( xAxis
->getGridProperties() );
539 Sequence
< Reference
< beans::XPropertySet
> > aSubGrids( xAxis
->getSubGridProperties() );
540 for( sal_Int32 nN
=0; nN
<aSubGrids
.getLength(); nN
++)
541 AxisHelper::makeGridInvisible( aSubGrids
[nN
] );
545 void AxisHelper::makeGridInvisible( const Reference
< beans::XPropertySet
>& xGridProperties
)
547 if( xGridProperties
.is() )
549 xGridProperties
->setPropertyValue( "Show", uno::Any( false ) );
553 bool AxisHelper::isGridShown( sal_Int32 nDimensionIndex
, sal_Int32 nCooSysIndex
, bool bMainGrid
554 , const Reference
< css::chart2::XDiagram
>& xDiagram
)
558 Reference
< XCoordinateSystem
> xCooSys
= AxisHelper::getCoordinateSystemByIndex( xDiagram
, nCooSysIndex
);
562 Reference
< XAxis
> xAxis( AxisHelper::getAxis( nDimensionIndex
, MAIN_AXIS_INDEX
, xCooSys
) );
567 bRet
= AxisHelper::isGridVisible( xAxis
->getGridProperties() );
570 Sequence
< Reference
< beans::XPropertySet
> > aSubGrids( xAxis
->getSubGridProperties() );
571 if( aSubGrids
.hasElements() )
572 bRet
= AxisHelper::isGridVisible( aSubGrids
[0] );
578 Reference
< XCoordinateSystem
> AxisHelper::getCoordinateSystemByIndex(
579 const Reference
< XDiagram
>& xDiagram
, sal_Int32 nIndex
)
581 Reference
< XCoordinateSystemContainer
> xCooSysContainer( xDiagram
, uno::UNO_QUERY
);
582 if(!xCooSysContainer
.is())
584 Sequence
< Reference
< XCoordinateSystem
> > aCooSysList
= xCooSysContainer
->getCoordinateSystems();
585 if(0<=nIndex
&& nIndex
<aCooSysList
.getLength())
586 return aCooSysList
[nIndex
];
590 Reference
< XAxis
> AxisHelper::getAxis( sal_Int32 nDimensionIndex
, bool bMainAxis
591 , const Reference
< XDiagram
>& xDiagram
)
593 Reference
< XAxis
> xRet
;
596 Reference
< XCoordinateSystem
> xCooSys
= AxisHelper::getCoordinateSystemByIndex( xDiagram
, 0 );
597 xRet
.set( AxisHelper::getAxis( nDimensionIndex
, bMainAxis
? 0 : 1, xCooSys
) );
599 catch( const uno::Exception
& )
605 Reference
< XAxis
> AxisHelper::getAxis( sal_Int32 nDimensionIndex
, sal_Int32 nAxisIndex
606 , const Reference
< XCoordinateSystem
>& xCooSys
)
608 Reference
< XAxis
> xRet
;
612 if(nDimensionIndex
>= xCooSys
->getDimension())
615 if(nAxisIndex
> xCooSys
->getMaximumAxisIndexByDimension(nDimensionIndex
))
618 assert(nAxisIndex
>= 0);
619 assert(nDimensionIndex
>= 0);
620 xRet
.set( xCooSys
->getAxisByDimension( nDimensionIndex
, nAxisIndex
) );
624 Reference
< XAxis
> AxisHelper::getCrossingMainAxis( const Reference
< XAxis
>& xAxis
625 , const Reference
< XCoordinateSystem
>& xCooSys
)
627 sal_Int32 nDimensionIndex
= 0;
628 sal_Int32 nAxisIndex
= 0;
629 AxisHelper::getIndicesForAxis( xAxis
, xCooSys
, nDimensionIndex
, nAxisIndex
);
630 if( nDimensionIndex
==2 )
633 bool bSwapXY
= false;
634 Reference
< beans::XPropertySet
> xCooSysProp( xCooSys
, uno::UNO_QUERY
);
635 if( xCooSysProp
.is() && (xCooSysProp
->getPropertyValue( "SwapXAndYAxis" ) >>= bSwapXY
) && bSwapXY
)
638 else if( nDimensionIndex
==1 )
642 return AxisHelper::getAxis( nDimensionIndex
, 0, xCooSys
);
645 Reference
< XAxis
> AxisHelper::getParallelAxis( const Reference
< XAxis
>& xAxis
646 , const Reference
< XDiagram
>& xDiagram
)
650 sal_Int32 nCooSysIndex
=-1;
651 sal_Int32 nDimensionIndex
=-1;
652 sal_Int32 nAxisIndex
=-1;
653 if( getIndicesForAxis( xAxis
, xDiagram
, nCooSysIndex
, nDimensionIndex
, nAxisIndex
) )
655 sal_Int32 nParallelAxisIndex
= (nAxisIndex
==1) ?0 :1;
656 return getAxis( nDimensionIndex
, nParallelAxisIndex
, getCoordinateSystemByIndex( xDiagram
, nCooSysIndex
) );
659 catch( const uno::RuntimeException
& )
665 bool AxisHelper::isAxisShown( sal_Int32 nDimensionIndex
, bool bMainAxis
666 , const Reference
< XDiagram
>& xDiagram
)
668 return AxisHelper::isAxisVisible( AxisHelper::getAxis( nDimensionIndex
, bMainAxis
, xDiagram
) );
671 bool AxisHelper::isAxisVisible( const Reference
< XAxis
>& xAxis
)
675 Reference
< beans::XPropertySet
> xProps( xAxis
, uno::UNO_QUERY
);
678 xProps
->getPropertyValue( "Show" ) >>= bRet
;
679 bRet
= bRet
&& ( LinePropertiesHelper::IsLineVisible( xProps
)
680 || areAxisLabelsVisible( xProps
) );
686 bool AxisHelper::areAxisLabelsVisible( const Reference
< beans::XPropertySet
>& xAxisProperties
)
689 if( xAxisProperties
.is() )
691 xAxisProperties
->getPropertyValue( "DisplayLabels" ) >>= bRet
;
696 bool AxisHelper::isGridVisible( const Reference
< beans::XPropertySet
>& xGridProperies
)
700 if( xGridProperies
.is() )
702 xGridProperies
->getPropertyValue( "Show" ) >>= bRet
;
703 bRet
= bRet
&& LinePropertiesHelper::IsLineVisible( xGridProperies
);
709 Reference
< beans::XPropertySet
> AxisHelper::getGridProperties(
710 const Reference
< XCoordinateSystem
>& xCooSys
711 , sal_Int32 nDimensionIndex
, sal_Int32 nAxisIndex
, sal_Int32 nSubGridIndex
)
713 Reference
< beans::XPropertySet
> xRet
;
715 Reference
< XAxis
> xAxis( AxisHelper::getAxis( nDimensionIndex
, nAxisIndex
, xCooSys
) );
718 if( nSubGridIndex
<0 )
719 xRet
.set( xAxis
->getGridProperties() );
722 Sequence
< Reference
< beans::XPropertySet
> > aSubGrids( xAxis
->getSubGridProperties() );
723 if (nSubGridIndex
< aSubGrids
.getLength())
724 xRet
.set( aSubGrids
[nSubGridIndex
] );
731 sal_Int32
AxisHelper::getDimensionIndexOfAxis(
732 const Reference
< XAxis
>& xAxis
733 , const Reference
< XDiagram
>& xDiagram
)
735 sal_Int32 nDimensionIndex
= -1;
736 sal_Int32 nCooSysIndex
= -1;
737 sal_Int32 nAxisIndex
= -1;
738 AxisHelper::getIndicesForAxis( xAxis
, xDiagram
, nCooSysIndex
, nDimensionIndex
, nAxisIndex
);
739 return nDimensionIndex
;
742 bool AxisHelper::getIndicesForAxis(
743 const Reference
< XAxis
>& xAxis
744 , const Reference
< XCoordinateSystem
>& xCooSys
745 , sal_Int32
& rOutDimensionIndex
, sal_Int32
& rOutAxisIndex
)
747 //returns true if indices are found
749 rOutDimensionIndex
= -1;
752 if( xCooSys
.is() && xAxis
.is() )
754 Reference
< XAxis
> xCurrentAxis
;
755 sal_Int32
nDimensionCount( xCooSys
->getDimension() );
756 for( sal_Int32 nDimensionIndex
= 0; nDimensionIndex
< nDimensionCount
; nDimensionIndex
++ )
758 sal_Int32 nMaxAxisIndex
= xCooSys
->getMaximumAxisIndexByDimension(nDimensionIndex
);
759 for( sal_Int32 nAxisIndex
= 0; nAxisIndex
<= nMaxAxisIndex
; nAxisIndex
++ )
761 xCurrentAxis
= xCooSys
->getAxisByDimension(nDimensionIndex
,nAxisIndex
);
762 if( xCurrentAxis
== xAxis
)
764 rOutDimensionIndex
= nDimensionIndex
;
765 rOutAxisIndex
= nAxisIndex
;
774 bool AxisHelper::getIndicesForAxis( const Reference
< XAxis
>& xAxis
, const Reference
< XDiagram
>& xDiagram
775 , sal_Int32
& rOutCooSysIndex
, sal_Int32
& rOutDimensionIndex
, sal_Int32
& rOutAxisIndex
)
777 //returns true if indices are found
779 rOutCooSysIndex
= -1;
780 rOutDimensionIndex
= -1;
783 Reference
< XCoordinateSystemContainer
> xCooSysContainer( xDiagram
, uno::UNO_QUERY
);
784 if(xCooSysContainer
.is())
786 Sequence
< Reference
< XCoordinateSystem
> > aCooSysList
= xCooSysContainer
->getCoordinateSystems();
787 for( sal_Int32 nC
=0; nC
<aCooSysList
.getLength(); ++nC
)
789 if( AxisHelper::getIndicesForAxis( xAxis
, aCooSysList
[nC
], rOutDimensionIndex
, rOutAxisIndex
) )
791 rOutCooSysIndex
= nC
;
800 std::vector
< Reference
< XAxis
> > AxisHelper::getAllAxesOfCoordinateSystem(
801 const Reference
< XCoordinateSystem
>& xCooSys
802 , bool bOnlyVisible
/* = false */ )
804 std::vector
< Reference
< XAxis
> > aAxisVector
;
808 sal_Int32 nMaxDimensionIndex
= xCooSys
->getDimension() -1;
809 if( nMaxDimensionIndex
>=0 )
811 sal_Int32 nDimensionIndex
= 0;
812 for(; nDimensionIndex
<=nMaxDimensionIndex
; ++nDimensionIndex
)
814 const sal_Int32 nMaximumAxisIndex
= xCooSys
->getMaximumAxisIndexByDimension(nDimensionIndex
);
815 for(sal_Int32 nAxisIndex
=0; nAxisIndex
<=nMaximumAxisIndex
; ++nAxisIndex
)
819 Reference
< XAxis
> xAxis( xCooSys
->getAxisByDimension( nDimensionIndex
, nAxisIndex
) );
822 bool bAddAxis
= true;
825 Reference
< beans::XPropertySet
> xAxisProp( xAxis
, uno::UNO_QUERY
);
826 if( !xAxisProp
.is() ||
827 !(xAxisProp
->getPropertyValue( "Show") >>= bAddAxis
) )
831 aAxisVector
.push_back( xAxis
);
834 catch( const uno::Exception
& )
836 DBG_UNHANDLED_EXCEPTION("chart2");
846 Sequence
< Reference
< XAxis
> > AxisHelper::getAllAxesOfDiagram(
847 const Reference
< XDiagram
>& xDiagram
848 , bool bOnlyVisible
)
850 std::vector
< Reference
< XAxis
> > aAxisVector
;
852 Reference
< XCoordinateSystemContainer
> xCooSysContainer( xDiagram
, uno::UNO_QUERY
);
853 if(xCooSysContainer
.is())
855 Sequence
< Reference
< XCoordinateSystem
> > aCooSysList
= xCooSysContainer
->getCoordinateSystems();
857 for( nC
=0; nC
<aCooSysList
.getLength(); ++nC
)
859 std::vector
< Reference
< XAxis
> > aAxesPerCooSys( AxisHelper::getAllAxesOfCoordinateSystem( aCooSysList
[nC
], bOnlyVisible
) );
860 aAxisVector
.insert( aAxisVector
.end(), aAxesPerCooSys
.begin(), aAxesPerCooSys
.end() );
864 return comphelper::containerToSequence( aAxisVector
);
867 Sequence
< Reference
< beans::XPropertySet
> > AxisHelper::getAllGrids( const Reference
< XDiagram
>& xDiagram
)
869 Sequence
< Reference
< XAxis
> > aAllAxes( AxisHelper::getAllAxesOfDiagram( xDiagram
) );
870 std::vector
< Reference
< beans::XPropertySet
> > aGridVector
;
873 for( nA
=0; nA
<aAllAxes
.getLength(); ++nA
)
875 Reference
< XAxis
> xAxis( aAllAxes
[nA
] );
878 Reference
< beans::XPropertySet
> xGridProperties( xAxis
->getGridProperties() );
879 if( xGridProperties
.is() )
880 aGridVector
.push_back( xGridProperties
);
882 Sequence
< Reference
< beans::XPropertySet
> > aSubGrids( xAxis
->getSubGridProperties() );
883 sal_Int32 nSubGrid
= 0;
884 for( nSubGrid
= 0; nSubGrid
< aSubGrids
.getLength(); ++nSubGrid
)
886 Reference
< beans::XPropertySet
> xSubGrid( aSubGrids
[nSubGrid
] );
888 aGridVector
.push_back( xSubGrid
);
892 return comphelper::containerToSequence( aGridVector
);
895 void AxisHelper::getAxisOrGridPossibilities( Sequence
< sal_Bool
>& rPossibilityList
896 , const Reference
< XDiagram
>& xDiagram
, bool bAxis
)
898 rPossibilityList
.realloc(6);
900 sal_Int32 nDimensionCount
= DiagramHelper::getDimension( xDiagram
);
904 Reference
< XChartType
> xChartType
= DiagramHelper::getChartTypeByIndex( xDiagram
, 0 );
905 for(nIndex
=0;nIndex
<3;nIndex
++)
906 rPossibilityList
[nIndex
]=ChartTypeHelper::isSupportingMainAxis(xChartType
,nDimensionCount
,nIndex
);
907 for(nIndex
=3;nIndex
<6;nIndex
++)
909 rPossibilityList
[nIndex
]=ChartTypeHelper::isSupportingSecondaryAxis(xChartType
,nDimensionCount
);
911 rPossibilityList
[nIndex
] = rPossibilityList
[nIndex
-3];
914 bool AxisHelper::isSecondaryYAxisNeeded( const Reference
< XCoordinateSystem
>& xCooSys
)
916 Reference
< chart2::XChartTypeContainer
> xCTCnt( xCooSys
, uno::UNO_QUERY
);
919 Sequence
< Reference
< chart2::XChartType
> > aChartTypes( xCTCnt
->getChartTypes() );
920 for( sal_Int32 i
=0; i
<aChartTypes
.getLength(); ++i
)
922 Reference
< XDataSeriesContainer
> xSeriesContainer( aChartTypes
[i
] , uno::UNO_QUERY
);
923 if( !xSeriesContainer
.is() )
926 Sequence
< Reference
< XDataSeries
> > aSeriesList( xSeriesContainer
->getDataSeries() );
927 for( sal_Int32 nS
= aSeriesList
.getLength(); nS
-- ; )
929 Reference
< beans::XPropertySet
> xProp( aSeriesList
[nS
], uno::UNO_QUERY
);
932 sal_Int32 nAttachedAxisIndex
= 0;
933 if( ( xProp
->getPropertyValue( "AttachedAxisIndex" ) >>= nAttachedAxisIndex
) && nAttachedAxisIndex
>0 )
942 bool AxisHelper::shouldAxisBeDisplayed( const Reference
< XAxis
>& xAxis
943 , const Reference
< XCoordinateSystem
>& xCooSys
)
947 if( xAxis
.is() && xCooSys
.is() )
949 sal_Int32 nDimensionIndex
=-1;
950 sal_Int32 nAxisIndex
=-1;
951 if( AxisHelper::getIndicesForAxis( xAxis
, xCooSys
, nDimensionIndex
, nAxisIndex
) )
953 sal_Int32 nDimensionCount
= xCooSys
->getDimension();
954 Reference
< XChartType
> xChartType( AxisHelper::getChartTypeByIndex( xCooSys
, 0 ) );
956 bool bMainAxis
= (nAxisIndex
==MAIN_AXIS_INDEX
);
958 bRet
= ChartTypeHelper::isSupportingMainAxis(xChartType
,nDimensionCount
,nDimensionIndex
);
960 bRet
= ChartTypeHelper::isSupportingSecondaryAxis(xChartType
,nDimensionCount
);
967 void AxisHelper::getAxisOrGridExcistence( Sequence
< sal_Bool
>& rExistenceList
968 , const Reference
< XDiagram
>& xDiagram
, bool bAxis
)
970 rExistenceList
.realloc(6);
976 rExistenceList
[nN
] = AxisHelper::isAxisShown( nN
, true, xDiagram
);
978 rExistenceList
[nN
] = AxisHelper::isAxisShown( nN
%3, false, xDiagram
);
985 rExistenceList
[nN
] = AxisHelper::isGridShown( nN
, 0, true, xDiagram
);
987 rExistenceList
[nN
] = AxisHelper::isGridShown( nN
%3, 0, false, xDiagram
);
991 bool AxisHelper::changeVisibilityOfAxes( const Reference
< XDiagram
>& xDiagram
992 , const Sequence
< sal_Bool
>& rOldExistenceList
993 , const Sequence
< sal_Bool
>& rNewExistenceList
994 , const Reference
< uno::XComponentContext
>& xContext
995 , ReferenceSizeProvider
* pRefSizeProvider
)
997 bool bChanged
= false;
998 for(sal_Int32 nN
=0;nN
<6;nN
++)
1000 if(rOldExistenceList
[nN
]!=rNewExistenceList
[nN
])
1003 if(rNewExistenceList
[nN
])
1005 AxisHelper::showAxis( nN
%3, nN
<3, xDiagram
, xContext
, pRefSizeProvider
);
1008 AxisHelper::hideAxis( nN
%3, nN
<3, xDiagram
);
1014 bool AxisHelper::changeVisibilityOfGrids( const Reference
< XDiagram
>& xDiagram
1015 , const Sequence
< sal_Bool
>& rOldExistenceList
1016 , const Sequence
< sal_Bool
>& rNewExistenceList
)
1018 bool bChanged
= false;
1019 for(sal_Int32 nN
=0;nN
<6;nN
++)
1021 if(rOldExistenceList
[nN
]!=rNewExistenceList
[nN
])
1024 if(rNewExistenceList
[nN
])
1025 AxisHelper::showGrid( nN
%3, 0, nN
<3, xDiagram
);
1027 AxisHelper::hideGrid( nN
%3, 0, nN
<3, xDiagram
);
1033 Reference
< XCoordinateSystem
> AxisHelper::getCoordinateSystemOfAxis(
1034 const Reference
< XAxis
>& xAxis
1035 , const Reference
< XDiagram
>& xDiagram
)
1037 Reference
< XCoordinateSystem
> xRet
;
1039 Reference
< XCoordinateSystemContainer
> xCooSysContainer( xDiagram
, uno::UNO_QUERY
);
1040 if( xCooSysContainer
.is() )
1042 Reference
< XCoordinateSystem
> xCooSys
;
1043 Sequence
< Reference
< XCoordinateSystem
> > aCooSysList( xCooSysContainer
->getCoordinateSystems() );
1044 for( sal_Int32 nCooSysIndex
= 0; nCooSysIndex
< aCooSysList
.getLength(); ++nCooSysIndex
)
1046 xCooSys
= aCooSysList
[nCooSysIndex
];
1047 std::vector
< Reference
< XAxis
> > aAllAxis( AxisHelper::getAllAxesOfCoordinateSystem( xCooSys
) );
1049 std::vector
< Reference
< XAxis
> >::iterator aFound
=
1050 std::find( aAllAxis
.begin(), aAllAxis
.end(), xAxis
);
1051 if( aFound
!= aAllAxis
.end())
1053 xRet
.set( xCooSys
);
1061 Reference
< XChartType
> AxisHelper::getChartTypeByIndex( const Reference
< XCoordinateSystem
>& xCooSys
, sal_Int32 nIndex
)
1063 Reference
< XChartType
> xChartType
;
1065 Reference
< XChartTypeContainer
> xChartTypeContainer( xCooSys
, uno::UNO_QUERY
);
1066 if( xChartTypeContainer
.is() )
1068 Sequence
< Reference
< XChartType
> > aChartTypeList( xChartTypeContainer
->getChartTypes() );
1069 if( nIndex
>= 0 && nIndex
< aChartTypeList
.getLength() )
1070 xChartType
.set( aChartTypeList
[nIndex
] );
1076 void AxisHelper::setRTLAxisLayout( const Reference
< XCoordinateSystem
>& xCooSys
)
1080 bool bCartesian
= xCooSys
->getViewServiceName() == CHART2_COOSYSTEM_CARTESIAN_VIEW_SERVICE_NAME
;
1083 bool bVertical
= false;
1084 Reference
< beans::XPropertySet
> xCooSysProp( xCooSys
, uno::UNO_QUERY
);
1085 if( xCooSysProp
.is() )
1086 xCooSysProp
->getPropertyValue( "SwapXAndYAxis" ) >>= bVertical
;
1088 sal_Int32 nHorizontalAxisDimension
= bVertical
? 1 : 0;
1089 sal_Int32 nVerticalAxisDimension
= bVertical
? 0 : 1;
1093 //reverse direction for horizontal main axis
1094 Reference
< chart2::XAxis
> xHorizontalMainAxis( AxisHelper::getAxis( nHorizontalAxisDimension
, MAIN_AXIS_INDEX
, xCooSys
) );
1095 if( xHorizontalMainAxis
.is() )
1097 chart2::ScaleData aScale
= xHorizontalMainAxis
->getScaleData();
1098 aScale
.Orientation
= chart2::AxisOrientation_REVERSE
;
1099 xHorizontalMainAxis
->setScaleData(aScale
);
1102 //mathematical direction for vertical main axis
1103 Reference
< chart2::XAxis
> xVerticalMainAxis( AxisHelper::getAxis( nVerticalAxisDimension
, MAIN_AXIS_INDEX
, xCooSys
) );
1104 if( xVerticalMainAxis
.is() )
1106 chart2::ScaleData aScale
= xVerticalMainAxis
->getScaleData();
1107 aScale
.Orientation
= chart2::AxisOrientation_MATHEMATICAL
;
1108 xVerticalMainAxis
->setScaleData(aScale
);
1111 catch( const uno::Exception
& )
1113 DBG_UNHANDLED_EXCEPTION("chart2" );
1118 //reverse direction for horizontal secondary axis
1119 Reference
< chart2::XAxis
> xHorizontalSecondaryAxis( AxisHelper::getAxis( nHorizontalAxisDimension
, SECONDARY_AXIS_INDEX
, xCooSys
) );
1120 if( xHorizontalSecondaryAxis
.is() )
1122 chart2::ScaleData aScale
= xHorizontalSecondaryAxis
->getScaleData();
1123 aScale
.Orientation
= chart2::AxisOrientation_REVERSE
;
1124 xHorizontalSecondaryAxis
->setScaleData(aScale
);
1127 //mathematical direction for vertical secondary axis
1128 Reference
< chart2::XAxis
> xVerticalSecondaryAxis( AxisHelper::getAxis( nVerticalAxisDimension
, SECONDARY_AXIS_INDEX
, xCooSys
) );
1129 if( xVerticalSecondaryAxis
.is() )
1131 chart2::ScaleData aScale
= xVerticalSecondaryAxis
->getScaleData();
1132 aScale
.Orientation
= chart2::AxisOrientation_MATHEMATICAL
;
1133 xVerticalSecondaryAxis
->setScaleData(aScale
);
1136 catch( const uno::Exception
& )
1138 DBG_UNHANDLED_EXCEPTION("chart2");
1144 Reference
< XChartType
> AxisHelper::getFirstChartTypeWithSeriesAttachedToAxisIndex( const Reference
< chart2::XDiagram
>& xDiagram
, const sal_Int32 nAttachedAxisIndex
)
1146 Reference
< XChartType
> xChartType
;
1147 std::vector
< Reference
< XDataSeries
> > aSeriesVector( DiagramHelper::getDataSeriesFromDiagram( xDiagram
) );
1148 for (auto const& series
: aSeriesVector
)
1150 sal_Int32 nCurrentIndex
= DataSeriesHelper::getAttachedAxisIndex(series
);
1151 if( nAttachedAxisIndex
== nCurrentIndex
)
1153 xChartType
= DiagramHelper::getChartTypeOfSeries(xDiagram
, series
);
1161 bool AxisHelper::isAxisPositioningEnabled()
1163 const SvtSaveOptions::ODFSaneDefaultVersion
nCurrentVersion(SvtSaveOptions().GetODFSaneDefaultVersion());
1164 return nCurrentVersion
>= SvtSaveOptions::ODFSVER_012
;
1169 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */