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