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 "BubbleDataInterpreter.hxx"
21 #include "DataSeries.hxx"
23 #include "DataSeriesHelper.hxx"
24 #include "CommonConverters.hxx"
25 #include "ContainerHelper.hxx"
26 #include <com/sun/star/beans/XPropertySet.hpp>
27 #include <com/sun/star/chart2/data/XDataSink.hpp>
28 #include <com/sun/star/util/XCloneable.hpp>
30 using namespace ::com::sun::star
;
31 using namespace ::com::sun::star::chart2
;
32 using namespace ::std
;
34 using ::com::sun::star::uno::Reference
;
35 using ::com::sun::star::uno::Sequence
;
40 BubbleDataInterpreter::BubbleDataInterpreter(
41 const uno::Reference
< uno::XComponentContext
> & xContext
) :
42 DataInterpreter( xContext
)
46 BubbleDataInterpreter::~BubbleDataInterpreter()
50 // ____ XDataInterpreter ____
51 chart2::InterpretedData SAL_CALL
BubbleDataInterpreter::interpretDataSource(
52 const Reference
< chart2::data::XDataSource
>& xSource
,
53 const Sequence
< beans::PropertyValue
>& aArguments
,
54 const Sequence
< Reference
< XDataSeries
> >& aSeriesToReUse
)
55 throw (uno::RuntimeException
, std::exception
)
58 return InterpretedData();
60 Sequence
< Reference
< data::XLabeledDataSequence
> > aData( xSource
->getDataSequences() );
62 Reference
< data::XLabeledDataSequence
> xValuesX
;
63 vector
< Reference
< data::XLabeledDataSequence
> > aYValuesVector
;
64 vector
< Reference
< data::XLabeledDataSequence
> > aSizeValuesVector
;
66 Reference
< data::XLabeledDataSequence
> xCategories
;
67 bool bHasCategories
= HasCategories( aArguments
, aData
);
68 bool bUseCategoriesAsX
= UseCategoriesAsX( aArguments
);
70 sal_Int32 nDataSeqCount
= aData
.getLength();
72 bool bSetXValues
= bHasCategories
? ( (nDataSeqCount
-1) > 2 && (nDataSeqCount
-1) % 2 != 0 )
73 :( nDataSeqCount
> 2 && nDataSeqCount
% 2 != 0 );
75 bool bCategoriesUsed
= false;
76 bool bNextIsYValues
= bHasCategories
? nDataSeqCount
>2 : nDataSeqCount
>1;
77 for( sal_Int32 nDataIdx
= 0; nDataIdx
< nDataSeqCount
; ++nDataIdx
)
81 if( bHasCategories
&& !bCategoriesUsed
)
83 xCategories
.set( aData
[nDataIdx
] );
86 SetRole( xCategories
->getValues(), "categories");
87 if( bUseCategoriesAsX
)
90 bNextIsYValues
= nDataSeqCount
> 2;
93 bCategoriesUsed
= true;
95 else if( !xValuesX
.is() && bSetXValues
)
97 xValuesX
.set( aData
[nDataIdx
] );
99 SetRole( xValuesX
->getValues(), "values-x");
101 else if( bNextIsYValues
)
103 aYValuesVector
.push_back( aData
[nDataIdx
] );
104 if( aData
[nDataIdx
].is())
105 SetRole( aData
[nDataIdx
]->getValues(), "values-y");
106 bNextIsYValues
= false;
108 else if( !bNextIsYValues
)
110 aSizeValuesVector
.push_back( aData
[nDataIdx
] );
111 if( aData
[nDataIdx
].is())
112 SetRole( aData
[nDataIdx
]->getValues(), "values-size");
113 bNextIsYValues
= (nDataSeqCount
-(nDataIdx
+1)) >= 2;//two or more left
116 catch( const uno::Exception
& ex
)
118 ASSERT_EXCEPTION( ex
);
123 sal_Int32 nSeriesIndex
= 0;
124 vector
< Reference
< XDataSeries
> > aSeriesVec
;
125 aSeriesVec
.reserve( aSizeValuesVector
.size());
127 Reference
< data::XLabeledDataSequence
> xClonedXValues
= xValuesX
;
128 Reference
< util::XCloneable
> xCloneableX( xValuesX
, uno::UNO_QUERY
);
130 for( size_t nN
= 0; nN
< aSizeValuesVector
.size(); ++nN
, ++nSeriesIndex
)
132 vector
< Reference
< data::XLabeledDataSequence
> > aNewData
;
135 if( nN
> 0 && xCloneableX
.is() )
136 xClonedXValues
.set( xCloneableX
->createClone(), uno::UNO_QUERY
);
137 aNewData
.push_back( xClonedXValues
);
139 if( aYValuesVector
.size() > nN
)
140 aNewData
.push_back( aYValuesVector
[nN
] );
141 if( aSizeValuesVector
.size() > nN
)
142 aNewData
.push_back( aSizeValuesVector
[nN
] );
144 Reference
< XDataSeries
> xSeries
;
145 if( nSeriesIndex
< aSeriesToReUse
.getLength())
146 xSeries
.set( aSeriesToReUse
[nSeriesIndex
] );
148 xSeries
.set( new DataSeries( GetComponentContext() ) );
149 OSL_ASSERT( xSeries
.is() );
150 Reference
< data::XDataSink
> xSink( xSeries
, uno::UNO_QUERY
);
151 OSL_ASSERT( xSink
.is() );
152 xSink
->setData( ContainerHelper::ContainerToSequence( aNewData
) );
154 aSeriesVec
.push_back( xSeries
);
157 Sequence
< Sequence
< Reference
< XDataSeries
> > > aSeries(1);
158 aSeries
[0] = ContainerHelper::ContainerToSequence( aSeriesVec
);
159 return InterpretedData( aSeries
, xCategories
);
162 chart2::InterpretedData SAL_CALL
BubbleDataInterpreter::reinterpretDataSeries(
163 const chart2::InterpretedData
& aInterpretedData
)
164 throw (uno::RuntimeException
, std::exception
)
166 InterpretedData
aResult( aInterpretedData
);
169 Sequence
< Reference
< XDataSeries
> > aSeries( FlattenSequence( aInterpretedData
.Series
));
170 const sal_Int32 nCount
= aSeries
.getLength();
171 for( ; i
<nCount
; ++i
)
175 Reference
< data::XDataSource
> xSeriesSource( aSeries
[i
], uno::UNO_QUERY_THROW
);
176 Sequence
< Reference
< data::XLabeledDataSequence
> > aNewSequences
;
178 Reference
< data::XLabeledDataSequence
> xValuesSize(
179 DataSeriesHelper::getDataSequenceByRole( xSeriesSource
, "values-size", false ));
180 Reference
< data::XLabeledDataSequence
> xValuesY(
181 DataSeriesHelper::getDataSequenceByRole( xSeriesSource
, "values-y", false ));
182 Reference
< data::XLabeledDataSequence
> xValuesX(
183 DataSeriesHelper::getDataSequenceByRole( xSeriesSource
, "values-x", false ));
185 if( ! xValuesX
.is() ||
189 vector
< Reference
< data::XLabeledDataSequence
> > aValueSeqVec(
190 DataSeriesHelper::getAllDataSequencesByRole(
191 xSeriesSource
->getDataSequences(), "values", true ));
193 aValueSeqVec
.erase( find( aValueSeqVec
.begin(), aValueSeqVec
.end(), xValuesX
));
195 aValueSeqVec
.erase( find( aValueSeqVec
.begin(), aValueSeqVec
.end(), xValuesY
));
196 if( xValuesSize
.is())
197 aValueSeqVec
.erase( find( aValueSeqVec
.begin(), aValueSeqVec
.end(), xValuesSize
));
201 if( ! xValuesSize
.is() &&
202 aValueSeqVec
.size() > nIndex
)
204 xValuesSize
.set( aValueSeqVec
[nIndex
++] );
205 if( xValuesSize
.is())
206 SetRole( xValuesSize
->getValues(), "values-size");
209 if( ! xValuesY
.is() &&
210 aValueSeqVec
.size() > nIndex
)
212 xValuesY
.set( aValueSeqVec
[nIndex
++] );
214 SetRole( xValuesY
->getValues(), "values-y");
217 if( ! xValuesX
.is() &&
218 aValueSeqVec
.size() > nIndex
)
220 xValuesX
.set( aValueSeqVec
[nIndex
++] );
222 SetRole( xValuesY
->getValues(), "values-x");
225 if( xValuesSize
.is())
231 aNewSequences
.realloc(3);
232 aNewSequences
[0] = xValuesX
;
233 aNewSequences
[1] = xValuesY
;
234 aNewSequences
[2] = xValuesSize
;
238 aNewSequences
.realloc(2);
239 aNewSequences
[0] = xValuesY
;
240 aNewSequences
[1] = xValuesSize
;
245 aNewSequences
.realloc(1);
246 aNewSequences
[0] = xValuesSize
;
250 Sequence
< Reference
< data::XLabeledDataSequence
> > aSeqs( xSeriesSource
->getDataSequences());
251 if( aSeqs
.getLength() != aNewSequences
.getLength() )
253 #if OSL_DEBUG_LEVEL > 1
255 for( ; j
<aSeqs
.getLength(); ++j
)
257 OSL_ENSURE( aSeqs
[j
] == xValuesY
|| aSeqs
[j
] == xValuesX
|| aSeqs
[j
] == xValuesSize
, "All sequences should be used" );
260 Reference
< data::XDataSink
> xSink( xSeriesSource
, uno::UNO_QUERY_THROW
);
261 xSink
->setData( aNewSequences
);
264 catch( const uno::Exception
& ex
)
266 ASSERT_EXCEPTION( ex
);
273 sal_Bool SAL_CALL
BubbleDataInterpreter::isDataCompatible(
274 const chart2::InterpretedData
& aInterpretedData
)
275 throw (uno::RuntimeException
, std::exception
)
277 Sequence
< Reference
< XDataSeries
> > aSeries( FlattenSequence( aInterpretedData
.Series
));
278 for( sal_Int32 i
=0; i
<aSeries
.getLength(); ++i
)
282 Reference
< data::XDataSource
> xSrc( aSeries
[i
], uno::UNO_QUERY_THROW
);
283 Sequence
< Reference
< data::XLabeledDataSequence
> > aSeq( xSrc
->getDataSequences());
284 if( aSeq
.getLength() != 3 )
287 catch( const uno::Exception
& ex
)
289 ASSERT_EXCEPTION( ex
);
298 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */