1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4*cdf0e10cSrcweir * 5*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6*cdf0e10cSrcweir * 7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * This file is part of OpenOffice.org. 10*cdf0e10cSrcweir * 11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13*cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14*cdf0e10cSrcweir * 15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22*cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24*cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25*cdf0e10cSrcweir * 26*cdf0e10cSrcweir ************************************************************************/ 27*cdf0e10cSrcweir 28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 29*cdf0e10cSrcweir #include "precompiled_chart2.hxx" 30*cdf0e10cSrcweir 31*cdf0e10cSrcweir #include "ExplicitCategoriesProvider.hxx" 32*cdf0e10cSrcweir #include "DiagramHelper.hxx" 33*cdf0e10cSrcweir #include "ChartTypeHelper.hxx" 34*cdf0e10cSrcweir #include "AxisHelper.hxx" 35*cdf0e10cSrcweir #include "CommonConverters.hxx" 36*cdf0e10cSrcweir #include "DataSourceHelper.hxx" 37*cdf0e10cSrcweir #include "ChartModelHelper.hxx" 38*cdf0e10cSrcweir #include "ContainerHelper.hxx" 39*cdf0e10cSrcweir #include "macros.hxx" 40*cdf0e10cSrcweir #include "NumberFormatterWrapper.hxx" 41*cdf0e10cSrcweir 42*cdf0e10cSrcweir #include <com/sun/star/chart2/AxisType.hpp> 43*cdf0e10cSrcweir #include <com/sun/star/util/NumberFormat.hpp> 44*cdf0e10cSrcweir #include <com/sun/star/util/XNumberFormatsSupplier.hpp> 45*cdf0e10cSrcweir 46*cdf0e10cSrcweir //............................................................................. 47*cdf0e10cSrcweir namespace chart 48*cdf0e10cSrcweir { 49*cdf0e10cSrcweir //............................................................................. 50*cdf0e10cSrcweir 51*cdf0e10cSrcweir using namespace ::com::sun::star; 52*cdf0e10cSrcweir using namespace ::com::sun::star::chart2; 53*cdf0e10cSrcweir using ::com::sun::star::uno::Reference; 54*cdf0e10cSrcweir using ::com::sun::star::uno::Sequence; 55*cdf0e10cSrcweir using ::rtl::OUString; 56*cdf0e10cSrcweir using ::std::vector; 57*cdf0e10cSrcweir 58*cdf0e10cSrcweir 59*cdf0e10cSrcweir ExplicitCategoriesProvider::ExplicitCategoriesProvider( const Reference< chart2::XCoordinateSystem >& xCooSysModel 60*cdf0e10cSrcweir , const uno::Reference< frame::XModel >& xChartModel ) 61*cdf0e10cSrcweir : m_bDirty(true) 62*cdf0e10cSrcweir , m_xCooSysModel( xCooSysModel ) 63*cdf0e10cSrcweir , m_xChartModel( xChartModel ) 64*cdf0e10cSrcweir , m_xOriginalCategories() 65*cdf0e10cSrcweir , m_bIsExplicitCategoriesInited(false) 66*cdf0e10cSrcweir , m_bIsDateAxis(false) 67*cdf0e10cSrcweir , m_bIsAutoDate(false) 68*cdf0e10cSrcweir { 69*cdf0e10cSrcweir try 70*cdf0e10cSrcweir { 71*cdf0e10cSrcweir if( xCooSysModel.is() ) 72*cdf0e10cSrcweir { 73*cdf0e10cSrcweir uno::Reference< XAxis > xAxis( xCooSysModel->getAxisByDimension(0,0) ); 74*cdf0e10cSrcweir if( xAxis.is() ) 75*cdf0e10cSrcweir { 76*cdf0e10cSrcweir ScaleData aScale( xAxis->getScaleData() ); 77*cdf0e10cSrcweir m_xOriginalCategories = aScale.Categories; 78*cdf0e10cSrcweir m_bIsAutoDate = (aScale.AutoDateAxis && aScale.AxisType==chart2::AxisType::CATEGORY); 79*cdf0e10cSrcweir m_bIsDateAxis = (aScale.AxisType == chart2::AxisType::DATE || m_bIsAutoDate); 80*cdf0e10cSrcweir } 81*cdf0e10cSrcweir } 82*cdf0e10cSrcweir 83*cdf0e10cSrcweir if( m_xOriginalCategories.is() ) 84*cdf0e10cSrcweir { 85*cdf0e10cSrcweir Reference< chart2::XChartDocument > xChartDoc( xChartModel, uno::UNO_QUERY ); 86*cdf0e10cSrcweir if( xChartDoc.is() ) 87*cdf0e10cSrcweir { 88*cdf0e10cSrcweir uno::Reference< data::XDataProvider > xDataProvider( xChartDoc->getDataProvider() ); 89*cdf0e10cSrcweir 90*cdf0e10cSrcweir OUString aCatgoriesRange( DataSourceHelper::getRangeFromValues( m_xOriginalCategories ) ); 91*cdf0e10cSrcweir if( xDataProvider.is() && aCatgoriesRange.getLength() ) 92*cdf0e10cSrcweir { 93*cdf0e10cSrcweir const bool bFirstCellAsLabel = false; 94*cdf0e10cSrcweir const bool bHasCategories = false; 95*cdf0e10cSrcweir const uno::Sequence< sal_Int32 > aSequenceMapping; 96*cdf0e10cSrcweir 97*cdf0e10cSrcweir uno::Reference< data::XDataSource > xColumnCategoriesSource( xDataProvider->createDataSource( 98*cdf0e10cSrcweir DataSourceHelper::createArguments( aCatgoriesRange, aSequenceMapping, true /*bUseColumns*/ 99*cdf0e10cSrcweir , bFirstCellAsLabel, bHasCategories ) ) ); 100*cdf0e10cSrcweir 101*cdf0e10cSrcweir uno::Reference< data::XDataSource > xRowCategoriesSource( xDataProvider->createDataSource( 102*cdf0e10cSrcweir DataSourceHelper::createArguments( aCatgoriesRange, aSequenceMapping, false /*bUseColumns*/ 103*cdf0e10cSrcweir , bFirstCellAsLabel, bHasCategories ) ) ); 104*cdf0e10cSrcweir 105*cdf0e10cSrcweir if( xColumnCategoriesSource.is() && xRowCategoriesSource.is() ) 106*cdf0e10cSrcweir { 107*cdf0e10cSrcweir Sequence< Reference< data::XLabeledDataSequence> > aColumns = xColumnCategoriesSource->getDataSequences(); 108*cdf0e10cSrcweir Sequence< Reference< data::XLabeledDataSequence> > aRows = xRowCategoriesSource->getDataSequences(); 109*cdf0e10cSrcweir 110*cdf0e10cSrcweir sal_Int32 nColumnCount = aColumns.getLength(); 111*cdf0e10cSrcweir sal_Int32 nRowCount = aRows.getLength(); 112*cdf0e10cSrcweir if( nColumnCount>1 && nRowCount>1 ) 113*cdf0e10cSrcweir { 114*cdf0e10cSrcweir //we have complex categories 115*cdf0e10cSrcweir //->split them in the direction of the first series 116*cdf0e10cSrcweir //detect whether the first series is a row or a column 117*cdf0e10cSrcweir bool bSeriesUsesColumns = true; 118*cdf0e10cSrcweir ::std::vector< Reference< XDataSeries > > aSeries( ChartModelHelper::getDataSeries( xChartModel ) ); 119*cdf0e10cSrcweir if( !aSeries.empty() ) 120*cdf0e10cSrcweir { 121*cdf0e10cSrcweir uno::Reference< data::XDataSource > xSeriesSource( aSeries.front(), uno::UNO_QUERY ); 122*cdf0e10cSrcweir ::rtl::OUString aStringDummy; 123*cdf0e10cSrcweir bool bDummy; 124*cdf0e10cSrcweir uno::Sequence< sal_Int32 > aSeqDummy; 125*cdf0e10cSrcweir DataSourceHelper::readArguments( xDataProvider->detectArguments( xSeriesSource), 126*cdf0e10cSrcweir aStringDummy, aSeqDummy, bSeriesUsesColumns, bDummy, bDummy ); 127*cdf0e10cSrcweir } 128*cdf0e10cSrcweir if( bSeriesUsesColumns ) 129*cdf0e10cSrcweir m_aSplitCategoriesList=aColumns; 130*cdf0e10cSrcweir else 131*cdf0e10cSrcweir m_aSplitCategoriesList=aRows; 132*cdf0e10cSrcweir } 133*cdf0e10cSrcweir } 134*cdf0e10cSrcweir } 135*cdf0e10cSrcweir } 136*cdf0e10cSrcweir if( !m_aSplitCategoriesList.getLength() ) 137*cdf0e10cSrcweir { 138*cdf0e10cSrcweir m_aSplitCategoriesList.realloc(1); 139*cdf0e10cSrcweir m_aSplitCategoriesList[0]=m_xOriginalCategories; 140*cdf0e10cSrcweir } 141*cdf0e10cSrcweir } 142*cdf0e10cSrcweir } 143*cdf0e10cSrcweir catch( const uno::Exception & ex ) 144*cdf0e10cSrcweir { 145*cdf0e10cSrcweir ASSERT_EXCEPTION( ex ); 146*cdf0e10cSrcweir } 147*cdf0e10cSrcweir } 148*cdf0e10cSrcweir 149*cdf0e10cSrcweir ExplicitCategoriesProvider::~ExplicitCategoriesProvider() 150*cdf0e10cSrcweir { 151*cdf0e10cSrcweir } 152*cdf0e10cSrcweir 153*cdf0e10cSrcweir Reference< chart2::data::XDataSequence > ExplicitCategoriesProvider::getOriginalCategories() 154*cdf0e10cSrcweir { 155*cdf0e10cSrcweir if( m_xOriginalCategories.is() ) 156*cdf0e10cSrcweir return m_xOriginalCategories->getValues(); 157*cdf0e10cSrcweir return 0; 158*cdf0e10cSrcweir } 159*cdf0e10cSrcweir 160*cdf0e10cSrcweir const Sequence< Reference< data::XLabeledDataSequence> >& ExplicitCategoriesProvider::getSplitCategoriesList() 161*cdf0e10cSrcweir { 162*cdf0e10cSrcweir return m_aSplitCategoriesList; 163*cdf0e10cSrcweir } 164*cdf0e10cSrcweir 165*cdf0e10cSrcweir bool ExplicitCategoriesProvider::hasComplexCategories() const 166*cdf0e10cSrcweir { 167*cdf0e10cSrcweir return m_aSplitCategoriesList.getLength() > 1; 168*cdf0e10cSrcweir } 169*cdf0e10cSrcweir 170*cdf0e10cSrcweir sal_Int32 ExplicitCategoriesProvider::getCategoryLevelCount() const 171*cdf0e10cSrcweir { 172*cdf0e10cSrcweir sal_Int32 nCount = m_aSplitCategoriesList.getLength(); 173*cdf0e10cSrcweir if(!nCount) 174*cdf0e10cSrcweir nCount = 1; 175*cdf0e10cSrcweir return nCount; 176*cdf0e10cSrcweir } 177*cdf0e10cSrcweir 178*cdf0e10cSrcweir std::vector<sal_Int32> lcl_getLimitingBorders( const std::vector< ComplexCategory >& rComplexCategories ) 179*cdf0e10cSrcweir { 180*cdf0e10cSrcweir std::vector<sal_Int32> aLimitingBorders; 181*cdf0e10cSrcweir std::vector< ComplexCategory >::const_iterator aIt( rComplexCategories.begin() ); 182*cdf0e10cSrcweir std::vector< ComplexCategory >::const_iterator aEnd( rComplexCategories.end() ); 183*cdf0e10cSrcweir sal_Int32 nBorderIndex = 0; /*border below the index*/ 184*cdf0e10cSrcweir for( ; aIt != aEnd; ++aIt ) 185*cdf0e10cSrcweir { 186*cdf0e10cSrcweir ComplexCategory aComplexCategory(*aIt); 187*cdf0e10cSrcweir nBorderIndex += aComplexCategory.Count; 188*cdf0e10cSrcweir aLimitingBorders.push_back(nBorderIndex); 189*cdf0e10cSrcweir } 190*cdf0e10cSrcweir return aLimitingBorders; 191*cdf0e10cSrcweir } 192*cdf0e10cSrcweir 193*cdf0e10cSrcweir void ExplicitCategoriesProvider::convertCategoryAnysToText( uno::Sequence< rtl::OUString >& rOutTexts, const uno::Sequence< uno::Any >& rInAnys, Reference< frame::XModel > xChartModel ) 194*cdf0e10cSrcweir { 195*cdf0e10cSrcweir sal_Int32 nCount = rInAnys.getLength(); 196*cdf0e10cSrcweir if(!nCount) 197*cdf0e10cSrcweir return; 198*cdf0e10cSrcweir rOutTexts.realloc(nCount); 199*cdf0e10cSrcweir Reference< util::XNumberFormatsSupplier > xNumberFormatsSupplier( xChartModel, uno::UNO_QUERY ); 200*cdf0e10cSrcweir Reference< util::XNumberFormats > xNumberFormats; 201*cdf0e10cSrcweir if( xNumberFormatsSupplier.is() ) 202*cdf0e10cSrcweir xNumberFormats = Reference< util::XNumberFormats >( xNumberFormatsSupplier->getNumberFormats() ); 203*cdf0e10cSrcweir 204*cdf0e10cSrcweir sal_Int32 nAxisNumberFormat = 0; 205*cdf0e10cSrcweir Reference< XCoordinateSystem > xCooSysModel( ChartModelHelper::getFirstCoordinateSystem( xChartModel ) ); 206*cdf0e10cSrcweir if( xCooSysModel.is() ) 207*cdf0e10cSrcweir { 208*cdf0e10cSrcweir Reference< chart2::XAxis > xAxis( xCooSysModel->getAxisByDimension(0,0) ); 209*cdf0e10cSrcweir nAxisNumberFormat = AxisHelper::getExplicitNumberFormatKeyForAxis( 210*cdf0e10cSrcweir xAxis, xCooSysModel, xNumberFormatsSupplier, false ); 211*cdf0e10cSrcweir } 212*cdf0e10cSrcweir 213*cdf0e10cSrcweir sal_Int32 nLabelColor; 214*cdf0e10cSrcweir bool bColorChanged = false; 215*cdf0e10cSrcweir 216*cdf0e10cSrcweir NumberFormatterWrapper aNumberFormatterWrapper( xNumberFormatsSupplier ); 217*cdf0e10cSrcweir 218*cdf0e10cSrcweir for(sal_Int32 nN=0;nN<nCount;nN++) 219*cdf0e10cSrcweir { 220*cdf0e10cSrcweir rtl::OUString aText; 221*cdf0e10cSrcweir uno::Any aAny = rInAnys[nN]; 222*cdf0e10cSrcweir if( aAny.hasValue() ) 223*cdf0e10cSrcweir { 224*cdf0e10cSrcweir double fDouble = 0; 225*cdf0e10cSrcweir if( aAny>>=fDouble ) 226*cdf0e10cSrcweir { 227*cdf0e10cSrcweir if( !::rtl::math::isNan(fDouble) ) 228*cdf0e10cSrcweir aText = aNumberFormatterWrapper.getFormattedString( 229*cdf0e10cSrcweir nAxisNumberFormat, fDouble, nLabelColor, bColorChanged ); 230*cdf0e10cSrcweir } 231*cdf0e10cSrcweir else 232*cdf0e10cSrcweir { 233*cdf0e10cSrcweir aAny>>=aText; 234*cdf0e10cSrcweir } 235*cdf0e10cSrcweir } 236*cdf0e10cSrcweir rOutTexts[nN] = aText; 237*cdf0e10cSrcweir } 238*cdf0e10cSrcweir } 239*cdf0e10cSrcweir 240*cdf0e10cSrcweir SplitCategoriesProvider::~SplitCategoriesProvider() 241*cdf0e10cSrcweir { 242*cdf0e10cSrcweir } 243*cdf0e10cSrcweir 244*cdf0e10cSrcweir class SplitCategoriesProvider_ForLabeledDataSequences : public SplitCategoriesProvider 245*cdf0e10cSrcweir { 246*cdf0e10cSrcweir public: 247*cdf0e10cSrcweir 248*cdf0e10cSrcweir explicit SplitCategoriesProvider_ForLabeledDataSequences( 249*cdf0e10cSrcweir const ::com::sun::star::uno::Sequence< 250*cdf0e10cSrcweir ::com::sun::star::uno::Reference< 251*cdf0e10cSrcweir ::com::sun::star::chart2::data::XLabeledDataSequence> >& rSplitCategoriesList 252*cdf0e10cSrcweir , const Reference< frame::XModel >& xChartModel ) 253*cdf0e10cSrcweir : m_rSplitCategoriesList( rSplitCategoriesList ) 254*cdf0e10cSrcweir , m_xChartModel( xChartModel ) 255*cdf0e10cSrcweir {} 256*cdf0e10cSrcweir virtual ~SplitCategoriesProvider_ForLabeledDataSequences() 257*cdf0e10cSrcweir {} 258*cdf0e10cSrcweir 259*cdf0e10cSrcweir virtual sal_Int32 getLevelCount() const; 260*cdf0e10cSrcweir virtual uno::Sequence< rtl::OUString > getStringsForLevel( sal_Int32 nIndex ) const; 261*cdf0e10cSrcweir 262*cdf0e10cSrcweir private: 263*cdf0e10cSrcweir const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< 264*cdf0e10cSrcweir ::com::sun::star::chart2::data::XLabeledDataSequence> >& m_rSplitCategoriesList; 265*cdf0e10cSrcweir 266*cdf0e10cSrcweir Reference< frame::XModel > m_xChartModel; 267*cdf0e10cSrcweir }; 268*cdf0e10cSrcweir 269*cdf0e10cSrcweir sal_Int32 SplitCategoriesProvider_ForLabeledDataSequences::getLevelCount() const 270*cdf0e10cSrcweir { 271*cdf0e10cSrcweir return m_rSplitCategoriesList.getLength(); 272*cdf0e10cSrcweir } 273*cdf0e10cSrcweir uno::Sequence< rtl::OUString > SplitCategoriesProvider_ForLabeledDataSequences::getStringsForLevel( sal_Int32 nLevel ) const 274*cdf0e10cSrcweir { 275*cdf0e10cSrcweir uno::Sequence< rtl::OUString > aRet; 276*cdf0e10cSrcweir Reference< data::XLabeledDataSequence > xLabeledDataSequence( m_rSplitCategoriesList[nLevel] ); 277*cdf0e10cSrcweir if( xLabeledDataSequence.is() ) 278*cdf0e10cSrcweir { 279*cdf0e10cSrcweir uno::Reference< data::XDataSequence > xDataSequence( xLabeledDataSequence->getValues() ); 280*cdf0e10cSrcweir if( xDataSequence.is() ) 281*cdf0e10cSrcweir ExplicitCategoriesProvider::convertCategoryAnysToText( aRet, xDataSequence->getData(), m_xChartModel ); 282*cdf0e10cSrcweir } 283*cdf0e10cSrcweir return aRet; 284*cdf0e10cSrcweir } 285*cdf0e10cSrcweir 286*cdf0e10cSrcweir std::vector< ComplexCategory > lcl_DataSequenceToComplexCategoryVector( 287*cdf0e10cSrcweir const uno::Sequence< rtl::OUString >& rStrings 288*cdf0e10cSrcweir , const std::vector<sal_Int32>& rLimitingBorders, bool bCreateSingleCategories ) 289*cdf0e10cSrcweir { 290*cdf0e10cSrcweir std::vector< ComplexCategory > aResult; 291*cdf0e10cSrcweir 292*cdf0e10cSrcweir sal_Int32 nMaxCount = rStrings.getLength(); 293*cdf0e10cSrcweir OUString aPrevious; 294*cdf0e10cSrcweir sal_Int32 nCurrentCount=0; 295*cdf0e10cSrcweir for( sal_Int32 nN=0; nN<nMaxCount; nN++ ) 296*cdf0e10cSrcweir { 297*cdf0e10cSrcweir OUString aCurrent = rStrings[nN]; 298*cdf0e10cSrcweir if( bCreateSingleCategories || ::std::find( rLimitingBorders.begin(), rLimitingBorders.end(), nN ) != rLimitingBorders.end() ) 299*cdf0e10cSrcweir { 300*cdf0e10cSrcweir aResult.push_back( ComplexCategory(aPrevious,nCurrentCount) ); 301*cdf0e10cSrcweir nCurrentCount=1; 302*cdf0e10cSrcweir aPrevious = aCurrent; 303*cdf0e10cSrcweir } 304*cdf0e10cSrcweir else 305*cdf0e10cSrcweir { 306*cdf0e10cSrcweir if( aCurrent.getLength() && aPrevious != aCurrent ) 307*cdf0e10cSrcweir { 308*cdf0e10cSrcweir aResult.push_back( ComplexCategory(aPrevious,nCurrentCount) ); 309*cdf0e10cSrcweir nCurrentCount=1; 310*cdf0e10cSrcweir aPrevious = aCurrent; 311*cdf0e10cSrcweir } 312*cdf0e10cSrcweir else 313*cdf0e10cSrcweir nCurrentCount++; 314*cdf0e10cSrcweir } 315*cdf0e10cSrcweir } 316*cdf0e10cSrcweir if( nCurrentCount ) 317*cdf0e10cSrcweir aResult.push_back( ComplexCategory(aPrevious,nCurrentCount) ); 318*cdf0e10cSrcweir 319*cdf0e10cSrcweir return aResult; 320*cdf0e10cSrcweir } 321*cdf0e10cSrcweir 322*cdf0e10cSrcweir sal_Int32 lcl_getCategoryCount( std::vector< ComplexCategory >& rComplexCategories ) 323*cdf0e10cSrcweir { 324*cdf0e10cSrcweir sal_Int32 nCount = 0; 325*cdf0e10cSrcweir std::vector< ComplexCategory >::iterator aIt( rComplexCategories.begin() ); 326*cdf0e10cSrcweir std::vector< ComplexCategory >::const_iterator aEnd( rComplexCategories.end() ); 327*cdf0e10cSrcweir for( ; aIt != aEnd; ++aIt ) 328*cdf0e10cSrcweir nCount+=aIt->Count; 329*cdf0e10cSrcweir return nCount; 330*cdf0e10cSrcweir } 331*cdf0e10cSrcweir 332*cdf0e10cSrcweir Sequence< OUString > lcl_getExplicitSimpleCategories( 333*cdf0e10cSrcweir const SplitCategoriesProvider& rSplitCategoriesProvider, 334*cdf0e10cSrcweir ::std::vector< ::std::vector< ComplexCategory > >& rComplexCats ) 335*cdf0e10cSrcweir { 336*cdf0e10cSrcweir Sequence< OUString > aRet; 337*cdf0e10cSrcweir 338*cdf0e10cSrcweir rComplexCats.clear(); 339*cdf0e10cSrcweir sal_Int32 nLCount = rSplitCategoriesProvider.getLevelCount(); 340*cdf0e10cSrcweir for( sal_Int32 nL = 0; nL < nLCount; nL++ ) 341*cdf0e10cSrcweir { 342*cdf0e10cSrcweir std::vector<sal_Int32> aLimitingBorders; 343*cdf0e10cSrcweir if(nL>0) 344*cdf0e10cSrcweir aLimitingBorders = lcl_getLimitingBorders( rComplexCats.back() ); 345*cdf0e10cSrcweir rComplexCats.push_back( lcl_DataSequenceToComplexCategoryVector( 346*cdf0e10cSrcweir rSplitCategoriesProvider.getStringsForLevel(nL), aLimitingBorders, nL==(nLCount-1) ) ); 347*cdf0e10cSrcweir } 348*cdf0e10cSrcweir 349*cdf0e10cSrcweir std::vector< std::vector< ComplexCategory > >::iterator aOuterIt( rComplexCats.begin() ); 350*cdf0e10cSrcweir std::vector< std::vector< ComplexCategory > >::const_iterator aOuterEnd( rComplexCats.end() ); 351*cdf0e10cSrcweir 352*cdf0e10cSrcweir //ensure that the category count is the same on each level 353*cdf0e10cSrcweir sal_Int32 nMaxCategoryCount = 0; 354*cdf0e10cSrcweir { 355*cdf0e10cSrcweir for( aOuterIt=rComplexCats.begin(); aOuterIt != aOuterEnd; ++aOuterIt ) 356*cdf0e10cSrcweir { 357*cdf0e10cSrcweir sal_Int32 nCurrentCount = lcl_getCategoryCount( *aOuterIt ); 358*cdf0e10cSrcweir nMaxCategoryCount = std::max( nCurrentCount, nMaxCategoryCount ); 359*cdf0e10cSrcweir } 360*cdf0e10cSrcweir for( aOuterIt=rComplexCats.begin(); aOuterIt != aOuterEnd; ++aOuterIt ) 361*cdf0e10cSrcweir { 362*cdf0e10cSrcweir sal_Int32 nCurrentCount = lcl_getCategoryCount( *aOuterIt ); 363*cdf0e10cSrcweir if( nCurrentCount< nMaxCategoryCount ) 364*cdf0e10cSrcweir { 365*cdf0e10cSrcweir ComplexCategory& rComplexCategory = aOuterIt->back(); 366*cdf0e10cSrcweir rComplexCategory.Count += (nMaxCategoryCount-nCurrentCount); 367*cdf0e10cSrcweir } 368*cdf0e10cSrcweir } 369*cdf0e10cSrcweir } 370*cdf0e10cSrcweir 371*cdf0e10cSrcweir //create a list with an element for every index 372*cdf0e10cSrcweir std::vector< std::vector< ComplexCategory > > aComplexCatsPerIndex; 373*cdf0e10cSrcweir for( aOuterIt=rComplexCats.begin() ; aOuterIt != aOuterEnd; ++aOuterIt ) 374*cdf0e10cSrcweir { 375*cdf0e10cSrcweir std::vector< ComplexCategory > aSingleLevel; 376*cdf0e10cSrcweir std::vector< ComplexCategory >::iterator aIt( aOuterIt->begin() ); 377*cdf0e10cSrcweir std::vector< ComplexCategory >::const_iterator aEnd( aOuterIt->end() ); 378*cdf0e10cSrcweir for( ; aIt != aEnd; ++aIt ) 379*cdf0e10cSrcweir { 380*cdf0e10cSrcweir ComplexCategory aComplexCategory( *aIt ); 381*cdf0e10cSrcweir sal_Int32 nCount = aComplexCategory.Count; 382*cdf0e10cSrcweir while( nCount-- ) 383*cdf0e10cSrcweir aSingleLevel.push_back(aComplexCategory); 384*cdf0e10cSrcweir } 385*cdf0e10cSrcweir aComplexCatsPerIndex.push_back( aSingleLevel ); 386*cdf0e10cSrcweir } 387*cdf0e10cSrcweir 388*cdf0e10cSrcweir if(nMaxCategoryCount) 389*cdf0e10cSrcweir { 390*cdf0e10cSrcweir aRet.realloc(nMaxCategoryCount); 391*cdf0e10cSrcweir aOuterEnd = aComplexCatsPerIndex.end(); 392*cdf0e10cSrcweir OUString aSpace(C2U(" ")); 393*cdf0e10cSrcweir for(sal_Int32 nN=0; nN<nMaxCategoryCount; nN++) 394*cdf0e10cSrcweir { 395*cdf0e10cSrcweir OUString aText; 396*cdf0e10cSrcweir for( aOuterIt=aComplexCatsPerIndex.begin() ; aOuterIt != aOuterEnd; ++aOuterIt ) 397*cdf0e10cSrcweir { 398*cdf0e10cSrcweir OUString aAddText = (*aOuterIt)[nN].Text; 399*cdf0e10cSrcweir if( aAddText.getLength() ) 400*cdf0e10cSrcweir { 401*cdf0e10cSrcweir if(aText.getLength()) 402*cdf0e10cSrcweir aText += aSpace; 403*cdf0e10cSrcweir aText += aAddText; 404*cdf0e10cSrcweir } 405*cdf0e10cSrcweir } 406*cdf0e10cSrcweir aRet[nN]=aText; 407*cdf0e10cSrcweir } 408*cdf0e10cSrcweir } 409*cdf0e10cSrcweir return aRet; 410*cdf0e10cSrcweir } 411*cdf0e10cSrcweir 412*cdf0e10cSrcweir Sequence< OUString > ExplicitCategoriesProvider::getExplicitSimpleCategories( 413*cdf0e10cSrcweir const SplitCategoriesProvider& rSplitCategoriesProvider ) 414*cdf0e10cSrcweir { 415*cdf0e10cSrcweir vector< vector< ComplexCategory > > aComplexCats; 416*cdf0e10cSrcweir return lcl_getExplicitSimpleCategories( rSplitCategoriesProvider, aComplexCats ); 417*cdf0e10cSrcweir } 418*cdf0e10cSrcweir 419*cdf0e10cSrcweir struct DatePlusIndexComparator 420*cdf0e10cSrcweir { 421*cdf0e10cSrcweir inline bool operator() ( const DatePlusIndex& aFirst, 422*cdf0e10cSrcweir const DatePlusIndex& aSecond ) 423*cdf0e10cSrcweir { 424*cdf0e10cSrcweir return ( aFirst.fValue < aSecond.fValue ); 425*cdf0e10cSrcweir } 426*cdf0e10cSrcweir }; 427*cdf0e10cSrcweir 428*cdf0e10cSrcweir bool lcl_fillDateCategories( const uno::Reference< data::XDataSequence >& xDataSequence, std::vector< DatePlusIndex >& rDateCategories, bool bIsAutoDate, Reference< util::XNumberFormatsSupplier > xNumberFormatsSupplier ) 429*cdf0e10cSrcweir { 430*cdf0e10cSrcweir bool bOnlyDatesFound = true; 431*cdf0e10cSrcweir bool bAnyDataFound = false; 432*cdf0e10cSrcweir 433*cdf0e10cSrcweir if( xDataSequence.is() ) 434*cdf0e10cSrcweir { 435*cdf0e10cSrcweir uno::Sequence< uno::Any > aValues = xDataSequence->getData(); 436*cdf0e10cSrcweir sal_Int32 nCount = aValues.getLength(); 437*cdf0e10cSrcweir rDateCategories.reserve(nCount); 438*cdf0e10cSrcweir Reference< util::XNumberFormats > xNumberFormats; 439*cdf0e10cSrcweir if( xNumberFormatsSupplier.is() ) 440*cdf0e10cSrcweir xNumberFormats = Reference< util::XNumberFormats >( xNumberFormatsSupplier->getNumberFormats() ); 441*cdf0e10cSrcweir 442*cdf0e10cSrcweir bool bOwnData = false; 443*cdf0e10cSrcweir bool bOwnDataAnddAxisHasAnyFormat = false; 444*cdf0e10cSrcweir bool bOwnDataAnddAxisHasDateFormat = false; 445*cdf0e10cSrcweir Reference< chart2::XChartDocument > xChartDoc( xNumberFormatsSupplier, uno::UNO_QUERY ); 446*cdf0e10cSrcweir Reference< XCoordinateSystem > xCooSysModel( ChartModelHelper::getFirstCoordinateSystem( Reference< frame::XModel >( xChartDoc, uno::UNO_QUERY ) ) ); 447*cdf0e10cSrcweir if( xChartDoc.is() && xCooSysModel.is() ) 448*cdf0e10cSrcweir { 449*cdf0e10cSrcweir if( xChartDoc->hasInternalDataProvider() ) 450*cdf0e10cSrcweir { 451*cdf0e10cSrcweir bOwnData = true; 452*cdf0e10cSrcweir Reference< beans::XPropertySet > xAxisProps( xCooSysModel->getAxisByDimension(0,0), uno::UNO_QUERY ); 453*cdf0e10cSrcweir sal_Int32 nAxisNumberFormat = 0; 454*cdf0e10cSrcweir if( xAxisProps.is() && (xAxisProps->getPropertyValue( C2U("NumberFormat") ) >>= nAxisNumberFormat) ) 455*cdf0e10cSrcweir { 456*cdf0e10cSrcweir bOwnDataAnddAxisHasAnyFormat = true; 457*cdf0e10cSrcweir bOwnDataAnddAxisHasDateFormat = DiagramHelper::isDateNumberFormat( nAxisNumberFormat, xNumberFormats ); 458*cdf0e10cSrcweir } 459*cdf0e10cSrcweir } 460*cdf0e10cSrcweir } 461*cdf0e10cSrcweir 462*cdf0e10cSrcweir for(sal_Int32 nN=0;nN<nCount;nN++) 463*cdf0e10cSrcweir { 464*cdf0e10cSrcweir bool bIsDate = false; 465*cdf0e10cSrcweir if( bIsAutoDate ) 466*cdf0e10cSrcweir { 467*cdf0e10cSrcweir if( bOwnData ) 468*cdf0e10cSrcweir bIsDate = bOwnDataAnddAxisHasAnyFormat ? bOwnDataAnddAxisHasDateFormat : true; 469*cdf0e10cSrcweir else 470*cdf0e10cSrcweir bIsDate = DiagramHelper::isDateNumberFormat( xDataSequence->getNumberFormatKeyByIndex( nN ), xNumberFormats ); 471*cdf0e10cSrcweir } 472*cdf0e10cSrcweir else 473*cdf0e10cSrcweir bIsDate = true; 474*cdf0e10cSrcweir 475*cdf0e10cSrcweir bool bContainsEmptyString = false; 476*cdf0e10cSrcweir bool bContainsNan = false; 477*cdf0e10cSrcweir uno::Any aAny = aValues[nN]; 478*cdf0e10cSrcweir if( aAny.hasValue() ) 479*cdf0e10cSrcweir { 480*cdf0e10cSrcweir OUString aTest; 481*cdf0e10cSrcweir double fTest = 0; 482*cdf0e10cSrcweir if( (aAny>>=aTest) && !aTest.getLength() ) //empty String 483*cdf0e10cSrcweir bContainsEmptyString = true; 484*cdf0e10cSrcweir else if( (aAny>>=fTest) && ::rtl::math::isNan(fTest) ) 485*cdf0e10cSrcweir bContainsNan = true; 486*cdf0e10cSrcweir 487*cdf0e10cSrcweir if( !bContainsEmptyString && !bContainsNan ) 488*cdf0e10cSrcweir bAnyDataFound = true; 489*cdf0e10cSrcweir } 490*cdf0e10cSrcweir DatePlusIndex aDatePlusIndex( 1.0, nN ); 491*cdf0e10cSrcweir if( bIsDate && (aAny >>= aDatePlusIndex.fValue) ) 492*cdf0e10cSrcweir rDateCategories.push_back( aDatePlusIndex ); 493*cdf0e10cSrcweir else 494*cdf0e10cSrcweir { 495*cdf0e10cSrcweir if( aAny.hasValue() && !bContainsEmptyString )//empty string does not count as non date value! 496*cdf0e10cSrcweir bOnlyDatesFound=false; 497*cdf0e10cSrcweir ::rtl::math::setNan( &aDatePlusIndex.fValue ); 498*cdf0e10cSrcweir rDateCategories.push_back( aDatePlusIndex ); 499*cdf0e10cSrcweir } 500*cdf0e10cSrcweir } 501*cdf0e10cSrcweir ::std::sort( rDateCategories.begin(), rDateCategories.end(), DatePlusIndexComparator() ); 502*cdf0e10cSrcweir } 503*cdf0e10cSrcweir 504*cdf0e10cSrcweir return bAnyDataFound && bOnlyDatesFound; 505*cdf0e10cSrcweir } 506*cdf0e10cSrcweir 507*cdf0e10cSrcweir void ExplicitCategoriesProvider::init() 508*cdf0e10cSrcweir { 509*cdf0e10cSrcweir if( m_bDirty ) 510*cdf0e10cSrcweir { 511*cdf0e10cSrcweir m_aComplexCats.clear();//not one per index 512*cdf0e10cSrcweir m_aDateCategories.clear(); 513*cdf0e10cSrcweir 514*cdf0e10cSrcweir if( m_xOriginalCategories.is() ) 515*cdf0e10cSrcweir { 516*cdf0e10cSrcweir if( !hasComplexCategories() ) 517*cdf0e10cSrcweir { 518*cdf0e10cSrcweir if(m_bIsDateAxis) 519*cdf0e10cSrcweir { 520*cdf0e10cSrcweir if( ChartTypeHelper::isSupportingDateAxis( AxisHelper::getChartTypeByIndex( m_xCooSysModel, 0 ), 2, 0 ) ) 521*cdf0e10cSrcweir m_bIsDateAxis = lcl_fillDateCategories( m_xOriginalCategories->getValues(), m_aDateCategories, m_bIsAutoDate, Reference< util::XNumberFormatsSupplier >( m_xChartModel.get(), uno::UNO_QUERY ) ); 522*cdf0e10cSrcweir else 523*cdf0e10cSrcweir m_bIsDateAxis = false; 524*cdf0e10cSrcweir } 525*cdf0e10cSrcweir } 526*cdf0e10cSrcweir else 527*cdf0e10cSrcweir { 528*cdf0e10cSrcweir m_bIsDateAxis = false; 529*cdf0e10cSrcweir } 530*cdf0e10cSrcweir } 531*cdf0e10cSrcweir else 532*cdf0e10cSrcweir m_bIsDateAxis=false; 533*cdf0e10cSrcweir m_bDirty = false; 534*cdf0e10cSrcweir } 535*cdf0e10cSrcweir } 536*cdf0e10cSrcweir 537*cdf0e10cSrcweir 538*cdf0e10cSrcweir Sequence< ::rtl::OUString > ExplicitCategoriesProvider::getSimpleCategories() 539*cdf0e10cSrcweir { 540*cdf0e10cSrcweir if( !m_bIsExplicitCategoriesInited ) 541*cdf0e10cSrcweir { 542*cdf0e10cSrcweir init(); 543*cdf0e10cSrcweir m_aExplicitCategories.realloc(0); 544*cdf0e10cSrcweir if( m_xOriginalCategories.is() ) 545*cdf0e10cSrcweir { 546*cdf0e10cSrcweir if( !hasComplexCategories() ) 547*cdf0e10cSrcweir { 548*cdf0e10cSrcweir uno::Reference< data::XDataSequence > xDataSequence( m_xOriginalCategories->getValues() ); 549*cdf0e10cSrcweir if( xDataSequence.is() ) 550*cdf0e10cSrcweir ExplicitCategoriesProvider::convertCategoryAnysToText( m_aExplicitCategories, xDataSequence->getData(), m_xChartModel ); 551*cdf0e10cSrcweir } 552*cdf0e10cSrcweir else 553*cdf0e10cSrcweir { 554*cdf0e10cSrcweir m_aExplicitCategories = lcl_getExplicitSimpleCategories( 555*cdf0e10cSrcweir SplitCategoriesProvider_ForLabeledDataSequences( m_aSplitCategoriesList, m_xChartModel ), m_aComplexCats ); 556*cdf0e10cSrcweir } 557*cdf0e10cSrcweir } 558*cdf0e10cSrcweir if(!m_aExplicitCategories.getLength()) 559*cdf0e10cSrcweir m_aExplicitCategories = DiagramHelper::generateAutomaticCategoriesFromCooSys( m_xCooSysModel ); 560*cdf0e10cSrcweir m_bIsExplicitCategoriesInited = true; 561*cdf0e10cSrcweir } 562*cdf0e10cSrcweir return m_aExplicitCategories; 563*cdf0e10cSrcweir } 564*cdf0e10cSrcweir 565*cdf0e10cSrcweir std::vector< ComplexCategory > ExplicitCategoriesProvider::getCategoriesByLevel( sal_Int32 nLevel ) 566*cdf0e10cSrcweir { 567*cdf0e10cSrcweir std::vector< ComplexCategory > aRet; 568*cdf0e10cSrcweir init(); 569*cdf0e10cSrcweir sal_Int32 nMaxIndex = m_aComplexCats.size()-1; 570*cdf0e10cSrcweir if( nLevel >= 0 && nLevel <= nMaxIndex ) 571*cdf0e10cSrcweir aRet = m_aComplexCats[nMaxIndex-nLevel]; 572*cdf0e10cSrcweir return aRet; 573*cdf0e10cSrcweir } 574*cdf0e10cSrcweir 575*cdf0e10cSrcweir OUString ExplicitCategoriesProvider::getCategoryByIndex( 576*cdf0e10cSrcweir const Reference< XCoordinateSystem >& xCooSysModel 577*cdf0e10cSrcweir , const uno::Reference< frame::XModel >& xChartModel 578*cdf0e10cSrcweir , sal_Int32 nIndex ) 579*cdf0e10cSrcweir { 580*cdf0e10cSrcweir if( xCooSysModel.is()) 581*cdf0e10cSrcweir { 582*cdf0e10cSrcweir ExplicitCategoriesProvider aExplicitCategoriesProvider( xCooSysModel, xChartModel ); 583*cdf0e10cSrcweir Sequence< OUString > aCategories( aExplicitCategoriesProvider.getSimpleCategories()); 584*cdf0e10cSrcweir if( nIndex < aCategories.getLength()) 585*cdf0e10cSrcweir return aCategories[ nIndex ]; 586*cdf0e10cSrcweir } 587*cdf0e10cSrcweir return OUString(); 588*cdf0e10cSrcweir } 589*cdf0e10cSrcweir 590*cdf0e10cSrcweir bool ExplicitCategoriesProvider::isDateAxis() 591*cdf0e10cSrcweir { 592*cdf0e10cSrcweir init(); 593*cdf0e10cSrcweir return m_bIsDateAxis; 594*cdf0e10cSrcweir } 595*cdf0e10cSrcweir 596*cdf0e10cSrcweir const std::vector< DatePlusIndex >& ExplicitCategoriesProvider::getDateCategories() 597*cdf0e10cSrcweir { 598*cdf0e10cSrcweir init(); 599*cdf0e10cSrcweir return m_aDateCategories; 600*cdf0e10cSrcweir } 601*cdf0e10cSrcweir 602*cdf0e10cSrcweir //............................................................................. 603*cdf0e10cSrcweir } //namespace chart 604*cdf0e10cSrcweir //............................................................................. 605