30#include <unonames.hxx>
34#include <com/sun/star/chart2/AxisType.hpp>
36#include <rtl/ustrbuf.hxx>
46using ::com::sun::star::uno::Reference;
47using ::com::sun::star::uno::Sequence;
51 , ChartModel& rModel )
53 , m_xCooSysModel( xCooSysModel.
get() )
55 , m_bIsExplicitCategoriesInited(false)
56 , m_bIsDateAxis(false)
57 , m_bIsAutoDate(false)
61 if( xCooSysModel.is() )
67 ScaleData aScale( xAxis->getScaleData() );
68 m_xOriginalCategories = aScale.Categories;
69 m_bIsAutoDate = (aScale.AutoDateAxis && aScale.AxisType==chart2::AxisType::CATEGORY);
70 m_bIsDateAxis = (aScale.AxisType == chart2::AxisType::DATE || m_bIsAutoDate);
74 if( m_xOriginalCategories.is() )
76 uno::Reference< data::XDataProvider > xDataProvider(
mrModel.getDataProvider() );
78 OUString aCategoriesRange( DataSourceHelper::getRangeFromValues( m_xOriginalCategories ) );
79 if( xDataProvider.is() && !aCategoriesRange.isEmpty() )
81 const bool bFirstCellAsLabel =
false;
82 const bool bHasCategories =
false;
83 const uno::Sequence< sal_Int32 > aSequenceMapping;
85 uno::Reference< data::XDataSource > xColumnCategoriesSource( xDataProvider->createDataSource(
86 DataSourceHelper::createArguments( aCategoriesRange, aSequenceMapping,
true
87 , bFirstCellAsLabel, bHasCategories ) ) );
89 uno::Reference< data::XDataSource > xRowCategoriesSource( xDataProvider->createDataSource(
90 DataSourceHelper::createArguments( aCategoriesRange, aSequenceMapping,
false
91 , bFirstCellAsLabel, bHasCategories ) ) );
93 if( xColumnCategoriesSource.is() && xRowCategoriesSource.is() )
95 Sequence< Reference< data::XLabeledDataSequence> > aColumns = xColumnCategoriesSource->getDataSequences();
96 Sequence< Reference< data::XLabeledDataSequence> > aRows = xRowCategoriesSource->getDataSequences();
98 sal_Int32 nColumnCount = aColumns.getLength();
99 sal_Int32 nRowCount = aRows.getLength();
100 if( nColumnCount>1 && nRowCount>1 )
105 bool bSeriesUsesColumns =
true;
106 std::vector< rtl::Reference< DataSeries > > aSeries = ChartModelHelper::getDataSeries( &
mrModel );
107 if( !aSeries.empty() )
110 OUString aStringDummy;
112 uno::Sequence< sal_Int32 > aSeqDummy;
113 DataSourceHelper::readArguments( xDataProvider->detectArguments( xSeriesSource),
114 aStringDummy, aSeqDummy, bSeriesUsesColumns, bDummy, bDummy );
116 if( bSeriesUsesColumns )
117 m_aSplitCategoriesList = comphelper::sequenceToContainer<std::vector<Reference<data::XLabeledDataSequence>>>(aColumns);
119 m_aSplitCategoriesList = comphelper::sequenceToContainer<std::vector<Reference<data::XLabeledDataSequence>>>(aRows);
123 if( m_aSplitCategoriesList.empty() )
125 m_aSplitCategoriesList = { m_xOriginalCategories };
129 catch(
const uno::Exception & )
135ExplicitCategoriesProvider::~ExplicitCategoriesProvider()
141 if( m_xOriginalCategories.is() )
142 return m_xOriginalCategories->getValues();
146bool ExplicitCategoriesProvider::hasComplexCategories()
const
148 return m_aSplitCategoriesList.size() > 1;
151sal_Int32 ExplicitCategoriesProvider::getCategoryLevelCount()
const
153 sal_Int32
nCount = m_aSplitCategoriesList.size();
161 std::vector<sal_Int32> aLimitingBorders;
162 sal_Int32 nBorderIndex = 0;
163 for (
auto const& complexCategory : rComplexCategories)
165 nBorderIndex += complexCategory.Count;
166 aLimitingBorders.push_back(nBorderIndex);
168 return aLimitingBorders;
173 sal_Int32
nCount = rInAnys.getLength();
176 rOutTexts.realloc(
nCount);
177 auto pOutTexts = rOutTexts.getArray();
179 sal_Int32 nAxisNumberFormat = 0;
181 if( xCooSysModel.is() )
184 nAxisNumberFormat = AxisHelper::getExplicitNumberFormatKeyForAxis(
185 xAxis, xCooSysModel, &rModel,
false );
189 bool bColorChanged =
false;
193 for(sal_Int32 nN=0;nN<
nCount;nN++)
202 if( !std::isnan(fDouble) )
204 nAxisNumberFormat, fDouble, nLabelColor, bColorChanged );
211 pOutTexts[nN] = aText;
215SplitCategoriesProvider::~SplitCategoriesProvider()
225 explicit SplitCategoriesProvider_ForLabeledDataSequences(
227 , ChartModel& rModel )
233 virtual uno::Sequence< OUString >
getStringsForLevel( sal_Int32 nIndex )
const override;
243sal_Int32 SplitCategoriesProvider_ForLabeledDataSequences::getLevelCount()
const
247uno::Sequence< OUString > SplitCategoriesProvider_ForLabeledDataSequences::getStringsForLevel( sal_Int32 nLevel )
const
249 uno::Sequence< OUString > aRet;
251 if( xLabeledDataSequence.is() )
253 uno::Reference< data::XDataSequence > xDataSequence( xLabeledDataSequence->getValues() );
254 if( xDataSequence.is() )
255 ExplicitCategoriesProvider::convertCategoryAnysToText( aRet, xDataSequence->getData(),
mrModel );
262 ,
const std::vector<sal_Int32>& rLimitingBorders,
bool bCreateSingleCategories )
264 std::vector< ComplexCategory > aResult;
266 sal_Int32 nMaxCount = rStrings.getLength();
268 sal_Int32 nCurrentCount=0;
269 for( sal_Int32 nN=0; nN<nMaxCount; nN++ )
271 const OUString& aCurrent = rStrings[nN];
272 if( bCreateSingleCategories || std::find( rLimitingBorders.begin(), rLimitingBorders.end(), nN ) != rLimitingBorders.end() )
274 aResult.emplace_back(aPrevious,nCurrentCount );
276 aPrevious = aCurrent;
284 if (aCurrent.isEmpty())
288 aResult.emplace_back(aPrevious,nCurrentCount );
290 aPrevious = aCurrent;
295 aResult.emplace_back(aPrevious,nCurrentCount );
303 for (
auto const& complexCategory : rComplexCategories)
304 nCount+=complexCategory.Count;
310 std::vector< std::vector< ComplexCategory > >& rComplexCats )
314 rComplexCats.clear();
315 sal_Int32 nLCount = rSplitCategoriesProvider.
getLevelCount();
316 for( sal_Int32 nL = 0; nL < nLCount; nL++ )
318 std::vector<sal_Int32> aLimitingBorders;
322 rSplitCategoriesProvider.
getStringsForLevel(nL), aLimitingBorders, nL==(nLCount-1) ) );
326 sal_Int32 nMaxCategoryCount = 0;
328 for (
auto & complexCat : rComplexCats)
331 nMaxCategoryCount = std::max( nCurrentCount, nMaxCategoryCount );
333 for (
auto & complexCat : rComplexCats)
335 if ( !complexCat.empty() )
338 if( nCurrentCount< nMaxCategoryCount )
341 rComplexCategory.
Count += (nMaxCategoryCount-nCurrentCount);
348 std::vector< std::vector< ComplexCategory > > aComplexCatsPerIndex;
349 for (
auto const& complexCat : rComplexCats)
351 std::vector< ComplexCategory > aSingleLevel;
352 for (
auto const& elem : complexCat)
354 sal_Int32
nCount = elem.Count;
356 aSingleLevel.push_back(elem);
358 aComplexCatsPerIndex.push_back( aSingleLevel );
361 if(nMaxCategoryCount)
363 aRet.realloc(nMaxCategoryCount);
364 auto pRet = aRet.getArray();
365 for(sal_Int32 nN=0; nN<nMaxCategoryCount; nN++)
367 OUStringBuffer aText;
368 for (
auto const& complexCatPerIndex : aComplexCatsPerIndex)
372 OUString aAddText = complexCatPerIndex[nN].Text;
373 if( !aAddText.isEmpty() )
377 aText.append(aAddText);
381 pRet[nN]=aText.makeStringAndClear();
390 vector< vector< ComplexCategory > > aComplexCats;
396 bool bOnlyDatesFound =
true;
397 bool bAnyDataFound =
false;
399 if( xDataSequence.is() )
402 sal_Int32
nCount = aValues.getLength();
403 rDateCategories.reserve(
nCount);
406 bool bOwnData =
false;
407 bool bOwnDataAnddAxisHasAnyFormat =
false;
408 bool bOwnDataAnddAxisHasDateFormat =
false;
410 if( xCooSysModel.is() )
412 if( rModel.hasInternalDataProvider() )
416 sal_Int32 nAxisNumberFormat = 0;
417 if (xAxisProps.is() && (xAxisProps->getPropertyValue(
CHART_UNONAME_NUMFMT) >>= nAxisNumberFormat))
419 bOwnDataAnddAxisHasAnyFormat =
true;
420 bOwnDataAnddAxisHasDateFormat = DiagramHelper::isDateNumberFormat( nAxisNumberFormat, xNumberFormats );
425 for(sal_Int32 nN=0;nN<
nCount;nN++)
427 bool bIsDate =
false;
431 bIsDate = !bOwnDataAnddAxisHasAnyFormat || bOwnDataAnddAxisHasDateFormat;
433 bIsDate = DiagramHelper::isDateNumberFormat( xDataSequence->getNumberFormatKeyByIndex( nN ), xNumberFormats );
438 bool bContainsEmptyString =
false;
444 bool bContainsNan =
false;
445 if( (aAny>>=aTest) && aTest.isEmpty() )
446 bContainsEmptyString =
true;
447 else if( (aAny>>=fTest) && std::isnan(fTest) )
450 if( !bContainsEmptyString && !bContainsNan )
451 bAnyDataFound =
true;
454 if( bIsDate && (aAny >>= aDate) )
455 rDateCategories.push_back( aDate );
458 if( aAny.
hasValue() && !bContainsEmptyString )
459 bOnlyDatesFound=
false;
460 rDateCategories.push_back( std::numeric_limits<double>::quiet_NaN() );
463 std::sort( rDateCategories.begin(), rDateCategories.end() );
466 return bAnyDataFound && bOnlyDatesFound;
469void ExplicitCategoriesProvider::init()
474 m_aComplexCats.clear();
475 m_aDateCategories.clear();
477 if( m_xOriginalCategories.is() )
479 if( !hasComplexCategories() )
483 if( ChartTypeHelper::isSupportingDateAxis( AxisHelper::getChartTypeByIndex( m_xCooSysModel.get(), 0 ), 0 ) )
486 m_bIsDateAxis =
false;
491 m_bIsDateAxis =
false;
501 if( !m_bIsExplicitCategoriesInited )
504 m_aExplicitCategories.realloc(0);
505 if( m_xOriginalCategories.is() )
507 if( !hasComplexCategories() )
510 if( xDataSequence.is() )
511 ExplicitCategoriesProvider::convertCategoryAnysToText( m_aExplicitCategories, xDataSequence->getData(),
mrModel );
516 SplitCategoriesProvider_ForLabeledDataSequences( m_aSplitCategoriesList,
mrModel ), m_aComplexCats );
519 if(!m_aExplicitCategories.hasElements())
520 m_aExplicitCategories = DiagramHelper::generateAutomaticCategoriesFromCooSys( m_xCooSysModel.get() );
521 m_bIsExplicitCategoriesInited =
true;
523 return m_aExplicitCategories;
526const std::vector<ComplexCategory>* ExplicitCategoriesProvider::getCategoriesByLevel( sal_Int32 nLevel )
529 sal_Int32 nMaxIndex = m_aComplexCats.size()-1;
530 if (nLevel >= 0 && nLevel <= nMaxIndex)
531 return &m_aComplexCats[nMaxIndex-nLevel];
535OUString ExplicitCategoriesProvider::getCategoryByIndex(
540 if( xCooSysModel.is())
544 if(
nIndex < aCategories.getLength())
545 return aCategories[
nIndex ];
550bool ExplicitCategoriesProvider::isDateAxis()
553 return m_bIsDateAxis;
556const std::vector< double >& ExplicitCategoriesProvider::getDateCategories()
559 return m_aDateCategories;
const std::vector< Reference< data::XLabeledDataSequence > > & m_rSplitCategoriesList
FILE * init(int, char **)
ExplicitCategoriesProvider(const rtl::Reference< ::chart::BaseCoordinateSystem > &xCooSysModel, ChartModel &rChartModel)
css::uno::Sequence< OUString > const & getSimpleCategories()
virtual css::uno::Sequence< OUString > getStringsForLevel(sal_Int32 nIndex) const =0
virtual sal_Int32 getLevelCount() const =0
#define DBG_UNHANDLED_EXCEPTION(...)
static std::vector< ComplexCategory > lcl_DataSequenceToComplexCategoryVector(const uno::Sequence< OUString > &rStrings, const std::vector< sal_Int32 > &rLimitingBorders, bool bCreateSingleCategories)
static std::vector< sal_Int32 > lcl_getLimitingBorders(const std::vector< ComplexCategory > &rComplexCategories)
static Sequence< OUString > lcl_getExplicitSimpleCategories(const SplitCategoriesProvider &rSplitCategoriesProvider, std::vector< std::vector< ComplexCategory > > &rComplexCats)
static sal_Int32 lcl_getCategoryCount(std::vector< ComplexCategory > &rComplexCategories)
static bool lcl_fillDateCategories(const uno::Reference< data::XDataSequence > &xDataSequence, std::vector< double > &rDateCategories, bool bIsAutoDate, ChartModel &rModel)
constexpr std::enable_if_t< std::is_signed_v< T >, std::make_unsigned_t< T > > make_unsigned(T value)
css::uno::Reference< css::linguistic2::XProofreadingIterator > get(css::uno::Reference< css::uno::XComponentContext > const &context)
constexpr OUStringLiteral CHART_UNONAME_NUMFMT