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 <Diagram.hxx>
23 #include <ChartTypeHelper.hxx>
24 #include <ChartType.hxx>
26 #include <AxisIndexDefines.hxx>
27 #include <DataSource.hxx>
28 #include <LinePropertiesHelper.hxx>
29 #include <servicenames_coosystems.hxx>
30 #include <DataSeries.hxx>
31 #include <DataSeriesHelper.hxx>
32 #include <Scaling.hxx>
33 #include <ChartModel.hxx>
34 #include <ChartModelHelper.hxx>
35 #include <DataSourceHelper.hxx>
36 #include <ReferenceSizeProvider.hxx>
37 #include <ExplicitCategoriesProvider.hxx>
38 #include <unonames.hxx>
39 #include <BaseCoordinateSystem.hxx>
40 #include <GridProperties.hxx>
42 #include <o3tl/safeint.hxx>
43 #include <unotools/saveopt.hxx>
45 #include <com/sun/star/chart/ChartAxisPosition.hpp>
46 #include <com/sun/star/chart2/AxisType.hpp>
48 #include <sal/log.hxx>
50 #include <com/sun/star/lang/XServiceName.hpp>
51 #include <com/sun/star/uno/XComponentContext.hpp>
52 #include <comphelper/sequence.hxx>
53 #include <comphelper/diagnose_ex.hxx>
60 using namespace ::com::sun::star
;
61 using namespace ::com::sun::star::chart2
;
62 using ::com::sun::star::uno::Reference
;
63 using ::com::sun::star::uno::Sequence
;
65 Reference
< chart2::XScaling
> AxisHelper::createLinearScaling()
67 return new LinearScaling( 1.0, 0.0 );
70 Reference
< chart2::XScaling
> AxisHelper::createLogarithmicScaling( double fBase
)
72 return new LogarithmicScaling( fBase
);
75 ScaleData
AxisHelper::createDefaultScale()
78 aScaleData
.AxisType
= chart2::AxisType::REALNUMBER
;
79 aScaleData
.AutoDateAxis
= true;
80 aScaleData
.ShiftedCategoryPosition
= false;
81 Sequence
< SubIncrement
> aSubIncrements
{ SubIncrement() };
82 aScaleData
.IncrementData
.SubIncrements
= aSubIncrements
;
86 void AxisHelper::removeExplicitScaling( ScaleData
& rScaleData
)
89 rScaleData
.Minimum
= rScaleData
.Maximum
= rScaleData
.Origin
= aEmpty
;
90 rScaleData
.Scaling
= nullptr;
91 ScaleData
aDefaultScale( createDefaultScale() );
92 rScaleData
.IncrementData
= aDefaultScale
.IncrementData
;
93 rScaleData
.TimeIncrement
= aDefaultScale
.TimeIncrement
;
96 bool AxisHelper::isLogarithmic( const Reference
< XScaling
>& xScaling
)
98 Reference
< lang::XServiceName
> xServiceName( xScaling
, uno::UNO_QUERY
);
99 return xServiceName
.is()
100 && xServiceName
->getServiceName() == "com.sun.star.chart2.LogarithmicScaling";
103 chart2::ScaleData
AxisHelper::getDateCheckedScale( const rtl::Reference
< Axis
>& xAxis
, ChartModel
& rModel
)
105 ScaleData aScale
= xAxis
->getScaleData();
106 rtl::Reference
< BaseCoordinateSystem
> xCooSys( ChartModelHelper::getFirstCoordinateSystem( &rModel
) );
107 if( aScale
.AutoDateAxis
&& aScale
.AxisType
== AxisType::CATEGORY
)
109 sal_Int32 nDimensionIndex
=0; sal_Int32 nAxisIndex
=0;
110 AxisHelper::getIndicesForAxis(xAxis
, xCooSys
, nDimensionIndex
, nAxisIndex
);
111 bool bChartTypeAllowsDateAxis
= ChartTypeHelper::isSupportingDateAxis( AxisHelper::getChartTypeByIndex( xCooSys
, 0 ), nDimensionIndex
);
112 if( bChartTypeAllowsDateAxis
)
113 aScale
.AxisType
= AxisType::DATE
;
115 if( aScale
.AxisType
== AxisType::DATE
)
117 ExplicitCategoriesProvider
aExplicitCategoriesProvider( xCooSys
, rModel
);
118 if( !aExplicitCategoriesProvider
.isDateAxis() )
119 aScale
.AxisType
= AxisType::CATEGORY
;
124 void AxisHelper::checkDateAxis( chart2::ScaleData
& rScale
, ExplicitCategoriesProvider
* pExplicitCategoriesProvider
, bool bChartTypeAllowsDateAxis
)
126 if( rScale
.AutoDateAxis
&& rScale
.AxisType
== AxisType::CATEGORY
&& bChartTypeAllowsDateAxis
)
128 rScale
.AxisType
= AxisType::DATE
;
129 removeExplicitScaling( rScale
);
131 if( rScale
.AxisType
== AxisType::DATE
&& (!pExplicitCategoriesProvider
|| !pExplicitCategoriesProvider
->isDateAxis()) )
133 rScale
.AxisType
= AxisType::CATEGORY
;
134 removeExplicitScaling( rScale
);
138 sal_Int32
AxisHelper::getExplicitNumberFormatKeyForAxis(
139 const rtl::Reference
< Axis
>& xAxis
140 , const rtl::Reference
< BaseCoordinateSystem
> & xCorrespondingCoordinateSystem
141 , const rtl::Reference
<ChartModel
>& xChartDoc
142 , bool bSearchForParallelAxisIfNothingIsFound
)
144 sal_Int32
nNumberFormatKey(0);
145 sal_Int32 nAxisIndex
= 0;
146 sal_Int32 nDimensionIndex
= 1;
147 AxisHelper::getIndicesForAxis( xAxis
, xCorrespondingCoordinateSystem
, nDimensionIndex
, nAxisIndex
);
152 bool bLinkToSource
= true;
153 xAxis
->getPropertyValue(CHART_UNONAME_LINK_TO_SRC_NUMFMT
) >>= bLinkToSource
;
154 xAxis
->getPropertyValue(CHART_UNONAME_NUMFMT
) >>= nNumberFormatKey
;
158 bool bFormatSet
= false;
159 //check whether we have a percent scale -> use percent format
162 ScaleData aData
= AxisHelper::getDateCheckedScale( xAxis
, *xChartDoc
);
163 if( aData
.AxisType
==AxisType::PERCENT
)
165 sal_Int32 nPercentFormat
= DiagramHelper::getPercentNumberFormat( xChartDoc
);
166 if( nPercentFormat
!= -1 )
168 nNumberFormatKey
= nPercentFormat
;
172 else if( aData
.AxisType
==AxisType::DATE
)
174 if( aData
.Categories
.is() )
176 Reference
< data::XDataSequence
> xSeq( aData
.Categories
->getValues());
177 if( xSeq
.is() && !( xChartDoc
.is() && xChartDoc
->hasInternalDataProvider()) )
178 nNumberFormatKey
= xSeq
->getNumberFormatKeyByIndex( -1 );
180 nNumberFormatKey
= DiagramHelper::getDateNumberFormat( xChartDoc
);
184 else if( xChartDoc
.is() && xChartDoc
->hasInternalDataProvider() && nDimensionIndex
== 0 ) //maybe date axis
186 rtl::Reference
< Diagram
> xDiagram( xChartDoc
->getFirstChartDiagram() );
187 if( xDiagram
->isSupportingDateAxis() )
189 nNumberFormatKey
= DiagramHelper::getDateNumberFormat( xChartDoc
);
193 rtl::Reference
< DataSource
> xSource
= DataSourceHelper::getUsedData( *xChartDoc
);
196 std::vector
< uno::Reference
< chart2::data::XLabeledDataSequence
> > aXValues(
197 DataSeriesHelper::getAllDataSequencesByRole( xSource
->getDataSequences(), "values-x" ) );
198 if( aXValues
.empty() )
200 uno::Reference
< chart2::data::XLabeledDataSequence
> xCategories( xDiagram
->getCategories() );
201 if( xCategories
.is() )
203 Reference
< data::XDataSequence
> xSeq( xCategories
->getValues());
206 bool bHasValidDoubles
= false;
208 Sequence
< uno::Any
> aCats( xSeq
->getData() );
209 sal_Int32 nCount
= aCats
.getLength();
210 for( sal_Int32 i
= 0; i
< nCount
; ++i
)
212 if( (aCats
[i
]>>=fTest
) && !std::isnan(fTest
) )
214 bHasValidDoubles
=true;
218 if( bHasValidDoubles
)
219 nNumberFormatKey
= DiagramHelper::getDateNumberFormat( xChartDoc
);
231 std::map
< sal_Int32
, sal_Int32
> aKeyMap
;
232 bool bNumberFormatKeyFoundViaAttachedData
= false;
236 OUString aRoleToMatch
;
237 if( nDimensionIndex
== 0 )
238 aRoleToMatch
= "values-x";
239 const std::vector
< rtl::Reference
< ChartType
> > & aChartTypes( xCorrespondingCoordinateSystem
->getChartTypes2());
240 for( rtl::Reference
< ChartType
> const & chartType
: aChartTypes
)
242 if( nDimensionIndex
!= 0 )
243 aRoleToMatch
= ChartTypeHelper::getRoleOfSequenceForYAxisNumberFormatDetection( chartType
);
244 for( rtl::Reference
< DataSeries
> const & xDataSeries
: chartType
->getDataSeries2() )
246 if( nDimensionIndex
== 1 )
248 //only take those series into account that are attached to this axis
249 sal_Int32 nAttachedAxisIndex
= DataSeriesHelper::getAttachedAxisIndex(xDataSeries
);
250 if( nAttachedAxisIndex
!= nAxisIndex
)
254 Reference
< data::XLabeledDataSequence
> xLabeledSeq(
255 DataSeriesHelper::getDataSequenceByRole( xDataSeries
, aRoleToMatch
) );
257 if( !xLabeledSeq
.is() && nDimensionIndex
==0 )
259 ScaleData aData
= xAxis
->getScaleData();
260 xLabeledSeq
= aData
.Categories
;
263 if( xLabeledSeq
.is() )
265 Reference
< data::XDataSequence
> xSeq( xLabeledSeq
->getValues());
268 sal_Int32 nKey
= xSeq
->getNumberFormatKeyByIndex( -1 );
269 // increase frequency
276 catch( const uno::Exception
& )
278 DBG_UNHANDLED_EXCEPTION("chart2");
281 if( ! aKeyMap
.empty())
283 sal_Int32 nMaxFreq
= 0;
284 // find most frequent key
285 for (auto const& elem
: aKeyMap
)
289 "NumberFormatKey " << elem
.first
<< " appears "
290 << elem
.second
<< " times");
291 // all values must at least be 1
292 if( elem
.second
> nMaxFreq
)
294 nNumberFormatKey
= elem
.first
;
295 bNumberFormatKeyFoundViaAttachedData
= true;
296 nMaxFreq
= elem
.second
;
301 if( bSearchForParallelAxisIfNothingIsFound
)
303 //no format is set to this axis and no data is set to this axis
304 //--> try to obtain the format from the parallel y-axis
305 if( !bNumberFormatKeyFoundViaAttachedData
&& nDimensionIndex
== 1 )
307 sal_Int32 nParallelAxisIndex
= (nAxisIndex
==1) ?0 :1;
308 rtl::Reference
< Axis
> xParallelAxis
= AxisHelper::getAxis( 1, nParallelAxisIndex
, xCorrespondingCoordinateSystem
);
309 nNumberFormatKey
= AxisHelper::getExplicitNumberFormatKeyForAxis(xParallelAxis
, xCorrespondingCoordinateSystem
, xChartDoc
, false);
315 return nNumberFormatKey
;
318 rtl::Reference
< Axis
> AxisHelper::createAxis(
319 sal_Int32 nDimensionIndex
320 , sal_Int32 nAxisIndex
// 0==main or 1==secondary axis
321 , const rtl::Reference
< BaseCoordinateSystem
>& xCooSys
322 , const Reference
< uno::XComponentContext
> & xContext
323 , ReferenceSizeProvider
* pRefSizeProvider
)
325 if( !xContext
.is() || !xCooSys
.is() )
327 if( nDimensionIndex
>= xCooSys
->getDimension() )
330 rtl::Reference
< Axis
> xAxis
= new Axis();
332 xCooSys
->setAxisByDimension( nDimensionIndex
, xAxis
, nAxisIndex
);
334 if( nAxisIndex
>0 )//when inserting secondary axes copy some things from the main axis
336 css::chart::ChartAxisPosition
eNewAxisPos( css::chart::ChartAxisPosition_END
);
338 rtl::Reference
< Axis
> xMainAxis
= xCooSys
->getAxisByDimension2( nDimensionIndex
, 0 );
341 ScaleData aScale
= xAxis
->getScaleData();
342 ScaleData aMainScale
= xMainAxis
->getScaleData();
344 aScale
.AxisType
= aMainScale
.AxisType
;
345 aScale
.AutoDateAxis
= aMainScale
.AutoDateAxis
;
346 aScale
.Categories
= aMainScale
.Categories
;
347 aScale
.Orientation
= aMainScale
.Orientation
;
348 aScale
.ShiftedCategoryPosition
= aMainScale
.ShiftedCategoryPosition
;
350 xAxis
->setScaleData( aScale
);
352 //ensure that the second axis is not placed on the main axis
353 css::chart::ChartAxisPosition
eMainAxisPos( css::chart::ChartAxisPosition_ZERO
);
354 xMainAxis
->getPropertyValue("CrossoverPosition") >>= eMainAxisPos
;
355 if( eMainAxisPos
== css::chart::ChartAxisPosition_END
)
356 eNewAxisPos
= css::chart::ChartAxisPosition_START
;
359 xAxis
->setPropertyValue("CrossoverPosition", uno::Any(eNewAxisPos
) );
364 // set correct initial AutoScale
365 if( pRefSizeProvider
)
366 pRefSizeProvider
->setValuesAtPropertySet( xAxis
);
368 catch( const uno::Exception
& )
370 TOOLS_WARN_EXCEPTION("chart2", "" );
375 rtl::Reference
< Axis
> AxisHelper::createAxis( sal_Int32 nDimensionIndex
, bool bMainAxis
376 , const rtl::Reference
< Diagram
>& xDiagram
377 , const Reference
< uno::XComponentContext
>& xContext
378 , ReferenceSizeProvider
* pRefSizeProvider
)
380 OSL_ENSURE( xContext
.is(), "need a context to create an axis" );
384 sal_Int32 nAxisIndex
= bMainAxis
? MAIN_AXIS_INDEX
: SECONDARY_AXIS_INDEX
;
385 rtl::Reference
< BaseCoordinateSystem
> xCooSys
= AxisHelper::getCoordinateSystemByIndex( xDiagram
, 0 );
388 return AxisHelper::createAxis(
389 nDimensionIndex
, nAxisIndex
, xCooSys
, xContext
, pRefSizeProvider
);
392 void AxisHelper::showAxis( sal_Int32 nDimensionIndex
, bool bMainAxis
393 , const rtl::Reference
< Diagram
>& xDiagram
394 , const Reference
< uno::XComponentContext
>& xContext
395 , ReferenceSizeProvider
* pRefSizeProvider
)
400 bool bNewAxisCreated
= false;
401 rtl::Reference
< Axis
> xAxis
= AxisHelper::getAxis( nDimensionIndex
, bMainAxis
, xDiagram
);
402 if( !xAxis
.is() && xContext
.is() )
405 bNewAxisCreated
= true;
406 xAxis
= AxisHelper::createAxis( nDimensionIndex
, bMainAxis
, xDiagram
, xContext
, pRefSizeProvider
);
409 OSL_ASSERT( xAxis
.is());
410 if( !bNewAxisCreated
) //default is true already if created
411 AxisHelper::makeAxisVisible( xAxis
);
414 void AxisHelper::showGrid( sal_Int32 nDimensionIndex
, sal_Int32 nCooSysIndex
, bool bMainGrid
415 , const rtl::Reference
< Diagram
>& xDiagram
)
420 rtl::Reference
< BaseCoordinateSystem
> xCooSys
= AxisHelper::getCoordinateSystemByIndex( xDiagram
, nCooSysIndex
);
424 rtl::Reference
< Axis
> xAxis
= AxisHelper::getAxis( nDimensionIndex
, MAIN_AXIS_INDEX
, xCooSys
);
427 //hhhh todo create axis without axis visibility
433 AxisHelper::makeGridVisible( xAxis
->getGridProperties2() );
436 std::vector
< rtl::Reference
< GridProperties
> > aSubGrids( xAxis
->getSubGridProperties2() );
437 for( auto const & i
: aSubGrids
)
438 AxisHelper::makeGridVisible( i
);
442 void AxisHelper::makeAxisVisible( const rtl::Reference
< Axis
>& xAxis
)
446 xAxis
->setPropertyValue( "Show", uno::Any( true ) );
447 LinePropertiesHelper::SetLineVisible( xAxis
);
448 xAxis
->setPropertyValue( "DisplayLabels", uno::Any( true ) );
452 void AxisHelper::makeGridVisible( const rtl::Reference
< GridProperties
>& xGridProperties
)
454 if( xGridProperties
.is() )
456 xGridProperties
->setPropertyValue( "Show", uno::Any( true ) );
457 LinePropertiesHelper::SetLineVisible( xGridProperties
);
461 void AxisHelper::hideAxis( sal_Int32 nDimensionIndex
, bool bMainAxis
462 , const rtl::Reference
< Diagram
>& xDiagram
)
464 AxisHelper::makeAxisInvisible( AxisHelper::getAxis( nDimensionIndex
, bMainAxis
, xDiagram
) );
467 void AxisHelper::makeAxisInvisible( const rtl::Reference
< Axis
>& xAxis
)
471 xAxis
->setPropertyValue( "Show", uno::Any( false ) );
475 void AxisHelper::hideAxisIfNoDataIsAttached( const rtl::Reference
< Axis
>& xAxis
, const rtl::Reference
< Diagram
>& xDiagram
)
477 //axis is hidden if no data is attached anymore but data is available
478 bool bOtherSeriesAttachedToThisAxis
= false;
479 std::vector
< rtl::Reference
< DataSeries
> > aSeriesVector
= xDiagram
->getDataSeries();
480 for (auto const& series
: aSeriesVector
)
482 rtl::Reference
< Axis
> xCurrentAxis
= xDiagram
->getAttachedAxis(series
);
483 if( xCurrentAxis
==xAxis
)
485 bOtherSeriesAttachedToThisAxis
= true;
489 if(!bOtherSeriesAttachedToThisAxis
&& !aSeriesVector
.empty() )
490 AxisHelper::makeAxisInvisible( xAxis
);
493 void AxisHelper::hideGrid( sal_Int32 nDimensionIndex
, sal_Int32 nCooSysIndex
, bool bMainGrid
494 , const rtl::Reference
< Diagram
>& xDiagram
)
499 rtl::Reference
< BaseCoordinateSystem
> xCooSys
= AxisHelper::getCoordinateSystemByIndex( xDiagram
, nCooSysIndex
);
503 rtl::Reference
< Axis
> xAxis
= AxisHelper::getAxis( nDimensionIndex
, MAIN_AXIS_INDEX
, xCooSys
);
508 AxisHelper::makeGridInvisible( xAxis
->getGridProperties2() );
511 std::vector
< rtl::Reference
< ::chart::GridProperties
> > aSubGrids( xAxis
->getSubGridProperties2() );
512 for( auto const & i
: aSubGrids
)
513 AxisHelper::makeGridInvisible( i
);
517 void AxisHelper::makeGridInvisible( const rtl::Reference
< ::chart::GridProperties
>& xGridProperties
)
519 if( xGridProperties
.is() )
521 xGridProperties
->setPropertyValue( "Show", uno::Any( false ) );
525 bool AxisHelper::isGridShown( sal_Int32 nDimensionIndex
, sal_Int32 nCooSysIndex
, bool bMainGrid
526 , const rtl::Reference
< Diagram
>& xDiagram
)
530 rtl::Reference
< BaseCoordinateSystem
> xCooSys
= AxisHelper::getCoordinateSystemByIndex( xDiagram
, nCooSysIndex
);
534 rtl::Reference
< Axis
> xAxis
= AxisHelper::getAxis( nDimensionIndex
, MAIN_AXIS_INDEX
, xCooSys
);
539 bRet
= AxisHelper::isGridVisible( xAxis
->getGridProperties2() );
542 std::vector
< rtl::Reference
< ::chart::GridProperties
> > aSubGrids( xAxis
->getSubGridProperties2() );
543 if( !aSubGrids
.empty() )
544 bRet
= AxisHelper::isGridVisible( aSubGrids
[0] );
550 rtl::Reference
< ::chart::BaseCoordinateSystem
> AxisHelper::getCoordinateSystemByIndex(
551 const rtl::Reference
< Diagram
>& xDiagram
, sal_Int32 nIndex
)
555 auto aCooSysList
= xDiagram
->getBaseCoordinateSystems();
556 if(0<=nIndex
&& o3tl::make_unsigned(nIndex
) < aCooSysList
.size())
557 return aCooSysList
[nIndex
];
561 rtl::Reference
< Axis
> AxisHelper::getAxis( sal_Int32 nDimensionIndex
, bool bMainAxis
562 , const rtl::Reference
< Diagram
>& xDiagram
)
564 rtl::Reference
< Axis
> xRet
;
567 rtl::Reference
< BaseCoordinateSystem
> xCooSys
= AxisHelper::getCoordinateSystemByIndex( xDiagram
, 0 );
568 xRet
= AxisHelper::getAxis( nDimensionIndex
, bMainAxis
? 0 : 1, xCooSys
);
570 catch( const uno::Exception
& )
576 rtl::Reference
< Axis
> AxisHelper::getAxis( sal_Int32 nDimensionIndex
, sal_Int32 nAxisIndex
577 , const rtl::Reference
< BaseCoordinateSystem
>& xCooSys
)
579 rtl::Reference
< Axis
> xRet
;
583 if(nDimensionIndex
>= xCooSys
->getDimension())
586 if(nAxisIndex
> xCooSys
->getMaximumAxisIndexByDimension(nDimensionIndex
))
589 assert(nAxisIndex
>= 0);
590 assert(nDimensionIndex
>= 0);
591 xRet
= xCooSys
->getAxisByDimension2( nDimensionIndex
, nAxisIndex
);
595 rtl::Reference
< Axis
> AxisHelper::getCrossingMainAxis( const rtl::Reference
< Axis
>& xAxis
596 , const rtl::Reference
< BaseCoordinateSystem
>& xCooSys
)
598 sal_Int32 nDimensionIndex
= 0;
599 sal_Int32 nAxisIndex
= 0;
600 AxisHelper::getIndicesForAxis( xAxis
, xCooSys
, nDimensionIndex
, nAxisIndex
);
601 if( nDimensionIndex
==2 )
604 bool bSwapXY
= false;
605 if( (xCooSys
->getPropertyValue( "SwapXAndYAxis" ) >>= bSwapXY
) && bSwapXY
)
608 else if( nDimensionIndex
==1 )
612 return AxisHelper::getAxis( nDimensionIndex
, 0, xCooSys
);
615 rtl::Reference
< Axis
> AxisHelper::getParallelAxis( const rtl::Reference
< Axis
>& xAxis
616 , const rtl::Reference
< Diagram
>& xDiagram
)
620 sal_Int32 nCooSysIndex
=-1;
621 sal_Int32 nDimensionIndex
=-1;
622 sal_Int32 nAxisIndex
=-1;
623 if( getIndicesForAxis( xAxis
, xDiagram
, nCooSysIndex
, nDimensionIndex
, nAxisIndex
) )
625 sal_Int32 nParallelAxisIndex
= (nAxisIndex
==1) ?0 :1;
626 return getAxis( nDimensionIndex
, nParallelAxisIndex
, getCoordinateSystemByIndex( xDiagram
, nCooSysIndex
) );
629 catch( const uno::RuntimeException
& )
635 bool AxisHelper::isAxisShown( sal_Int32 nDimensionIndex
, bool bMainAxis
636 , const rtl::Reference
< Diagram
>& xDiagram
)
638 return AxisHelper::isAxisVisible( AxisHelper::getAxis( nDimensionIndex
, bMainAxis
, xDiagram
) );
641 bool AxisHelper::isAxisVisible( const rtl::Reference
< Axis
>& xAxis
)
647 xAxis
->getPropertyValue( "Show" ) >>= bRet
;
648 bRet
= bRet
&& ( LinePropertiesHelper::IsLineVisible( xAxis
)
649 || areAxisLabelsVisible( xAxis
) );
655 bool AxisHelper::areAxisLabelsVisible( const rtl::Reference
< Axis
>& xAxis
)
660 xAxis
->getPropertyValue( "DisplayLabels" ) >>= bRet
;
665 bool AxisHelper::isGridVisible( const rtl::Reference
< ::chart::GridProperties
>& xGridproperties
)
669 if( xGridproperties
.is() )
671 xGridproperties
->getPropertyValue( "Show" ) >>= bRet
;
672 bRet
= bRet
&& LinePropertiesHelper::IsLineVisible( xGridproperties
);
678 rtl::Reference
< GridProperties
> AxisHelper::getGridProperties(
679 const rtl::Reference
< BaseCoordinateSystem
>& xCooSys
680 , sal_Int32 nDimensionIndex
, sal_Int32 nAxisIndex
, sal_Int32 nSubGridIndex
)
682 rtl::Reference
< GridProperties
> xRet
;
684 rtl::Reference
< Axis
> xAxis( AxisHelper::getAxis( nDimensionIndex
, nAxisIndex
, xCooSys
) );
687 if( nSubGridIndex
<0 )
688 xRet
= xAxis
->getGridProperties2();
691 std::vector
< rtl::Reference
< GridProperties
> > aSubGrids( xAxis
->getSubGridProperties2() );
692 if (nSubGridIndex
< static_cast<sal_Int32
>(aSubGrids
.size()))
693 xRet
= aSubGrids
[nSubGridIndex
];
700 sal_Int32
AxisHelper::getDimensionIndexOfAxis(
701 const rtl::Reference
< Axis
>& xAxis
702 , const rtl::Reference
< Diagram
>& xDiagram
)
704 sal_Int32 nDimensionIndex
= -1;
705 sal_Int32 nCooSysIndex
= -1;
706 sal_Int32 nAxisIndex
= -1;
707 AxisHelper::getIndicesForAxis( xAxis
, xDiagram
, nCooSysIndex
, nDimensionIndex
, nAxisIndex
);
708 return nDimensionIndex
;
711 bool AxisHelper::getIndicesForAxis(
712 const rtl::Reference
< Axis
>& xAxis
713 , const rtl::Reference
< BaseCoordinateSystem
>& xCooSys
714 , sal_Int32
& rOutDimensionIndex
, sal_Int32
& rOutAxisIndex
)
716 //returns true if indices are found
718 rOutDimensionIndex
= -1;
721 if( !xCooSys
|| !xAxis
)
724 rtl::Reference
< Axis
> xCurrentAxis
;
725 sal_Int32
nDimensionCount( xCooSys
->getDimension() );
726 for( sal_Int32 nDimensionIndex
= 0; nDimensionIndex
< nDimensionCount
; nDimensionIndex
++ )
728 sal_Int32 nMaxAxisIndex
= xCooSys
->getMaximumAxisIndexByDimension(nDimensionIndex
);
729 for( sal_Int32 nAxisIndex
= 0; nAxisIndex
<= nMaxAxisIndex
; nAxisIndex
++ )
731 xCurrentAxis
= xCooSys
->getAxisByDimension2(nDimensionIndex
,nAxisIndex
);
732 if( xCurrentAxis
== xAxis
)
734 rOutDimensionIndex
= nDimensionIndex
;
735 rOutAxisIndex
= nAxisIndex
;
743 bool AxisHelper::getIndicesForAxis( const rtl::Reference
< Axis
>& xAxis
, const rtl::Reference
< Diagram
>& xDiagram
744 , sal_Int32
& rOutCooSysIndex
, sal_Int32
& rOutDimensionIndex
, sal_Int32
& rOutAxisIndex
)
746 //returns true if indices are found
748 rOutCooSysIndex
= -1;
749 rOutDimensionIndex
= -1;
752 const std::vector
< rtl::Reference
< BaseCoordinateSystem
> > & aCooSysList
= xDiagram
->getBaseCoordinateSystems();
753 for( std::size_t nC
=0; nC
< aCooSysList
.size(); ++nC
)
755 if( AxisHelper::getIndicesForAxis( xAxis
, aCooSysList
[nC
], rOutDimensionIndex
, rOutAxisIndex
) )
757 rOutCooSysIndex
= nC
;
765 std::vector
< rtl::Reference
< Axis
> > AxisHelper::getAllAxesOfCoordinateSystem(
766 const rtl::Reference
< BaseCoordinateSystem
>& xCooSys
767 , bool bOnlyVisible
/* = false */ )
769 std::vector
< rtl::Reference
< Axis
> > aAxisVector
;
773 sal_Int32 nMaxDimensionIndex
= xCooSys
->getDimension() -1;
774 if( nMaxDimensionIndex
>=0 )
776 sal_Int32 nDimensionIndex
= 0;
777 for(; nDimensionIndex
<=nMaxDimensionIndex
; ++nDimensionIndex
)
779 const sal_Int32 nMaximumAxisIndex
= xCooSys
->getMaximumAxisIndexByDimension(nDimensionIndex
);
780 for(sal_Int32 nAxisIndex
=0; nAxisIndex
<=nMaximumAxisIndex
; ++nAxisIndex
)
784 rtl::Reference
< Axis
> xAxis
= xCooSys
->getAxisByDimension2( nDimensionIndex
, nAxisIndex
);
787 bool bAddAxis
= true;
790 if( !(xAxis
->getPropertyValue( "Show") >>= bAddAxis
) )
794 aAxisVector
.push_back( xAxis
);
797 catch( const uno::Exception
& )
799 DBG_UNHANDLED_EXCEPTION("chart2");
809 std::vector
< rtl::Reference
< Axis
> > AxisHelper::getAllAxesOfDiagram(
810 const rtl::Reference
< Diagram
>& xDiagram
811 , bool bOnlyVisible
)
813 std::vector
< rtl::Reference
< Axis
> > aAxisVector
;
815 for( rtl::Reference
< BaseCoordinateSystem
> const & coords
: xDiagram
->getBaseCoordinateSystems() )
817 std::vector
< rtl::Reference
< Axis
> > aAxesPerCooSys
= AxisHelper::getAllAxesOfCoordinateSystem( coords
, bOnlyVisible
);
818 aAxisVector
.insert( aAxisVector
.end(), aAxesPerCooSys
.begin(), aAxesPerCooSys
.end() );
824 std::vector
< rtl::Reference
< GridProperties
> > AxisHelper::getAllGrids( const rtl::Reference
< Diagram
>& xDiagram
)
826 const std::vector
< rtl::Reference
< Axis
> > aAllAxes
= AxisHelper::getAllAxesOfDiagram( xDiagram
);
827 std::vector
< rtl::Reference
< GridProperties
> > aGridVector
;
829 for( rtl::Reference
< Axis
> const & xAxis
: aAllAxes
)
831 rtl::Reference
< GridProperties
> xGridProperties( xAxis
->getGridProperties2() );
832 if( xGridProperties
.is() )
833 aGridVector
.push_back( xGridProperties
);
835 std::vector
< rtl::Reference
< GridProperties
> > aSubGrids( xAxis
->getSubGridProperties2() );
836 for( rtl::Reference
< GridProperties
> const & xSubGrid
: aSubGrids
)
839 aGridVector
.push_back( xSubGrid
);
846 void AxisHelper::getAxisOrGridPossibilities( Sequence
< sal_Bool
>& rPossibilityList
847 , const rtl::Reference
< Diagram
>& xDiagram
, bool bAxis
)
849 rPossibilityList
.realloc(6);
850 sal_Bool
* pPossibilityList
= rPossibilityList
.getArray();
852 sal_Int32 nDimensionCount
= -1;
854 nDimensionCount
= xDiagram
->getDimension();
858 rtl::Reference
< ChartType
> xChartType
;
860 xChartType
= xDiagram
->getChartTypeByIndex( 0 );
861 for(nIndex
=0;nIndex
<3;nIndex
++)
862 pPossibilityList
[nIndex
]=ChartTypeHelper::isSupportingMainAxis(xChartType
,nDimensionCount
,nIndex
);
863 for(nIndex
=3;nIndex
<6;nIndex
++)
865 pPossibilityList
[nIndex
]=ChartTypeHelper::isSupportingSecondaryAxis(xChartType
,nDimensionCount
);
867 pPossibilityList
[nIndex
] = rPossibilityList
[nIndex
-3];
870 bool AxisHelper::isSecondaryYAxisNeeded( const rtl::Reference
< BaseCoordinateSystem
>& xCooSys
)
875 const std::vector
< rtl::Reference
< ChartType
> > & aChartTypes( xCooSys
->getChartTypes2() );
876 for( rtl::Reference
< ChartType
> const & chartType
: aChartTypes
)
878 const std::vector
< rtl::Reference
< DataSeries
> > & aSeriesList
= chartType
->getDataSeries2();
879 for( sal_Int32 nS
= aSeriesList
.size(); nS
-- ; )
881 sal_Int32 nAttachedAxisIndex
= 0;
882 if( ( aSeriesList
[nS
]->getPropertyValue( "AttachedAxisIndex" ) >>= nAttachedAxisIndex
) &&
883 nAttachedAxisIndex
>0 )
890 bool AxisHelper::shouldAxisBeDisplayed( const rtl::Reference
< Axis
>& xAxis
891 , const rtl::Reference
< BaseCoordinateSystem
>& xCooSys
)
895 if( xAxis
.is() && xCooSys
.is() )
897 sal_Int32 nDimensionIndex
=-1;
898 sal_Int32 nAxisIndex
=-1;
899 if( AxisHelper::getIndicesForAxis( xAxis
, xCooSys
, nDimensionIndex
, nAxisIndex
) )
901 sal_Int32 nDimensionCount
= xCooSys
->getDimension();
902 rtl::Reference
< ChartType
> xChartType( AxisHelper::getChartTypeByIndex( xCooSys
, 0 ) );
904 bool bMainAxis
= (nAxisIndex
==MAIN_AXIS_INDEX
);
906 bRet
= ChartTypeHelper::isSupportingMainAxis(xChartType
,nDimensionCount
,nDimensionIndex
);
908 bRet
= ChartTypeHelper::isSupportingSecondaryAxis(xChartType
,nDimensionCount
);
915 void AxisHelper::getAxisOrGridExistence( Sequence
< sal_Bool
>& rExistenceList
916 , const rtl::Reference
< Diagram
>& xDiagram
, bool bAxis
)
918 rExistenceList
.realloc(6);
919 sal_Bool
* pExistenceList
= rExistenceList
.getArray();
925 pExistenceList
[nN
] = AxisHelper::isAxisShown( nN
, true, xDiagram
);
927 pExistenceList
[nN
] = AxisHelper::isAxisShown( nN
%3, false, xDiagram
);
934 pExistenceList
[nN
] = AxisHelper::isGridShown( nN
, 0, true, xDiagram
);
936 pExistenceList
[nN
] = AxisHelper::isGridShown( nN
%3, 0, false, xDiagram
);
940 bool AxisHelper::changeVisibilityOfAxes( const rtl::Reference
< Diagram
>& xDiagram
941 , const Sequence
< sal_Bool
>& rOldExistenceList
942 , const Sequence
< sal_Bool
>& rNewExistenceList
943 , const Reference
< uno::XComponentContext
>& xContext
944 , ReferenceSizeProvider
* pRefSizeProvider
)
946 bool bChanged
= false;
947 for(sal_Int32 nN
=0;nN
<6;nN
++)
949 if(rOldExistenceList
[nN
]!=rNewExistenceList
[nN
])
952 if(rNewExistenceList
[nN
])
954 AxisHelper::showAxis( nN
%3, nN
<3, xDiagram
, xContext
, pRefSizeProvider
);
957 AxisHelper::hideAxis( nN
%3, nN
<3, xDiagram
);
963 bool AxisHelper::changeVisibilityOfGrids( const rtl::Reference
< Diagram
>& xDiagram
964 , const Sequence
< sal_Bool
>& rOldExistenceList
965 , const Sequence
< sal_Bool
>& rNewExistenceList
)
967 bool bChanged
= false;
968 for(sal_Int32 nN
=0;nN
<6;nN
++)
970 if(rOldExistenceList
[nN
]!=rNewExistenceList
[nN
])
973 if(rNewExistenceList
[nN
])
974 AxisHelper::showGrid( nN
%3, 0, nN
<3, xDiagram
);
976 AxisHelper::hideGrid( nN
%3, 0, nN
<3, xDiagram
);
982 rtl::Reference
< BaseCoordinateSystem
> AxisHelper::getCoordinateSystemOfAxis(
983 const rtl::Reference
< Axis
>& xAxis
984 , const rtl::Reference
< Diagram
>& xDiagram
)
989 rtl::Reference
< BaseCoordinateSystem
> xRet
;
990 for( rtl::Reference
< BaseCoordinateSystem
> const & xCooSys
: xDiagram
->getBaseCoordinateSystems() )
992 std::vector
< rtl::Reference
< Axis
> > aAllAxis
= AxisHelper::getAllAxesOfCoordinateSystem( xCooSys
);
994 auto aFound
= std::find( aAllAxis
.begin(), aAllAxis
.end(), xAxis
);
995 if( aFound
!= aAllAxis
.end())
1004 rtl::Reference
< ChartType
> AxisHelper::getChartTypeByIndex( const rtl::Reference
< BaseCoordinateSystem
>& xCooSys
, sal_Int32 nIndex
)
1006 rtl::Reference
< ChartType
> xChartType
;
1010 const std::vector
< rtl::Reference
< ChartType
> > aChartTypeList( xCooSys
->getChartTypes2() );
1011 if( nIndex
>= 0 && o3tl::make_unsigned(nIndex
) < aChartTypeList
.size() )
1012 xChartType
= aChartTypeList
[nIndex
];
1018 void AxisHelper::setRTLAxisLayout( const rtl::Reference
< BaseCoordinateSystem
>& xCooSys
)
1023 bool bCartesian
= xCooSys
->getViewServiceName() == CHART2_COOSYSTEM_CARTESIAN_VIEW_SERVICE_NAME
;
1027 bool bVertical
= false;
1028 xCooSys
->getPropertyValue( "SwapXAndYAxis" ) >>= bVertical
;
1030 sal_Int32 nHorizontalAxisDimension
= bVertical
? 1 : 0;
1031 sal_Int32 nVerticalAxisDimension
= bVertical
? 0 : 1;
1035 //reverse direction for horizontal main axis
1036 rtl::Reference
< Axis
> xHorizontalMainAxis
= AxisHelper::getAxis( nHorizontalAxisDimension
, MAIN_AXIS_INDEX
, xCooSys
);
1037 if( xHorizontalMainAxis
.is() )
1039 chart2::ScaleData aScale
= xHorizontalMainAxis
->getScaleData();
1040 aScale
.Orientation
= chart2::AxisOrientation_REVERSE
;
1041 xHorizontalMainAxis
->setScaleData(aScale
);
1044 //mathematical direction for vertical main axis
1045 rtl::Reference
< Axis
> xVerticalMainAxis
= AxisHelper::getAxis( nVerticalAxisDimension
, MAIN_AXIS_INDEX
, xCooSys
);
1046 if( xVerticalMainAxis
.is() )
1048 chart2::ScaleData aScale
= xVerticalMainAxis
->getScaleData();
1049 aScale
.Orientation
= chart2::AxisOrientation_MATHEMATICAL
;
1050 xVerticalMainAxis
->setScaleData(aScale
);
1053 catch( const uno::Exception
& )
1055 DBG_UNHANDLED_EXCEPTION("chart2" );
1060 //reverse direction for horizontal secondary axis
1061 rtl::Reference
< Axis
> xHorizontalSecondaryAxis
= AxisHelper::getAxis( nHorizontalAxisDimension
, SECONDARY_AXIS_INDEX
, xCooSys
);
1062 if( xHorizontalSecondaryAxis
.is() )
1064 chart2::ScaleData aScale
= xHorizontalSecondaryAxis
->getScaleData();
1065 aScale
.Orientation
= chart2::AxisOrientation_REVERSE
;
1066 xHorizontalSecondaryAxis
->setScaleData(aScale
);
1069 //mathematical direction for vertical secondary axis
1070 rtl::Reference
< Axis
> xVerticalSecondaryAxis
= AxisHelper::getAxis( nVerticalAxisDimension
, SECONDARY_AXIS_INDEX
, xCooSys
);
1071 if( xVerticalSecondaryAxis
.is() )
1073 chart2::ScaleData aScale
= xVerticalSecondaryAxis
->getScaleData();
1074 aScale
.Orientation
= chart2::AxisOrientation_MATHEMATICAL
;
1075 xVerticalSecondaryAxis
->setScaleData(aScale
);
1078 catch( const uno::Exception
& )
1080 DBG_UNHANDLED_EXCEPTION("chart2");
1084 rtl::Reference
< ChartType
> AxisHelper::getFirstChartTypeWithSeriesAttachedToAxisIndex( const rtl::Reference
< Diagram
>& xDiagram
, const sal_Int32 nAttachedAxisIndex
)
1086 rtl::Reference
< ChartType
> xChartType
;
1087 std::vector
< rtl::Reference
< DataSeries
> > aSeriesVector
= xDiagram
->getDataSeries();
1088 for (auto const& series
: aSeriesVector
)
1090 sal_Int32 nCurrentIndex
= DataSeriesHelper::getAttachedAxisIndex(series
);
1091 if( nAttachedAxisIndex
== nCurrentIndex
)
1093 xChartType
= xDiagram
->getChartTypeOfSeries(series
);
1101 bool AxisHelper::isAxisPositioningEnabled()
1103 const SvtSaveOptions::ODFSaneDefaultVersion
nCurrentVersion(GetODFSaneDefaultVersion());
1104 return nCurrentVersion
>= SvtSaveOptions::ODFSVER_012
;
1109 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */