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 "XYDataInterpreter.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 XYDataInterpreter::XYDataInterpreter(
41 const uno::Reference
< uno::XComponentContext
> & xContext
) :
42 DataInterpreter( xContext
)
46 XYDataInterpreter::~XYDataInterpreter()
50 // ____ XDataInterpreter ____
51 chart2::InterpretedData SAL_CALL
XYDataInterpreter::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
> > aSequencesVec
;
65 Reference
< data::XLabeledDataSequence
> xCategories
;
66 bool bHasCategories
= HasCategories( aArguments
, aData
);
67 bool bUseCategoriesAsX
= UseCategoriesAsX( aArguments
);
70 bool bCategoriesUsed
= false;
71 bool bSetXValues
= aData
.getLength()>1;
72 for( sal_Int32 nDataIdx
= 0; nDataIdx
< aData
.getLength(); ++nDataIdx
)
76 if( bHasCategories
&& ! bCategoriesUsed
)
78 xCategories
.set( aData
[nDataIdx
] );
81 SetRole( xCategories
->getValues(), "categories");
82 if( bUseCategoriesAsX
)
85 bCategoriesUsed
= true;
87 else if( !xValuesX
.is() && bSetXValues
)
89 xValuesX
.set( aData
[nDataIdx
] );
91 SetRole( xValuesX
->getValues(), "values-x");
95 aSequencesVec
.push_back( aData
[nDataIdx
] );
96 if( aData
[nDataIdx
].is())
97 SetRole( aData
[nDataIdx
]->getValues(), "values-y");
100 catch( const uno::Exception
& ex
)
102 ASSERT_EXCEPTION( ex
);
107 vector
< Reference
< data::XLabeledDataSequence
> >::const_iterator
108 aSequencesVecIt
= aSequencesVec
.begin();
110 sal_Int32 nSeriesIndex
= 0;
111 vector
< Reference
< XDataSeries
> > aSeriesVec
;
112 aSeriesVec
.reserve( aSequencesVec
.size());
114 Reference
< data::XLabeledDataSequence
> xClonedXValues
= xValuesX
;
115 Reference
< util::XCloneable
> xCloneable( xValuesX
, uno::UNO_QUERY
);
117 for( ;aSequencesVecIt
!= aSequencesVec
.end(); ++aSequencesVecIt
, ++nSeriesIndex
)
119 vector
< Reference
< data::XLabeledDataSequence
> > aNewData
;
121 if( aSequencesVecIt
!= aSequencesVec
.begin() && xCloneable
.is() )
122 xClonedXValues
.set( xCloneable
->createClone(), uno::UNO_QUERY
);
124 aNewData
.push_back( xClonedXValues
);
126 aNewData
.push_back( *aSequencesVecIt
);
128 Reference
< XDataSeries
> xSeries
;
129 if( nSeriesIndex
< aSeriesToReUse
.getLength())
130 xSeries
.set( aSeriesToReUse
[nSeriesIndex
] );
132 xSeries
.set( new DataSeries( GetComponentContext() ) );
133 OSL_ASSERT( xSeries
.is() );
134 Reference
< data::XDataSink
> xSink( xSeries
, uno::UNO_QUERY
);
135 OSL_ASSERT( xSink
.is() );
136 xSink
->setData( ContainerHelper::ContainerToSequence( aNewData
) );
138 aSeriesVec
.push_back( xSeries
);
141 Sequence
< Sequence
< Reference
< XDataSeries
> > > aSeries(1);
142 aSeries
[0] = ContainerHelper::ContainerToSequence( aSeriesVec
);
143 return InterpretedData( aSeries
, xCategories
);
146 chart2::InterpretedData SAL_CALL
XYDataInterpreter::reinterpretDataSeries(
147 const chart2::InterpretedData
& aInterpretedData
)
148 throw (uno::RuntimeException
, std::exception
)
150 InterpretedData
aResult( aInterpretedData
);
153 Sequence
< Reference
< XDataSeries
> > aSeries( FlattenSequence( aInterpretedData
.Series
));
154 const sal_Int32 nCount
= aSeries
.getLength();
155 for( ; i
<nCount
; ++i
)
159 Reference
< data::XDataSource
> xSeriesSource( aSeries
[i
], uno::UNO_QUERY_THROW
);
160 Sequence
< Reference
< data::XLabeledDataSequence
> > aNewSequences
;
163 Reference
< data::XLabeledDataSequence
> xValuesY(
164 DataSeriesHelper::getDataSequenceByRole( xSeriesSource
, "values-y", false ));
165 Reference
< data::XLabeledDataSequence
> xValuesX(
166 DataSeriesHelper::getDataSequenceByRole( xSeriesSource
, "values-x", false ));
167 // re-use values-... as values-x/values-y
168 if( ! xValuesX
.is() ||
171 vector
< Reference
< data::XLabeledDataSequence
> > aValueSeqVec(
172 DataSeriesHelper::getAllDataSequencesByRole(
173 xSeriesSource
->getDataSequences(), "values", true ));
175 aValueSeqVec
.erase( find( aValueSeqVec
.begin(), aValueSeqVec
.end(), xValuesX
));
177 aValueSeqVec
.erase( find( aValueSeqVec
.begin(), aValueSeqVec
.end(), xValuesY
));
180 if( ! xValuesY
.is() &&
181 aValueSeqVec
.size() > nIndex
)
183 xValuesY
.set( aValueSeqVec
[nIndex
++] );
185 SetRole( xValuesY
->getValues(), "values-y");
188 if( ! xValuesX
.is() &&
189 aValueSeqVec
.size() > nIndex
)
191 xValuesX
.set( aValueSeqVec
[nIndex
++] );
193 SetRole( xValuesY
->getValues(), "values-x");
200 aNewSequences
.realloc(2);
201 aNewSequences
[0] = xValuesX
;
202 aNewSequences
[1] = xValuesY
;
206 aNewSequences
.realloc(1);
207 aNewSequences
[0] = xValuesY
;
211 Sequence
< Reference
< data::XLabeledDataSequence
> > aSeqs( xSeriesSource
->getDataSequences());
212 if( aSeqs
.getLength() != aNewSequences
.getLength() )
214 #if OSL_DEBUG_LEVEL > 1
216 for( ; j
<aSeqs
.getLength(); ++j
)
218 OSL_ENSURE( aSeqs
[j
] == xValuesY
|| aSeqs
[j
] == xValuesX
, "All sequences should be used" );
221 Reference
< data::XDataSink
> xSink( xSeriesSource
, uno::UNO_QUERY_THROW
);
222 xSink
->setData( aNewSequences
);
225 catch( const uno::Exception
& ex
)
227 ASSERT_EXCEPTION( ex
);
234 // criterion: all series must have exactly two data::XLabeledDataSequences
235 sal_Bool SAL_CALL
XYDataInterpreter::isDataCompatible(
236 const chart2::InterpretedData
& aInterpretedData
)
237 throw (uno::RuntimeException
, std::exception
)
239 Sequence
< Reference
< XDataSeries
> > aSeries( FlattenSequence( aInterpretedData
.Series
));
240 for( sal_Int32 i
=0; i
<aSeries
.getLength(); ++i
)
244 Reference
< data::XDataSource
> xSrc( aSeries
[i
], uno::UNO_QUERY_THROW
);
245 Sequence
< Reference
< data::XLabeledDataSequence
> > aSeq( xSrc
->getDataSequences());
246 if( aSeq
.getLength() != 2 )
249 catch( const uno::Exception
& ex
)
251 ASSERT_EXCEPTION( ex
);
260 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */